Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add methods to hide filled and expired posts #2449

Draft
wants to merge 20 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5afad7d
Add methods to hide filled and expired posts
anaemnesis Jun 6, 2023
7a924f6
Remove unused method
anaemnesis Jun 7, 2023
41f374d
Hide expired and filled jobs
anaemnesis Jun 13, 2023
2fccb36
Remove an 's' from 'jobs' in method name
anaemnesis Jun 13, 2023
eeb42e0
Update maybe_hide_filled_expired_job_listings_from_search logic
anaemnesis Jun 13, 2023
068a162
Account for 'trash' post status
anaemnesis Jun 13, 2023
d1d04d4
Add additional query checks
anaemnesis Jun 21, 2023
cd94313
Remove post_type check, as search page is querying "any"
anaemnesis Jun 21, 2023
3fedb2b
Refactor hide/filled
anaemnesis Jun 21, 2023
fc8e201
Explicitly query 'publish' post status
anaemnesis Jun 21, 2023
2522485
Refactor how $expired posts are hidden from search
anaemnesis Jun 22, 2023
27685ac
Nonce verification for $_GET['s'] isn't necessary here, so let's try …
anaemnesis Jun 22, 2023
d3b5123
Update issue reference
anaemnesis Jun 23, 2023
d23b3a3
Rename $is_expired_hidden variable to be more readable
anaemnesis Jun 28, 2023
ea63e66
Update PHP doc for the get_filled_job_listings() method to state the …
anaemnesis Jun 28, 2023
3a210fb
Early return on get_filled_job_listings() method isn't necessary, as …
anaemnesis Jun 28, 2023
1a7b7da
Revert how expired posts are hidden to previous implementation
anaemnesis Jul 2, 2023
de746c4
Delete 'hide_filled_jobs_transient' on 'updated_post_meta' action.
anaemnesis Jul 2, 2023
82e75e6
Refactor maybe_hide_expired_posts()
anaemnesis Jul 4, 2023
27b3be7
Add comments explaining conditional logic in the maybe_hide_* methods.
anaemnesis Jul 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 88 additions & 35 deletions includes/class-wp-job-manager-post-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ public function __construct() {
add_filter( 'wp_insert_post_data', [ $this, 'fix_post_name' ], 10, 2 );
add_action( 'add_post_meta', [ $this, 'maybe_add_geolocation_data' ], 10, 3 );
add_action( 'update_post_meta', [ $this, 'update_post_meta' ], 10, 4 );
add_action( 'updated_post_meta', [ $this, 'delete_filled_job_listing_transient' ], 10, 4 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this should be update_post_meta and not updated ? I couldn't find the updated_post_meta hook.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add_action( 'wp_insert_post', [ $this, 'maybe_add_default_meta_data' ], 10, 2 );
add_filter( 'post_types_to_delete_with_user', [ $this, 'delete_user_add_job_listings_post_type' ] );

add_action( 'transition_post_status', [ $this, 'track_job_submission' ], 10, 3 );

add_action( 'parse_query', [ $this, 'add_feed_query_args' ] );
add_action( 'pre_get_posts', [ $this, 'maybe_hide_filled_expired_job_listings_from_search' ] );
add_action( 'pre_get_posts', [ $this, 'maybe_hide_filled_job_listings' ] );
add_action( 'pre_get_posts', [ $this, 'maybe_hide_expired_job_listings' ] );

// Single job content.
$this->job_content_filter( true );
Expand Down Expand Up @@ -661,22 +663,21 @@ public function job_feed() {
}

/**
* Get filled jobs.
* Retrieve and return the post IDs of any job listings marked as filled.
*
* @return array
* @return array Array of filled job listing post IDs.
*/
public function get_filled_job_listings(): array {
if ( ! get_option( 'job_manager_hide_filled_positions' ) ) {
return [];
}

$filled_jobs_transient = get_transient( 'hide_filled_jobs_transient' );
if ( false === $filled_jobs_transient ) {
$filled_jobs_transient = get_posts(
[
'post_type' => 'job_listing',
'fields' => 'ids',
'meta_query' => [
'post_status' => 'publish',
'post_type' => 'job_listing',
yscik marked this conversation as resolved.
Show resolved Hide resolved
'fields' => 'ids',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_filled',
'value' => '1',
Expand All @@ -691,49 +692,83 @@ public function get_filled_job_listings(): array {
}

/**
* Get expired jobs.
* Maybe exclude filled job listings from search and archive pages.
*
* @return array
* @param $query WP_Query $query
*
* @return void
*/
public function get_expired_job_listings(): array {
if ( ! get_option( 'job_manager_hide_expired' ) ) {
return [];
public function maybe_hide_filled_job_listings( WP_Query $query ): void {
$hide_filled_positions = get_option( 'job_manager_hide_filled_positions' );

if ( ! $hide_filled_positions ) {
return;
}

$expired_jobs_transient = get_transient( 'hide_expired_jobs_transient' );
if ( false === $expired_jobs_transient ) {
$expired_jobs_transient = get_posts(
[
'post_type' => 'job_listing',
'post_status' => 'expired',
'fields' => 'ids',
]
);
set_transient( 'hide_expired_jobs_transient', $expired_jobs_transient, DAY_IN_SECONDS );
if (
! is_admin()
&& $query->is_main_query()
&& ( $query->is_search() || $query->is_archive() )
Comment on lines +721 to +723
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to add a comment here clarifying the reason for this logic: We want the filtering to apply only to search and archive public facing queries. We don't want it to apply in the admin panel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Committed 27b3be7

) {

$query->set( 'post__not_in', $this->get_filled_job_listings() );
}
return $expired_jobs_transient;
}

/**
* Maybe exclude expired and/or filled job listings from search.
* Maybe exclude expired job listings from search and archive pages.
*
* @param $query WP_Query $query
*
* @return void
*/
public function maybe_hide_filled_expired_job_listings_from_search( WP_Query $query ): void {
$hide_filled_positions = get_option( 'job_manager_hide_filled_positions' );
$hide_expired = get_option( 'job_manager_hide_expired' );
public function maybe_hide_expired_job_listings( WP_Query $query ): void {
$hide_expired = get_option( 'job_manager_hide_expired' );

if ( ! $hide_filled_positions && ! $hide_expired ) {
if ( ! $hide_expired ) {
return;
}

if ( ! is_admin() && $query->is_search() ) {
$jobs_to_exclude = array_merge( $this->get_filled_job_listings(), $this->get_expired_job_listings() );
if ( ! empty( $jobs_to_exclude ) ) {
$query->set( 'post__not_in', $jobs_to_exclude );
}
if (
! is_admin()
&& $query->is_main_query()
&& ( $query->is_search() || $query->is_archive() )
) {
Comment on lines +750 to +753
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here about the comment explaining the logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Committed 27b3be7


$this->make_expired_private();

add_action( 'posts_selection', [ $this, 'make_expired_public' ] );
}
}

/**
* Make the expired post status public.
*
* @return void
* @internal
*/
public function make_expired_public(): void {

global $wp_post_statuses;

if ( isset( $wp_post_statuses['expired'] ) ) {
$wp_post_statuses['expired']->public = true;
}

}
Comment on lines +767 to +775
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn´t find any information about this global. Can you make a brief summary on what is it and what is this supposed to do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jom and I discussed this global in a call. AFAIK it's first mentioned here in post.php:

https://github.com/WordPress/wordpress-develop/blob/bea4307daa21a3f97d159898b0ac676332e0e7de/src/wp-includes/post.php#L1287-L1292

function register_post_status( $post_status, $args = array() ) {
	global $wp_post_statuses;

	if ( ! is_array( $wp_post_statuses ) ) {
		$wp_post_statuses = array();
	}

It is an array of all post statuses. What we're doing here is checking that the expired post status is registered, and if it is, we either set its public argument to true or false via the maybe_hide_expired_job_listings() method.

From there, if $hide_expired is true, $this->make_expired_private(); sets the public argument to false during query generation, after which it sets it back to true with add_action:

if (
! is_admin()
&& $query->is_main_query()
&& ( $query->is_search() || $query->is_archive() )
) {
$this->make_expired_private();
add_action( 'posts_selection', [ $this, 'make_expired_public' ] );
}


/**
* Make the expired post status private.
*
* @return void
* @internal
*/
public function make_expired_private() {

global $wp_post_statuses;

if ( isset( $wp_post_statuses['expired'] ) ) {
$wp_post_statuses['expired']->public = false;
}
}

Expand Down Expand Up @@ -1977,4 +2012,22 @@ public function delete_user_add_job_listings_post_type( $types ) {
return $types;
}

/**
* Delete the 'job_manager_hide_filled_jobs' transient when meta is updated.
*
* @param int $meta_id ID of updated metadata entry.
* @param int $object_id ID of the object metadata is for.
* @param string $meta_key Metadata key.
* @param mixed $_meta_value Metadata value. This will be a PHP-serialized string representation of the value if the value is an array, an object, or itself a PHP-serialized string.
*
* @return void
*/
public function delete_filled_job_listing_transient( $meta_id, $object_id, $meta_key, $_meta_value ) {

if ( '_edit_lock' !== $meta_key || 'job_listing' !== get_post_type( $object_id ) ) {
return;
}

delete_transient( 'hide_filled_jobs_transient' );
}
}
23 changes: 0 additions & 23 deletions wp-job-manager-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1712,26 +1712,3 @@ function job_manager_get_salary_unit_options( $include_empty = true ) {
*/
return apply_filters( 'job_manager_get_salary_unit_options', $options, $include_empty );
}

/**
* Delete filled_jobs_transient and expired_jobs_transient transients when a job listing is saved or updated.
*
* @param int $post_id The ID of the post being saved.
* @param WP_Post $post The post object being saved.
*/
function delete_job_listings_transients_on_save( int $post_id, WP_Post $post ): void {

if ( 'job_listing' === $post->post_type ) {

if ( '1' === get_post_meta( $post_id, '_filled', true ) ) {
delete_transient( 'hide_filled_jobs_transient' );
}

$post_status = [ 'publish', 'expired', 'trash' ];
if ( in_array( $post->post_status, $post_status, true ) ) {
delete_transient( 'hide_expired_jobs_transient' );
}
}

}
add_action( 'save_post', 'delete_job_listings_transients_on_save', 10, 2 );