PluginProbe ʕ •ᴥ•ʔ
WP Job Manager / 2.4.7
WP Job Manager v2.4.7
2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.10.0 1.11.0 1.11.1 1.12.0 1.12.1 1.13.0 1.14.0 1.15.0 1.16.0 1.16.1 1.17.0 1.18.0 1.19.0 1.2.0 1.20.0 1.20.1 1.21.0 1.21.1 1.21.2 1.21.3 1.21.4 1.22.0 1.22.1 1.22.2 1.22.3 1.23.0 1.23.1 1.23.10 1.23.11 1.23.12 1.23.13 1.23.2 1.23.3 1.23.4 1.23.5 1.23.6 1.23.7 1.23.8 1.23.9 1.24.0 1.24.0.1 1.25.0 1.25.0.1 1.25.1 1.25.1.1 1.25.2 1.25.2.1 1.25.3 1.25.3.1 1.26.0 1.26.0.1 1.26.1 1.26.1.1 1.26.2 1.26.2.1 1.27.0 1.27.0.1 1.28.0 1.28.0.1 1.29.0 1.29.0.1 1.29.1 1.29.1.1 1.29.2 1.29.2.1 1.29.3 1.29.3.1 1.3.0 1.3.1 1.30.0 1.30.0.1 1.30.1 1.30.1.1 1.30.2 1.30.2.1 1.31.0 1.31.0.1 1.31.1 1.31.1.1 1.31.2 1.31.3 1.32.0 1.32.1 1.32.2 1.32.3 1.33.0 1.33.1 1.33.2 1.33.3 1.33.4 1.33.5 1.34.0 1.34.1 1.34.2 1.34.3 1.34.4 1.34.5 1.35.0 1.35.1 1.35.2 1.35.3 1.36.0 1.36.1 1.36.2 1.37.0 1.38.0 1.38.1 1.39.0 1.4.0 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.5.0 1.5.1 1.5.2 1.6.0 1.7.0 1.7.1 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 1.9.1 1.9.2 1.9.3 2.0.0 2.1.0 2.1.1 2.2.0 2.2.1 2.2.2 2.3.0 2.4.0 2.4.1
wp-job-manager / includes / class-wp-job-manager-cache-helper.php
wp-job-manager / includes Last commit date
3rd-party 4 days ago abstracts 3 months ago admin 2 weeks ago emails 2 weeks ago forms 4 days ago helper 3 months ago promoted-jobs 4 days ago ui 2 weeks ago widgets 2 weeks ago class-access-token.php 2 years ago class-dev-tools.php 2 years ago class-guest-session.php 2 years ago class-guest-user.php 2 years ago class-job-dashboard-shortcode.php 6 months ago class-job-listing-stats.php 2 years ago class-job-overlay.php 2 years ago class-stats-dashboard.php 2 years ago class-stats-script.php 3 months ago class-stats.php 3 months ago class-wp-job-manager-ajax.php 2 months ago class-wp-job-manager-api.php 6 years ago class-wp-job-manager-blocks.php 2 weeks ago class-wp-job-manager-cache-helper.php 3 months ago class-wp-job-manager-category-walker.php 6 years ago class-wp-job-manager-com-api.php 2 years ago class-wp-job-manager-data-cleaner.php 2 years ago class-wp-job-manager-data-exporter.php 3 months ago class-wp-job-manager-dependency-checker.php 2 years ago class-wp-job-manager-email-notifications.php 2 years ago class-wp-job-manager-forms.php 5 years ago class-wp-job-manager-geocode.php 2 weeks ago class-wp-job-manager-install.php 2 years ago class-wp-job-manager-post-types.php 4 days ago class-wp-job-manager-recaptcha.php 6 months ago class-wp-job-manager-rest-api.php 2 months ago class-wp-job-manager-shortcodes.php 2 weeks ago class-wp-job-manager-usage-tracking-data.php 2 years ago class-wp-job-manager-usage-tracking.php 2 years ago class-wp-job-manager-widget.php 2 weeks ago class-wp-job-manager.php 3 months ago trait-singleton.php 2 years ago
class-wp-job-manager-cache-helper.php
270 lines
1 <?php
2 /**
3 * File containing the class WP_Job_Manager_Cache_Helper.
4 *
5 * @package wp-job-manager
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Assists in cache management for WP Job Management posts and terms.
14 *
15 * @package wp-job-manager
16 * @since 1.0.0
17 */
18 class WP_Job_Manager_Cache_Helper {
19
20 /**
21 * Initializes cache hooks.
22 */
23 public static function init() {
24 add_action( 'save_post', [ __CLASS__, 'flush_get_job_listings_cache' ] );
25 add_action( 'update_post_meta', [ __CLASS__, 'maybe_flush_get_job_listings_cache_on_meta_update' ], 10, 2 );
26 add_action( 'delete_post', [ __CLASS__, 'flush_get_job_listings_cache' ] );
27 add_action( 'trash_post', [ __CLASS__, 'flush_get_job_listings_cache' ] );
28 add_action( 'job_manager_my_job_do_action', [ __CLASS__, 'job_manager_my_job_do_action' ] );
29 add_action( 'set_object_terms', [ __CLASS__, 'set_term' ], 10, 4 );
30 add_action( 'edited_term', [ __CLASS__, 'edited_term' ], 10, 3 );
31 add_action( 'create_term', [ __CLASS__, 'edited_term' ], 10, 3 );
32 add_action( 'delete_term', [ __CLASS__, 'edited_term' ], 10, 3 );
33 add_action( 'transition_post_status', [ __CLASS__, 'maybe_clear_count_transients' ], 10, 3 );
34
35 // Bump the listings cache when capability gates change so cached results don't outlive the policy that produced them.
36 foreach ( [ 'job_manager_browse_job_listings_capability', 'job_manager_view_job_listing_capability' ] as $option ) {
37 add_action( "add_option_{$option}", [ __CLASS__, 'flush_get_job_listings_transient_version' ] );
38 add_action( "update_option_{$option}", [ __CLASS__, 'flush_get_job_listings_transient_version' ] );
39 add_action( "delete_option_{$option}", [ __CLASS__, 'flush_get_job_listings_transient_version' ] );
40 }
41 }
42
43 /**
44 * Bumps the get_job_listings transient version unconditionally.
45 */
46 public static function flush_get_job_listings_transient_version() {
47 self::get_transient_version( 'get_job_listings', true );
48 }
49
50 /**
51 * Flushes the cache.
52 *
53 * @param int|WP_Post $post_id
54 */
55 public static function flush_get_job_listings_cache( $post_id ) {
56 if ( \WP_Job_Manager_Post_Types::PT_LISTING === get_post_type( $post_id ) ) {
57 self::get_transient_version( 'get_job_listings', true );
58 }
59 }
60
61 /**
62 * Flush the cache on updates to job listing meta.
63 *
64 * @param int $meta_id
65 * @param int $post_id
66 */
67 public static function maybe_flush_get_job_listings_cache_on_meta_update( $meta_id, $post_id ) {
68 self::flush_get_job_listings_cache( $post_id );
69 }
70
71 /**
72 * Refreshes the Job Listing cache when performing actions on it.
73 *
74 * @param string $action
75 */
76 public static function job_manager_my_job_do_action( $action ) {
77 if ( 'mark_filled' === $action || 'mark_not_filled' === $action ) {
78 self::get_transient_version( 'get_job_listings', true );
79 }
80 }
81
82 /**
83 * Refreshes the Job Listing cache when terms are updated.
84 *
85 * @param string|int $object_id
86 * @param string $terms
87 * @param string $tt_ids
88 * @param string $taxonomy
89 */
90 public static function set_term( $object_id = '', $terms = '', $tt_ids = '', $taxonomy = '' ) {
91 self::get_transient_version( 'jm_get_' . sanitize_text_field( $taxonomy ), true );
92 }
93
94 /**
95 * Refreshes the Job Listing cache when terms are updated.
96 *
97 * @param string|int $term_id
98 * @param string|int $tt_id
99 * @param string $taxonomy
100 */
101 public static function edited_term( $term_id = '', $tt_id = '', $taxonomy = '' ) {
102 self::get_transient_version( 'jm_get_' . sanitize_text_field( $taxonomy ), true );
103 }
104
105 /**
106 * Gets transient version.
107 *
108 * When using transients with unpredictable names, e.g. those containing an md5
109 * hash in the name, we need a way to invalidate them all at once.
110 *
111 * When using default WP transients we're able to do this with a DB query to
112 * delete transients manually.
113 *
114 * With external cache however, this isn't possible. Instead, this function is used
115 * to append a unique string (based on time()) to each transient. When transients
116 * are invalidated, the transient version will increment and data will be regenerated.
117 *
118 * @param string $group Name for the group of transients we need to invalidate.
119 * @param boolean $refresh True to force a new version (Default: false).
120 * @return string Transient version based on time(), 10 digits.
121 */
122 public static function get_transient_version( $group, $refresh = false ) {
123 $transient_name = $group . '-transient-version';
124 $transient_value = get_transient( $transient_name );
125
126 if ( false === $transient_value || true === $refresh ) {
127 self::delete_version_transients( $transient_value );
128 set_transient( $transient_name, $transient_value = time() );
129 }
130 return $transient_value;
131 }
132
133 /**
134 * When the transient version increases, this is used to remove all past transients to avoid filling the DB.
135 *
136 * Note: this only works on transients appended with the transient version, and when object caching is not being used.
137 *
138 * @param string $version
139 */
140 private static function delete_version_transients( $version ) {
141 global $wpdb;
142
143 if ( ! wp_using_ext_object_cache() && ! empty( $version ) ) {
144 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Only used when object caching is disabled.
145 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s;", '\_transient\_%' . $version ) );
146 }
147 }
148
149 /**
150 * Clear expired transients.
151 *
152 * @deprecated 1.33.4 Handled by WordPress since 4.9.
153 */
154 public static function clear_expired_transients() {
155 _deprecated_function( __METHOD__, '1.33.4', 'handled by WordPress core since 4.9' );
156 }
157
158 /**
159 * Maybe remove pending count transients
160 *
161 * When a supported post type status is updated, check if any cached count transients
162 * need to be removed, and remove the
163 *
164 * @since 1.27.0
165 *
166 * @param string $new_status New post status.
167 * @param string $old_status Old post status.
168 * @param WP_Post $post Post object.
169 */
170 public static function maybe_clear_count_transients( $new_status, $old_status, $post ) {
171 global $wpdb;
172
173 /**
174 * Get supported post types for count caching
175 *
176 * @since 1.27.0
177 *
178 * @param array $post_types Post types that should be cached.
179 * @param string $new_status New post status.
180 * @param string $old_status Old post status.
181 * @param WP_Post $post Post object.
182 */
183 $post_types = apply_filters( 'wpjm_count_cache_supported_post_types', [ \WP_Job_Manager_Post_Types::PT_LISTING ], $new_status, $old_status, $post );
184
185 // Only proceed when statuses do not match, and post type is supported post type.
186 if ( $new_status === $old_status || ! in_array( $post->post_type, $post_types, true ) ) {
187 return;
188 }
189
190 /**
191 * Get supported post statuses for count caching
192 *
193 * @since 1.27.0
194 *
195 * @param array $post_statuses Post statuses that should be cached.
196 * @param string $new_status New post status.
197 * @param string $old_status Old post status.
198 * @param WP_Post $post Post object.
199 */
200 $valid_statuses = apply_filters( 'wpjm_count_cache_supported_statuses', [ 'pending' ], $new_status, $old_status, $post );
201
202 $rlike = [];
203 // New status transient option name.
204 if ( in_array( $new_status, $valid_statuses, true ) ) {
205 $rlike[] = "^_transient_jm_{$new_status}_{$post->post_type}_count_user_";
206 }
207 // Old status transient option name.
208 if ( in_array( $old_status, $valid_statuses, true ) ) {
209 $rlike[] = "^_transient_jm_{$old_status}_{$post->post_type}_count_user_";
210 }
211
212 if ( empty( $rlike ) ) {
213 return;
214 }
215
216 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Fetches dynamic list of cached counts.
217 $transients = $wpdb->get_col(
218 $wpdb->prepare(
219 "SELECT option_name FROM $wpdb->options WHERE option_name RLIKE %s",
220 implode( '|', $rlike )
221 )
222 );
223
224 // For each transient...
225 foreach ( $transients as $transient ) {
226 // Strip away the WordPress prefix in order to arrive at the transient key.
227 $key = str_replace( '_transient_', '', $transient );
228 // Now that we have the key, use WordPress core to the delete the transient.
229 delete_transient( $key );
230 }
231
232 // Sometimes transients are not in the DB, so we have to do this too:.
233 wp_cache_flush();
234 }
235
236 /**
237 * Get Listings Count from Cache
238 *
239 * @since 1.27.0
240 *
241 * @param string $post_type
242 * @param string $status
243 * @param bool $force Force update cache.
244 *
245 * @return int
246 */
247 public static function get_listings_count( $post_type = \WP_Job_Manager_Post_Types::PT_LISTING, $status = 'pending', $force = false ) {
248
249 // Get user based cache transient.
250 $user_id = get_current_user_id();
251 $transient = "jm_{$status}_{$post_type}_count_user_{$user_id}";
252
253 // Set listings_count value from cache if exists, otherwise set to 0 as default.
254 $cached_count = get_transient( $transient );
255 $status_count = $cached_count ? $cached_count : 0;
256
257 // $cached_count will be false if transient does not exist.
258 if ( false === $cached_count || $force ) {
259 $count_posts = wp_count_posts( $post_type, 'readable' );
260 // Default to 0 $status if object does not have a value.
261 $status_count = isset( $count_posts->$status ) ? $count_posts->$status : 0;
262 set_transient( $transient, $status_count, DAY_IN_SECONDS * 7 );
263 }
264
265 return $status_count;
266 }
267 }
268
269 WP_Job_Manager_Cache_Helper::init();
270