| @@ -35,19 +35,27 @@ | ||
| 35 | 35 | * @since 2.2.0 |
| 36 | 36 | */ |
| 37 | 37 | public function ajax_clearcache() { |
| 38 | 38 | |
| 39 | - if ( ! current_user_can( 'manage_options' ) ) { | |
| 39 | + $network_wide = isset( $_POST['network_wide'] ) && '1' === sanitize_key( wp_unslash( $_POST['network_wide'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 40 | + $capability = $network_wide ? 'manage_network_options' : 'manage_options'; | |
| 41 | + | |
| 42 | + if ( ! current_user_can( $capability ) ) { | |
| 40 | 43 | wp_die(); |
| 41 | 44 | } |
| 42 | 45 | check_ajax_referer( 'tptn-admin', 'security' ); |
| 43 | 46 | |
| 44 | - $count = $this->delete(); | |
| 47 | + $count = $network_wide ? self::delete_network() : $this->delete(); | |
| 45 | 48 | |
| 46 | 49 | wp_send_json_success( |
| 47 | 50 | array( |
| 48 | 51 | /* translators: 1: Number of entries cleared. */ |
| 49 | - 'message' => sprintf( _n( '%s entry cleared', '%s entries cleared', $count, 'top-10' ), number_format_i18n( $count ) ), | |
| 52 | + 'message' => sprintf( | |
| 53 | + $network_wide | |
| 54 | + ? _n( '%s cache entry cleared across the network', '%s cache entries cleared across the network', $count, 'top-10' ) | |
| 55 | + : _n( '%s entry cleared', '%s entries cleared', $count, 'top-10' ), | |
| 56 | + number_format_i18n( $count ) | |
| 57 | + ), | |
| 50 | 58 | ) |
| 51 | 59 | ); |
| 52 | 60 | } |
| 53 | 61 | |
| @@ -79,8 +87,53 @@ | ||
| 79 | 87 | return $loop; |
| 80 | 88 | } |
| 81 | 89 | |
| 82 | 90 | /** |
| 91 | + * Delete the Top 10 cache across all active network sites. | |
| 92 | + * | |
| 93 | + * @since 4.5.0 | |
| 94 | + * | |
| 95 | + * @return int Number of transients deleted. | |
| 96 | + */ | |
| 97 | + public static function delete_network() { | |
| 98 | + if ( ! is_multisite() ) { | |
| 99 | + return self::delete(); | |
| 100 | + } | |
| 101 | + | |
| 102 | + $site_ids = wp_list_pluck( | |
| 103 | + get_sites( | |
| 104 | + array( | |
| 105 | + 'archived' => 0, | |
| 106 | + 'spam' => 0, | |
| 107 | + 'deleted' => 0, | |
| 108 | + 'number' => 0, | |
| 109 | + ) | |
| 110 | + ), | |
| 111 | + 'blog_id' | |
| 112 | + ); | |
| 113 | + $count = 0; | |
| 114 | + $current_blog_id = get_current_blog_id(); | |
| 115 | + | |
| 116 | + foreach ( $site_ids as $site_id ) { | |
| 117 | + $site_id = absint( $site_id ); | |
| 118 | + $switched = $site_id !== $current_blog_id; | |
| 119 | + if ( $switched ) { | |
| 120 | + switch_to_blog( $site_id ); | |
| 121 | + } | |
| 122 | + | |
| 123 | + try { | |
| 124 | + $count += self::delete(); | |
| 125 | + } finally { | |
| 126 | + if ( $switched ) { | |
| 127 | + restore_current_blog(); | |
| 128 | + } | |
| 129 | + } | |
| 130 | + } | |
| 131 | + | |
| 132 | + return $count; | |
| 133 | + } | |
| 134 | + | |
| 135 | + /** | |
| 83 | 136 | * Get the default meta keys used for the cache |
| 84 | 137 | * |
| 85 | 138 | * @return array Transient meta keys |
| 86 | 139 | */ |
| @@ -302,10 +355,10 @@ | ||
| 302 | 355 | unset( $args[ $key ] ); |
| 303 | 356 | } |
| 304 | 357 | } |
| 305 | 358 | |
| 306 | - // Generate cache key. | |
| 307 | - return md5( wp_json_encode( $args ) ); | |
| 359 | + // Keep generated keys discoverable by get_widget_keys() and delete(). | |
| 360 | + return 'tptn_cache_' . md5( wp_json_encode( $args ) ); | |
| 308 | 361 | } |
| 309 | 362 | |
| 310 | 363 | /** |
| 311 | 364 | * Get the transient names for the Top 10 widgets. |
| @@ -332,7 +385,14 @@ | ||
| 332 | 385 | $keys[] = str_replace( '_transient_', '', $result->option_name ); |
| 333 | 386 | } |
| 334 | 387 | } |
| 335 | 388 | |
| 389 | + /** | |
| 390 | + * Filters the list of Top 10 cache keys found in the options table. | |
| 391 | + * | |
| 392 | + * @since 2.5.0 | |
| 393 | + * | |
| 394 | + * @param string[] $keys Cache keys without the transient prefix. | |
| 395 | + */ | |
| 336 | 396 | return apply_filters( 'tptn_cache_get_widget_keys', $keys ); |
| 337 | 397 | } |
| 338 | 398 | } |