Changeset 3723494
- Timestamp:
- 10/01/2026 04:36:35 PM (3 weeks ago)
- Location:
- w3-total-cache/tags/2.10.7
- Files:
-
- 2 added
- 38 edited
-
BrowserCache_Plugin.php (modified) (1 diff)
-
Cdn_Core.php (modified) (2 diffs)
-
Cdn_Core_Admin.php (modified) (1 diff)
-
Cli.php (modified) (1 diff)
-
ConfigKeys.php (modified) (5 diffs)
-
ConfigState.php (modified) (2 diffs)
-
Generic_AdminActions_Config.php (modified) (3 diffs)
-
Generic_Plugin.php (modified) (1 diff)
-
Licensing_Plugin_Admin.php (modified) (2 diffs)
-
Minify_AutoJs.php (modified) (1 diff)
-
Minify_MinifiedFileRequestHandler.php (modified) (5 diffs)
-
Minify_Plugin.php (modified) (3 diffs)
-
ObjectCache_WpObjectCache_Regular.php (modified) (10 diffs)
-
PageSpeed_Api.php (modified) (8 diffs)
-
PageSpeed_Page.php (modified) (2 diffs)
-
PageSpeed_Page_View.js (modified) (1 diff)
-
PageSpeed_Widget.php (modified) (2 diffs)
-
PageSpeed_Widget_View.js (modified) (1 diff)
-
PgCache_ConfigLabels.php (modified) (1 diff)
-
PgCache_ContentGrabber.php (modified) (2 diffs)
-
PgCache_Environment.php (modified) (5 diffs)
-
PgCache_Plugin.php (modified) (1 diff)
-
PgCache_Plugin_Admin.php (modified) (12 diffs)
-
Root_Environment.php (modified) (1 diff)
-
Util_Cookie.php (modified) (8 diffs)
-
Util_Environment.php (modified) (2 diffs)
-
Util_Http.php (modified) (5 diffs)
-
changelog.txt (modified) (1 diff)
-
docs (added)
-
docs/hooks.md (added)
-
inc/options/common/footer.php (modified) (1 diff)
-
inc/options/general.php (modified) (2 diffs)
-
inc/options/pgcache.php (modified) (1 diff)
-
languages/w3-total-cache.pot (modified) (53 diffs)
-
pub/css/lightbox.css (modified) (1 diff)
-
pub/js/options.js (modified) (1 diff)
-
readme.txt (modified) (3 diffs)
-
vendor/composer/installed.php (modified) (2 diffs)
-
w3-total-cache-api.php (modified) (2 diffs)
-
w3-total-cache.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
w3-total-cache/tags/2.10.7/BrowserCache_Plugin.php
r3585227 r3723494 207 207 // without quotes. 208 208 $buffer = preg_replace_callback( 209 '~(href|src|action|extsrc|asyncsrc)=((' . $domain_url_regexp . ')?(/[^\\s>][^\\s>]*\.([a-z-_]+)([\?#][^\\s> ]*)?))([\\s>])~Ui',209 '~(href|src|action|extsrc|asyncsrc)=((' . $domain_url_regexp . ')?(/[^\\s>][^\\s>]*\.([a-z-_]+)([\?#][^\\s>\'"]*)?))([\\s>])~Ui', 210 210 array( $this, 'link_replace_callback_noquote' ), 211 211 $buffer -
w3-total-cache/tags/2.10.7/Cdn_Core.php
r3680101 r3723494 106 106 107 107 if ( $upload_info ) { 108 $w3tc_file = $this->normalize_attachment_file( $w3tc_file ); 108 $w3tc_file = $this->normalize_attachment_file( $w3tc_file ); 109 if ( '' === $w3tc_file ) { 110 return $files; 111 } 112 109 113 $local_file = $upload_info['basedir'] . '/' . $w3tc_file; 110 114 $parsed = wp_parse_url( rtrim( $upload_info['baseurl'], '/' ) . '/' . $w3tc_file ); … … 351 355 $upload_info = Util_Http::upload_info(); 352 356 353 if ( $upload_info ) { 354 $w3tc_file = ltrim( str_replace( $upload_info['basedir'], '', $w3tc_file ), '/\\' ); 355 $matches = null; 356 357 if ( preg_match( '~(\d{4}/\d{2}/)?[^/]+$~', $w3tc_file, $matches ) ) { 358 $w3tc_file = $matches[0]; 359 } 357 if ( ! $upload_info ) { 358 return ''; 359 } 360 361 return $this->normalize_attachment_file_under_basedir( $upload_info['basedir'], $w3tc_file ); 362 } 363 364 /** 365 * Normalize an attachment path against a specific uploads basedir. 366 * 367 * @since 2.10.7 368 * 369 * @param string $basedir Upload basedir. 370 * @param string $w3tc_file Candidate attachment path. 371 * 372 * @return string Relative path under basedir, or empty string when rejected. 373 */ 374 private function normalize_attachment_file_under_basedir( $basedir, $w3tc_file ) { 375 if ( ! is_string( $basedir ) || '' === $basedir || ! is_string( $w3tc_file ) || '' === $w3tc_file || false !== strpos( $w3tc_file, "\0" ) ) { 376 return ''; 377 } 378 379 $basedir = Util_Environment::normalize_path( $basedir ); 380 $w3tc_file = Util_Environment::normalize_path( $w3tc_file ); 381 382 if ( preg_match( '~^(?:/|[a-zA-Z]:/)~', $w3tc_file ) ) { 383 $basedir_prefix = $basedir . '/'; 384 385 if ( ! $this->absolute_path_has_prefix( $w3tc_file, $basedir_prefix ) ) { 386 return ''; 387 } 388 389 $w3tc_file = substr( $w3tc_file, strlen( $basedir_prefix ) ); 390 } 391 392 if ( '' === $w3tc_file || preg_match( '~(?:^|/)\.{1,2}(?:/|$)~', $w3tc_file ) ) { 393 return ''; 360 394 } 361 395 362 396 return $w3tc_file; 397 } 398 399 /** 400 * Whether an absolute path is contained by a basedir prefix. 401 * 402 * Drive-letter case is ignored for Windows-style paths; the remainder 403 * of the path comparison stays case-sensitive. 404 * 405 * @since 2.10.7 406 * 407 * @param string $path Normalized absolute path. 408 * @param string $prefix Normalized basedir prefix ending in `/`. 409 * 410 * @return bool 411 */ 412 private function absolute_path_has_prefix( $path, $prefix ) { 413 if ( preg_match( '~^[a-zA-Z]:/~', $path ) && preg_match( '~^[a-zA-Z]:/~', $prefix ) ) { 414 $path = \strtoupper( $path[0] ) . \substr( $path, 1 ); 415 $prefix = \strtoupper( $prefix[0] ) . \substr( $prefix, 1 ); 416 } 417 418 return 0 === \strpos( $path, $prefix ); 363 419 } 364 420 -
w3-total-cache/tags/2.10.7/Cdn_Core_Admin.php
r3680101 r3723494 280 280 $w3tc_file = $common->normalize_attachment_file( $post->file ); 281 281 282 $local_file = $upload_info['basedir'] . '/' . $w3tc_file; 283 $remote_file = ltrim( $upload_info['baseurlpath'] . $w3tc_file, '/' ); 284 285 $post_files[] = $common->build_file_descriptor( $local_file, $remote_file ); 282 if ( '' !== $w3tc_file ) { 283 $local_file = $upload_info['basedir'] . '/' . $w3tc_file; 284 $remote_file = ltrim( $upload_info['baseurlpath'] . $w3tc_file, '/' ); 285 286 $post_files[] = $common->build_file_descriptor( $local_file, $remote_file ); 287 } 286 288 } 287 289 -
w3-total-cache/tags/2.10.7/Cli.php
r3585227 r3723494 591 591 ( isset( $vars['start'] ) ? $vars['start'] - 1 : null ), 592 592 ( isset( $vars['limit'] ) ? $vars['limit'] : null ), 593 $log_callback 593 $log_callback, 594 false 594 595 ); 595 596 -
w3-total-cache/tags/2.10.7/ConfigKeys.php
r3680101 r3723494 196 196 'type' => 'boolean', 197 197 'default' => false, 198 ), 199 'dbcache.wp_cron' => array( 200 'type' => 'boolean', 201 'default' => false, 202 ), 203 'dbcache.wp_cron_time' => array( 204 'type' => 'integer', 205 'default' => 0, 206 ), 207 'dbcache.wp_cron_interval' => array( 208 'type' => 'string', 209 'default' => 'daily', 198 210 ), 199 211 'docroot_fix.enable' => array( … … 385 397 'default' => false, 386 398 ), 399 'objectcache.wp_cron' => array( 400 'type' => 'boolean', 401 'default' => false, 402 ), 403 'objectcache.wp_cron_time' => array( 404 'type' => 'integer', 405 'default' => 0, 406 ), 407 'objectcache.wp_cron_interval' => array( 408 'type' => 'string', 409 'default' => 'daily', 410 ), 411 'allcache.wp_cron' => array( 412 'type' => 'boolean', 413 'default' => false, 414 ), 415 'allcache.wp_cron_time' => array( 416 'type' => 'integer', 417 'default' => 0, 418 ), 419 'allcache.wp_cron_interval' => array( 420 'type' => 'string', 421 'default' => 'daily', 422 ), 387 423 'pgcache.configuration_overloaded' => array( 388 424 'type' => 'boolean', … … 708 744 'type' => 'integer', 709 745 'default' => 10, 746 ), 747 'pgcache.prime.sitemap_one_pass' => array( 748 'type' => 'boolean', 749 'default' => false, 710 750 ), 711 751 'pgcache.prime.sitemap' => array( … … 757 797 ), 758 798 ), 799 'pgcache.wp_cron' => array( 800 'type' => 'boolean', 801 'default' => false, 802 ), 803 'pgcache.wp_cron_time' => array( 804 'type' => 'integer', 805 'default' => 0, 806 ), 807 'pgcache.wp_cron_interval' => array( 808 'type' => 'string', 809 'default' => 'daily', 810 ), 759 811 'stats.enabled' => array( 760 812 'type' => 'boolean', … … 1218 1270 'type' => 'boolean', 1219 1271 'default' => false, 1272 ), 1273 'minify.wp_cron' => array( 1274 'type' => 'boolean', 1275 'default' => false, 1276 ), 1277 'minify.wp_cron_time' => array( 1278 'type' => 'integer', 1279 'default' => 0, 1280 ), 1281 'minify.wp_cron_interval' => array( 1282 'type' => 'string', 1283 'default' => 'daily', 1220 1284 ), 1221 1285 'cdn.configuration_overloaded' => array( -
w3-total-cache/tags/2.10.7/ConfigState.php
r3585227 r3723494 82 82 83 83 /** 84 * Whether stored option data has been loaded. 85 * 86 * @var bool 87 */ 88 private $_loaded; 89 90 /** 91 * Encoded option payload from the last successful load or save. 92 * 93 * @since 2.10.7 94 * 95 * @var string|null 96 */ 97 private $_saved_encoded; 98 99 /** 84 100 * Initializes the configuration state. 85 101 * … … 89 105 */ 90 106 public function __construct( $is_master ) { 91 $this->_is_master = $is_master; 92 93 if ( $is_master ) { 94 $data_raw = get_site_option( 'w3tc_state' ); 107 $this->_is_master = $is_master; 108 $this->_data = array(); 109 $this->_loaded = false; 110 $this->_saved_encoded = null; 111 112 $this->load(); 113 } 114 115 /** 116 * Retrieves a value from the configuration state by key. 117 * 118 * @param string $w3tc_key The key to retrieve. 119 * @param mixed $default_value The default value to return if the key is not set. 120 * 121 * @return mixed The value associated with the key, or the default value. 122 */ 123 public function get( $w3tc_key, $default_value ) { 124 $this->load(); 125 126 if ( ! isset( $this->_data[ $w3tc_key ] ) ) { 127 return $default_value; 128 } 129 130 return $this->_data[ $w3tc_key ]; 131 } 132 133 /** 134 * Retrieves a string value from the configuration state. 135 * 136 * @param string $w3tc_key The key to retrieve. 137 * @param string $default_value The default string to return if the key is not set. Default is an empty string. 138 * @param bool $trim Whether to trim the returned string. Default is true. 139 * 140 * @return string The string value associated with the key, or the default string. 141 */ 142 public function get_string( $w3tc_key, $default_value = '', $trim = true ) { 143 $w3tc_value = (string) $this->get( $w3tc_key, $default_value ); 144 145 return $trim ? trim( $w3tc_value ) : $w3tc_value; 146 } 147 148 /** 149 * Retrieves an integer value from the configuration state. 150 * 151 * @param string $w3tc_key The key to retrieve. 152 * @param int $default_value The default integer to return if the key is not set. Default is 0. 153 * 154 * @return int The integer value associated with the key, or the default integer. 155 */ 156 public function get_integer( $w3tc_key, $default_value = 0 ) { 157 return (int) $this->get( $w3tc_key, $default_value ); 158 } 159 160 /** 161 * Retrieves a boolean value from the configuration state. 162 * 163 * @param string $w3tc_key The key to retrieve. 164 * @param bool $default_value The default boolean to return if the key is not set. Default is false. 165 * 166 * @return bool The boolean value associated with the key, or the default boolean. 167 */ 168 public function get_boolean( $w3tc_key, $default_value = false ) { 169 $v = $this->get( $w3tc_key, $default_value ); 170 if ( 'false' === $v || empty( $v ) ) { 171 $v = false; 172 } 173 174 return (bool) $v; 175 } 176 177 /** 178 * Retrieves an array value from the configuration state. 179 * 180 * @param string $w3tc_key The key to retrieve. 181 * @param array $default_value The default array to return if the key is not set. Default is an empty array. 182 * 183 * @return array The array value associated with the key, or the default array. 184 */ 185 public function get_array( $w3tc_key, $default_value = array() ) { 186 return (array) $this->get( $w3tc_key, $default_value ); 187 } 188 189 /** 190 * Sets a value in the configuration state. 191 * 192 * @param string $w3tc_key The key to set. 193 * @param mixed $w3tc_value The value to associate with the key. 194 * 195 * @return void 196 */ 197 public function set( $w3tc_key, $w3tc_value ) { 198 $this->load(); 199 200 $this->_data[ $w3tc_key ] = $w3tc_value; 201 } 202 203 /** 204 * Resets the configuration state to its default values. 205 * 206 * @return void 207 */ 208 public function reset() { 209 $this->_data = array(); 210 $this->_loaded = true; 211 $this->_saved_encoded = null; 212 $this->apply_defaults(); 213 } 214 215 /** 216 * Saves the current configuration state. 217 * 218 * @return void 219 */ 220 public function save() { 221 $this->load(); 222 223 if ( ! $this->_loaded ) { 224 return; 225 } 226 227 $encoded = \wp_json_encode( $this->_data ); 228 if ( false === $encoded || $encoded === $this->_saved_encoded ) { 229 return; 230 } 231 232 if ( $this->_is_master ) { 233 if ( ! \function_exists( 'update_site_option' ) ) { 234 return; 235 } 236 $saved = \update_site_option( 'w3tc_state', $encoded ); 95 237 } else { 96 $data_raw = get_option( 'w3tc_state' ); 97 } 98 99 $this->_data = @json_decode( $data_raw, true ); 238 if ( ! \function_exists( 'update_option' ) ) { 239 return; 240 } 241 $saved = \update_option( 'w3tc_state', $encoded ); 242 } 243 244 if ( $saved ) { 245 $this->_saved_encoded = $encoded; 246 } 247 } 248 249 /** 250 * Loads stored option data when the Options API is available. 251 * 252 * @since 2.10.7 253 * 254 * @return void 255 */ 256 private function load() { 257 if ( $this->_loaded ) { 258 return; 259 } 260 261 if ( $this->_is_master ) { 262 if ( ! \function_exists( 'get_site_option' ) ) { 263 return; 264 } 265 $data_raw = \get_site_option( 'w3tc_state' ); 266 } else { 267 if ( ! \function_exists( 'get_option' ) ) { 268 return; 269 } 270 $data_raw = \get_option( 'w3tc_state' ); 271 } 272 273 $this->_loaded = true; 274 $this->_data = @json_decode( $data_raw, true ); 100 275 if ( ! is_array( $this->_data ) ) { 101 276 $this->_data = array(); 102 277 $this->apply_defaults(); 103 278 $this->save(); 104 } 105 } 106 107 /** 108 * Retrieves a value from the configuration state by key. 109 * 110 * @param string $w3tc_key The key to retrieve. 111 * @param mixed $default_value The default value to return if the key is not set. 112 * 113 * @return mixed The value associated with the key, or the default value. 114 */ 115 public function get( $w3tc_key, $default_value ) { 116 if ( ! isset( $this->_data[ $w3tc_key ] ) ) { 117 return $default_value; 118 } 119 120 return $this->_data[ $w3tc_key ]; 121 } 122 123 /** 124 * Retrieves a string value from the configuration state. 125 * 126 * @param string $w3tc_key The key to retrieve. 127 * @param string $default_value The default string to return if the key is not set. Default is an empty string. 128 * @param bool $trim Whether to trim the returned string. Default is true. 129 * 130 * @return string The string value associated with the key, or the default string. 131 */ 132 public function get_string( $w3tc_key, $default_value = '', $trim = true ) { 133 $w3tc_value = (string) $this->get( $w3tc_key, $default_value ); 134 135 return $trim ? trim( $w3tc_value ) : $w3tc_value; 136 } 137 138 /** 139 * Retrieves an integer value from the configuration state. 140 * 141 * @param string $w3tc_key The key to retrieve. 142 * @param int $default_value The default integer to return if the key is not set. Default is 0. 143 * 144 * @return int The integer value associated with the key, or the default integer. 145 */ 146 public function get_integer( $w3tc_key, $default_value = 0 ) { 147 return (int) $this->get( $w3tc_key, $default_value ); 148 } 149 150 /** 151 * Retrieves a boolean value from the configuration state. 152 * 153 * @param string $w3tc_key The key to retrieve. 154 * @param bool $default_value The default boolean to return if the key is not set. Default is false. 155 * 156 * @return bool The boolean value associated with the key, or the default boolean. 157 */ 158 public function get_boolean( $w3tc_key, $default_value = false ) { 159 $v = $this->get( $w3tc_key, $default_value ); 160 if ( 'false' === $v || empty( $v ) ) { 161 $v = false; 162 } 163 164 return (bool) $v; 165 } 166 167 /** 168 * Retrieves an array value from the configuration state. 169 * 170 * @param string $w3tc_key The key to retrieve. 171 * @param array $default_value The default array to return if the key is not set. Default is an empty array. 172 * 173 * @return array The array value associated with the key, or the default array. 174 */ 175 public function get_array( $w3tc_key, $default_value = array() ) { 176 return (array) $this->get( $w3tc_key, $default_value ); 177 } 178 179 /** 180 * Sets a value in the configuration state. 181 * 182 * @param string $w3tc_key The key to set. 183 * @param mixed $w3tc_value The value to associate with the key. 184 * 185 * @return void 186 */ 187 public function set( $w3tc_key, $w3tc_value ) { 188 $this->_data[ $w3tc_key ] = $w3tc_value; 189 } 190 191 /** 192 * Resets the configuration state to its default values. 193 * 194 * @return void 195 */ 196 public function reset() { 197 $this->_data = array(); 198 $this->apply_defaults(); 199 } 200 201 /** 202 * Saves the current configuration state. 203 * 204 * @return void 205 */ 206 public function save() { 207 if ( $this->_is_master ) { 208 update_site_option( 'w3tc_state', wp_json_encode( $this->_data ) ); 209 } else { 210 update_option( 'w3tc_state', wp_json_encode( $this->_data ) ); 211 } 279 return; 280 } 281 282 $this->_saved_encoded = \wp_json_encode( $this->_data ); 212 283 } 213 284 -
w3-total-cache/tags/2.10.7/Generic_AdminActions_Config.php
r3585227 r3723494 559 559 * Saves the "Support Us" configuration settings. 560 560 * 561 * Updates settings based on user actions like tweeting or signing up. 561 * Updates settings based on user actions like tweeting or accepting 562 * the community terms. 562 563 * 563 564 * @return void … … 565 566 public function w3tc_config_save_support_us() { 566 567 $tweeted = Util_Request::get_boolean( 'tweeted' ); 567 $signmeup = Util_Request::get_boolean( 'signmeup' );568 568 $accept_terms = Util_Request::get_boolean( 'accept_terms' ); 569 569 $this->_config->set( 'common.tweeted', $tweeted ); … … 576 576 $state_master->save(); 577 577 578 if ( $signmeup ) {579 if ( Util_Environment::is_w3tc_pro( $this->_config ) ) {580 $w3tc_license = 'pro';581 } else {582 $w3tc_license = 'community';583 }584 585 /**586 * RT9-218: Bind the mailing-list signup to the currently587 * authenticated admin's verified WordPress account email,588 * rather than trusting whatever address was POSTed. The589 * original handler took `email` straight from the request590 * body, which let any admin (or anyone driving the shared591 * `w3tc` nonce) submit arbitrary third-party addresses to592 * `api.w3-edge.com/v1/signup-newsletter` as an outbound593 * abuse primitive. wp_get_current_user() is safe here594 * because the surrounding admin-page dispatcher already595 * gates this action behind an authenticated session.596 */597 $current = \wp_get_current_user();598 $email = ( $current instanceof \WP_User && ! empty( $current->user_email ) )599 ? $current->user_email600 : '';601 602 if ( \is_string( $email ) && '' !== $email603 && false !== \filter_var( $email, FILTER_VALIDATE_EMAIL )604 ) {605 wp_remote_post(606 W3TC_MAILLINGLIST_SIGNUP_URL,607 array(608 'body' => array(609 'email' => $email,610 'license' => $w3tc_license,611 ),612 )613 );614 }615 }616 578 $this->_config->save(); 617 579 -
w3-total-cache/tags/2.10.7/Generic_Plugin.php
r3680101 r3723494 1186 1186 foreach ( $rejected_roles as $role ) { 1187 1187 Util_Cookie::clear( 'w3tc_logged_' . Util_Cookie::role_cookie_name( $role ) ); 1188 /**1189 * Always clear leftover MD5-named cookies on logout even1190 * though cache-auth readers no longer honor them by1191 * default. Stale names would otherwise linger in the1192 * browser until expiry.1193 */1194 Util_Cookie::clear( 'w3tc_logged_' . Util_Cookie::role_cookie_name_legacy( $role ) );1195 1188 } 1196 1189 -
w3-total-cache/tags/2.10.7/Licensing_Plugin_Admin.php
r3680101 r3723494 687 687 ); 688 688 689 /* 690 * Longer prefixes must be tested first. _status_is() is a prefix 691 * match, so inactive.by_rooturi also matches 692 * inactive.by_rooturi.activations_limit_reached. 693 */ 694 case $this->_status_is( $status, 'inactive.by_rooturi.activations_limit_reached' ): 695 return sprintf( 696 // Translators: 1 Product name. 697 __( 698 'Your %1$s license key is not active and cannot be activated due to the license activation limit being reached.', 699 'w3-total-cache' 700 ), 701 W3TC_POWERED_BY 702 ); 703 689 704 case $this->_status_is( $status, 'inactive.by_rooturi' ) || $this->_status_is( $status, 'inactive.by_rooturi.activations_limit_not_reached' ): 690 705 // Only show this notice if there's actually a license key. … … 707 722 '<a class="w3tc_licensing_reset_rooturi" href="' . esc_url( $reset_url ) . '">', 708 723 '</a>' 709 );710 711 case $this->_status_is( $status, 'inactive.by_rooturi.activations_limit_reached' ):712 return sprintf(713 // Translators: 1 Product name.714 __(715 'Your %1$s license key is not active and cannot be activated due to the license activation limit being reached.',716 'w3-total-cache'717 ),718 W3TC_POWERED_BY719 724 ); 720 725 -
w3-total-cache/tags/2.10.7/Minify_AutoJs.php
r3585227 r3723494 251 251 if ( 'url' === $step1_result ) { 252 252 $w3tc_file = $script_src; 253 if ( ! $this->minify_helpers->is_external_script_cached( $script_src ) ) { 254 $step1_result = ''; 255 } 253 256 } 254 257 -
w3-total-cache/tags/2.10.7/Minify_MinifiedFileRequestHandler.php
r3680101 r3723494 74 74 */ 75 75 const PROBE_TOKEN_HEADER = 'X-W3TC-Minify-Probe'; 76 77 /** 78 * Limits for external JavaScript retrieval. 79 * 80 * @since 2.10.7 81 */ 82 const EXTERNAL_JS_TIMEOUT = 5; 83 const EXTERNAL_JS_MAX_SIZE = 1048576; 84 85 /** 86 * Cron hook that retrieves selected external JavaScript. 87 * 88 * @since 2.10.7 89 */ 90 const EXTERNAL_JS_PRECACHE_HOOK = 'w3tc_minify_precache_external_script'; 76 91 77 92 /** … … 859 874 public function _precache_file( $w3tc_url, $type ) { 860 875 $w3tc_url = Util_Url::normalize_protocol_relative_url( $w3tc_url ); 861 if ( '' === $w3tc_url || ! Util_Url::is_allowed_outbound_url( $w3tc_url )) {876 if ( ! in_array( $type, array( 'css', 'js' ), true ) || '' === $w3tc_url ) { 862 877 return false; 863 878 } 864 879 865 $lifetime = $this->_config->get_integer( 'minify.lifetime' ); 866 $cache_path = sprintf( '%s/minify_%s.%s', Util_Environment::cache_blog_dir( 'minify' ), md5( $w3tc_url ), $type ); 880 if ( 'js' === $type ) { 881 $cache_path = $this->external_javascript_cache_path( $w3tc_url ); 882 if ( '' === $cache_path ) { 883 return false; 884 } 885 886 $lifetime = $this->external_javascript_lifetime(); 887 } else { 888 if ( ! Util_Url::is_allowed_outbound_url( $w3tc_url ) ) { 889 return false; 890 } 891 892 $lifetime = $this->_config->get_integer( 'minify.lifetime' ); 893 $cache_path = sprintf( '%s/minify_%s.%s', Util_Environment::cache_blog_dir( 'minify' ), md5( $w3tc_url ), $type ); 894 } 867 895 868 896 if ( ! file_exists( $cache_path ) || @filemtime( $cache_path ) < ( time() - $lifetime ) ) { … … 871 899 } 872 900 901 $download_path = $cache_path; 902 $download_args = array( 903 'user-agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92', 904 ); 905 if ( 'js' === $type ) { 906 $download_path .= '.' . \uniqid( 'tmp-', true ); 907 $download_args['timeout'] = self::EXTERNAL_JS_TIMEOUT; 908 $download_args['w3tc_public_only'] = true; 909 $download_args['w3tc_https_only'] = true; 910 $download_args['w3tc_same_host'] = true; 911 $download_args['w3tc_max_response_size'] = self::EXTERNAL_JS_MAX_SIZE; 912 $download_args['w3tc_response_validator'] = array( __CLASS__, 'validate_external_javascript_response' ); 913 } 914 873 915 // google-fonts (most used for external inclusion) doesnt return full content (unicode-range) for simple useragents. 874 Util_Http::download(916 $downloaded = Util_Http::download( 875 917 $w3tc_url, 876 $cache_path, 877 array( 878 'user-agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92', 879 ) 918 $download_path, 919 $download_args 880 920 ); 921 922 if ( 'js' === $type ) { 923 if ( $downloaded ) { 924 @rename( $download_path, $cache_path ); 925 } 926 if ( file_exists( $download_path ) ) { 927 @unlink( $download_path ); 928 } 929 } 881 930 } 882 931 883 932 return file_exists( $cache_path ) ? $this->_get_minify_source( $cache_path, $w3tc_url, $type ) : false; 933 } 934 935 /** 936 * Retrieves an existing external JavaScript cache entry without refreshing it. 937 * 938 * @since 2.10.7 939 * 940 * @param string $w3tc_url Script URL. 941 * 942 * @return mixed The minified source or false when no usable cache exists. 943 */ 944 public function get_cached_external_script( $w3tc_url ) { 945 $w3tc_url = Util_Url::normalize_protocol_relative_url( $w3tc_url ); 946 $cache_path = $this->external_javascript_cache_path( $w3tc_url ); 947 948 if ( '' === $cache_path || ! file_exists( $cache_path ) ) { 949 return false; 950 } 951 952 return $this->_get_minify_source( $cache_path, $w3tc_url, 'js' ); 953 } 954 955 /** 956 * Queues retrieval of an external script that has no usable cache yet. 957 * 958 * Page output must never wait on the network, so the first copy is fetched 959 * by cron. Once a copy exists the tag is rewritten to the minify URL and 960 * the minify request handler keeps it refreshed. 961 * 962 * @since 2.10.7 963 * 964 * @param string $w3tc_url Script URL. 965 * 966 * @return bool Whether retrieval is queued. 967 */ 968 public function schedule_external_script_precache( $w3tc_url ) { 969 $w3tc_url = Util_Url::normalize_protocol_relative_url( $w3tc_url ); 970 $cache_path = $this->external_javascript_cache_path( $w3tc_url ); 971 972 if ( '' === $cache_path ) { 973 return false; 974 } 975 976 if ( file_exists( $cache_path ) && @filemtime( $cache_path ) >= ( time() - $this->external_javascript_lifetime() ) ) { 977 return false; 978 } 979 980 $args = array( $w3tc_url ); 981 if ( \wp_next_scheduled( self::EXTERNAL_JS_PRECACHE_HOOK, $args ) ) { 982 return true; 983 } 984 985 return true === \wp_schedule_single_event( time(), self::EXTERNAL_JS_PRECACHE_HOOK, $args ); 986 } 987 988 /** 989 * Returns the cache path of an external script eligible for local caching. 990 * 991 * @since 2.10.7 992 * 993 * @param string $w3tc_url Normalized script URL. 994 * 995 * @return string Empty string when the URL may not be cached. 996 */ 997 private function external_javascript_cache_path( $w3tc_url ) { 998 if ( 999 '' === $w3tc_url || 1000 'https' !== \wp_parse_url( $w3tc_url, PHP_URL_SCHEME ) || 1001 ! Util_Url::is_public_host( $w3tc_url ) 1002 ) { 1003 return ''; 1004 } 1005 1006 return sprintf( '%s/minify_%s.js', Util_Environment::cache_blog_dir( 'minify' ), md5( $w3tc_url ) ); 1007 } 1008 1009 /** 1010 * Returns the bounded refresh interval for external scripts. 1011 * 1012 * @since 2.10.7 1013 * 1014 * @return int 1015 */ 1016 private function external_javascript_lifetime() { 1017 return max( HOUR_IN_SECONDS, min( WEEK_IN_SECONDS, $this->_config->get_integer( 'minify.lifetime' ) ) ); 1018 } 1019 1020 /** 1021 * Accepts only non-empty responses with a JavaScript content type. 1022 * 1023 * @since 2.10.7 1024 * 1025 * @param array $response HTTP response. 1026 * 1027 * @return bool 1028 */ 1029 public static function validate_external_javascript_response( $response ) { 1030 $body = isset( $response['body'] ) && \is_string( $response['body'] ) ? $response['body'] : ''; 1031 if ( '' === $body ) { 1032 return false; 1033 } 1034 1035 $content_type = \strtolower( \trim( \wp_remote_retrieve_header( $response, 'content-type' ) ) ); 1036 $content_type_parts = \explode( ';', $content_type ); 1037 $content_type = \trim( $content_type_parts[0] ); 1038 1039 return \in_array( 1040 $content_type, 1041 array( 1042 'application/javascript', 1043 'application/ecmascript', 1044 'application/x-ecmascript', 1045 'application/x-javascript', 1046 'text/ecmascript', 1047 'text/javascript', 1048 'text/x-ecmascript', 1049 'text/x-javascript', 1050 ), 1051 true 1052 ); 884 1053 } 885 1054 … … 1174 1343 } 1175 1344 1176 $segments = explode( '.', $remote_url ); 1177 $w3tc_ext = strtolower( array_pop( $segments ) ); 1345 $w3tc_ext = self::remote_source_type( $remote_url, $type ); 1346 if ( '' === $w3tc_ext ) { 1347 return false; 1348 } 1349 1178 1350 $pc_source = $this->_precache_file( $remote_url, $w3tc_ext ); 1179 1351 if ( ! $pc_source || empty( $pc_source->filepath ) ) { … … 1308 1480 1309 1481 /** 1482 * Resolves the asset type of a remote minify source. 1483 * 1484 * The URL path is authoritative when it carries a css/js extension; 1485 * versioned or extensionless URLs (e.g. "app.js?ver=1") fall back to 1486 * the type of the group being hashed. 1487 * 1488 * @since 2.10.7 1489 * 1490 * @param string $remote_url Remote asset URL. 1491 * @param string $group_type Type of the group being hashed (css/js). 1492 * 1493 * @return string Asset type, or an empty string when neither is usable. 1494 */ 1495 private static function remote_source_type( $remote_url, $group_type ) { 1496 $path = \wp_parse_url( $remote_url, PHP_URL_PATH ); 1497 $extension = \is_string( $path ) ? \strtolower( \pathinfo( $path, PATHINFO_EXTENSION ) ) : ''; 1498 1499 if ( \in_array( $extension, array( 'css', 'js' ), true ) ) { 1500 return $extension; 1501 } 1502 1503 return \in_array( $group_type, array( 'css', 'js' ), true ) ? $group_type : ''; 1504 } 1505 1506 /** 1310 1507 * Flattens a multidimensional array into a single-dimensional array. 1311 1508 * -
w3-total-cache/tags/2.10.7/Minify_Plugin.php
r3680101 r3723494 90 90 add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) ); // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected 91 91 add_action( 'w3tc_minifycache_purge_wpcron', array( $this, 'w3tc_minifycache_purge_wpcron' ) ); 92 add_action( 93 Minify_MinifiedFileRequestHandler::EXTERNAL_JS_PRECACHE_HOOK, 94 array( $this, 'w3tc_minify_precache_external_script' ) 95 ); 92 96 93 97 add_filter( 'w3tc_admin_bar_menu', array( $this, 'w3tc_admin_bar_menu' ) ); … … 182 186 $flusher = Dispatcher::component( 'CacheFlush' ); 183 187 $flusher->minifycache_flush(); 188 } 189 190 /** 191 * Retrieves a queued external script outside of page generation. 192 * 193 * @since 2.10.7 194 * 195 * @param string $w3tc_url Script URL. 196 * 197 * @return void 198 */ 199 public function w3tc_minify_precache_external_script( $w3tc_url ) { 200 if ( ! is_string( $w3tc_url ) || '' === $w3tc_url ) { 201 return; 202 } 203 204 // The selection may have changed since the event was queued. 205 $helpers = new _W3_MinifyHelpers( $this->_config ); 206 if ( 'url' !== $helpers->is_file_for_minification( $w3tc_url, null ) ) { 207 return; 208 } 209 210 $minify = Dispatcher::component( 'Minify_MinifiedFileRequestHandler' ); 211 $minify->_precache_file( $w3tc_url, 'js' ); 184 212 } 185 213 … … 1207 1235 1208 1236 /** 1237 * Confirms that an external script already has a usable cached source. 1238 * 1239 * This check must not retrieve the script because it runs while page HTML 1240 * is being generated. Cache population and refresh happen in the minify 1241 * request handler. 1242 * 1243 * @since 2.10.7 1244 * 1245 * @param string $w3tc_url Script URL. 1246 * 1247 * @return bool 1248 */ 1249 public function is_external_script_cached( $w3tc_url ) { 1250 $minify = Dispatcher::component( 'Minify_MinifiedFileRequestHandler' ); 1251 $cached = false !== $minify->get_cached_external_script( $w3tc_url ); 1252 1253 if ( ! $cached ) { 1254 $minify->schedule_external_script_precache( $w3tc_url ); 1255 } 1256 1257 return $cached; 1258 } 1259 1260 /** 1209 1261 * Retrieves the minified content for a given set of files and type. 1210 1262 * -
w3-total-cache/tags/2.10.7/ObjectCache_WpObjectCache_Regular.php
r3680101 r3723494 206 206 $found = true; 207 207 $w3tc_value = $this->cache[ $w3tc_key ]; 208 } elseif ( 209 $this->_caching 210 && ! in_array( $w3tc_group, $this->nonpersistent_groups, true ) 211 && $this->_check_can_cache_runtime( $w3tc_group ) 212 ) { 208 } elseif ( $this->_should_use_persistent_cache( $id, $w3tc_group ) ) { 213 209 $cache = $this->_get_cache( null, $w3tc_group ); 214 210 $v = $cache->get( $w3tc_key, $w3tc_group ); … … 346 342 } 347 343 344 $persistent_misses = array_filter( 345 $runtime_misses, 346 function ( $storage_key, $id ) use ( $w3tc_group ) { 347 return $this->_should_use_persistent_cache( $id, $w3tc_group ); 348 }, 349 ARRAY_FILTER_USE_BOTH 350 ); 351 348 352 // Attempt a batched persistent fetch for the remaining keys when allowed. 349 if ( 350 ! empty( $runtime_misses ) && 351 $this->_caching && 352 ! in_array( $w3tc_group, $this->nonpersistent_groups, true ) && 353 $this->_check_can_cache_runtime( $w3tc_group ) 354 ) { 353 if ( ! empty( $persistent_misses ) ) { 355 354 $cache = $this->_get_cache( null, $w3tc_group ); 356 $storage_map = $ runtime_misses;355 $storage_map = $persistent_misses; 357 356 $raw_values = array(); 358 357 … … 365 364 } 366 365 367 foreach ( $ runtime_misses as $id => $storage_key ) {366 foreach ( $persistent_misses as $id => $storage_key ) { 368 367 ++$cache_total_inc; 369 368 $v = isset( $raw_values[ $storage_key ] ) ? $raw_values[ $storage_key ] : null; … … 382 381 } 383 382 } 384 } else { 385 // Not eligible for persistent fetch; fall back to per-key get() honoring $force. 386 foreach ( $runtime_misses as $id => $unused_key ) { 383 } 384 385 // Fall back for keys that were not eligible for persistent fetch. 386 foreach ( $runtime_misses as $id => $unused_key ) { 387 if ( ! array_key_exists( $id, $results ) ) { 387 388 $results[ $id ] = $this->get( $id, $w3tc_group, $force ); 388 389 } … … 436 437 $cache_sets_inc = 0; 437 438 438 if ( 439 $this->_caching 440 && ! in_array( $w3tc_group, $this->nonpersistent_groups, true ) 441 && $this->_check_can_cache_runtime( $w3tc_group ) 442 ) { 439 if ( $this->_should_use_persistent_cache( $id, $w3tc_group ) ) { 443 440 $cache = $this->_get_cache( null, $w3tc_group ); 444 441 … … 528 525 } 529 526 530 $results = array(); 531 $payload = array(); 532 $cache_key_to_id = array(); 533 $cache_sets_inc = 0; 534 $time_start_debug = ( $this->_debug || $this->stats_enabled ) ? Util_Debug::microtime() : 0; 535 $key_version_all = $this->key_version_all_get(); 536 $persistent_allowed = ( 537 $this->_caching && 538 ! in_array( $w3tc_group, $this->nonpersistent_groups, true ) && 539 $this->_check_can_cache_runtime( $w3tc_group ) 540 ); 527 $results = array(); 528 $payload = array(); 529 $cache_key_to_id = array(); 530 $cache_sets_inc = 0; 531 $time_start_debug = ( $this->_debug || $this->stats_enabled ) ? Util_Debug::microtime() : 0; 532 $key_version_all = $this->key_version_all_get(); 541 533 542 534 foreach ( $items as $id => $w3tc_value ) { … … 552 544 $results[ $id ] = true; 553 545 554 if ( $ persistent_allowed) {546 if ( $this->_should_use_persistent_cache( $id, $w3tc_group ) ) { 555 547 $stored_content = $stored; 556 548 … … 570 562 } 571 563 572 if ( $persistent_allowed &&! empty( $payload ) ) {564 if ( ! empty( $payload ) ) { 573 565 $cache = $this->_get_cache( null, $w3tc_group ); 574 566 $results = $this->set_multiple_to_cache( … … 609 601 */ 610 602 public function delete( $id, $w3tc_group = 'default', $force = false ) { 611 if ( ! $force && $this->get( $id, $w3tc_group ) === false) {612 return false;603 if ( empty( $w3tc_group ) ) { 604 $w3tc_group = 'default'; 613 605 } 614 606 615 607 $w3tc_key = $this->_get_cache_key( $id, $w3tc_group ); 616 $return = true; 608 609 $can_persist = $this->_caching && ! in_array( $w3tc_group, $this->nonpersistent_groups, true ); 610 611 if ( ! $force && ! isset( $this->cache[ $w3tc_key ] ) ) { 612 $should_check_exists = ! $can_persist || $this->_check_can_cache_runtime( $w3tc_group ); 613 614 if ( $should_check_exists && $this->get( $id, $w3tc_group ) === false ) { 615 return false; 616 } 617 } 618 619 $return = true; 617 620 618 621 unset( $this->cache[ $w3tc_key ] ); 619 622 620 if ( $ this->_caching && ! in_array( $w3tc_group, $this->nonpersistent_groups, true )) {623 if ( $can_persist ) { 621 624 $cache = $this->_get_cache( null, $w3tc_group ); 622 625 $return = $cache->delete( $w3tc_key, $w3tc_group ); … … 1358 1361 1359 1362 /** 1363 * Whether a key should use the persistent backend. 1364 * 1365 * Admin requests typically skip persistent cache so admin queries are not stored. 1366 * `last_changed` still writes through so frontend query salts invalidate. 1367 * 1368 * @since 2.10.7 1369 * 1370 * @param string $id Cache key. 1371 * @param string $w3tc_group Cache group. 1372 * 1373 * @return bool 1374 */ 1375 private function _should_use_persistent_cache( $id, $w3tc_group ) { 1376 if ( ! $this->_caching || in_array( $w3tc_group, $this->nonpersistent_groups, true ) ) { 1377 return false; 1378 } 1379 1380 if ( $this->_check_can_cache_runtime( $w3tc_group ) ) { 1381 return true; 1382 } 1383 1384 return 'last_changed' === (string) $id; 1385 } 1386 1387 /** 1360 1388 * Checks if caching is allowed for runtime based on the group. 1361 1389 * -
w3-total-cache/tags/2.10.7/PageSpeed_Api.php
r3680101 r3723494 18 18 */ 19 19 class PageSpeed_Api { 20 /** 21 * Delay automatic retries after a failed token refresh. 22 * 23 * @var int 24 */ 25 const REFRESH_RETRY_DELAY = 15 * MINUTE_IN_SECONDS; 26 20 27 /** 21 28 * Config. … … 231 238 $w3tc_site_id = Util_Http::generate_site_id(); 232 239 $w3tc_pagespeed_key = $this->w3tc_config->get_string( 'widget.pagespeed.w3tc_pagespeed_key' ); 233 if ( $this->client->isAccessTokenExpired() && ! empty( $w3tc_pagespeed_key ) ) { 240 $retry_after = (int) get_option( 'w3tcps_refresh_retry_after' ); 241 242 if ( 243 $this->client->isAccessTokenExpired() && 244 ! empty( $w3tc_pagespeed_key ) && 245 $retry_after <= time() 246 ) { 234 247 $this->refresh_token( $w3tc_site_id, $w3tc_pagespeed_key ); 235 248 } … … 246 259 public function refresh_token( $w3tc_site_id, $w3tc_pagespeed_key ) { 247 260 if ( empty( $w3tc_site_id ) || empty( $w3tc_pagespeed_key ) ) { 248 update_option( 249 'w3tcps_refresh_fail', 261 $this->set_refresh_failure( 250 262 __( 'Google PageSpeed access token refresh missing required parameters!', 'w3-total-cache' ) 251 263 ); … … 262 274 ); 263 275 264 $response_body_json = wp_remote_retrieve_body( $response );265 $response_body = json_decode( $response_body_json, true );266 267 276 if ( is_wp_error( $response ) ) { 268 return wp_json_encode( 269 array( 270 'error' => array( 271 'code' => $response->get_error_code(), 272 'message' => $response->get_error_message(), 277 $this->set_refresh_failure( 278 __( 'Google PageSpeed access token refresh failed.', 'w3-total-cache' ), 279 $response->get_error_message() 280 ); 281 return; 282 } 283 284 $response_code = (int) wp_remote_retrieve_response_code( $response ); 285 $response_body = json_decode( wp_remote_retrieve_body( $response ), true ); 286 if ( ! is_array( $response_body ) ) { 287 $response_body = array(); 288 } 289 290 $w3tc_error_id = ''; 291 if ( isset( $response_body['error'] ) && is_array( $response_body['error'] ) ) { 292 $w3tc_error_id = isset( $response_body['error']['id'] ) ? (string) $response_body['error']['id'] : ''; 293 } 294 295 if ( 296 $response_code < 200 || 297 $response_code >= 300 || 298 isset( $response_body['error'] ) 299 ) { 300 $this->set_refresh_failure( 301 __( 'Google PageSpeed access token refresh failed.', 'w3-total-cache' ), 302 $this->get_refresh_failure_message( $w3tc_error_id, $response_body, $response_code ) 303 ); 304 305 if ( 306 in_array( 307 $w3tc_error_id, 308 array( 309 'refresh-token-not-found', 310 'refresh-token-missing-refresh-token', 273 311 ), 312 true 274 313 ) 275 ); 276 } elseif ( isset( $response_body['error']['code'] ) && 200 !== $response_body['error']['code'] ) { 277 if ( 'refresh-token-missing-site-id' === $response_body['error']['id'] ) { 278 $w3tc_message = __( 'No site ID provided for access key refresh!', 'w3-total-cache' ); 279 } elseif ( 'refresh-token-missing-w3tc-pagespeed-key' === $response_body['error']['id'] ) { 280 $w3tc_message = __( 'No W3TC API key provided for access key refresh!', 'w3-total-cache' ); 281 } elseif ( 'refresh-token-not-found' === $response_body['error']['id'] ) { 282 $w3tc_message = __( 'No matching Google access record found for W3TC API key!', 'w3-total-cache' ); 283 } elseif ( 'refresh-token-missing-refresh-token' === $response_body['error']['id'] ) { 284 $w3tc_message = __( 'Matching Google access record found but the refresh token value is blank!', 'w3-total-cache' ); 314 ) { 315 $this->clear_pagespeed_credentials(); 285 316 } 286 287 update_option(288 'w3tcps_refresh_fail',289 __( 'Google PageSpeed access token refresh failed.', 'w3-total-cache' )290 );291 update_option(292 'w3tcps_refresh_fail_message',293 $w3tc_message294 );295 296 // Reset the token and key.297 $this->w3tc_config->set( 'widget.pagespeed.access_token', '' );298 $this->w3tc_config->set( 'widget.pagespeed.w3tc_pagespeed_key', '' );299 $this->w3tc_config->save();300 301 317 return; 302 318 } 303 319 304 $w3tc_access_token = $response_body_json; 305 306 if ( empty( $w3tc_access_token ) || empty( $response_body['access_token'] ) ) { 307 update_option( 308 'w3tcps_refresh_fail', 309 __( 'Google PageSpeed access token refresh failed due to response missing access token.', 'w3-total-cache' ) 320 $w3tc_access_token = self::prepare_access_token_json( $response_body ); 321 if ( false === $w3tc_access_token ) { 322 $this->set_refresh_failure( 323 __( 'Google PageSpeed access token refresh failed due to an unusable token response.', 'w3-total-cache' ) 310 324 ); 311 325 return; … … 315 329 $this->w3tc_config->save(); 316 330 $this->client->setAccessToken( $w3tc_access_token ); 331 self::clear_failure_notices(); 332 } 333 334 /** 335 * Records a token refresh failure for the admin notice. 336 * 337 * @since 2.10.7 338 * 339 * @param string $title Notice title. 340 * @param string $message Optional failure detail. 341 * 342 * @return void 343 */ 344 private function set_refresh_failure( $title, $message = '' ) { 345 update_option( 'w3tcps_refresh_fail', $title ); 346 update_option( 'w3tcps_refresh_fail_message', $message ); 347 update_option( 'w3tcps_refresh_retry_after', time() + self::REFRESH_RETRY_DELAY ); 348 } 349 350 /** 351 * Returns operator-facing text for a token refresh failure. 352 * 353 * @since 2.10.7 354 * 355 * @param string $w3tc_error_id Nested W3 API error ID, if any. 356 * @param array $response_body Decoded response body. 357 * @param int $response_code HTTP response code. 358 * 359 * @return string 360 */ 361 private function get_refresh_failure_message( $w3tc_error_id, $response_body, $response_code ) { 362 switch ( $w3tc_error_id ) { 363 case 'refresh-token-missing-site-id': 364 return __( 'No site ID provided for access key refresh!', 'w3-total-cache' ); 365 366 case 'refresh-token-missing-w3tc-pagespeed-key': 367 return __( 'No W3TC API key provided for access key refresh!', 'w3-total-cache' ); 368 369 case 'refresh-token-not-found': 370 return __( 'No matching Google access record found for W3TC API key!', 'w3-total-cache' ); 371 372 case 'refresh-token-missing-refresh-token': 373 return __( 'Matching Google access record found but the refresh token value is blank!', 'w3-total-cache' ); 374 375 case 'refresh-token-google-failed': 376 return __( 'Google rejected the access token refresh. Local authorization was kept for retry.', 'w3-total-cache' ); 377 378 case 'refresh-token-persist-failed': 379 return __( 'The renewed Google access token could not be saved by the W3 API. Local authorization was kept for retry.', 'w3-total-cache' ); 380 } 381 382 if ( isset( $response_body['error'] ) && is_string( $response_body['error'] ) ) { 383 return __( 'Google rejected the access token refresh. Local authorization was kept for retry.', 'w3-total-cache' ); 384 } 385 386 return sprintf( 387 /* translators: %d: HTTP response code. */ 388 __( 'Unexpected token refresh response (HTTP %d).', 'w3-total-cache' ), 389 $response_code 390 ); 391 } 392 393 /** 394 * Removes local PageSpeed credentials after an irrecoverable API response. 395 * 396 * @since 2.10.7 397 * 398 * @return void 399 */ 400 private function clear_pagespeed_credentials() { 401 $this->w3tc_config->set( 'widget.pagespeed.access_token', '' ); 402 $this->w3tc_config->set( 'widget.pagespeed.w3tc_pagespeed_key', '' ); 403 $this->w3tc_config->save(); 404 delete_option( 'w3tcps_refresh_retry_after' ); 405 self::clear_pagespeed_cache(); 406 } 407 408 /** 409 * Validates a Google access token payload and stamps its creation time. 410 * 411 * `W3TCG_Google_Auth_OAuth2::isAccessTokenExpired()` treats a missing `created` 412 * value as expired, so every persist path must set it. 413 * 414 * @since 2.10.7 415 * 416 * @param array|string $w3tc_access_token Token payload or token JSON. 417 * 418 * @return string|false Token JSON to persist, or false when unusable. 419 */ 420 public static function prepare_access_token_json( $w3tc_access_token ) { 421 if ( is_string( $w3tc_access_token ) ) { 422 $w3tc_access_token = json_decode( $w3tc_access_token, true ); 423 } 424 425 if ( ! is_array( $w3tc_access_token ) ) { 426 return false; 427 } 428 429 if ( 430 empty( $w3tc_access_token['access_token'] ) || 431 ! is_string( $w3tc_access_token['access_token'] ) || 432 empty( $w3tc_access_token['expires_in'] ) || 433 ! is_numeric( $w3tc_access_token['expires_in'] ) 434 ) { 435 return false; 436 } 437 438 $w3tc_access_token['created'] = time(); 439 440 $w3tc_access_token_json = wp_json_encode( $w3tc_access_token ); 441 442 return is_string( $w3tc_access_token_json ) ? $w3tc_access_token_json : false; 443 } 444 445 /** 446 * Removes stored PageSpeed analysis results. 447 * 448 * Cache-first AJAX handlers must not serve scores once authorization is gone. 449 * 450 * @since 2.10.7 451 * 452 * @return void 453 */ 454 public static function clear_pagespeed_cache() { 455 global $wpdb; 456 457 delete_option( 'w3tc_pagespeed_data_' . get_home_url() ); 458 459 $option_names = $wpdb->get_col( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 460 $wpdb->prepare( 461 "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", 462 $wpdb->esc_like( 'w3tc_pagespeed_data_' ) . '%' 463 ) 464 ); 465 466 foreach ( (array) $option_names as $option_name ) { 467 delete_option( $option_name ); 468 } 469 } 470 471 /** 472 * Returns operator-facing text for PageSpeed access that was never authorized. 473 * 474 * @since 2.10.7 475 * 476 * @return string 477 */ 478 public static function get_authorize_required_message() { 479 return sprintf( 480 // translators: 1 HTML a tag to W3TC settings page Google PageSpeed meta box. 481 __( 482 'Before you can get started using the Google PageSpeed tool, you’ll first need to authorize access. Please click %1$s.', 483 'w3-total-cache' 484 ), 485 '<a href="' . esc_url( Util_Ui::admin_url( 'admin.php?page=w3tc_general#google_pagespeed' ) ) . '" target="_blank">' . esc_html__( 'here', 'w3-total-cache' ) . '</a>' 486 ); 487 } 488 489 /** 490 * Returns operator-facing text for stored PageSpeed access that could not be renewed. 491 * 492 * @since 2.10.7 493 * 494 * @return string 495 */ 496 public static function get_refresh_pending_message() { 497 return sprintf( 498 // translators: 1 HTML a tag to W3TC settings page Google PageSpeed meta box. 499 __( 500 'Google PageSpeed access is authorized but could not be renewed on the last attempt. W3 Total Cache will retry automatically. If this continues, reauthorize access %1$s.', 501 'w3-total-cache' 502 ), 503 '<a href="' . esc_url( Util_Ui::admin_url( 'admin.php?page=w3tc_general#google_pagespeed' ) ) . '" target="_blank">' . esc_html__( 'here', 'w3-total-cache' ) . '</a>' 504 ); 317 505 } 318 506 … … 387 575 388 576 /** 577 * Returns operator-facing text for an authorization failure. 578 * 579 * @since 2.10.7 580 * 581 * @param string $error_json W3 API authorization error JSON. 582 * 583 * @return string 584 */ 585 public static function get_authorize_failure_message( $error_json ) { 586 if ( ! is_string( $error_json ) ) { 587 $error_json = ''; 588 } 589 590 $error = json_decode( $error_json ); 591 $error_id = isset( $error->error->id ) ? (string) $error->error->id : ''; 592 if ( 1 !== preg_match( '/\A[a-z0-9-]+\z/', $error_id ) ) { 593 $error_id = ''; 594 } 595 596 switch ( $error_id ) { 597 case 'authorize-in-missing-site-id': 598 return __( 'Unique site ID missing for authorize request!', 'w3-total-cache' ); 599 600 case 'authorize-in-missing-auth-url': 601 return __( 'Authorize URL missing for authorize request!', 'w3-total-cache' ); 602 603 case 'authorize-in-missing-return-url': 604 return __( 'Return URL missing for authorize request!', 'w3-total-cache' ); 605 606 case 'authorize-in-failed': 607 return __( 'Failed to process authorize request!', 'w3-total-cache' ); 608 609 case 'authorize-out-code-missing': 610 return __( 'No authorize code returned to W3-API from Google!', 'w3-total-cache' ); 611 612 case 'authorize-out-site-id-missing': 613 return __( 'Unique site ID missing during Google authorization return processing!', 'w3-total-cache' ); 614 615 case 'authorize-out-w3tc-pagespeed-key-missing': 616 return __( 'No W3Key returned to W3-API from Google!', 'w3-total-cache' ); 617 618 case 'authorize-out-not-found': 619 return __( 'No W3-API matching record found during Google authorization return processing!', 'w3-total-cache' ); 620 621 case 'authorize-out-token-missing': 622 return __( 'No Google access token found during Google authorization return processing!', 'w3-total-cache' ); 623 624 case 'authorize-out-google-failed': 625 return __( 'Google rejected the authorization request. Please try authorizing Google PageSpeed again.', 'w3-total-cache' ); 626 627 case 'authorize-out-refresh-token-missing': 628 return __( 'Google did not return a refresh token. Please authorize Google PageSpeed again.', 'w3-total-cache' ); 629 630 case 'authorize-out-refresh-token-persist-failed': 631 return __( 'The Google refresh token could not be saved by the W3 API. Please try authorizing again after the service is updated.', 'w3-total-cache' ); 632 } 633 634 return sprintf( 635 /* translators: %s: Google authorization error ID. */ 636 __( 'Unexpected Google PageSpeed authorization error: %s', 'w3-total-cache' ), 637 '' !== $error_id ? $error_id : __( 'unknown', 'w3-total-cache' ) 638 ); 639 } 640 641 /** 642 * Clears PageSpeed failure notices and automatic refresh cooldown. 643 * 644 * @since 2.10.7 645 * 646 * @return void 647 */ 648 public static function clear_failure_notices() { 649 delete_option( 'w3tcps_refresh_fail' ); 650 delete_option( 'w3tcps_refresh_fail_message' ); 651 delete_option( 'w3tcps_refresh_retry_after' ); 652 delete_option( 'w3tcps_revoke_fail' ); 653 delete_option( 'w3tcps_revoke_fail_message' ); 654 } 655 656 /** 389 657 * Reset authentication. 390 658 * 391 659 * @since 2.3.0 660 * 661 * @return bool Whether local and remote authorization were reset. 392 662 */ 393 663 public function reset() { … … 401 671 __( 'Google PageSpeed access token revocation missing required parameters!', 'w3-total-cache' ) 402 672 ); 403 return ;673 return false; 404 674 } 405 675 … … 413 683 ); 414 684 415 $response_body_json = wp_remote_retrieve_body( $response );416 $response_body = json_decode( $response_body_json, true );417 418 685 if ( is_wp_error( $response ) ) { 419 return wp_json_encode( 420 array( 421 'error' => array( 422 'code' => $response->get_error_code(), 423 'message' => $response->get_error_message(), 424 ), 425 ) 426 ); 427 } elseif ( isset( $response_body['error']['code'] ) && 200 !== $response_body['error']['code'] ) { 428 if ( 'revoke-token-access-token-missing' === $response_body['error']['id'] ) { 429 $w3tc_message = __( 'No access token provided for revoke!', 'w3-total-cache' ); 430 } elseif ( 'revoke-token-api-key-missing' === $response_body['error']['id'] ) { 431 $w3tc_message = __( 'No W3TC API key provided for revoke!', 'w3-total-cache' ); 432 } elseif ( 'revoke-token-not-found' === $response_body['error']['id'] ) { 433 $w3tc_message = __( 'No matching Google access record found for W3TC API key!', 'w3-total-cache' ); 686 $this->set_revoke_failure( 687 $response->get_error_message() 688 ); 689 return false; 690 } 691 692 $response_code = (int) wp_remote_retrieve_response_code( $response ); 693 $response_body = json_decode( wp_remote_retrieve_body( $response ), true ); 694 if ( ! is_array( $response_body ) ) { 695 $response_body = array(); 696 } 697 698 $w3tc_error_id = ''; 699 if ( isset( $response_body['error'] ) && is_array( $response_body['error'] ) ) { 700 $w3tc_error_id = isset( $response_body['error']['id'] ) ? (string) $response_body['error']['id'] : ''; 701 } 702 703 if ( 704 $response_code < 200 || 705 $response_code >= 300 || 706 isset( $response_body['error'] ) 707 ) { 708 if ( 'revoke-token-not-found' === $w3tc_error_id ) { 709 $this->clear_pagespeed_credentials(); 710 self::clear_failure_notices(); 711 return true; 434 712 } 435 713 436 update_option( 437 'w3tcps_revoke_fail', 438 __( 'Google PageSpeed Access Token revocation failed.', 'w3-total-cache' ) 439 ); 440 update_option( 441 'w3tcps_revoke_fail_message', 442 $w3tc_message 443 ); 444 445 return; 446 } 447 448 $this->w3tc_config->set( 'widget.pagespeed.access_token', '' ); 449 $this->w3tc_config->set( 'widget.pagespeed.w3tc_pagespeed_key', '' ); 450 $this->w3tc_config->save(); 714 $this->set_revoke_failure( 715 $this->get_revoke_failure_message( $w3tc_error_id, $response_code ) 716 ); 717 return false; 718 } 719 720 $this->clear_pagespeed_credentials(); 721 self::clear_failure_notices(); 722 return true; 723 } 724 725 /** 726 * Records a token revocation failure for the admin notice. 727 * 728 * @since 2.10.7 729 * 730 * @param string $message Failure detail. 731 * 732 * @return void 733 */ 734 private function set_revoke_failure( $message ) { 735 update_option( 736 'w3tcps_revoke_fail', 737 __( 'Google PageSpeed Access Token revocation failed.', 'w3-total-cache' ) 738 ); 739 update_option( 'w3tcps_revoke_fail_message', $message ); 740 } 741 742 /** 743 * Returns operator-facing text for a token revocation failure. 744 * 745 * @since 2.10.7 746 * 747 * @param string $w3tc_error_id Nested W3 API error ID, if any. 748 * @param int $response_code HTTP response code. 749 * 750 * @return string 751 */ 752 private function get_revoke_failure_message( $w3tc_error_id, $response_code ) { 753 if ( 1 !== preg_match( '/\A[a-z0-9-]+\z/', $w3tc_error_id ) ) { 754 $w3tc_error_id = ''; 755 } 756 757 switch ( $w3tc_error_id ) { 758 case 'revoke-token-access-token-missing': 759 return __( 'No access token provided for revoke!', 'w3-total-cache' ); 760 761 case 'revoke-token-site-id-missing': 762 return __( 'No site ID provided for revoke!', 'w3-total-cache' ); 763 764 case 'revoke-token-api-key-missing': 765 return __( 'No W3TC API key provided for revoke!', 'w3-total-cache' ); 766 767 case 'revoke-token-not-found': 768 return __( 'No matching Google access record found for W3TC API key!', 'w3-total-cache' ); 769 770 case 'revoke-token-google-failed': 771 return __( 'Google rejected the access token revocation. Local authorization was kept for retry.', 'w3-total-cache' ); 772 773 case 'revoke-token-persist-failed': 774 return __( 'Google revoked the access token, but the W3 API could not save the result. Local authorization was kept for retry.', 'w3-total-cache' ); 775 } 776 777 return sprintf( 778 /* translators: 1: HTTP response code, 2: API error ID. */ 779 __( 'Unexpected token revocation response (HTTP %1$d, error %2$s).', 'w3-total-cache' ), 780 $response_code, 781 '' !== $w3tc_error_id ? $w3tc_error_id : __( 'unknown', 'w3-total-cache' ) 782 ); 451 783 } 452 784 } -
w3-total-cache/tags/2.10.7/PageSpeed_Page.php
r3585227 r3723494 101 101 $w3tc_config = Dispatcher::config(); 102 102 $w3tc_access_token = ! empty( $w3tc_config->get_string( 'widget.pagespeed.access_token' ) ) ? $w3tc_config->get_string( 'widget.pagespeed.access_token' ) : null; 103 104 if ( empty( $w3tc_access_token ) ) { 103 $w3tc_w3_pagespeed = empty( $w3tc_access_token ) ? null : new PageSpeed_Api( $w3tc_access_token ); 104 105 // Construction may clear credentials when a refresh is irrecoverable, so re-read the stored token. 106 $w3tc_stored_token = $w3tc_config->get_string( 'widget.pagespeed.access_token' ); 107 108 if ( empty( $w3tc_w3_pagespeed ) || empty( $w3tc_stored_token ) ) { 105 109 echo wp_json_encode( 106 110 array( 107 'missing_token' => sprintf( 108 // translators: 1 HTML a tag to W3TC settings page Google PageSpeed meta box. 109 __( 110 'Before you can get started using the Google PageSpeed tool, you’ll first need to authorize access. Please click %1$s.', 111 'w3-total-cache' 112 ), 113 '<a href="' . esc_url( Util_Ui::admin_url( 'admin.php?page=w3tc_general#google_pagespeed' ) ) . '" target="_blank">' . esc_html__( 'here', 'w3-total-cache' ) . '</a>' 114 ), 111 'missing_token' => PageSpeed_Api::get_authorize_required_message(), 115 112 ) 116 113 ); … … 118 115 } 119 116 120 $w3tc_w3_pagespeed = new PageSpeed_Api( $w3tc_access_token ); 121 $api_response = $w3tc_w3_pagespeed->analyze( $w3tc_url ); 117 if ( $w3tc_w3_pagespeed->client->isAccessTokenExpired() ) { 118 echo wp_json_encode( 119 array( 120 'refresh_failed' => PageSpeed_Api::get_refresh_pending_message(), 121 ) 122 ); 123 return; 124 } 125 126 $api_response = $w3tc_w3_pagespeed->analyze( $w3tc_url ); 122 127 123 128 if ( ! $api_response ) { -
w3-total-cache/tags/2.10.7/PageSpeed_Page_View.js
r3585227 r3723494 60 60 .removeClass("w3tc_none"); 61 61 return; 62 } else if (data.missing_token ) {62 } else if (data.missing_token || data.refresh_failed) { 63 63 $(".w3tcps_buttons").addClass("w3tc_none"); 64 64 $("#" + page_post_id) 65 65 .prev() 66 66 .find(".w3tcps_missing_token") 67 .html(data.missing_token );67 .html(data.missing_token || data.refresh_failed); 68 68 $("#" + page_post_id) 69 69 .prev() -
w3-total-cache/tags/2.10.7/PageSpeed_Widget.php
r3585227 r3723494 140 140 $w3tc_config = Dispatcher::config(); 141 141 $w3tc_access_token = ! empty( $w3tc_config->get_string( 'widget.pagespeed.access_token' ) ) ? $w3tc_config->get_string( 'widget.pagespeed.access_token' ) : null; 142 143 if ( empty( $w3tc_access_token ) ) { 142 $w3tc_w3_pagespeed = empty( $w3tc_access_token ) ? null : new PageSpeed_Api( $w3tc_access_token ); 143 144 // Construction may clear credentials when a refresh is irrecoverable, so re-read the stored token. 145 $w3tc_stored_token = $w3tc_config->get_string( 'widget.pagespeed.access_token' ); 146 147 if ( empty( $w3tc_w3_pagespeed ) || empty( $w3tc_stored_token ) ) { 144 148 echo wp_json_encode( 145 149 array( 146 'missing_token' => sprintf( 147 // translators: 1 HTML a tag to W3TC settings page Google PageSpeed meta box. 148 __( 149 'Before you can get started using the Google PageSpeed tool, you’ll first need to authorize access. Please click %1$s.', 150 'w3-total-cache' 151 ), 152 '<a href="' . esc_url( Util_Ui::admin_url( 'admin.php?page=w3tc_general#google_pagespeed' ) ) . '" target="_blank">' . esc_html__( 'here', 'w3-total-cache' ) . '</a>' 153 ), 150 'missing_token' => PageSpeed_Api::get_authorize_required_message(), 154 151 ) 155 152 ); … … 157 154 } 158 155 159 $w3tc_w3_pagespeed = new PageSpeed_Api( $w3tc_access_token ); 160 $api_response = $w3tc_w3_pagespeed->analyze( $home_url ); 156 if ( $w3tc_w3_pagespeed->client->isAccessTokenExpired() ) { 157 echo wp_json_encode( 158 array( 159 'refresh_failed' => PageSpeed_Api::get_refresh_pending_message(), 160 ) 161 ); 162 return; 163 } 164 165 $api_response = $w3tc_w3_pagespeed->analyze( $home_url ); 161 166 162 167 if ( ! $api_response ) { -
w3-total-cache/tags/2.10.7/PageSpeed_Widget_View.js
r3585227 r3723494 44 44 $(".w3tcps_error").removeClass("w3tc_none"); 45 45 return; 46 } else if (data.missing_token ) {46 } else if (data.missing_token || data.refresh_failed) { 47 47 $(".w3tcps_analyze").addClass("w3tc_none"); 48 $(".w3tcps_missing_token").html(data.missing_token); 48 $(".w3tcps_missing_token").html( 49 data.missing_token || data.refresh_failed, 50 ); 49 51 $(".w3tcps_missing_token").removeClass("w3tc_none"); 50 52 return; -
w3-total-cache/tags/2.10.7/PgCache_ConfigLabels.php
r3409715 r3723494 68 68 'pgcache.prime.interval' => __( 'Update interval:', 'w3-total-cache' ), 69 69 'pgcache.prime.limit' => __( 'Pages per interval:', 'w3-total-cache' ), 70 'pgcache.prime.sitemap_one_pass' => __( 'Preload the sitemap once', 'w3-total-cache' ), 70 71 'pgcache.prime.sitemap' => wp_kses( 71 72 sprintf( -
w3-total-cache/tags/2.10.7/PgCache_ContentGrabber.php
r3680101 r3723494 760 760 } 761 761 762 /**763 * Rewrite rules always list leftover MD5 names so a later764 * grace-constant toggle reaches PHP. That request must not765 * write a rejected-role page into the shared store when the766 * reader is still fail-closed.767 */768 762 if ( $this->_config->get_boolean( 'pgcache.reject.logged_roles' ) ) { 769 763 $roles = $this->_config->get_array( 'pgcache.reject.roles' ); 770 if ( ! empty( $roles ) && Util_Cookie::request_has_legacy_role_cookie( $roles ) ) {771 $this->cache_reject_reason = 'Rejected user role leftover cookie';764 if ( Util_Cookie::current_user_has_rejected_role( $roles ) ) { 765 $this->cache_reject_reason = 'Rejected user role is logged in'; 772 766 $this->process_status = 'miss_logged_in'; 773 767 return false; … … 1290 1284 } 1291 1285 1292 /**1293 * HMAC names always reject cache. Legacy MD5 names reject1294 * cache only when `W3TC_COOKIE_LEGACY_NAMES_ACCEPTED` is1295 * defined true in wp-config.php (default false as of 2.10.6).1296 */1297 1286 return ! Util_Cookie::request_has_rejected_role_cookie( $roles ); 1298 1287 } -
w3-total-cache/tags/2.10.7/PgCache_Environment.php
r3680101 r3723494 122 122 123 123 // Schedule prime event. 124 if ( $pgcache_enabled && $w3tc_config->get_boolean( 'pgcache.prime.enabled' ) ) { 124 $prime_enabled = $pgcache_enabled && $w3tc_config->get_boolean( 'pgcache.prime.enabled' ); 125 $one_pass = $w3tc_config->get_boolean( 'pgcache.prime.sitemap_one_pass' ); 126 $restart_prime = false; 127 $signature = $this->prime_settings_signature( $w3tc_config ); 128 129 if ( null !== $old_config ) { 130 $old_prime_enabled = ( 131 $old_config->get_boolean( 'pgcache.enabled' ) && 132 $old_config->get_boolean( 'pgcache.prime.enabled' ) 133 ); 134 $restart_prime = $prime_enabled && ( 135 ! $old_prime_enabled || 136 $one_pass !== $old_config->get_boolean( 'pgcache.prime.sitemap_one_pass' ) || 137 $w3tc_config->get_string( 'pgcache.prime.sitemap' ) !== 138 $old_config->get_string( 'pgcache.prime.sitemap' ) 139 ); 140 } else { 141 $stored_signature = get_option( PgCache_Plugin_Admin::PRIME_SETTINGS_OPTION, false ); 142 $restart_prime = ( 143 $prime_enabled && 144 false !== $stored_signature && 145 ! hash_equals( (string) $stored_signature, $signature ) 146 ); 147 } 148 149 if ( 'activate' === $event && $prime_enabled ) { 150 $restart_prime = true; 151 } 152 153 if ( ! $prime_enabled || $restart_prime ) { 154 PgCache_Plugin_Admin::reset_prime(); 155 } 156 157 update_option( PgCache_Plugin_Admin::PRIME_SETTINGS_OPTION, $signature, false ); 158 159 $prime_completed = ( 160 $one_pass && 161 PgCache_Plugin_Admin::prime_generation() === 162 get_option( PgCache_Plugin_Admin::PRIME_COMPLETED_OPTION, false ) 163 ); 164 165 if ( $prime_enabled && ! $prime_completed ) { 125 166 $new_interval = $w3tc_config->get_integer( 'pgcache.prime.interval' ); 126 167 $old_interval = $old_config ? $old_config->get_integer( 'pgcache.prime.interval' ) : -1; 127 168 128 if ( null !== $old_config && $new_interval !== $old_interval) {169 if ( $restart_prime || ( null !== $old_config && $new_interval !== $old_interval ) ) { 129 170 $this->unschedule_prime(); 130 171 } … … 146 187 } 147 188 } 189 } 190 191 /** 192 * Creates the per-site signature for effective preload settings. 193 * 194 * @since 2.10.7 195 * 196 * @param Config $w3tc_config W3TC configuration. 197 * 198 * @return string 199 */ 200 private function prime_settings_signature( $w3tc_config ) { 201 return hash( 202 'sha256', 203 wp_json_encode( 204 array( 205 'enabled' => ( 206 $w3tc_config->get_boolean( 'pgcache.enabled' ) && 207 $w3tc_config->get_boolean( 'pgcache.prime.enabled' ) 208 ), 209 'one_pass' => $w3tc_config->get_boolean( 'pgcache.prime.sitemap_one_pass' ), 210 'sitemap' => $w3tc_config->get_string( 'pgcache.prime.sitemap' ), 211 ) 212 ) 213 ); 148 214 } 149 215 … … 190 256 $this->unschedule_prime(); 191 257 $this->unschedule_purge_wpcron(); 258 PgCache_Plugin_Admin::reset_prime(); 192 259 193 260 if ( count( $exs->exceptions() ) > 0 ) { … … 496 563 private function wp_config_add_directive() { 497 564 $config_path = Util_Environment::wp_config_path(); 565 if ( ! is_string( $config_path ) || '' === $config_path ) { 566 return; 567 } 498 568 499 569 $config_data = @file_get_contents( $config_path ); … … 540 610 private function wp_config_remove_directive() { 541 611 $config_path = Util_Environment::wp_config_path(); 612 if ( ! is_string( $config_path ) || '' === $config_path ) { 613 return; 614 } 542 615 543 616 $config_data = @file_get_contents( $config_path ); -
w3-total-cache/tags/2.10.7/PgCache_Plugin.php
r3610528 r3723494 134 134 */ 135 135 public function prime() { 136 $this->get_admin()->prime(); 136 $one_pass = $this->_config->get_boolean( 'pgcache.prime.sitemap_one_pass' ); 137 $generation = PgCache_Plugin_Admin::prime_generation(); 138 139 if ( 140 $one_pass && 141 get_option( PgCache_Plugin_Admin::PRIME_COMPLETED_OPTION, false ) === $generation 142 ) { 143 wp_clear_scheduled_hook( 'w3_pgcache_prime' ); 144 return; 145 } 146 147 $lock = PgCache_Plugin_Admin::acquire_prime_lock(); 148 if ( false === $lock ) { 149 return; 150 } 151 152 try { 153 $result = $this->get_admin()->prime( null, null, null, true, $lock['generation'] ); 154 155 if ( 156 $one_pass && 157 ! empty( $result['success'] ) && 158 ! empty( $result['complete'] ) && 159 empty( $result['stale'] ) && 160 PgCache_Plugin_Admin::prime_generation() === $lock['generation'] 161 ) { 162 update_option( PgCache_Plugin_Admin::PRIME_COMPLETED_OPTION, $lock['generation'], false ); 163 164 if ( PgCache_Plugin_Admin::prime_generation() === $lock['generation'] ) { 165 wp_clear_scheduled_hook( 'w3_pgcache_prime' ); 166 } 167 } 168 } finally { 169 PgCache_Plugin_Admin::release_prime_lock( $lock['token'] ); 170 } 137 171 } 138 172 -
w3-total-cache/tags/2.10.7/PgCache_Plugin_Admin.php
r3585227 r3723494 17 17 class PgCache_Plugin_Admin { 18 18 /** 19 * Option storing the next sitemap entry to preload. 20 * 21 * @since 2.10.7 22 * 23 * @var string 24 */ 25 const PRIME_OFFSET_OPTION = 'w3tc_pgcache_prime_offset'; 26 27 /** 28 * Option recording completion of a one-pass preload. 29 * 30 * @since 2.10.7 31 * 32 * @var string 33 */ 34 const PRIME_COMPLETED_OPTION = 'w3tc_pgcache_prime_completed'; 35 36 /** 37 * Option identifying the current preload pass. 38 * 39 * @since 2.10.7 40 * 41 * @var string 42 */ 43 const PRIME_GENERATION_OPTION = 'w3tc_pgcache_prime_generation'; 44 45 /** 46 * Option coordinating overlapping preload callbacks. 47 * 48 * @since 2.10.7 49 * 50 * @var string 51 */ 52 const PRIME_LOCK_OPTION = 'w3tc_pgcache_prime_lock'; 53 54 /** 55 * Option storing the effective preload settings signature. 56 * 57 * @since 2.10.7 58 * 59 * @var string 60 */ 61 const PRIME_SETTINGS_OPTION = 'w3tc_pgcache_prime_settings'; 62 63 /** 64 * Maximum preload lock lifetime. 65 * 66 * @since 2.10.7 67 * 68 * @var int 69 */ 70 const PRIME_LOCK_TTL = 3600; 71 72 /** 73 * Sitemap traversal completed. 74 * 75 * @since 2.10.7 76 * 77 * @var string 78 */ 79 const SITEMAP_OUTCOME_SUCCESS = 'success'; 80 81 /** 82 * Sitemap entry was excluded by traversal policy. 83 * 84 * @since 2.10.7 85 * 86 * @var string 87 */ 88 const SITEMAP_OUTCOME_SKIPPED = 'skipped'; 89 90 /** 91 * Sitemap traversal encountered a retryable failure. 92 * 93 * @since 2.10.7 94 * 95 * @var string 96 */ 97 const SITEMAP_OUTCOME_FAILURE = 'failure'; 98 99 /** 19 100 * Config 20 101 * … … 30 111 public function __construct() { 31 112 $this->_config = Dispatcher::config(); 113 } 114 115 /** 116 * Returns the current per-site preload generation. 117 * 118 * @since 2.10.7 119 * 120 * @return string 121 */ 122 public static function prime_generation() { 123 $generation = get_option( self::PRIME_GENERATION_OPTION, '' ); 124 125 if ( '' === $generation ) { 126 $generation = wp_generate_uuid4(); 127 add_option( self::PRIME_GENERATION_OPTION, $generation, '', false ); 128 $generation = get_option( self::PRIME_GENERATION_OPTION, $generation ); 129 } 130 131 return (string) $generation; 132 } 133 134 /** 135 * Resets per-site preload progress and starts a new generation. 136 * 137 * The lock is retained so an in-flight callback remains the only writer. 138 * Its generation becomes stale and it will discard any progress. 139 * 140 * @since 2.10.7 141 * 142 * @return string New generation. 143 */ 144 public static function reset_prime() { 145 $generation = wp_generate_uuid4(); 146 147 update_option( self::PRIME_GENERATION_OPTION, $generation, false ); 148 update_option( self::PRIME_OFFSET_OPTION, 0, false ); 149 delete_option( self::PRIME_COMPLETED_OPTION ); 150 151 return $generation; 152 } 153 154 /** 155 * Acquires the per-site preload lock. 156 * 157 * @since 2.10.7 158 * 159 * @return array|false Lock data, or false when another run is active. 160 */ 161 public static function acquire_prime_lock() { 162 $lock = get_option( self::PRIME_LOCK_OPTION, false ); 163 164 if ( is_array( $lock ) && isset( $lock['expires'] ) && (int) $lock['expires'] <= time() ) { 165 delete_option( self::PRIME_LOCK_OPTION ); 166 $lock = false; 167 } 168 169 if ( false !== $lock ) { 170 return false; 171 } 172 173 $lock = array( 174 'token' => wp_generate_uuid4(), 175 'generation' => self::prime_generation(), 176 'expires' => time() + self::PRIME_LOCK_TTL, 177 ); 178 179 if ( ! add_option( self::PRIME_LOCK_OPTION, $lock, '', false ) ) { 180 return false; 181 } 182 183 return $lock; 184 } 185 186 /** 187 * Releases a preload lock owned by the supplied token. 188 * 189 * @since 2.10.7 190 * 191 * @param string $token Lock token. 192 * 193 * @return void 194 */ 195 public static function release_prime_lock( $token ) { 196 $lock = get_option( self::PRIME_LOCK_OPTION, false ); 197 198 if ( is_array( $lock ) && isset( $lock['token'] ) && hash_equals( (string) $lock['token'], (string) $token ) ) { 199 delete_option( self::PRIME_LOCK_OPTION ); 200 } 32 201 } 33 202 … … 137 306 * @param int|null $w3tc_limit The limit for how many pages to prime, or null for the default limit. 138 307 * @param callable|null $log_callback A callback function for logging progress, or null to disable logging. 139 * 140 * @return void 141 */ 142 public function prime( $start = null, $w3tc_limit = null, $log_callback = null ) { 308 * @param bool $update_progress Whether to update scheduled preload progress. 309 * @param string|null $generation Preload generation allowed to update progress. 310 * 311 * @return array Preload result. 312 */ 313 public function prime( 314 $start = null, 315 $w3tc_limit = null, 316 $log_callback = null, 317 $update_progress = true, 318 $generation = null 319 ) { 320 $result = array( 321 'success' => false, 322 'processed' => 0, 323 'complete' => false, 324 'stale' => false, 325 ); 326 143 327 if ( is_null( $start ) ) { 144 $start = get_option( 'w3tc_pgcache_prime_offset');328 $start = get_option( self::PRIME_OFFSET_OPTION ); 145 329 } 146 330 … … 149 333 } 150 334 151 $interval = $this->_config->get_integer( 'pgcache.prime.interval' );152 335 if ( is_null( $w3tc_limit ) ) { 153 336 $w3tc_limit = $this->_config->get_integer( 'pgcache.prime.limit' ); … … 166 349 } 167 350 168 // Parse XML sitemap. 169 $urls = $this->parse_sitemap( $sitemap ); 351 $parse_outcome = self::SITEMAP_OUTCOME_FAILURE; 352 $urls = $this->parse_sitemap( $sitemap, null, 0, $parse_outcome ); 353 354 if ( self::SITEMAP_OUTCOME_FAILURE === $parse_outcome ) { 355 return $result; 356 } 357 358 if ( empty( $urls ) ) { 359 $result['success'] = true; 360 $result['complete'] = true; 361 362 if ( $update_progress ) { 363 if ( self::prime_generation() !== $generation ) { 364 $result['stale'] = true; 365 return $result; 366 } 367 368 update_option( self::PRIME_OFFSET_OPTION, 0, false ); 369 } 370 371 return $result; 372 } 170 373 171 374 // Queue URLs. … … 178 381 } 179 382 180 update_option( 'w3tc_pgcache_prime_offset', $next_offset, false ); 383 if ( empty( $queue ) ) { 384 if ( $update_progress && self::prime_generation() === $generation ) { 385 update_option( self::PRIME_OFFSET_OPTION, 0, false ); 386 } 387 388 return $result; 389 } 181 390 182 391 /** … … 185 394 */ 186 395 foreach ( $queue as $w3tc_url ) { 187 Util_Http::get( $w3tc_url, array( 'user-agent' => 'WordPress' ) ); 396 $response = Util_Http::get( $w3tc_url, array( 'user-agent' => 'WordPress' ) ); 397 398 if ( 399 is_wp_error( $response ) || 400 200 > wp_remote_retrieve_response_code( $response ) || 401 500 <= wp_remote_retrieve_response_code( $response ) 402 ) { 403 return $result; 404 } 188 405 189 406 if ( ! is_null( $log_callback ) ) { … … 191 408 } 192 409 } 410 411 $result['success'] = true; 412 $result['processed'] = count( $queue ); 413 $result['complete'] = 0 === $next_offset; 414 415 if ( $update_progress ) { 416 if ( self::prime_generation() !== $generation ) { 417 $result['stale'] = true; 418 return $result; 419 } 420 421 update_option( self::PRIME_OFFSET_OPTION, $next_offset, false ); 422 423 if ( self::prime_generation() !== $generation ) { 424 update_option( self::PRIME_OFFSET_OPTION, 0, false ); 425 $result['stale'] = true; 426 } 427 } 428 429 return $result; 193 430 } 194 431 … … 216 453 * fetches must match. Auto-populated. 217 454 * @param int $depth Internal: current recursion depth (0-based). 455 * @param string|null $outcome Set to a SITEMAP_OUTCOME_* value. 218 456 * 219 457 * @return array The list of URLs parsed from the sitemap. 220 458 */ 221 public function parse_sitemap( $w3tc_url, $origin_host = null, $depth = 0 ) { 459 public function parse_sitemap( $w3tc_url, $origin_host = null, $depth = 0, &$outcome = null ) { 460 $outcome = self::SITEMAP_OUTCOME_FAILURE; 461 222 462 if ( ! Util_Environment::is_url( $w3tc_url ) ) { 223 463 $w3tc_url = home_url( $w3tc_url ); … … 235 475 */ 236 476 if ( $depth > 3 ) { 477 $outcome = self::SITEMAP_OUTCOME_SKIPPED; 237 478 return array(); 238 479 } … … 243 484 */ 244 485 if ( ! Util_Url::is_public_host( $w3tc_url ) ) { 486 // A refused root may be a transient resolution failure and must retry. 487 if ( $depth > 0 ) { 488 $outcome = self::SITEMAP_OUTCOME_SKIPPED; 489 } 245 490 return array(); 246 491 } … … 255 500 * drop it from the fetch list. 256 501 */ 502 $outcome = self::SITEMAP_OUTCOME_SKIPPED; 257 503 return array(); 258 504 } 259 505 260 $urls = array( $w3tc_url);506 $urls = array(); 261 507 $response = Util_Http::get( $w3tc_url ); 262 508 263 if ( ! is_wp_error( $response ) && 200 === $response['response']['code'] ) { 264 $url_matches = null; 265 $sitemap_matches = null; 266 267 /** 268 * Parse the fetched sitemap XML with XXE protections. The body is 269 * fetched from an admin-configured (and origin-host-constrained) 270 * sitemap URL, so a hostile or compromised endpoint must not be 271 * able to use external entities to read local files or pivot to 272 * internal services. Util_Environment::safe_simplexml_load_string() 273 * also handles the libxml error-suppression dance. 274 */ 275 $xml = Util_Environment::safe_simplexml_load_string( $response['body'] ); 276 277 // Check if the XML load failed; return the URLs found so far (sitemap URL). 278 if ( false === $xml ) { 279 return $urls; 280 } 281 282 if ( $xml->getName() === 'sitemapindex' ) { 283 foreach ( $xml->sitemap as $sitemap ) { 284 if ( $sitemap->loc ) { 285 $urls = array_merge( 286 $urls, 287 $this->parse_sitemap( (string) $sitemap->loc, $origin_host, $depth + 1 ) 288 ); 509 if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { 510 return $urls; 511 } 512 513 /** 514 * Parse the fetched sitemap XML with XXE protections. The body is 515 * fetched from an admin-configured (and origin-host-constrained) 516 * sitemap URL, so a hostile or compromised endpoint must not be 517 * able to use external entities to read local files or pivot to 518 * internal services. Util_Environment::safe_simplexml_load_string() 519 * also handles the libxml error-suppression dance. 520 */ 521 $xml = Util_Environment::safe_simplexml_load_string( $response['body'] ); 522 523 if ( false === $xml ) { 524 return $urls; 525 } 526 527 if ( $xml->getName() === 'sitemapindex' ) { 528 foreach ( $xml->sitemap as $sitemap ) { 529 if ( $sitemap->loc ) { 530 $child_outcome = self::SITEMAP_OUTCOME_FAILURE; 531 $child_urls = $this->parse_sitemap( 532 (string) $sitemap->loc, 533 $origin_host, 534 $depth + 1, 535 $child_outcome 536 ); 537 538 if ( self::SITEMAP_OUTCOME_FAILURE === $child_outcome ) { 539 return array(); 289 540 } 541 542 $urls = array_merge( $urls, $child_urls ); 290 543 } 291 } elseif ( $xml->getName() === 'urlset' ) {292 $locs = array();293 294 foreach ( $xml->url as $w3tc_url ) { 295 if ( $w3tc_url->loc) {296 $priority = isset( $w3tc_url->priority ) ? (float) $w3tc_url->priority : 0.5;297 $locs[ (string) $w3tc_url->loc ] = $priority;298 }544 } 545 } elseif ( $xml->getName() === 'urlset' ) { 546 $locs = array(); 547 548 foreach ( $xml->url as $w3tc_url ) { 549 if ( $w3tc_url->loc ) { 550 $priority = isset( $w3tc_url->priority ) ? (float) $w3tc_url->priority : 0.5; 551 $locs[ (string) $w3tc_url->loc ] = $priority; 299 552 } 300 301 arsort( $locs ); 302 303 $urls = array_merge( $urls, array_keys( $locs ) ); 304 } elseif ( $xml->getName() === 'rss' ) {305 foreach ( $xml->channel->item as $w3tc_item) {306 if ( $w3tc_item->link) {307 $urls[] = (string) $w3tc_item->link;308 }553 } 554 555 arsort( $locs ); 556 557 $urls = array_keys( $locs ); 558 } elseif ( $xml->getName() === 'rss' ) { 559 foreach ( $xml->channel->item as $w3tc_item ) { 560 if ( $w3tc_item->link ) { 561 $urls[] = (string) $w3tc_item->link; 309 562 } 310 563 } 311 } 312 564 } else { 565 return $urls; 566 } 567 568 $outcome = self::SITEMAP_OUTCOME_SUCCESS; 313 569 return $urls; 314 570 } -
w3-total-cache/tags/2.10.7/Root_Environment.php
r3585227 r3723494 79 79 foreach ( $this->get_handlers() as $h ) { 80 80 try { 81 $h->fix_on_event( $w3tc_config, $event );81 $h->fix_on_event( $w3tc_config, $event, $old_config ); 82 82 } catch ( Util_Environment_Exceptions $ex ) { 83 83 $exs->push( $ex ); -
w3-total-cache/tags/2.10.7/Util_Cookie.php
r3680101 r3723494 42 42 * `AUTH_KEY`/`AUTH_SALT` invalidates these cookies cleanly. 43 43 * 44 * Migration: HMAC names are written and accepted. Legacy MD5 45 * names are no longer accepted on the cache-auth read path 46 * unless `W3TC_COOKIE_LEGACY_NAMES_ACCEPTED` is defined true in 47 * wp-config.php. Rewrite-rule emitters always list both names so 48 * a later constant toggle reaches PHP on disk-enhanced installs 49 * without regenerating rules. The PHP writer still refuses to 50 * store a response when a leftover MD5 name is present, so the 51 * rewrite superset cannot land a rejected-role page in the 52 * shared store. Logout still clears leftover legacy cookies. 44 * Role cookies use HMAC names only. Pre-HMAC leftover cookies 45 * are ignored on read and write. 53 46 * 54 47 * @since 2.10.0 55 48 */ 56 49 class Util_Cookie { 57 58 /**59 * Whether a legacy role cookie has already been audit-logged60 * this request.61 *62 * @since 2.10.663 *64 * @var bool65 */66 private static $legacy_honor_logged = false;67 68 /**69 * Role slug waiting to be audit-logged after plugins load.70 *71 * @since 2.10.672 *73 * @var string|null74 */75 private static $legacy_honor_pending_role = null;76 50 77 51 /** … … 205 179 206 180 /** 207 * Returns the legacy MD5 cookie-name suffix for a given WP role.208 *209 * Writers always use `role_cookie_name()`. Cache-auth readers210 * honor this only when `legacy_role_names_accepted()` is true.211 * Rewrite-rule emitters always list it so toggling the212 * wp-config constant does not require regenerating rules.213 * Logout still uses it to clear leftover pre-upgrade cookies.214 *215 * @since 2.10.0216 *217 * @param string $role WordPress role slug.218 *219 * @return string 32-char lowercase hex.220 */221 public static function role_cookie_name_legacy( $role ) {222 $nonce_key = defined( 'NONCE_KEY' ) ? (string) NONCE_KEY : '';223 224 return \md5( $nonce_key . (string) $role );225 }226 227 /**228 * Whether cache-auth readers may honor the pre-HMAC MD5229 * role-cookie name.230 *231 * Default is false (fail closed). The only production switch is232 * `W3TC_COOKIE_LEGACY_NAMES_ACCEPTED` defined true in233 * wp-config.php. A plugin filter cannot reach the234 * `advanced-cache.php` path and is therefore not consulted.235 * Rewrite reject lists always include both names; this method236 * is the live PHP read decision. The PHP writer uses237 * `request_has_legacy_role_cookie()` and refuses leftover MD5238 * names even when this returns false.239 *240 * @since 2.10.6241 *242 * @return bool243 */244 public static function legacy_role_names_accepted() {245 return defined( 'W3TC_COOKIE_LEGACY_NAMES_ACCEPTED' ) && true === W3TC_COOKIE_LEGACY_NAMES_ACCEPTED;246 }247 248 /**249 181 * Cookie names written into page-cache rewrite reject lists 250 182 * for a given role. 251 *252 * Always includes the HMAC name and the leftover MD5 name.253 * Disk-enhanced Apache/Nginx serve static files before PHP254 * runs, so the leftover name must stay in the generated rules255 * or a later `W3TC_COOKIE_LEGACY_NAMES_ACCEPTED` toggle cannot256 * take effect until rules are rewritten. The PHP reader still257 * consults `legacy_role_names_accepted()` on every request.258 183 * 259 184 * @since 2.10.6 … … 266 191 return array( 267 192 'w3tc_logged_' . self::role_cookie_name( $role ), 268 'w3tc_logged_' . self::role_cookie_name_legacy( $role ),269 193 ); 270 194 } … … 272 196 /** 273 197 * Whether a request cookie name matches a rejected role. 274 *275 * HMAC names always match. Legacy MD5 names match only when276 * `legacy_role_names_accepted()` is true; a match is audit-logged277 * once per request so a site that turns the grace window on is278 * visible in `w3tc_audit_log`.279 198 * 280 199 * Malformed or unrecognized `w3tc_logged_*` names never match. … … 292 211 } 293 212 294 $role = (string) $role; 295 296 if ( false !== \strstr( $cookie_name, self::role_cookie_name( $role ) ) ) { 297 return true; 298 } 299 300 if ( ! self::cookie_matches_legacy_role_name( $cookie_name, $role ) ) { 301 return false; 302 } 303 304 if ( ! self::legacy_role_names_accepted() ) { 305 return false; 306 } 307 308 self::log_legacy_role_cookie_honored( $role ); 309 return true; 310 } 311 312 /** 313 * Whether a request cookie name is the leftover MD5 name for a role. 314 * 315 * Independent of `legacy_role_names_accepted()`. Used to refuse 316 * page-cache writes so a rewrite-listed leftover cookie cannot 317 * store a rejected-role response. 318 * 319 * @since 2.10.6 320 * 321 * @param string $cookie_name Raw cookie name from the request. 322 * @param string $role WordPress role slug. 323 * 324 * @return bool 325 */ 326 public static function cookie_matches_legacy_role_name( $cookie_name, $role ) { 327 if ( ! is_string( $cookie_name ) || 0 !== \strpos( $cookie_name, 'w3tc_logged_' ) ) { 328 return false; 329 } 330 331 return false !== \strstr( $cookie_name, self::role_cookie_name_legacy( (string) $role ) ); 213 return false !== \strstr( $cookie_name, self::role_cookie_name( (string) $role ) ); 332 214 } 333 215 … … 362 244 363 245 /** 364 * Whether the current request carries a leftover MD5 role cookie. 365 * 366 * True regardless of `W3TC_COOKIE_LEGACY_NAMES_ACCEPTED`. Page 367 * cache must not *write* in that case; *read* still follows 368 * `request_has_rejected_role_cookie()`. 369 * 370 * @since 2.10.6 246 * Whether the current WordPress user has a rejected page-cache role. 247 * 248 * Used on the page-cache write path after WordPress has loaded. 249 * The early `advanced-cache.php` read path cannot use this. 250 * 251 * @since 2.10.7 371 252 * 372 253 * @param string[] $roles Role slugs configured for cache rejection. … … 374 255 * @return bool 375 256 */ 376 public static function request_has_legacy_role_cookie( $roles ) {257 public static function current_user_has_rejected_role( $roles ) { 377 258 if ( ! is_array( $roles ) || empty( $roles ) ) { 378 259 return false; 379 260 } 380 261 381 if ( empty( $_COOKIE ) || ! is_array( $_COOKIE ) ) { 382 return false; 383 } 384 385 foreach ( \array_keys( $_COOKIE ) as $cookie_name ) { 386 foreach ( $roles as $role ) { 387 if ( self::cookie_matches_legacy_role_name( (string) $cookie_name, (string) $role ) ) { 388 return true; 389 } 262 if ( ! \function_exists( 'is_user_logged_in' ) || ! \function_exists( 'wp_get_current_user' ) ) { 263 return false; 264 } 265 266 if ( ! \is_user_logged_in() ) { 267 return false; 268 } 269 270 $current_user = \wp_get_current_user(); 271 272 if ( empty( $current_user->roles ) || ! is_array( $current_user->roles ) ) { 273 return false; 274 } 275 276 foreach ( $current_user->roles as $role ) { 277 if ( \in_array( $role, $roles, true ) ) { 278 return true; 390 279 } 391 280 } … … 393 282 return false; 394 283 } 395 396 /**397 * Audit-log that a legacy MD5 role cookie was honored.398 *399 * Once per request. Does not record cookie names. When this400 * runs from `advanced-cache.php`, `w3tc_audit_log` subscribers401 * have not registered yet, so the event is deferred until402 * `plugins_loaded`. Honoring the cookie skips page cache, so403 * WordPress continues and the hook fires.404 *405 * @since 2.10.6406 *407 * @param string $role WordPress role slug.408 *409 * @return void410 */411 private static function log_legacy_role_cookie_honored( $role ) {412 if ( self::$legacy_honor_logged ) {413 return;414 }415 416 self::$legacy_honor_logged = true;417 self::$legacy_honor_pending_role = (string) $role;418 419 if ( \function_exists( 'did_action' ) && \function_exists( 'add_action' ) && ! \did_action( 'plugins_loaded' ) ) {420 \add_action(421 'plugins_loaded',422 array( __CLASS__, 'flush_legacy_honor_log' ),423 \PHP_INT_MAX424 );425 return;426 }427 428 self::flush_legacy_honor_log();429 }430 431 /**432 * Dispatch a deferred legacy-honor audit event.433 *434 * @since 2.10.6435 *436 * @internal Invoked from `plugins_loaded`. Unit tests may call directly.437 *438 * @return void439 */440 public static function flush_legacy_honor_log() {441 if ( null === self::$legacy_honor_pending_role ) {442 return;443 }444 445 $role = self::$legacy_honor_pending_role;446 self::$legacy_honor_pending_role = null;447 448 Util_Debug::audit_log(449 'cookie.legacy_role_name',450 array(451 'role' => $role,452 )453 );454 }455 456 /**457 * Resets the once-per-request legacy honor log.458 *459 * @since 2.10.6460 *461 * @internal Unit tests only.462 *463 * @return void464 */465 public static function reset_legacy_honor_log() {466 self::$legacy_honor_logged = false;467 self::$legacy_honor_pending_role = null;468 469 if ( \function_exists( 'remove_action' ) ) {470 \remove_action( 'plugins_loaded', array( __CLASS__, 'flush_legacy_honor_log' ), \PHP_INT_MAX );471 }472 }473 284 } -
w3-total-cache/tags/2.10.7/Util_Environment.php
r3680101 r3723494 2207 2207 $cidrs = array(); 2208 2208 } 2209 } catch ( \ Exception$e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch2209 } catch ( \Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch 2210 2210 $cidrs = array(); 2211 2211 } … … 2249 2249 ); 2250 2250 } 2251 } catch ( \ Exception$e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch2251 } catch ( \Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch 2252 2252 $cidrs = array(); 2253 2253 } -
w3-total-cache/tags/2.10.7/Util_Http.php
r3680101 r3723494 103 103 } 104 104 105 $public_only = ! empty( $args['w3tc_public_only'] ); 106 $https_only = ! empty( $args['w3tc_https_only'] ); 107 $same_host = ! empty( $args['w3tc_same_host'] ); 108 $max_size = isset( $args['w3tc_max_response_size'] ) ? (int) $args['w3tc_max_response_size'] : 0; 109 $validator = isset( $args['w3tc_response_validator'] ) && \is_callable( $args['w3tc_response_validator'] ) ? 110 $args['w3tc_response_validator'] : 111 null; 112 unset( 113 $args['w3tc_public_only'], 114 $args['w3tc_https_only'], 115 $args['w3tc_same_host'], 116 $args['w3tc_max_response_size'], 117 $args['w3tc_response_validator'] 118 ); 119 120 $original_host = self::normalized_url_host( $w3tc_url ); 121 if ( $same_host && '' === $original_host ) { 122 return false; 123 } 124 105 125 /** 106 126 * Follow Location responses manually so each hop is evaluated 107 * with {@see Util_Url::is_allowed_outbound_url()} before the next 108 * request. Automatic redirect following would skip that check. 127 * against the requested policy before the next request. 109 128 */ 110 129 $max_redirects = 5; 111 130 for ( $hop = 0; $hop <= $max_redirects; $hop++ ) { 112 if ( ! Util_Url::is_allowed_outbound_url( $w3tc_url ) ) { 131 if ( $https_only && 'https' !== \wp_parse_url( $w3tc_url, PHP_URL_SCHEME ) ) { 132 return false; 133 } 134 135 if ( $same_host && self::normalized_url_host( $w3tc_url ) !== $original_host ) { 136 return false; 137 } 138 139 $allowed = $public_only ? 140 Util_Url::is_public_host( $w3tc_url ) : 141 Util_Url::is_allowed_outbound_url( $w3tc_url ); 142 if ( ! $allowed ) { 113 143 return false; 114 144 } … … 120 150 ) 121 151 ); 152 if ( $max_size > 0 ) { 153 $request_args['limit_response_size'] = $max_size + 1; 154 } 122 155 123 156 $response = self::get( $w3tc_url, $request_args ); … … 145 178 } 146 179 147 return (bool) @file_put_contents( $w3tc_file, $response['body'] ); 180 $body = isset( $response['body'] ) && \is_string( $response['body'] ) ? $response['body'] : ''; 181 if ( ( $max_size > 0 && \strlen( $body ) > $max_size ) || ( $validator && ! \call_user_func( $validator, $response ) ) ) { 182 return false; 183 } 184 185 return (bool) @file_put_contents( $w3tc_file, $body ); 148 186 } 149 187 150 188 return false; 189 } 190 191 /** 192 * Returns a normalized host for redirect comparisons. 193 * 194 * @since 2.10.7 195 * 196 * @param string $url URL to inspect. 197 * 198 * @return string 199 */ 200 private static function normalized_url_host( $url ) { 201 $host = \wp_parse_url( $url, PHP_URL_HOST ); 202 203 return \is_string( $host ) ? \strtolower( \rtrim( $host, '.' ) ) : ''; 151 204 } 152 205 … … 196 249 } 197 250 198 $location = Util_Url::normalize_protocol_relative_url( $location );199 if ( '' === $location ) {200 return '';201 }202 203 if ( Util_Environment::is_url( $location ) ) {204 return $location;205 }206 207 251 $parts = \wp_parse_url( $current ); 208 252 if ( ! \is_array( $parts ) || empty( $parts['scheme'] ) || empty( $parts['host'] ) ) { … … 210 254 } 211 255 212 $authority = $parts['scheme'] . '://' . $parts['host']; 213 if ( ! empty( $parts['port'] ) ) { 214 $authority .= ':' . $parts['port']; 215 } 216 217 if ( isset( $location[0] ) && '/' === $location[0] ) { 218 return $authority . $location; 219 } 220 221 $base_path = isset( $parts['path'] ) ? $parts['path'] : '/'; 222 $base_dir = \trailingslashit( \dirname( $base_path ) ); 223 224 return $authority . $base_dir . $location; 256 // A protocol-relative Location keeps the scheme of the hop that returned it. 257 if ( 0 === \strpos( $location, '//' ) ) { 258 $location = $parts['scheme'] . ':' . $location; 259 } 260 261 if ( ! \class_exists( '\WP_Http' ) ) { 262 return ''; 263 } 264 265 $resolved = \WP_Http::make_absolute_url( $location, $current ); 266 267 return Util_Url::is_valid_http_scheme( $resolved ) ? $resolved : ''; 225 268 } 226 269 -
w3-total-cache/tags/2.10.7/changelog.txt
r3680101 r3723494 1 1 === W3 Total Cache Changelog === 2 3 = 2.10.7 = 4 * Feature: Minify: Cache selected external scripts locally for auto minify 5 * Feature: Page Cache: Add a one-pass mode for sitemap cache preload 6 * Enhancement: Developers: Add a generated reference of supported actions and filters 7 * Fix: Browser Cache: Constrain unquoted URL rewriting when removing query strings from static resources 8 * Fix: Page Cache: Remove the expired role-cookie compatibility path and skip caching for rejected roles 9 * Fix: Page Cache: Avoid Options API calls before WordPress has loaded them during early bootstrap 10 * Fix: Object Cache: Persist cache invalidation from wp-admin when admin object caching is disabled 11 * Fix: CDN: Preserve custom attachment directories when pushing media 12 * Fix: Google PageSpeed: Renew expired access tokens without discarding authorization 13 * Fix: Licensing: Show the activation-limit notice for licenses that have reached their limit 14 * Fix: Settings: Persist Purge via WP-Cron schedule settings 15 * Fix: Settings: Skip unchanged w3tc_state option writes 16 * Update: Remove leftover newsletter signup code 17 * Update: Build: Omit development-only files from the release ZIP 2 18 3 19 = 2.10.6 = -
w3-total-cache/tags/2.10.7/inc/options/common/footer.php
r3585227 r3723494 112 112 <div class="w3tc-footer-inner-column-50"> 113 113 <h2><?php esc_html_e( 'Follow Us', 'w3-total-cache' ); ?></h2> 114 <a class="w3tc-footer-link" target="_blank" href="<?php echo esc_url( 'https://www.boldgrid.com/w3-total-cache/newsletter-signup/?utm_source=w3tc&utm_medium=footer_link&utm_campaign=newsletter_signup' ); ?>">115 <span class="dashicons dashicons-email-alt"></span><?php esc_html_e( 'Newsletter Sign Up', 'w3-total-cache' ); ?>116 </a>117 114 <a class="w3tc-footer-link" target="_blank" href="<?php echo esc_url( 'https://twitter.com/w3edge' ); ?>" alt="<?php esc_attr_e( 'W3 Edge', 'w3-total-cache' ); ?>"> 118 115 <span class="dashicons dashicons-twitter"></span><?php esc_html_e( 'W3 Edge', 'w3-total-cache' ); ?> -
w3-total-cache/tags/2.10.7/inc/options/general.php
r3680101 r3723494 1266 1266 1267 1267 if ( ! empty( $w3tc_authorize_error ) ) { 1268 $w3tc_authorize_error = json_decode( $w3tc_authorize_error ); 1269 1270 if ( 'authorize-in-missing-site-id' === $w3tc_authorize_error->error->id ) { 1271 $w3tc_message = __( 'Unique site ID missing for authorize request!', 'w3-total-cache' ); 1272 } elseif ( 'authorize-in-missing-auth-url' === $w3tc_authorize_error->error->id ) { 1273 $w3tc_message = __( 'Authorize URL missing for authorize request!', 'w3-total-cache' ); 1274 } elseif ( 'authorize-in-missing-return-url' === $w3tc_authorize_error->error->id ) { 1275 $w3tc_message = __( 'Return URL missing for authorize request!', 'w3-total-cache' ); 1276 } elseif ( 'authorize-in-failed' === $w3tc_authorize_error->error->id ) { 1277 $w3tc_message = __( 'Failed to process authorize request!', 'w3-total-cache' ); 1278 } 1279 1280 if ( 'authorize-out-code-missing' === $w3tc_authorize_error->error->id ) { 1281 $w3tc_message = __( 'No authorize code returned to W3-API from Google!', 'w3-total-cache' ); 1282 } elseif ( 'authorize-out-w3tc-pagespeed-key-missing' === $w3tc_authorize_error->error->id ) { 1283 $w3tc_message = __( 'No W3Key return to W3-API from Google!', 'w3-total-cache' ); 1284 } elseif ( 'authorize-out-not-found' === $w3tc_authorize_error->error->id ) { 1285 $w3tc_message = __( 'No W3-API matching record found during Google authorization return processing!', 'w3-total-cache' ); 1286 } elseif ( 'authorize-out-token-missing' === $w3tc_authorize_error->error->id ) { 1287 $w3tc_message = __( 'No Google access token found during Google authorization return processing!', 'w3-total-cache' ); 1288 } 1268 $w3tc_message = PageSpeed_Api::get_authorize_failure_message( $w3tc_authorize_error ); 1289 1269 1290 1270 update_option( … … 1300 1280 exit; 1301 1281 } elseif ( ! empty( $w3tc_access_token ) && ! empty( $w3tc_pagespeed_key ) ) { 1302 $this->_config->set( 'widget.pagespeed.access_token', $w3tc_access_token ); 1303 $this->_config->set( 'widget.pagespeed.w3tc_pagespeed_key', $w3tc_pagespeed_key ); 1304 $this->_config->save(); 1282 $w3tc_access_token_prepared = PageSpeed_Api::prepare_access_token_json( $w3tc_access_token ); 1283 1284 if ( false === $w3tc_access_token_prepared ) { 1285 update_option( 1286 'w3tcps_authorize_fail', 1287 __( 'Google PageSpeed Insights API authorization failed.', 'w3-total-cache' ) 1288 ); 1289 update_option( 1290 'w3tcps_authorize_fail_message', 1291 __( 'Google PageSpeed authorization returned an unusable access token.', 'w3-total-cache' ) 1292 ); 1293 } else { 1294 $this->_config->set( 'widget.pagespeed.access_token', $w3tc_access_token_prepared ); 1295 $this->_config->set( 'widget.pagespeed.w3tc_pagespeed_key', $w3tc_pagespeed_key ); 1296 $this->_config->save(); 1297 PageSpeed_Api::clear_failure_notices(); 1298 } 1305 1299 1306 1300 wp_safe_redirect( $w3tc_return_url ); 1307 1301 exit; 1308 1302 } elseif ( $w3tc_deauthorize ) { 1309 $w3tc_w3_pagespeed->reset(); 1310 update_option( 1311 'w3tcps_authorize_success', 1312 __( 'Google PageSpeed Insights API authorization successfully reset.', 'w3-total-cache' ) 1313 ); 1303 if ( $w3tc_w3_pagespeed->reset() ) { 1304 update_option( 1305 'w3tcps_authorize_success', 1306 __( 'Google PageSpeed Insights API authorization successfully reset.', 'w3-total-cache' ) 1307 ); 1308 } 1314 1309 wp_safe_redirect( $w3tc_return_url ); 1315 1310 exit; -
w3-total-cache/tags/2.10.7/inc/options/pgcache.php
r3598169 r3723494 400 400 </p> 401 401 </td> 402 </tr> 403 <tr> 404 <th colspan="2"> 405 <?php $this->checkbox( 'pgcache.prime.sitemap_one_pass' ); ?> <?php Util_Ui::e_config_label( 'pgcache.prime.sitemap_one_pass' ); ?></label> 406 <p class="description"> 407 <?php esc_html_e( 'Stop cache preloading after every URL in the sitemap has been processed. Disable and re-enable cache preloading to start a new pass.', 'w3-total-cache' ); ?> 408 </p> 409 </th> 402 410 </tr> 403 411 <tr> -
w3-total-cache/tags/2.10.7/languages/w3-total-cache.pot
r3680101 r3723494 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: W3 Total Cache 2.10. 6\n"5 "Project-Id-Version: W3 Total Cache 2.10.7\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/w3-total-cache\n" 7 7 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2026- 09-03T16:54:00+00:00\n"12 "POT-Creation-Date: 2026-10-01T16:35:43+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.12.0\n" … … 36 36 #. Author of the plugin 37 37 #: w3-total-cache.php 38 #: inc/options/common/footer.php:117 39 #: inc/options/common/footer.php:118 38 40 #: inc/options/common/footer.php:120 39 41 #: inc/options/common/footer.php:121 40 #: inc/options/common/footer.php:12341 #: inc/options/common/footer.php:12442 42 msgid "BoldGrid" 43 43 msgstr "" … … 156 156 #: inc/options/minify.php:908 157 157 #: inc/options/minify.php:1211 158 #: inc/options/pgcache.php:11 18158 #: inc/options/pgcache.php:1126 159 159 #: Minify_ConfigLabels.php:176 160 160 #: Minify_ConfigLabels.php:195 161 #: PgCache_ConfigLabels.php:13 0161 #: PgCache_ConfigLabels.php:131 162 162 msgid "Hypertext Transfer Protocol" 163 163 msgstr "" … … 268 268 #: inc/options/browsercache.php:594 269 269 #: inc/options/browsercache.php:920 270 #: inc/options/pgcache.php:7 39271 #: inc/options/pgcache.php:8 42270 #: inc/options/pgcache.php:747 271 #: inc/options/pgcache.php:850 272 272 #: Minify_ConfigLabels.php:87 273 #: PgCache_ConfigLabels.php:7 7273 #: PgCache_ConfigLabels.php:78 274 274 msgid "Uniform Resource Locator" 275 275 msgstr "" … … 1079 1079 #: inc/options/objectcache.php:233 1080 1080 #: inc/options/pgcache.php:273 1081 #: inc/options/pgcache.php:6 621082 #: inc/options/pgcache.php:6 751083 #: inc/options/pgcache.php:10 561081 #: inc/options/pgcache.php:670 1082 #: inc/options/pgcache.php:683 1083 #: inc/options/pgcache.php:1064 1084 1084 #: Minify_ConfigLabels.php:98 1085 1085 #: Minify_ConfigLabels.php:133 1086 1086 #: Minify_ConfigLabels.php:185 1087 #: PgCache_ConfigLabels.php:10 51087 #: PgCache_ConfigLabels.php:106 1088 1088 #: SystemOpCache_GeneralPage_View.php:62 1089 1089 #: UsageStatistics_GeneralPage_View.php:42 … … 1491 1491 #: Cdn_BunnyCdn_Page_View.php:32 1492 1492 #: Cdn_BunnyCdn_Popup_View_Deauthorize.php:59 1493 #: inc/options/general.php:13 301493 #: inc/options/general.php:1325 1494 1494 msgid "Deauthorize" 1495 1495 msgstr "" … … 1503 1503 #: Cdn_RackSpaceCloudFiles_Page_View.php:20 1504 1504 #: Extension_CloudFlare_Page_View.php:68 1505 #: inc/options/general.php:13 411505 #: inc/options/general.php:1336 1506 1506 msgid "Authorize" 1507 1507 msgstr "" … … 2762 2762 #: Cdn_ConfigLabels.php:193 2763 2763 #: Minify_ConfigLabels.php:239 2764 #: PgCache_ConfigLabels.php:14 32764 #: PgCache_ConfigLabels.php:144 2765 2765 msgid "Rejected user agents:" 2766 2766 msgstr "" … … 2770 2770 msgstr "" 2771 2771 2772 #: Cdn_Core_Admin.php:81 52772 #: Cdn_Core_Admin.php:817 2773 2773 msgid "Purge from CDN" 2774 2774 msgstr "" … … 3045 3045 #: inc/options/minify.php:204 3046 3046 #: inc/options/minify.php:230 3047 #: inc/options/pgcache.php:112 03047 #: inc/options/pgcache.php:1128 3048 3048 #: Minify_ConfigLabels.php:38 3049 3049 #: Util_Ui.php:2388 … … 3112 3112 #: inc/options/general.php:747 3113 3113 #: inc/options/general.php:782 3114 #: inc/options/pgcache.php:5 633115 #: inc/options/pgcache.php:6 353114 #: inc/options/pgcache.php:571 3115 #: inc/options/pgcache.php:643 3116 3116 msgid "Application Programming Interface" 3117 3117 msgstr "" … … 3456 3456 3457 3457 #. translators: 1: Error message. 3458 #: Cli.php:60 03458 #: Cli.php:601 3459 3459 #, php-format 3460 3460 msgid "PageCache Priming did failed: %1$s" 3461 3461 msgstr "" 3462 3462 3463 #: Cli.php:60 63463 #: Cli.php:607 3464 3464 msgid "PageCache Priming triggered successfully." 3465 3465 msgstr "" 3466 3466 3467 #: Cli.php:61 73467 #: Cli.php:618 3468 3468 msgid "Always Cached feature is not enabled." 3469 3469 msgstr "" 3470 3470 3471 3471 #. translators: 1: Error message. 3472 #: Cli.php:62 83472 #: Cli.php:629 3473 3473 #, php-format 3474 3474 msgid "Always Cached queue processer failed: %1$s" 3475 3475 msgstr "" 3476 3476 3477 #: Cli.php:63 43477 #: Cli.php:635 3478 3478 msgid "Always Cached queue processed successfully." 3479 3479 msgstr "" 3480 3480 3481 #: Cli.php:64 53481 #: Cli.php:646 3482 3482 msgid "Always Cached feature is not enabled" 3483 3483 msgstr "" 3484 3484 3485 3485 #. translators: 1: Error message. 3486 #: Cli.php:65 63486 #: Cli.php:657 3487 3487 #, php-format 3488 3488 msgid "Always Cached queue empty failed: %1$s" 3489 3489 msgstr "" 3490 3490 3491 #: Cli.php:66 23491 #: Cli.php:663 3492 3492 msgid "Always Cached queue emptied successfully." 3493 3493 msgstr "" … … 3791 3791 3792 3792 #: DbCache_ConfigLabels.php:29 3793 #: PgCache_ConfigLabels.php:1 393793 #: PgCache_ConfigLabels.php:140 3794 3794 msgid "Maximum lifetime of cache objects:" 3795 3795 msgstr "" … … 3799 3799 #: Minify_ConfigLabels.php:205 3800 3800 #: ObjectCache_ConfigLabels.php:29 3801 #: PgCache_ConfigLabels.php:14 03801 #: PgCache_ConfigLabels.php:141 3802 3802 msgid "Garbage collection interval:" 3803 3803 msgstr "" 3804 3804 3805 3805 #: DbCache_ConfigLabels.php:31 3806 #: PgCache_ConfigLabels.php:14 53806 #: PgCache_ConfigLabels.php:146 3807 3807 msgid "Never cache the following pages:" 3808 3808 msgstr "" … … 3828 3828 #: Extension_AlwaysCached_Page_View_BoxCron.php:35 3829 3829 #: inc/options/general.php:565 3830 #: inc/options/pgcache.php:10 553830 #: inc/options/pgcache.php:1063 3831 3831 #: Minify_ConfigLabels.php:242 3832 3832 #: ObjectCache_ConfigLabels.php:34 … … 3837 3837 #: Extension_AlwaysCached_Page_View_BoxCron.php:59 3838 3838 #: inc/options/general.php:584 3839 #: inc/options/pgcache.php:10 753839 #: inc/options/pgcache.php:1083 3840 3840 #: Minify_ConfigLabels.php:243 3841 3841 #: ObjectCache_ConfigLabels.php:35 … … 3848 3848 #: Extension_AlwaysCached_Page_View_BoxCron.php:73 3849 3849 #: inc/options/general.php:595 3850 #: inc/options/pgcache.php:10 863850 #: inc/options/pgcache.php:1094 3851 3851 #: Minify_ConfigLabels.php:244 3852 3852 #: ObjectCache_ConfigLabels.php:36 … … 4199 4199 #: inc/options/minify.php:1172 4200 4200 #: inc/options/objectcache.php:257 4201 #: inc/options/pgcache.php:10 784201 #: inc/options/pgcache.php:1086 4202 4202 msgid "This setting controls the initial start time of the cron job. If the selected time has already passed, it will schedule the job for the following day at the selected time." 4203 4203 msgstr "" … … 4208 4208 #: inc/options/minify.php:1183 4209 4209 #: inc/options/objectcache.php:268 4210 #: inc/options/pgcache.php:10 894210 #: inc/options/pgcache.php:1097 4211 4211 msgid "Hourly" 4212 4212 msgstr "" … … 4217 4217 #: inc/options/minify.php:1184 4218 4218 #: inc/options/objectcache.php:269 4219 #: inc/options/pgcache.php:109 04219 #: inc/options/pgcache.php:1098 4220 4220 msgid "Twice Daily" 4221 4221 msgstr "" … … 4226 4226 #: inc/options/minify.php:1185 4227 4227 #: inc/options/objectcache.php:270 4228 #: inc/options/pgcache.php:109 14228 #: inc/options/pgcache.php:1099 4229 4229 msgid "Daily" 4230 4230 msgstr "" … … 4235 4235 #: inc/options/minify.php:1186 4236 4236 #: inc/options/objectcache.php:271 4237 #: inc/options/pgcache.php:1 0924237 #: inc/options/pgcache.php:1100 4238 4238 msgid "Weekly" 4239 4239 msgstr "" … … 4244 4244 #: inc/options/minify.php:1188 4245 4245 #: inc/options/objectcache.php:273 4246 #: inc/options/pgcache.php:1 0944246 #: inc/options/pgcache.php:1102 4247 4247 msgid "This setting controls the interval that the cron job should occur." 4248 4248 msgstr "" … … 5165 5165 #: inc/options/objectcache.php:200 5166 5166 #: inc/options/pgcache.php:30 5167 #: inc/options/pgcache.php:102 05167 #: inc/options/pgcache.php:1028 5168 5168 #: ObjectCache_DiskPopup_View.php:33 5169 5169 #: UserExperience_Preload_Requests_Page_View.php:31 … … 5224 5224 #: inc/options/minify.php:943 5225 5225 #: inc/options/objectcache.php:79 5226 #: inc/options/pgcache.php:6 545226 #: inc/options/pgcache.php:662 5227 5227 #: Util_Ui.php:2367 5228 5228 #: Util_Ui.php:2441 … … 5252 5252 #: inc/options/objectcache.php:105 5253 5253 #: inc/options/pgcache.php:344 5254 #: inc/options/pgcache.php:7 595255 #: inc/options/pgcache.php:7 855256 #: inc/options/pgcache.php: 7975254 #: inc/options/pgcache.php:767 5255 #: inc/options/pgcache.php:793 5256 #: inc/options/pgcache.php:805 5257 5257 msgid "seconds" 5258 5258 msgstr "" … … 5268 5268 #: inc/options/minify.php:979 5269 5269 #: inc/options/objectcache.php:107 5270 #: inc/options/pgcache.php:7 875270 #: inc/options/pgcache.php:795 5271 5271 msgid "If caching to disk, specify how frequently expired cache data is removed. For busy sites, a lower value is best." 5272 5272 msgstr "" … … 6087 6087 #: PageSpeed_Instructions.php:263 6088 6088 #: PgCache_ConfigLabels.php:27 6089 #: PgCache_Plugin.php:3 536090 #: PgCache_Plugin.php:3 616091 #: PgCache_Plugin.php: 3696092 #: PgCache_Plugin.php: 3896089 #: PgCache_Plugin.php:387 6090 #: PgCache_Plugin.php:395 6091 #: PgCache_Plugin.php:403 6092 #: PgCache_Plugin.php:423 6093 6093 #: Root_AdminMenu.php:63 6094 6094 #: Root_AdminMenu.php:64 … … 8896 8896 #. translators: 1 W3TC_CACHE_FILE_EXPIRE_MAX constant name, 2 W3TC_CACHE_FILE_EXPIRE_MAX value. 8897 8897 #: inc/options/browsercache.php:681 8898 #: inc/options/pgcache.php:7 668898 #: inc/options/pgcache.php:774 8899 8899 #, php-format 8900 8900 msgid "Max lifetime is limited by the %1$s constant (%2$s seconds) which can be overridden in wp-config.php." … … 9537 9537 msgstr "" 9538 9538 9539 #: inc/options/common/footer.php:114 9539 9540 #: inc/options/common/footer.php:115 9540 msgid "Newsletter Sign Up"9541 msgstr ""9542 9543 #: inc/options/common/footer.php:1179544 #: inc/options/common/footer.php:1189545 9541 msgid "W3 Edge" 9546 9542 msgstr "" 9547 9543 9548 #: inc/options/common/footer.php:12 89544 #: inc/options/common/footer.php:125 9549 9545 msgid "Partners" 9550 9546 msgstr "" … … 9662 9658 #: inc/options/minify.php:1104 9663 9659 #: inc/options/objectcache.php:195 9664 #: inc/options/pgcache.php:101 09660 #: inc/options/pgcache.php:1018 9665 9661 #: Util_Ui.php:2284 9666 9662 #: Util_Ui.php:2368 … … 9677 9673 #: inc/options/dbcache.php:218 9678 9674 #: inc/options/minify.php:1113 9679 #: inc/options/pgcache.php:10 199675 #: inc/options/pgcache.php:1027 9680 9676 msgid "Scheduling Page Cache purges" 9681 9677 msgstr "" … … 9706 9702 #: inc/options/edd/buy.php:47 9707 9703 #: inc/options/pgcache.php:105 9704 #: PageSpeed_Api.php:485 9705 #: PageSpeed_Api.php:503 9708 9706 #: PageSpeed_Instructions.php:295 9709 9707 #: PageSpeed_Instructions.php:362 9710 #: PageSpeed_Page.php:1139711 9708 #: PageSpeed_Widget.php:104 9712 #: PageSpeed_Widget.php:1529713 9709 msgid "here" 9714 9710 msgstr "" … … 10252 10248 msgstr "" 10253 10249 10254 #: inc/options/general.php:1271 10255 msgid "Unique site ID missing for authorize request!" 10256 msgstr "" 10257 10258 #: inc/options/general.php:1273 10259 msgid "Authorize URL missing for authorize request!" 10260 msgstr "" 10261 10262 #: inc/options/general.php:1275 10263 msgid "Return URL missing for authorize request!" 10264 msgstr "" 10265 10266 #: inc/options/general.php:1277 10267 msgid "Failed to process authorize request!" 10268 msgstr "" 10269 10270 #: inc/options/general.php:1281 10271 msgid "No authorize code returned to W3-API from Google!" 10272 msgstr "" 10273 10274 #: inc/options/general.php:1283 10275 msgid "No W3Key return to W3-API from Google!" 10276 msgstr "" 10277 10278 #: inc/options/general.php:1285 10279 msgid "No W3-API matching record found during Google authorization return processing!" 10280 msgstr "" 10281 10250 #: inc/options/general.php:1272 10282 10251 #: inc/options/general.php:1287 10283 msgid "No Google access token found during Google authorization return processing!"10284 msgstr ""10285 10286 #: inc/options/general.php:129210287 10252 msgid "Google PageSpeed Insights API authorization failed." 10288 10253 msgstr "" 10289 10254 10290 #: inc/options/general.php:1312 10255 #: inc/options/general.php:1291 10256 msgid "Google PageSpeed authorization returned an unusable access token." 10257 msgstr "" 10258 10259 #: inc/options/general.php:1306 10291 10260 msgid "Google PageSpeed Insights API authorization successfully reset." 10292 10261 msgstr "" 10293 10262 10294 #: inc/options/general.php:132 510263 #: inc/options/general.php:1320 10295 10264 msgid "Valid" 10296 10265 msgstr "" 10297 10266 10298 #: inc/options/general.php:13 4210267 #: inc/options/general.php:1337 10299 10268 msgid "Allow W3 Total Cache to connect to the PageSpeed Insights API on your behalf." 10300 10269 msgstr "" 10301 10270 10302 #: inc/options/general.php:135 810271 #: inc/options/general.php:1353 10303 10272 #: Util_Ui.php:2332 10304 10273 msgid "Import / Export Settings" 10305 10274 msgstr "" 10306 10275 10307 #: inc/options/general.php:135 910276 #: inc/options/general.php:1354 10308 10277 msgid "This tool allows users to easily transfer their W3 Total Cache plugin settings between different WordPress installations by exporting the current configuration as a file and importing it on another site, ensuring consistent caching and performance optimizations across multiple websites." 10309 10278 msgstr "" 10310 10279 10311 #: inc/options/general.php:13 7010280 #: inc/options/general.php:1365 10312 10281 msgid "Import configuration:" 10313 10282 msgstr "" 10314 10283 10284 #: inc/options/general.php:1368 10285 msgid "Upload" 10286 msgstr "" 10287 10288 #: inc/options/general.php:1369 10289 msgid "Upload and replace the active settings file." 10290 msgstr "" 10291 10315 10292 #: inc/options/general.php:1373 10316 msgid "Upload"10317 msgstr ""10318 10319 #: inc/options/general.php:137410320 msgid "Upload and replace the active settings file."10321 msgstr ""10322 10323 #: inc/options/general.php:137810324 10293 msgid "Export configuration:" 10325 10294 msgstr "" 10326 10295 10296 #: inc/options/general.php:1375 10297 msgid "Download" 10298 msgstr "" 10299 10300 #: inc/options/general.php:1376 10301 msgid "Download the active settings file." 10302 msgstr "" 10303 10327 10304 #: inc/options/general.php:1380 10328 msgid "Download"10329 msgstr ""10330 10331 #: inc/options/general.php:138110332 msgid "Download the active settings file."10333 msgstr ""10334 10335 #: inc/options/general.php:138510336 10305 msgid "Reset configuration:" 10337 10306 msgstr "" 10338 10307 10339 #: inc/options/general.php:138 710308 #: inc/options/general.php:1382 10340 10309 msgid "Restore Default Settings" 10341 10310 msgstr "" 10342 10311 10343 #: inc/options/general.php:138 810312 #: inc/options/general.php:1383 10344 10313 msgid "Revert all settings to the defaults. Any settings staged in preview mode will not be modified." 10345 10314 msgstr "" … … 10789 10758 10790 10759 #: inc/options/minify.php:1237 10791 #: inc/options/pgcache.php:8 0810792 #: inc/options/pgcache.php:81 010760 #: inc/options/pgcache.php:816 10761 #: inc/options/pgcache.php:818 10793 10762 msgid "Time to Live" 10794 10763 msgstr "" … … 11221 11190 11222 11191 #: inc/options/pgcache.php:407 11192 msgid "Stop cache preloading after every URL in the sitemap has been processed. Disable and re-enable cache preloading to start a new pass." 11193 msgstr "" 11194 11195 #: inc/options/pgcache.php:415 11223 11196 msgid "Only applies to pages, posts, and custom post types whose status transitioned from a non-published status to the \"published\" status." 11224 11197 msgstr "" 11225 11198 11226 #: inc/options/pgcache.php:4 1611199 #: inc/options/pgcache.php:424 11227 11200 msgid "Applies after updating any page, post, or custom post type with the final status being \"published\"." 11228 11201 msgstr "" 11229 11202 11230 #: inc/options/pgcache.php:4 3611203 #: inc/options/pgcache.php:444 11231 11204 msgid "Purge Policy: " 11232 11205 msgstr "" 11233 11206 11234 #: inc/options/pgcache.php:4 4211207 #: inc/options/pgcache.php:450 11235 11208 msgid "Specify the pages and feeds to purge when posts are created, edited, or comments posted. The defaults are recommended because additional options may reduce server performance:" 11236 11209 msgstr "" 11237 11210 11238 #: inc/options/pgcache.php:4 4311211 #: inc/options/pgcache.php:451 11239 11212 msgid "Specify pages and feeds to purge" 11240 11213 msgstr "" 11241 11214 11242 #: inc/options/pgcache.php:4 7911215 #: inc/options/pgcache.php:487 11243 11216 msgid "Choose which feed types should be automatically purged." 11244 11217 msgstr "" 11245 11218 11246 11219 #. translators: 1 HTML line break tag. 11247 #: inc/options/pgcache.php:5 0611220 #: inc/options/pgcache.php:514 11248 11221 #, php-format 11249 11222 msgid "Specify number of pages that lists posts (archive etc.) that should be purged on post updates etc., i.e. example.com/ ... example.com/page/5. %1$s0 means all pages that lists posts are purged, i.e. example.com/page/2 ... " 11250 11223 msgstr "" 11251 11224 11252 #: inc/options/pgcache.php:53 011225 #: inc/options/pgcache.php:538 11253 11226 msgid "Specify additional pages to purge. Including parent page in path. Ex: parent/posts." 11254 11227 msgstr "" 11255 11228 11256 #: inc/options/pgcache.php:5 4211229 #: inc/options/pgcache.php:550 11257 11230 msgid "Specify a regular expression that matches your sitemaps." 11258 11231 msgstr "" 11259 11232 11260 11233 #. translators: 3 opening HTML acronym tag, 4 closing HTML acronym tag. 11261 #: inc/options/pgcache.php:5 5711234 #: inc/options/pgcache.php:565 11262 11235 #, php-format 11263 11236 msgid "%1$sREST%2$s %3$sAPI%4$s" 11264 11237 msgstr "" 11265 11238 11266 #: inc/options/pgcache.php:56 111267 #: inc/options/pgcache.php:6 3311239 #: inc/options/pgcache.php:569 11240 #: inc/options/pgcache.php:641 11268 11241 msgid "REpresentational State Transfer" 11269 11242 msgstr "" 11270 11243 11271 11244 #. translators: 1 opening HTML acronym tag, 2 closing HTML acronym tag, 3 opening HTML acronym tag, 4 closing HTML acronym tag. 11272 #: inc/options/pgcache.php:5 8211245 #: inc/options/pgcache.php:590 11273 11246 #, php-format 11274 11247 msgid "Use these controls to determine how the WordPress %1$sREST%2$s %3$sAPI%4$s responds to visitors and integrations. Caching API responses can dramatically reduce load when headless frontends, mobile apps, or third-party services request the same data repeatedly, but you can keep responses uncached for highly dynamic endpoints or disable the API altogether when it is not needed to reduce attack surface." 11275 11248 msgstr "" 11276 11249 11277 #: inc/options/pgcache.php: 59711250 #: inc/options/pgcache.php:605 11278 11251 msgid "REST API" 11279 11252 msgstr "" 11280 11253 11281 #: inc/options/pgcache.php:6 0911254 #: inc/options/pgcache.php:617 11282 11255 msgid "Don't cache" 11283 11256 msgstr "" 11284 11257 11285 #: inc/options/pgcache.php:61 111258 #: inc/options/pgcache.php:619 11286 11259 msgid "Cache" 11287 11260 msgstr "" 11288 11261 11289 #: inc/options/pgcache.php:6 1411262 #: inc/options/pgcache.php:622 11290 11263 msgid "If you're using the WordPress API make sure to use caching to scale performance." 11291 11264 msgstr "" 11292 11265 11293 #: inc/options/pgcache.php:6 1611266 #: inc/options/pgcache.php:624 11294 11267 msgid "If you use WordPress as a backend for integrations, API caching may be for you. Similar to page caching, repeat requests will benefit by having significantly lower response times and consume fewer resources to deliver. If WordPress is not used as a backend, for additional security, the API can be disabled completely." 11295 11268 msgstr "" 11296 11269 11297 #: inc/options/pgcache.php:6 1911270 #: inc/options/pgcache.php:627 11298 11271 msgid "Potential API Response Time Gain" 11299 11272 msgstr "" 11300 11273 11301 #: inc/options/pgcache.php:62 111274 #: inc/options/pgcache.php:629 11302 11275 msgid "API Response Time" 11303 11276 msgstr "" 11304 11277 11305 #: inc/options/pgcache.php:6 2211278 #: inc/options/pgcache.php:630 11306 11279 msgid "In a recent test, enabling REST API Caching increased API response times by 84%!" 11307 11280 msgstr "" 11308 11281 11309 11282 #. translators: 3 opening HTML acronym tag, 4 closing HTML acronym tag. 11310 #: inc/options/pgcache.php:6 2911283 #: inc/options/pgcache.php:637 11311 11284 #, php-format 11312 11285 msgid "Disable %1$sREST%2$s %3$sAPI%4$s" 11313 11286 msgstr "" 11314 11287 11315 #: inc/options/pgcache.php:6 5811288 #: inc/options/pgcache.php:666 11316 11289 msgid "Late initialization:" 11317 11290 msgstr "" 11318 11291 11319 #: inc/options/pgcache.php:6 6411292 #: inc/options/pgcache.php:672 11320 11293 msgid "Enables support for WordPress functionality in fragment caching for the page caching engine. Use of this feature may increase response times." 11321 11294 msgstr "" 11322 11295 11323 #: inc/options/pgcache.php:6 6511296 #: inc/options/pgcache.php:673 11324 11297 msgid "Late initialization" 11325 11298 msgstr "" 11326 11299 11327 #: inc/options/pgcache.php:67 111300 #: inc/options/pgcache.php:679 11328 11301 msgid "Late caching:" 11329 11302 msgstr "" 11330 11303 11331 #: inc/options/pgcache.php:6 7711304 #: inc/options/pgcache.php:685 11332 11305 msgid "Overwrites key of page caching via custom filters by postponing entry extraction during the init action." 11333 11306 msgstr "" 11334 11307 11335 #: inc/options/pgcache.php:6 7811308 #: inc/options/pgcache.php:686 11336 11309 msgid "Late caching" 11337 11310 msgstr "" 11338 11311 11339 #: inc/options/pgcache.php: 69411312 #: inc/options/pgcache.php:702 11340 11313 msgid "Compatibility mode:" 11341 11314 msgstr "" 11342 11315 11343 #: inc/options/pgcache.php: 69911316 #: inc/options/pgcache.php:707 11344 11317 msgid "Decreases performance by ~20% at scale in exchange for increasing interoperability with more hosting environments and WordPress idiosyncrasies. Enable this option if you experience issues with the Apache rules." 11345 11318 msgstr "" 11346 11319 11347 #: inc/options/pgcache.php:7 0711320 #: inc/options/pgcache.php:715 11348 11321 msgid "Charset:" 11349 11322 msgstr "" 11350 11323 11351 #: inc/options/pgcache.php:7 1211324 #: inc/options/pgcache.php:720 11352 11325 msgid "Resolve issues incorrect odd character encoding that may appear in cached pages." 11353 11326 msgstr "" 11354 11327 11355 #: inc/options/pgcache.php:72 011328 #: inc/options/pgcache.php:728 11356 11329 msgid "Reject HEAD requests:" 11357 11330 msgstr "" 11358 11331 11359 11332 #. translators: 1 opening HTML acronym tag, 2 closing HTML acronym tag. 11360 #: inc/options/pgcache.php:7 3511333 #: inc/options/pgcache.php:743 11361 11334 #, php-format 11362 11335 msgid "If disabled, HEAD requests can often be cached resulting in \"empty pages\" being returned for subsequent requests for a %1$sURL%2$s." 11363 11336 msgstr "" 11364 11337 11365 #: inc/options/pgcache.php:76 011338 #: inc/options/pgcache.php:768 11366 11339 msgid "Determines the natural expiration time of cache items. The higher the value, the larger the cache." 11367 11340 msgstr "" 11368 11341 11369 11342 #. translators: 3 opening HTML acronym tag, 4 closing HTML acronym tag. 11370 #: inc/options/pgcache.php:8 0411343 #: inc/options/pgcache.php:812 11371 11344 #, php-format 11372 11345 msgid "Significantly reduce the default %1$sTTL%2$s for comment cookies to reduce the number of authenticated user traffic. Enter -1 to revert to default %3$sTTL%4$s." … … 11374 11347 11375 11348 #. translators: 1 opening HTML acronym tag, 2 closing HTML acronym tag. 11376 #: inc/options/pgcache.php:8 3811349 #: inc/options/pgcache.php:846 11377 11350 #, php-format 11378 11351 msgid "Always cache %1$sURL%2$ss that use these query string name-value pairs. The value part is not required. But if used, separate name-value pairs with an equals sign (i.e., name=value). Each pair should be on their own line." 11379 11352 msgstr "" 11380 11353 11381 #: inc/options/pgcache.php:8 6511354 #: inc/options/pgcache.php:873 11382 11355 msgid "Never send cache pages for these user agents." 11383 11356 msgstr "" 11384 11357 11385 #: inc/options/pgcache.php:8 7911358 #: inc/options/pgcache.php:887 11386 11359 msgid "Never cache pages that use the specified cookies." 11387 11360 msgstr "" 11388 11361 11389 #: inc/options/pgcache.php: 89411362 #: inc/options/pgcache.php:902 11390 11363 msgid "Always ignore the specified pages / directories. Supports regular expressions." 11391 11364 msgstr "" 11392 11365 11393 #: inc/options/pgcache.php:9 0811366 #: inc/options/pgcache.php:916 11394 11367 msgid "Always ignore all pages filed under the specified category slugs." 11395 11368 msgstr "" 11396 11369 11397 #: inc/options/pgcache.php:9 2211370 #: inc/options/pgcache.php:930 11398 11371 msgid "Always ignore all pages filed under the specified tag slugs." 11399 11372 msgstr "" 11400 11373 11401 #: inc/options/pgcache.php:9 3611374 #: inc/options/pgcache.php:944 11402 11375 msgid "Always ignore all pages filed under the specified author usernames." 11403 11376 msgstr "" 11404 11377 11405 #: inc/options/pgcache.php:95 011378 #: inc/options/pgcache.php:958 11406 11379 msgid "Always ignore all pages filed under the specified custom fields. Separate name-value pairs with an equals sign (i.e., name=value)." 11407 11380 msgstr "" 11408 11381 11409 #: inc/options/pgcache.php:9 6611382 #: inc/options/pgcache.php:974 11410 11383 msgid "Cache the specified pages / directories even if listed in the \"never cache the following pages\" field. Supports regular expression." 11411 11384 msgstr "" 11412 11385 11413 #: inc/options/pgcache.php:9 8611386 #: inc/options/pgcache.php:994 11414 11387 msgid "Cache the specified pages even if they don't have trailing slash." 11415 11388 msgstr "" 11416 11389 11417 #: inc/options/pgcache.php:100 111390 #: inc/options/pgcache.php:1009 11418 11391 msgid "Specify additional page headers to cache." 11419 11392 msgstr "" 11420 11393 11421 #: inc/options/pgcache.php:10 1411394 #: inc/options/pgcache.php:1022 11422 11395 msgid "Enabling this will schedule a WP-Cron event that will flush the Page Cache. If you prefer to use a system cron job instead of WP-Cron, you can schedule the following command to run at your desired interval: \"wp w3tc flush posts\". If the Always Cached extension is active and enabled, page cache entries will instead be added to the queue instead of being purged from the cache." 11423 11396 msgstr "" 11424 11397 11425 11398 #. Translators: 3 closing HTML a tag, 4 closing HTML p tag followed by closing HTML div tag. 11426 #: inc/options/pgcache.php:10 3411399 #: inc/options/pgcache.php:1042 11427 11400 #, php-format 11428 11401 msgid "%1$sPage Cache is disabled! Enable it %2$shere%3$s to enable this feature.%4$s" 11429 11402 msgstr "" 11430 11403 11431 #: inc/options/pgcache.php:11 0211404 #: inc/options/pgcache.php:1110 11432 11405 #: Util_Ui.php:2369 11433 11406 #: Util_Ui.php:2443 … … 11437 11410 11438 11411 #. translators: 5 opening HTML a tag to W3TC BrowserCache admin page, 6 closing HTML a tag. 11439 #: inc/options/pgcache.php:11 1411412 #: inc/options/pgcache.php:1122 11440 11413 #, php-format 11441 11414 msgid "Enable %1$sHTTP%2$s compression in the \"%3$sHTML%4$s\" section on %5$sBrowser Cache</a> Settings tab." … … 11658 11631 11659 11632 #: lib/NetDNA/NetDNAPresentation.php:74 11633 #: PageSpeed_Api.php:637 11634 #: PageSpeed_Api.php:781 11660 11635 msgid "unknown" 11661 11636 msgstr "" … … 11735 11710 msgstr "" 11736 11711 11712 #. Translators: 1 Product name. 11713 #: Licensing_Plugin_Admin.php:697 11714 #, php-format 11715 msgid "Your %1$s license key is not active and cannot be activated due to the license activation limit being reached." 11716 msgstr "" 11717 11737 11718 #. Translators: 1 Product name, 2 opening HTML a tag to reset license URIs, 3 closing HTML a tag. 11738 #: Licensing_Plugin_Admin.php:7 0211719 #: Licensing_Plugin_Admin.php:717 11739 11720 #, php-format 11740 11721 msgid "Your %1$s license key is not active for this site. You can switch your license to this website following %2$sthis link%3$s" … … 11742 11723 11743 11724 #. Translators: 1 Product name. 11744 #: Licensing_Plugin_Admin.php:714 11745 #, php-format 11746 msgid "Your %1$s license key is not active and cannot be activated due to the license activation limit being reached." 11747 msgstr "" 11748 11749 #. Translators: 1 Product name. 11750 #: Licensing_Plugin_Admin.php:724 11725 #: Licensing_Plugin_Admin.php:729 11751 11726 #, php-format 11752 11727 msgid "The %1$s license key is not active." … … 11754 11729 11755 11730 #. Translators: 1 Product name, 2 opening HTML a tag to license setting, 3 closing HTML a tag. 11756 #: Licensing_Plugin_Admin.php:7 3711731 #: Licensing_Plugin_Admin.php:742 11757 11732 #, php-format 11758 11733 msgid "Your current %1$s Pro license key is not valid. %2$sPlease confirm it%3$s." … … 11760 11735 11761 11736 #. translators: 1: Product name, 2: HTML anchor open tag, 3: HTML anchor close tag. 11762 #: Licensing_Plugin_Admin.php:75 211737 #: Licensing_Plugin_Admin.php:757 11763 11738 #, php-format 11764 11739 msgid "The %1$s license key cannot be verified. Please %2$scontact support%3$s for assistance." 11765 11740 msgstr "" 11766 11741 11767 #: Licensing_Plugin_Admin.php:86 111742 #: Licensing_Plugin_Admin.php:866 11768 11743 #: SetupGuide_Plugin_Admin.php:1574 11769 11744 msgid "Accept" 11770 11745 msgstr "" 11771 11746 11772 #: Licensing_Plugin_Admin.php:8 6511747 #: Licensing_Plugin_Admin.php:870 11773 11748 #: SetupGuide_Plugin_Admin.php:1575 11774 11749 msgid "Decline" … … 11776 11751 11777 11752 #. translators: 1 opening HTML a tag to W3TC Terms page, 2 closing HTML a tag. 11778 #: Licensing_Plugin_Admin.php:89 011753 #: Licensing_Plugin_Admin.php:895 11779 11754 #, php-format 11780 11755 msgid "Our terms of use and privacy policies have been updated. Please %1$sreview%2$s and accept them." … … 11782 11757 11783 11758 #. translators: 1: Product name, 2: HTML break tag, 3: Anchor/link open tag, 4: Anchor/link close tag. 11784 #: Licensing_Plugin_Admin.php:90 011759 #: Licensing_Plugin_Admin.php:905 11785 11760 #, php-format 11786 11761 msgid "By allowing us to collect data about how %1$s is used, we can improve our features and experience for everyone. This data will not include any personally identifiable information.%2$sFeel free to review our %3$sterms of use and privacy policy%4$s." … … 12111 12086 msgstr "" 12112 12087 12113 #: Minify_MinifiedFileRequestHandler.php: 79312088 #: Minify_MinifiedFileRequestHandler.php:808 12114 12089 msgid "Too many minify requests." 12115 12090 msgstr "" 12116 12091 12117 12092 #. translators: 1 interval in seconds. 12118 #: Minify_Plugin.php:16 512093 #: Minify_Plugin.php:169 12119 12094 #, php-format 12120 12095 msgid "[W3TC] Minify Cache file GC (every %d seconds)" 12121 12096 msgstr "" 12122 12097 12123 #: Minify_Plugin.php:3 6312098 #: Minify_Plugin.php:391 12124 12099 #: Minify_Plugin_Admin.php:68 12125 12100 msgid "Minify Cache" … … 12127 12102 12128 12103 #. Translators: 1 engine name, 2 reject reason. 12129 #: Minify_Plugin.php: 38512104 #: Minify_Plugin.php:413 12130 12105 #, php-format 12131 12106 msgid "Minified using %1$s%2$s" … … 12225 12200 12226 12201 #. translators: 1: Cache hits, 2: Cache total cache objects, 3: Engine anme, 4: Reason. 12227 #: ObjectCache_WpObjectCache_Regular.php:14 1612202 #: ObjectCache_WpObjectCache_Regular.php:1444 12228 12203 #, php-format 12229 12204 msgid "Object Caching %1$d/%2$d objects using %3$s%4$s" 12230 12205 msgstr "" 12231 12206 12232 #: ObjectCache_WpObjectCache_Regular.php:14 2512207 #: ObjectCache_WpObjectCache_Regular.php:1453 12233 12208 msgid "Object Cache debug info:" 12234 12209 msgstr "" 12235 12210 12236 #: ObjectCache_WpObjectCache_Regular.php:1 47712211 #: ObjectCache_WpObjectCache_Regular.php:1505 12237 12212 msgid "Object caching is disabled" 12238 12213 msgstr "" 12239 12214 12240 #: ObjectCache_WpObjectCache_Regular.php:1 47912215 #: ObjectCache_WpObjectCache_Regular.php:1507 12241 12216 msgid "DONOTCACHEOBJECT constant is defined" 12242 12217 msgstr "" 12243 12218 12244 #: PageSpeed_Api.php:1 4812219 #: PageSpeed_Api.php:155 12245 12220 msgid "Missing Google access token." 12246 12221 msgstr "" 12247 12222 12248 #: PageSpeed_Api.php:2 5012223 #: PageSpeed_Api.php:262 12249 12224 msgid "Google PageSpeed access token refresh missing required parameters!" 12250 12225 msgstr "" 12251 12226 12252 12227 #: PageSpeed_Api.php:278 12228 #: PageSpeed_Api.php:301 12229 msgid "Google PageSpeed access token refresh failed." 12230 msgstr "" 12231 12232 #: PageSpeed_Api.php:323 12233 msgid "Google PageSpeed access token refresh failed due to an unusable token response." 12234 msgstr "" 12235 12236 #: PageSpeed_Api.php:364 12253 12237 msgid "No site ID provided for access key refresh!" 12254 12238 msgstr "" 12255 12239 12256 #: PageSpeed_Api.php: 28012240 #: PageSpeed_Api.php:367 12257 12241 msgid "No W3TC API key provided for access key refresh!" 12258 12242 msgstr "" 12259 12243 12260 #: PageSpeed_Api.php: 28212261 #: PageSpeed_Api.php: 43312244 #: PageSpeed_Api.php:370 12245 #: PageSpeed_Api.php:768 12262 12246 msgid "No matching Google access record found for W3TC API key!" 12263 12247 msgstr "" 12264 12248 12265 #: PageSpeed_Api.php: 28412249 #: PageSpeed_Api.php:373 12266 12250 msgid "Matching Google access record found but the refresh token value is blank!" 12267 12251 msgstr "" 12268 12252 12269 #: PageSpeed_Api.php:289 12270 msgid "Google PageSpeed access token refresh failed." 12271 msgstr "" 12272 12273 #: PageSpeed_Api.php:309 12274 msgid "Google PageSpeed access token refresh failed due to response missing access token." 12275 msgstr "" 12276 12277 #: PageSpeed_Api.php:401 12253 #: PageSpeed_Api.php:376 12254 #: PageSpeed_Api.php:383 12255 msgid "Google rejected the access token refresh. Local authorization was kept for retry." 12256 msgstr "" 12257 12258 #: PageSpeed_Api.php:379 12259 msgid "The renewed Google access token could not be saved by the W3 API. Local authorization was kept for retry." 12260 msgstr "" 12261 12262 #. translators: %d: HTTP response code. 12263 #: PageSpeed_Api.php:388 12264 #, php-format 12265 msgid "Unexpected token refresh response (HTTP %d)." 12266 msgstr "" 12267 12268 #. translators: 1 HTML a tag to W3TC settings page Google PageSpeed meta box. 12269 #: PageSpeed_Api.php:481 12270 #: PageSpeed_Widget.php:100 12271 #, php-format 12272 msgid "Before you can get started using the Google PageSpeed tool, you’ll first need to authorize access. Please click %1$s." 12273 msgstr "" 12274 12275 #. translators: 1 HTML a tag to W3TC settings page Google PageSpeed meta box. 12276 #: PageSpeed_Api.php:499 12277 #, php-format 12278 msgid "Google PageSpeed access is authorized but could not be renewed on the last attempt. W3 Total Cache will retry automatically. If this continues, reauthorize access %1$s." 12279 msgstr "" 12280 12281 #: PageSpeed_Api.php:598 12282 msgid "Unique site ID missing for authorize request!" 12283 msgstr "" 12284 12285 #: PageSpeed_Api.php:601 12286 msgid "Authorize URL missing for authorize request!" 12287 msgstr "" 12288 12289 #: PageSpeed_Api.php:604 12290 msgid "Return URL missing for authorize request!" 12291 msgstr "" 12292 12293 #: PageSpeed_Api.php:607 12294 msgid "Failed to process authorize request!" 12295 msgstr "" 12296 12297 #: PageSpeed_Api.php:610 12298 msgid "No authorize code returned to W3-API from Google!" 12299 msgstr "" 12300 12301 #: PageSpeed_Api.php:613 12302 msgid "Unique site ID missing during Google authorization return processing!" 12303 msgstr "" 12304 12305 #: PageSpeed_Api.php:616 12306 msgid "No W3Key returned to W3-API from Google!" 12307 msgstr "" 12308 12309 #: PageSpeed_Api.php:619 12310 msgid "No W3-API matching record found during Google authorization return processing!" 12311 msgstr "" 12312 12313 #: PageSpeed_Api.php:622 12314 msgid "No Google access token found during Google authorization return processing!" 12315 msgstr "" 12316 12317 #: PageSpeed_Api.php:625 12318 msgid "Google rejected the authorization request. Please try authorizing Google PageSpeed again." 12319 msgstr "" 12320 12321 #: PageSpeed_Api.php:628 12322 msgid "Google did not return a refresh token. Please authorize Google PageSpeed again." 12323 msgstr "" 12324 12325 #: PageSpeed_Api.php:631 12326 msgid "The Google refresh token could not be saved by the W3 API. Please try authorizing again after the service is updated." 12327 msgstr "" 12328 12329 #. translators: %s: Google authorization error ID. 12330 #: PageSpeed_Api.php:636 12331 #, php-format 12332 msgid "Unexpected Google PageSpeed authorization error: %s" 12333 msgstr "" 12334 12335 #: PageSpeed_Api.php:671 12278 12336 msgid "Google PageSpeed access token revocation missing required parameters!" 12279 12337 msgstr "" 12280 12338 12281 #: PageSpeed_Api.php:429 12339 #: PageSpeed_Api.php:737 12340 msgid "Google PageSpeed Access Token revocation failed." 12341 msgstr "" 12342 12343 #: PageSpeed_Api.php:759 12282 12344 msgid "No access token provided for revoke!" 12283 12345 msgstr "" 12284 12346 12285 #: PageSpeed_Api.php:431 12347 #: PageSpeed_Api.php:762 12348 msgid "No site ID provided for revoke!" 12349 msgstr "" 12350 12351 #: PageSpeed_Api.php:765 12286 12352 msgid "No W3TC API key provided for revoke!" 12287 12353 msgstr "" 12288 12354 12289 #: PageSpeed_Api.php:438 12290 msgid "Google PageSpeed Access Token revocation failed." 12355 #: PageSpeed_Api.php:771 12356 msgid "Google rejected the access token revocation. Local authorization was kept for retry." 12357 msgstr "" 12358 12359 #: PageSpeed_Api.php:774 12360 msgid "Google revoked the access token, but the W3 API could not save the result. Local authorization was kept for retry." 12361 msgstr "" 12362 12363 #. translators: 1: HTTP response code, 2: API error ID. 12364 #: PageSpeed_Api.php:779 12365 #, php-format 12366 msgid "Unexpected token revocation response (HTTP %1$d, error %2$s)." 12291 12367 msgstr "" 12292 12368 … … 12927 13003 msgstr "" 12928 13004 12929 #. translators: 1 HTML a tag to W3TC settings page Google PageSpeed meta box. 12930 #: PageSpeed_Page.php:109 12931 #: PageSpeed_Widget.php:100 12932 #: PageSpeed_Widget.php:148 12933 #, php-format 12934 msgid "Before you can get started using the Google PageSpeed tool, you’ll first need to authorize access. Please click %1$s." 12935 msgstr "" 12936 12937 #: PageSpeed_Page.php:125 12938 #: PageSpeed_Widget.php:164 13005 #: PageSpeed_Page.php:130 13006 #: PageSpeed_Widget.php:169 12939 13007 msgid "API request failed!" 12940 13008 msgstr "" 12941 13009 12942 #: PageSpeed_Page.php:1 2612943 #: PageSpeed_Page.php:1 3512944 #: PageSpeed_Page.php:1 4812945 #: PageSpeed_Widget.php:1 6512946 #: PageSpeed_Widget.php:17 412947 #: PageSpeed_Widget.php:1 8713010 #: PageSpeed_Page.php:131 13011 #: PageSpeed_Page.php:140 13012 #: PageSpeed_Page.php:153 13013 #: PageSpeed_Widget.php:170 13014 #: PageSpeed_Widget.php:179 13015 #: PageSpeed_Widget.php:192 12948 13016 msgid "Analyze URL : " 12949 13017 msgstr "" 12950 13018 12951 #: PageSpeed_Page.php:13 412952 #: PageSpeed_Page.php:1 4712953 #: PageSpeed_Widget.php:17 312954 #: PageSpeed_Widget.php:1 8613019 #: PageSpeed_Page.php:139 13020 #: PageSpeed_Page.php:152 13021 #: PageSpeed_Widget.php:178 13022 #: PageSpeed_Widget.php:191 12955 13023 msgid "API request error!" 12956 13024 msgstr "" 12957 13025 12958 #: PageSpeed_Page.php:1 3612959 #: PageSpeed_Widget.php:1 7513026 #: PageSpeed_Page.php:141 13027 #: PageSpeed_Widget.php:180 12960 13028 msgid "Response Code : " 12961 13029 msgstr "" 12962 13030 12963 #: PageSpeed_Page.php:1 3712964 #: PageSpeed_Widget.php:1 7613031 #: PageSpeed_Page.php:142 13032 #: PageSpeed_Widget.php:181 12965 13033 msgid "Response Message : " 12966 13034 msgstr "" 12967 13035 12968 #: PageSpeed_Page.php:1 4912969 #: PageSpeed_Widget.php:1 8813036 #: PageSpeed_Page.php:154 13037 #: PageSpeed_Widget.php:193 12970 13038 msgid "Mobile response Code : " 12971 13039 msgstr "" 12972 13040 12973 #: PageSpeed_Page.php:15 012974 #: PageSpeed_Widget.php:1 8913041 #: PageSpeed_Page.php:155 13042 #: PageSpeed_Widget.php:194 12975 13043 msgid "Mobile response Message : " 12976 13044 msgstr "" 12977 13045 12978 #: PageSpeed_Page.php:15 112979 #: PageSpeed_Widget.php:19 013046 #: PageSpeed_Page.php:156 13047 #: PageSpeed_Widget.php:195 12980 13048 msgid "Desktop response Code : " 12981 13049 msgstr "" 12982 13050 12983 #: PageSpeed_Page.php:15 212984 #: PageSpeed_Widget.php:19 113051 #: PageSpeed_Page.php:157 13052 #: PageSpeed_Widget.php:196 12985 13053 msgid "Desktop response Message : " 12986 13054 msgstr "" … … 13188 13256 msgstr "" 13189 13257 13258 #: PgCache_ConfigLabels.php:70 13259 msgid "Preload the sitemap once" 13260 msgstr "" 13261 13190 13262 #. translators: 1: opening acronym tag for URL, 2: closing acronym tag. 13191 #: PgCache_ConfigLabels.php:7 313263 #: PgCache_ConfigLabels.php:74 13192 13264 #, php-format 13193 13265 msgid "Sitemap %1$sURL%2$s:" 13194 13266 msgstr "" 13195 13267 13196 #: PgCache_ConfigLabels.php:8 613268 #: PgCache_ConfigLabels.php:87 13197 13269 msgid "Preload cache upon publishing a post" 13198 13270 msgstr "" 13199 13271 13200 #: PgCache_ConfigLabels.php:8 713272 #: PgCache_ConfigLabels.php:88 13201 13273 msgid "Preload cache upon updating a post" 13202 13274 msgstr "" 13203 13275 13204 #: PgCache_ConfigLabels.php:8813205 13276 #: PgCache_ConfigLabels.php:89 13277 #: PgCache_ConfigLabels.php:90 13206 13278 msgid "Front page" 13207 13279 msgstr "" 13208 13280 13209 #: PgCache_ConfigLabels.php: 8913281 #: PgCache_ConfigLabels.php:90 13210 13282 msgid "Posts page" 13211 13283 msgstr "" 13212 13284 13213 #: PgCache_ConfigLabels.php:9 013285 #: PgCache_ConfigLabels.php:91 13214 13286 msgid "Post page" 13215 13287 msgstr "" 13216 13288 13217 #: PgCache_ConfigLabels.php:9 113289 #: PgCache_ConfigLabels.php:92 13218 13290 msgid "Blog feed" 13219 13291 msgstr "" 13220 13292 13221 #: PgCache_ConfigLabels.php:9 213293 #: PgCache_ConfigLabels.php:93 13222 13294 msgid "Post comments pages" 13223 13295 msgstr "" 13224 13296 13225 #: PgCache_ConfigLabels.php:9 313297 #: PgCache_ConfigLabels.php:94 13226 13298 msgid "Post author pages" 13227 13299 msgstr "" 13228 13300 13229 #: PgCache_ConfigLabels.php:9 413301 #: PgCache_ConfigLabels.php:95 13230 13302 msgid "Post terms pages" 13231 13303 msgstr "" 13232 13304 13233 #: PgCache_ConfigLabels.php:9 513305 #: PgCache_ConfigLabels.php:96 13234 13306 msgid "Post comments feed" 13235 13307 msgstr "" 13236 13308 13237 #: PgCache_ConfigLabels.php:9 613309 #: PgCache_ConfigLabels.php:97 13238 13310 msgid "Post author feed" 13239 13311 msgstr "" 13240 13312 13241 #: PgCache_ConfigLabels.php:9 713313 #: PgCache_ConfigLabels.php:98 13242 13314 msgid "Post terms feeds" 13243 13315 msgstr "" 13244 13316 13245 #: PgCache_ConfigLabels.php:9 813317 #: PgCache_ConfigLabels.php:99 13246 13318 msgid "Daily archive pages" 13247 13319 msgstr "" 13248 13320 13249 #: PgCache_ConfigLabels.php: 9913321 #: PgCache_ConfigLabels.php:100 13250 13322 msgid "Monthly archive pages" 13251 13323 msgstr "" 13252 13324 13253 #: PgCache_ConfigLabels.php:10 013325 #: PgCache_ConfigLabels.php:101 13254 13326 msgid "Yearly archive pages" 13255 13327 msgstr "" 13256 13328 13257 #: PgCache_ConfigLabels.php:10 113329 #: PgCache_ConfigLabels.php:102 13258 13330 msgid "Specify the feed types to purge:" 13259 13331 msgstr "" 13260 13332 13261 #: PgCache_ConfigLabels.php:10 213333 #: PgCache_ConfigLabels.php:103 13262 13334 msgid "Purge limit:" 13263 13335 msgstr "" 13264 13336 13265 #: PgCache_ConfigLabels.php:10 313337 #: PgCache_ConfigLabels.php:104 13266 13338 msgid "Additional pages:" 13267 13339 msgstr "" 13268 13340 13269 #: PgCache_ConfigLabels.php:10 413341 #: PgCache_ConfigLabels.php:105 13270 13342 msgid "Purge sitemaps:" 13271 13343 msgstr "" 13272 13344 13273 13345 #. translators: 1: opening acronym tag for UTF, 2: closing acronym tag. 13274 #: PgCache_ConfigLabels.php:1 0913346 #: PgCache_ConfigLabels.php:110 13275 13347 #, php-format 13276 13348 msgid "Disable %1$sUTF%2$s-8 blog charset support" 13277 13349 msgstr "" 13278 13350 13279 #: PgCache_ConfigLabels.php:11 313280 #: PgCache_ConfigLabels.php:16 013351 #: PgCache_ConfigLabels.php:114 13352 #: PgCache_ConfigLabels.php:161 13281 13353 msgid "Unicode Transformation Format" 13282 13354 msgstr "" 13283 13355 13284 13356 #. translators: 1: opening acronym tag for HTTP, 2: closing acronym tag. 13285 #: PgCache_ConfigLabels.php:12 613357 #: PgCache_ConfigLabels.php:127 13286 13358 #, php-format 13287 13359 msgid " Disable caching of HEAD %1$sHTTP%2$s requests" 13288 13360 msgstr "" 13289 13361 13290 #: PgCache_ConfigLabels.php:14 113362 #: PgCache_ConfigLabels.php:142 13291 13363 msgid "Comment cookie lifetime:" 13292 13364 msgstr "" 13293 13365 13294 #: PgCache_ConfigLabels.php:14 213366 #: PgCache_ConfigLabels.php:143 13295 13367 msgid "Accepted query strings:" 13296 13368 msgstr "" 13297 13369 13298 #: PgCache_ConfigLabels.php:14 413370 #: PgCache_ConfigLabels.php:145 13299 13371 msgid "Rejected cookies:" 13300 13372 msgstr "" 13301 13373 13302 #: PgCache_ConfigLabels.php:14 613374 #: PgCache_ConfigLabels.php:147 13303 13375 msgid "Never cache pages associated with these categories:" 13304 13376 msgstr "" 13305 13377 13306 #: PgCache_ConfigLabels.php:14 713378 #: PgCache_ConfigLabels.php:148 13307 13379 msgid "Never cache pages that use these tags:" 13308 13380 msgstr "" 13309 13381 13310 #: PgCache_ConfigLabels.php:14 813382 #: PgCache_ConfigLabels.php:149 13311 13383 msgid "Never cache pages by these authors:" 13312 13384 msgstr "" 13313 13385 13314 #: PgCache_ConfigLabels.php:1 4913386 #: PgCache_ConfigLabels.php:150 13315 13387 msgid "Never cache pages that use these custom fields:" 13316 13388 msgstr "" 13317 13389 13318 #: PgCache_ConfigLabels.php:15 013390 #: PgCache_ConfigLabels.php:151 13319 13391 msgid "Cache exception list:" 13320 13392 msgstr "" 13321 13393 13322 #: PgCache_ConfigLabels.php:15 113394 #: PgCache_ConfigLabels.php:152 13323 13395 msgid "Non-trailing slash pages:" 13324 13396 msgstr "" 13325 13397 13326 #: PgCache_ConfigLabels.php:15 213398 #: PgCache_ConfigLabels.php:153 13327 13399 msgid "Specify page headers:" 13328 13400 msgstr "" 13329 13401 13330 13402 #. translators: 1: opening acronym tag for UTF, 2: closing acronym tag. 13331 #: PgCache_ConfigLabels.php:15 613403 #: PgCache_ConfigLabels.php:157 13332 13404 #, php-format 13333 13405 msgid "Handle %1$sXML%2$s mime type" 13334 13406 msgstr "" 13335 13407 13336 #: PgCache_ConfigLabels.php:1 6913408 #: PgCache_ConfigLabels.php:170 13337 13409 msgid "Cache alias hostnames:" 13338 13410 msgstr "" 13339 13411 13340 #: PgCache_ConfigLabels.php:17 013412 #: PgCache_ConfigLabels.php:171 13341 13413 msgid "Additional home URLs:" 13342 13414 msgstr "" 13343 13415 13344 13416 #. translators: 1: Engine name, 2: Reject reason placeholder, 3: Page key extension. 13345 #: PgCache_ContentGrabber.php:18 3913417 #: PgCache_ContentGrabber.php:1828 13346 13418 #, php-format 13347 13419 msgid "Page Caching using %1$s%2$s%3$s" … … 13353 13425 13354 13426 #. translators: 1 interval in seconds. 13355 #: PgCache_Plugin.php: 16613427 #: PgCache_Plugin.php:200 13356 13428 #, php-format 13357 13429 msgid "[W3TC] Page Cache file GC (every %d seconds)" … … 13359 13431 13360 13432 #. translators: 1 interval in seconds. 13361 #: PgCache_Plugin.php: 17813433 #: PgCache_Plugin.php:212 13362 13434 #, php-format 13363 13435 msgid "[W3TC] Page Cache prime (every %d seconds)" 13364 13436 msgstr "" 13365 13437 13366 #: PgCache_Plugin.php:4 0213438 #: PgCache_Plugin.php:436 13367 13439 msgid "Page Cache: Current Page" 13368 13440 msgstr "" 13369 13441 13370 13442 #. Translators: 1 memcached servers. 13371 #: PgCache_Plugin_Admin.php: 43413443 #: PgCache_Plugin_Admin.php:690 13372 13444 #, php-format 13373 13445 msgid "Page Cache: %1$s." -
w3-total-cache/tags/2.10.7/pub/css/lightbox.css
r3598169 r3723494 429 429 } 430 430 431 .w3tc_signup_email {432 margin-bottom: 5px;433 }434 435 431 .w3tc-overlay-logo { 436 432 margin-top: -57px; -
w3-total-cache/tags/2.10.7/pub/js/options.js
r3680101 r3723494 1831 1831 }); 1832 1832 1833 // Footer subscribe hide response.1834 jQuery("#mc-embedded-subscribe").on("click", function (e) {1835 // Hide response after 20 seconds.1836 setTimeout(function () {1837 jQuery("#w3tc-footer .response").hide();1838 }, 20000);1839 });1840 1841 1833 // Bootstrap dropdown hide on click away. 1842 1834 jQuery(document).mouseup(function (e) { -
w3-total-cache/tags/2.10.7/readme.txt
r3680101 r3723494 4 4 Requires at least: 6.0 5 5 Tested up to: 7.1 6 Stable tag: 2.10. 66 Stable tag: 2.10.7 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 366 366 == Changelog == 367 367 368 = 2.10.7 = 369 * Feature: Minify: Cache selected external scripts locally for auto minify 370 * Feature: Page Cache: Add a one-pass mode for sitemap cache preload 371 * Enhancement: Developers: Add a generated reference of supported actions and filters 372 * Fix: Browser Cache: Constrain unquoted URL rewriting when removing query strings from static resources 373 * Fix: Page Cache: Remove the expired role-cookie compatibility path and skip caching for rejected roles 374 * Fix: Page Cache: Avoid Options API calls before WordPress has loaded them during early bootstrap 375 * Fix: Object Cache: Persist cache invalidation from wp-admin when admin object caching is disabled 376 * Fix: CDN: Preserve custom attachment directories when pushing media 377 * Fix: Google PageSpeed: Renew expired access tokens without discarding authorization 378 * Fix: Licensing: Show the activation-limit notice for licenses that have reached their limit 379 * Fix: Settings: Persist Purge via WP-Cron schedule settings 380 * Fix: Settings: Skip unchanged w3tc_state option writes 381 * Update: Remove leftover newsletter signup code 382 * Update: Build: Omit development-only files from the release ZIP 383 384 368 385 = 2.10.6 = 369 386 * Fix: Database Cluster: Restore placeholder unescape so admin searches with wildcards match … … 460 477 == Upgrade Notice == 461 478 479 = 2.10.7 = 480 This is a security update. All users are strongly encouraged to update. 481 This update also adds local caching of selected external scripts, one-pass sitemap preload, and fixes for CDN media paths, Google PageSpeed authorization, and settings persistence. 482 483 462 484 = 2.10.6 = 463 485 This is a security update. All users are strongly encouraged to update. -
w3-total-cache/tags/2.10.7/vendor/composer/installed.php
r3680101 r3723494 2 2 'root' => array( 3 3 'name' => 'boldgrid/w3-total-cache', 4 'pretty_version' => '2.10. 6',5 'version' => '2.10. 6.0',6 'reference' => ' 681679d97f9efd065c448b22a80ac1d73f4e0fb2',4 'pretty_version' => '2.10.7', 5 'version' => '2.10.7.0', 6 'reference' => 'b9385f7c67395655e32e02fe3246800e5be485b7', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 39 39 ), 40 40 'boldgrid/w3-total-cache' => array( 41 'pretty_version' => '2.10. 6',42 'version' => '2.10. 6.0',43 'reference' => ' 681679d97f9efd065c448b22a80ac1d73f4e0fb2',41 'pretty_version' => '2.10.7', 42 'version' => '2.10.7.0', 43 'reference' => 'b9385f7c67395655e32e02fe3246800e5be485b7', 44 44 'type' => 'wordpress-plugin', 45 45 'install_path' => __DIR__ . '/../../', -
w3-total-cache/tags/2.10.7/w3-total-cache-api.php
r3680101 r3723494 11 11 12 12 define( 'W3TC', true ); 13 define( 'W3TC_VERSION', '2.10. 6' );13 define( 'W3TC_VERSION', '2.10.7' ); 14 14 define( 'W3TC_POWERED_BY', 'W3 Total Cache' ); 15 15 define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' ); … … 29 29 define( 'W3TC_TERMS_URL', 'https://api.w3-edge.com/v1/redirects/policies-terms' ); 30 30 define( 'W3TC_TERMS_ACCEPT_URL', 'https://api.w3-edge.com/v1/redirects/policies-accept' ); 31 define( 'W3TC_MAILLINGLIST_SIGNUP_URL', 'https://api.w3-edge.com/v1/signup-newsletter' );32 31 define( 'W3TC_NEWRELIC_SIGNUP_URL', 'https://api.w3-edge.com/v1/redirects/newrelic/signup' ); 33 32 define( 'W3TC_GOOGLE_DRIVE_AUTHORIZE_URL', 'https://api.w3-edge.com/v1/googledrive/authorize' ); -
w3-total-cache/tags/2.10.7/w3-total-cache.php
r3680101 r3723494 4 4 * Plugin URI: https://www.boldgrid.com/totalcache/ 5 5 * Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress. 6 * Version: 2.10. 66 * Version: 2.10.7 7 7 * Requires at least: 6.0 8 8 * Requires PHP: 7.4
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)