PluginProbe
WebberZone Top 10 — Popular Posts / 4.4.0
WebberZone Top 10 — Popular Posts v4.4.0
4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 1.6.1 All 117 releases
top-10 / includes / util / class-cache.php

class-cache.php in WebberZone Top 10 — Popular Posts 4.4.0, at includes/util/class-cache.php

339 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Cache class.
4 *
5 * @package WebberZone\Top_Ten\Util
6 */
7
8 namespace WebberZone\Top_Ten\Util;
9
10 use WebberZone\Top_Ten\Util\Hook_Registry;
11
12 if ( ! defined( 'WPINC' ) ) {
13 die;
14 }
15
16 /**
17 * Cache class.
18 *
19 * @since 3.3.0
20 */
21 class Cache {
22
23 /**
24 * Constructor class.
25 *
26 * @since 3.3.0
27 */
28 public function __construct() {
29 Hook_Registry::add_action( 'wp_ajax_tptn_clear_cache', array( $this, 'ajax_clearcache' ) );
30 }
31
32 /**
33 * Function to clear the Top 10 Cache with Ajax.
34 *
35 * @since 2.2.0
36 */
37 public function ajax_clearcache() {
38
39 if ( ! current_user_can( 'manage_options' ) ) {
40 wp_die();
41 }
42 check_ajax_referer( 'tptn-admin', 'security' );
43
44 $count = $this->delete();
45
46 wp_send_json_success(
47 array(
48 /* translators: 1: Number of entries cleared. */
49 'message' => sprintf( _n( '%s entry cleared', '%s entries cleared', $count, 'top-10' ), number_format_i18n( $count ) ),
50 )
51 );
52 }
53
54 /**
55 * Delete the Top 10 cache.
56 *
57 * @since 2.3.0
58 *
59 * @param array $transients Array of transients to delete.
60 * @return int Number of transients deleted.
61 */
62 public static function delete( $transients = array() ) {
63 $loop = 0;
64
65 $default_transients = self::get_keys();
66
67 if ( ! empty( $transients ) ) {
68 $transients = array_intersect( $default_transients, (array) $transients );
69 } else {
70 $transients = $default_transients;
71 }
72
73 foreach ( $transients as $transient ) {
74 $del = delete_transient( $transient );
75 if ( $del ) {
76 ++$loop;
77 }
78 }
79 return $loop;
80 }
81
82 /**
83 * Get the default meta keys used for the cache
84 *
85 * @return array Transient meta keys
86 */
87 public static function get_keys() {
88
89 $meta_keys = array(
90 'tptn_total',
91 'tptn_daily',
92 'tptn_total_shortcode',
93 'tptn_daily_shortcode',
94 'tptn_total_widget',
95 'tptn_daily_widget',
96 'tptn_total_manual',
97 'tptn_daily_manual',
98 );
99
100 $meta_keys = array_merge( $meta_keys, self::get_widget_keys() );
101
102 /**
103 * Filters the array containing the various cache keys.
104 *
105 * @since 1.9
106 *
107 * @param array $default_meta_keys Array of meta keys
108 */
109 return apply_filters( 'tptn_cache_keys', $meta_keys );
110 }
111
112 /**
113 * Get the cache key based on a list of parameters.
114 *
115 * @since 4.2.0
116 *
117 * @param mixed $attr Array of attributes typically.
118 * @return string Cache meta key
119 */
120 public static function get_key( $attr ): string {
121 $args = (array) $attr;
122
123 static $setting_types = null;
124 if ( null === $setting_types ) {
125 $setting_types = function_exists( 'tptn_get_registered_settings_types' ) ? tptn_get_registered_settings_types() : array();
126 }
127
128 // Remove args that don't affect query results.
129 $exclude_keys = array(
130 'after_list',
131 'after_list_item',
132 'before_list',
133 'before_list_item',
134 'blank_output',
135 'blank_output_text',
136 'cache',
137 'className',
138 'echo',
139 'excerpt_length',
140 'extra_class',
141 'heading',
142 'is_block',
143 'is_manual',
144 'is_shortcode',
145 'is_widget',
146 'link_new_window',
147 'link_nofollow',
148 'more_link_text',
149 'no_found_rows',
150 'other_attributes',
151 'post_types',
152 'post_id',
153 'postid',
154 'same_post_type',
155 'show_author',
156 'show_credit',
157 'show_date',
158 'show_excerpt',
159 'show_metabox',
160 'show_metabox_admins',
161 'suppress_filters',
162 'title',
163 'title_length',
164 );
165
166 foreach ( $exclude_keys as $key ) {
167 unset( $args[ $key ] );
168 }
169
170 // Remove any keys ending in _header or _desc, or with type 'header'.
171 foreach ( $args as $key => $value ) {
172 if ( '_header' === substr( $key, -7 ) || '_desc' === substr( $key, -5 ) ) {
173 unset( $args[ $key ] );
174 continue;
175 }
176
177 if ( isset( $setting_types[ $key ] ) && 'header' === $setting_types[ $key ] ) {
178 unset( $args[ $key ] );
179 }
180 }
181
182 // Define categories of types for normalization.
183 $id_array_types = array( 'postids', 'numbercsv', 'taxonomies' );
184 $string_array_types = array( 'posttypes', 'csv', 'multicheck' );
185 $numeric_types = array( 'number', 'checkbox', 'select', 'radio', 'radiodesc' );
186
187 // Process arguments based on their registered types.
188 foreach ( $args as $key => $value ) {
189 $type = $setting_types[ $key ] ?? '';
190
191 if ( in_array( $type, $numeric_types, true ) && is_numeric( $value ) ) {
192 $args[ $key ] = (int) $value;
193 } elseif ( in_array( $type, $id_array_types, true ) ) {
194 $args[ $key ] = is_array( $value ) ? $value : wp_parse_id_list( $value );
195 $args[ $key ] = array_unique( array_map( 'absint', $args[ $key ] ) );
196 $args[ $key ] = array_filter( $args[ $key ] );
197 sort( $args[ $key ] );
198 if ( empty( $args[ $key ] ) ) {
199 unset( $args[ $key ] );
200 }
201 } elseif ( in_array( $type, $string_array_types, true ) ) {
202 if ( is_string( $value ) && strpos( $value, '=' ) !== false ) {
203 parse_str( $value, $parsed );
204 $value = array_keys( $parsed );
205 } elseif ( is_string( $value ) ) {
206 $value = explode( ',', $value );
207 }
208 $args[ $key ] = is_array( $value ) ? $value : array( $value );
209 $args[ $key ] = array_unique( array_map( 'strval', $args[ $key ] ) );
210 $args[ $key ] = array_filter( $args[ $key ] );
211 sort( $args[ $key ] );
212 if ( empty( $args[ $key ] ) ) {
213 unset( $args[ $key ] );
214 }
215 }
216 }
217
218 // Fallback for known keys that might not be in $setting_types or need specific handling.
219 $id_arrays = array(
220 'author__in',
221 'author__not_in',
222 'category__and',
223 'category__in',
224 'category__not_in',
225 'cornerstone_post_ids',
226 'exclude_categories',
227 'exclude_on_categories',
228 'exclude_on_post_ids',
229 'exclude_post_ids',
230 'include_cat_ids',
231 'include_post_ids',
232 'manual_related',
233 'post__in',
234 'post__not_in',
235 'post_parent__in',
236 'post_parent__not_in',
237 'tag__and',
238 'tag__in',
239 'tag__not_in',
240 'tag_slug__and',
241 'tag_slug__in',
242 );
243
244 foreach ( $id_arrays as $key ) {
245 if ( array_key_exists( $key, $args ) && ! isset( $setting_types[ $key ] ) ) {
246 if ( null !== $args[ $key ] ) {
247 $args[ $key ] = is_array( $args[ $key ] ) ? $args[ $key ] : wp_parse_id_list( $args[ $key ] );
248 $args[ $key ] = array_unique( array_map( 'absint', $args[ $key ] ) );
249 $args[ $key ] = array_filter( $args[ $key ] );
250 sort( $args[ $key ] );
251
252 if ( empty( $args[ $key ] ) ) {
253 unset( $args[ $key ] );
254 }
255 } else {
256 unset( $args[ $key ] );
257 }
258 }
259 }
260
261 $string_arrays = array(
262 'exclude_cat_slugs',
263 'exclude_on_cat_slugs',
264 'exclude_on_post_types',
265 'post_name__in',
266 'post_status',
267 'post_type',
268 'same_taxes',
269 );
270
271 foreach ( $string_arrays as $key ) {
272 if ( array_key_exists( $key, $args ) && ! isset( $setting_types[ $key ] ) ) {
273 if ( null !== $args[ $key ] ) {
274 if ( is_string( $args[ $key ] ) && strpos( $args[ $key ], '=' ) !== false ) {
275 parse_str( $args[ $key ], $parsed );
276 $parsed_value = array_keys( $parsed );
277 } elseif ( is_string( $args[ $key ] ) ) {
278 $parsed_value = explode( ',', $args[ $key ] );
279 } else {
280 $parsed_value = $args[ $key ];
281 }
282 $args[ $key ] = is_array( $parsed_value ) ? $parsed_value : array( $parsed_value );
283 $args[ $key ] = array_unique( array_map( 'strval', $args[ $key ] ) );
284 $args[ $key ] = array_filter( $args[ $key ] );
285 sort( $args[ $key ] );
286
287 if ( empty( $args[ $key ] ) ) {
288 unset( $args[ $key ] );
289 }
290 } else {
291 unset( $args[ $key ] );
292 }
293 }
294 }
295
296 // Sort top-level arguments.
297 ksort( $args );
298
299 // Remove any remaining empty strings or null values.
300 foreach ( $args as $key => $value ) {
301 if ( '' === $value || null === $value ) {
302 unset( $args[ $key ] );
303 }
304 }
305
306 // Generate cache key.
307 return md5( wp_json_encode( $args ) );
308 }
309
310 /**
311 * Get the transient names for the Top 10 widgets.
312 *
313 * @since 2.3.0
314 *
315 * @return array Top 10 Cache widget keys.
316 */
317 public static function get_widget_keys() {
318 global $wpdb;
319
320 $keys = array();
321
322 $sql = "
323 SELECT option_name
324 FROM {$wpdb->options}
325 WHERE `option_name` LIKE '_transient_tptn_%'
326 ";
327
328 $results = $wpdb->get_results( $sql ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
329
330 if ( is_array( $results ) ) {
331 foreach ( $results as $result ) {
332 $keys[] = str_replace( '_transient_', '', $result->option_name );
333 }
334 }
335
336 return apply_filters( 'tptn_cache_get_widget_keys', $keys );
337 }
338 }
339