Changeset 3029656
- Timestamp:
- 01/31/2024 04:43:55 PM (2 years ago)
- Location:
- spinupwp/trunk
- Files:
-
- 3 edited
-
drop-ins/object-cache.php (modified) (39 diffs)
-
readme.txt (modified) (2 diffs)
-
src/Cache.php (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
spinupwp/trunk/drop-ins/object-cache.php
r2812614 r3029656 10 10 License URI: http://www.gnu.org/licenses/gpl-3.0.html 11 11 12 Based on Till Krüss’ Redis Object Cache :12 Based on Till Krüss’ Redis Object Cache v2.5.0: 13 13 - https://wordpress.org/plugins/redis-cache/ 14 14 - https://github.com/rhubarbgroup/redis-cache/ … … 17 17 defined( '\\ABSPATH' ) || exit; 18 18 19 // phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact, Generic.WhiteSpace.ScopeIndent.Incorrect 19 20 if ( ! defined( 'WP_REDIS_DISABLED' ) || ! WP_REDIS_DISABLED ) : 21 22 /** 23 * Determines whether the object cache implementation supports a particular feature. 24 * 25 * Possible values include: 26 * - `add_multiple`, `set_multiple`, `get_multiple` and `delete_multiple` 27 * - `flush_runtime` and `flush_group` 28 * 29 * @param string $feature Name of the feature to check for. 30 * @return bool True if the feature is supported, false otherwise. 31 */ 32 function wp_cache_supports( $feature ) { 33 switch ( $feature ) { 34 case 'add_multiple': 35 case 'set_multiple': 36 case 'get_multiple': 37 case 'delete_multiple': 38 case 'flush_runtime': 39 case 'flush_group': 40 return true; 41 42 default: 43 return false; 44 } 45 } 46 20 47 21 48 /** … … 116 143 * only keys prefixed with the `WP_REDIS_PREFIX` are flushed. 117 144 * 118 * @param int $delay Number of seconds to wait before invalidating the items.119 *120 145 * @return bool Returns TRUE on success or FALSE on failure. 121 146 */ 122 function wp_cache_flush( $delay = 0) {147 function wp_cache_flush() { 123 148 global $wp_object_cache; 124 149 125 return $wp_object_cache->flush( $delay ); 150 return $wp_object_cache->flush(); 151 } 152 153 /** 154 * Removes all cache items in a group. 155 * 156 * @param string $group Name of group to remove from cache. 157 * @return true Returns TRUE on success or FALSE on failure. 158 */ 159 function wp_cache_flush_group( $group ) 160 { 161 global $wp_object_cache; 162 163 return $wp_object_cache->flush_group( $group ); 126 164 } 127 165 … … 196 234 197 235 if ( ! defined( 'WP_REDIS_PREFIX' ) ) { 198 define( 'WP_REDIS_PREFIX', get_cache_key_salt());236 define( 'WP_REDIS_PREFIX', get_cache_key_salt()); 199 237 } 200 238 … … 204 242 205 243 if ( ! ( $wp_object_cache instanceof WP_Object_Cache ) ) { 206 $fail_gracefully = ! defined( 'WP_REDIS_GRACEFUL' ) || WP_REDIS_GRACEFUL; 207 208 // We need to override this WordPress global in order to inject our cache. 244 $fail_gracefully = defined( 'WP_REDIS_GRACEFUL' ) && WP_REDIS_GRACEFUL; 245 209 246 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited 210 247 $wp_object_cache = new WP_Object_Cache( $fail_gracefully ); … … 382 419 * List of global groups. 383 420 * 384 * @var array 421 * @var array<string> 385 422 */ 386 423 public $global_groups = [ … … 416 453 * @var array 417 454 */ 418 public $ignored_groups = [ 419 'counts', 420 'plugins', 421 'themes', 422 ]; 455 public $ignored_groups = []; 423 456 424 457 /** … … 476 509 * @param bool $fail_gracefully Handles and logs errors if true throws exceptions otherwise. 477 510 */ 478 public function __construct( $fail_gracefully = true ) {511 public function __construct( $fail_gracefully = false ) { 479 512 global $blog_id, $table_prefix; 480 513 … … 497 530 $this->cache_group_types(); 498 531 499 if ( defined( 'WP_REDIS_TRACE' ) && WP_REDIS_TRACE && function_exists( '_doing_it_wrong' ) ) { 500 _doing_it_wrong( __FUNCTION__ , 'Tracing feature was removed.' , '2.1.2' ); 532 if ( function_exists( '_doing_it_wrong' ) ) { 533 if ( defined( 'WP_REDIS_TRACE' ) && WP_REDIS_TRACE ) { 534 _doing_it_wrong( __FUNCTION__ , 'Tracing feature was removed.' , '2.1.2' ); 535 } 501 536 } 502 537 … … 525 560 526 561 if ( defined( 'WP_REDIS_CLUSTER' ) ) { 527 $connectionI D= is_string( WP_REDIS_CLUSTER )562 $connectionId = is_string( WP_REDIS_CLUSTER ) 528 563 ? WP_REDIS_CLUSTER 529 564 : current( $this->build_cluster_connection_array() ); 530 565 531 566 $this->diagnostics[ 'ping' ] = $client === 'predis' 532 ? $this->redis->getClient For( $connectionID)->ping()533 : $this->redis->ping( $connectionI D);567 ? $this->redis->getClientBy( 'id', $connectionId )->ping() 568 : $this->redis->ping( $connectionId ); 534 569 } else { 535 570 $this->diagnostics[ 'ping' ] = $this->redis->ping(); … … 600 635 'port' => 6379, 601 636 'database' => 0, 602 'timeout' => 1,603 'read_timeout' => 1,637 'timeout' => 5, 638 'read_timeout' => 5, 604 639 'retry_interval' => null, 605 640 'persistent' => false, … … 677 712 ]; 678 713 714 if ( version_compare( $version, '3.1.3', '>=' ) ) { 715 $args['read_timeout'] = $parameters['read_timeout']; 716 } 717 679 718 if ( strcasecmp( 'tls', $parameters['scheme'] ) === 0 ) { 680 719 $args['host'] = sprintf( … … 683 722 str_replace( 'tls://', '', $parameters['host'] ) 684 723 ); 724 725 if ( version_compare( $version, '5.3.0', '>=' ) && defined( 'WP_REDIS_SSL_CONTEXT' ) && ! empty( WP_REDIS_SSL_CONTEXT ) ) { 726 $args['others']['stream'] = WP_REDIS_SSL_CONTEXT; 727 } 685 728 } 686 729 … … 688 731 $args['host'] = $parameters['path']; 689 732 $args['port'] = -1; 690 }691 692 if ( version_compare( $version, '3.1.3', '>=' ) ) {693 $args['read_timeout'] = $parameters['read_timeout'];694 733 } 695 734 … … 718 757 if ( defined( 'WP_REDIS_SERIALIZER' ) && ! empty( WP_REDIS_SERIALIZER ) ) { 719 758 $this->redis->setOption( Redis::OPT_SERIALIZER, WP_REDIS_SERIALIZER ); 759 760 if ( function_exists( '_doing_it_wrong' ) ) { 761 _doing_it_wrong( __FUNCTION__ , 'The `WP_REDIS_SERIALIZER` configuration constant has been deprecated, use `WP_REDIS_IGBINARY` instead.', '2.3.1' ); 762 } 720 763 } 721 764 } … … 747 790 ]; 748 791 792 $args['read_timeout'] = $parameters['read_timeout']; 793 749 794 if ( strcasecmp( 'tls', $parameters['scheme'] ) === 0 ) { 750 795 $args['host'] = sprintf( … … 753 798 str_replace( 'tls://', '', $parameters['host'] ) 754 799 ); 800 801 if ( defined( 'WP_REDIS_SSL_CONTEXT' ) && ! empty( WP_REDIS_SSL_CONTEXT ) ) { 802 $args['others']['stream'] = WP_REDIS_SSL_CONTEXT; 803 } 755 804 } 756 805 … … 759 808 $args['port'] = -1; 760 809 } 761 762 $args['read_timeout'] = $parameters['read_timeout'];763 810 764 811 call_user_func_array( [ $this->redis, 'connect' ], array_values( $args ) ); … … 786 833 if ( defined( 'WP_REDIS_SERIALIZER' ) && ! empty( WP_REDIS_SERIALIZER ) ) { 787 834 $this->redis->setOption( Relay\Relay::OPT_SERIALIZER, WP_REDIS_SERIALIZER ); 835 836 if ( function_exists( '_doing_it_wrong' ) ) { 837 _doing_it_wrong( __FUNCTION__ , 'The `WP_REDIS_SERIALIZER` configuration constant has been deprecated, use `WP_REDIS_IGBINARY` instead.', '2.3.1' ); 838 } 788 839 } 789 840 } … … 801 852 // Load bundled Predis library. 802 853 if ( ! class_exists( 'Predis\Client' ) ) { 803 $predis = sprintf( 804 '%s/redis-cache/dependencies/predis/predis/autoload.php', 805 defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins' 806 ); 807 808 if ( is_readable( $predis ) ) { 809 require_once $predis; 854 $predis = '/dependencies/predis/predis/autoload.php'; 855 856 $pluginDir = defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR . '/redis-cache' : null; 857 $contentDir = defined( 'WP_CONTENT_DIR' ) ? WP_CONTENT_DIR . '/plugins/redis-cache' : null; 858 $pluginPath = defined( 'WP_REDIS_PLUGIN_PATH' ) ? WP_REDIS_PLUGIN_PATH : null; 859 860 if ( $pluginDir && is_readable( $pluginDir . $predis ) ) { 861 require_once $pluginDir . $predis; 862 } elseif ( $contentDir && is_readable( $contentDir . $predis ) ) { 863 require_once $contentDir . $predis; 864 } elseif ( $pluginPath && is_readable( $pluginPath . $predis ) ) { 865 require_once $pluginPath . $predis; 810 866 } else { 811 867 throw new Exception( … … 836 892 } 837 893 894 if ( strcasecmp( 'unix', $parameters['scheme'] ) === 0 ) { 895 unset($parameters['host'], $parameters['port']); 896 } 897 838 898 if ( isset( $parameters['read_timeout'] ) && $parameters['read_timeout'] ) { 839 899 $parameters['read_write_timeout'] = $parameters['read_timeout']; … … 847 907 848 908 if ( isset( $parameters['password'] ) ) { 849 $options['parameters']['password'] = WP_REDIS_PASSWORD; 909 if ( is_array( $parameters['password'] ) ) { 910 $options['parameters']['username'] = WP_REDIS_PASSWORD[0]; 911 $options['parameters']['password'] = WP_REDIS_PASSWORD[1]; 912 } else { 913 $options['parameters']['password'] = WP_REDIS_PASSWORD; 914 } 850 915 } 851 916 } 917 } 918 919 if ( isset( $parameters['password'] ) ) { 920 if ( is_array( $parameters['password'] ) ) { 921 $parameters['username'] = array_shift( $parameters['password'] ); 922 $parameters['password'] = implode( '', $parameters['password'] ); 923 } 924 925 if ( defined( 'WP_REDIS_USERNAME' ) ) { 926 $parameters['username'] = WP_REDIS_USERNAME; 927 } 928 } 929 930 if ( defined( 'WP_REDIS_SSL_CONTEXT' ) && ! empty( WP_REDIS_SSL_CONTEXT ) ) { 931 $parameters['ssl'] = WP_REDIS_SSL_CONTEXT; 852 932 } 853 933 … … 921 1001 if ( is_array( WP_REDIS_SERVERS ) && count( WP_REDIS_SERVERS ) > 1 ) { 922 1002 throw new Exception( 923 'Multip e sentinel servers are not supported by the bundled Credis library. Please review your Redis Cache configuration.'1003 'Multiple sentinel servers are not supported by the bundled Credis library. Please review your Redis Cache configuration.' 924 1004 ); 925 1005 } … … 1068 1148 1069 1149 if ( defined( 'WP_REDIS_CLUSTER' ) ) { 1070 $connectionI D= is_string( WP_REDIS_CLUSTER )1150 $connectionId = is_string( WP_REDIS_CLUSTER ) 1071 1151 ? 'SERVER' 1072 1152 : current( $this->build_cluster_connection_array() ); 1073 1153 1074 1154 $info = $this->determine_client() === 'predis' 1075 ? $this->redis->getClient For( $connectionID)->info()1076 : $this->redis->info( $connectionI D);1155 ? $this->redis->getClientBy( 'id', $connectionId )->info() 1156 : $this->redis->info( $connectionId ); 1077 1157 } else { 1078 1158 $info = $this->redis->info(); … … 1181 1261 $orig_exp = $expire; 1182 1262 $expire = $this->validate_expiration( $expire ); 1263 $derived_keys = []; 1183 1264 1184 1265 foreach ( $data as $key => $value ) { … … 1224 1305 return (bool) $this->parse_redis_response( $response ); 1225 1306 }, $tx->{$method}() ); 1307 1308 if ( count( $results ) !== count( $keys ) ) { 1309 $tx->discard(); 1310 1311 return array_fill_keys( $keys, false ); 1312 } 1226 1313 1227 1314 $results = array_combine( $keys, $results ); … … 1371 1458 * @return bool Returns TRUE on success or FALSE on failure. 1372 1459 */ 1373 public function delete( $key, $group = 'default' ) {1460 public function delete( $key, $group = 'default', $deprecated = false ) { 1374 1461 $result = false; 1375 1462 … … 1469 1556 return (bool) $this->parse_redis_response( $response ); 1470 1557 }, $tx->{$method}() ); 1558 1559 if ( count( $results ) !== count( $keys ) ) { 1560 $tx->discard(); 1561 1562 return array_fill_keys( $keys, false ); 1563 } 1471 1564 1472 1565 $execute_time = microtime( true ) - $start_time; … … 1509 1602 * only keys prefixed with the `WP_REDIS_PREFIX` are flushed. 1510 1603 * 1511 * @param int $delay Number of seconds to wait before invalidating the items. 1512 * @return bool Returns TRUE on success or FALSE on failure. 1513 */ 1514 public function flush( $delay = 0 ) { 1515 $delay = abs( (int) $delay ); 1516 1517 if ( $delay ) { 1518 sleep( $delay ); 1519 } 1520 1604 * @return bool True on success, false on failure. 1605 */ 1606 public function flush() { 1521 1607 $results = []; 1522 1608 $this->cache = []; … … 1583 1669 * @since 1.3.5 1584 1670 * @param null|array $results Array of flush results. 1585 * @param int $de lay Given number of seconds to waited before invalidating the items.1671 * @param int $deprecated Unused. Default 0. 1586 1672 * @param bool $seletive Whether a selective flush took place. 1587 1673 * @param string $salt The defined key prefix. 1588 1674 * @param float $execute_time Execution time for the request in seconds. 1589 1675 */ 1590 do_action( 'redis_object_cache_flush', $results, $delay, $selective, $salt, $execute_time );1676 do_action( 'redis_object_cache_flush', $results, 0, $selective, $salt, $execute_time ); 1591 1677 } 1592 1678 } … … 1594 1680 if ( empty( $results ) ) { 1595 1681 return false; 1682 } 1683 1684 foreach ( $results as $result ) { 1685 if ( ! $result ) { 1686 return false; 1687 } 1688 } 1689 1690 return true; 1691 } 1692 1693 /** 1694 * Removes all cache items in a group. 1695 * 1696 * @param string $group Name of group to remove from cache. 1697 * @return bool Returns TRUE on success or FALSE on failure. 1698 */ 1699 public function flush_group( $group ) 1700 { 1701 $san_group = $this->sanitize_key_part( $group ); 1702 1703 if ( is_multisite() && ! $this->is_global_group( $san_group ) ) { 1704 $salt = str_replace( "{$this->blog_prefix}:{$san_group}", "*:{$san_group}", $this->fast_build_key( '*', $san_group ) ); 1705 } else { 1706 $salt = $this->fast_build_key( '*', $san_group ); 1707 } 1708 1709 foreach ( $this->cache as $key => $value ) { 1710 if ( strpos( $key, "{$san_group}:" ) === 0 || strpos( $key, ":{$san_group}:" ) !== false ) { 1711 unset( $this->cache[ $key ] ); 1712 } 1713 } 1714 1715 if ( in_array( $san_group, $this->unflushable_groups ) ) { 1716 return false; 1717 } 1718 1719 if ( ! $this->redis_status() ) { 1720 return false; 1721 } 1722 1723 $results = []; 1724 1725 $start_time = microtime( true ); 1726 $script = $this->lua_flush_closure( $salt, false ); 1727 1728 try { 1729 if ( defined( 'WP_REDIS_CLUSTER' ) ) { 1730 foreach ( $this->redis->_masters() as $master ) { 1731 $redis = new Redis; 1732 $redis->connect( $master[0], $master[1] ); 1733 $results[] = $this->parse_redis_response( $script() ); 1734 unset( $redis ); 1735 } 1736 } else { 1737 $results[] = $this->parse_redis_response( $script() ); 1738 } 1739 } catch ( Exception $exception ) { 1740 $this->handle_exception( $exception ); 1741 1742 return false; 1743 } 1744 1745 if ( function_exists( 'do_action' ) ) { 1746 $execute_time = microtime( true ) - $start_time; 1747 1748 /** 1749 * Fires on every group cache flush 1750 * 1751 * @param null|array $results Array of flush results. 1752 * @param string $salt The defined key prefix. 1753 * @param float $execute_time Execution time for the request in seconds. 1754 * @since 2.2.3 1755 */ 1756 do_action( 'redis_object_cache_flush_group', $results, $salt, $execute_time ); 1596 1757 } 1597 1758 … … 1644 1805 * 1645 1806 * @param string $salt The salt to be used to differentiate. 1807 * @param bool $escape ... 1646 1808 * @return callable Generated callable executing the lua script. 1647 1809 */ 1648 protected function lua_flush_closure( $salt ) {1649 $salt = $ this->glob_quote( $salt );1810 protected function lua_flush_closure( $salt, $escape = true ) { 1811 $salt = $escape ? $this->glob_quote( $salt ) : $salt; 1650 1812 1651 1813 return function () use ( $salt ) { 1652 1814 $script = <<<LUA 1653 local cur = 0 1654 local i = 0 1655 local tmp 1656 repeat 1657 tmp = redis.call('SCAN', cur, 'MATCH', '{$salt}*') 1658 cur = tonumber(tmp[1]) 1659 if tmp[2] then 1660 for _, v in pairs(tmp[2]) do 1661 redis.call('del', v) 1662 i = i + 1 1815 local cur = 0 1816 local i = 0 1817 local tmp 1818 repeat 1819 tmp = redis.call('SCAN', cur, 'MATCH', '{$salt}*') 1820 cur = tonumber(tmp[1]) 1821 if tmp[2] then 1822 for _, v in pairs(tmp[2]) do 1823 redis.call('del', v) 1824 i = i + 1 1825 end 1663 1826 end 1664 end 1665 until 0 == cur 1666 return i 1827 until 0 == cur 1828 return i 1667 1829 LUA; 1668 1830 … … 1697 1859 1698 1860 $script = <<<LUA 1699 local cur = 0 1700 local i = 0 1701 local d, tmp 1702 repeat 1703 tmp = redis.call('SCAN', cur, 'MATCH', '{$salt}*') 1704 cur = tonumber(tmp[1]) 1705 if tmp[2] then 1706 for _, v in pairs(tmp[2]) do 1707 d = true 1708 for _, s in pairs(KEYS) do 1709 d = d and not v:find(s, {$salt_length}) 1710 if not d then break end 1711 end 1712 if d then 1713 redis.call('del', v) 1714 i = i + 1 1861 local cur = 0 1862 local i = 0 1863 local d, tmp 1864 repeat 1865 tmp = redis.call('SCAN', cur, 'MATCH', '{$salt}*') 1866 cur = tonumber(tmp[1]) 1867 if tmp[2] then 1868 for _, v in pairs(tmp[2]) do 1869 d = true 1870 for _, s in pairs(KEYS) do 1871 d = d and not v:find(s, {$salt_length}) 1872 if not d then break end 1873 end 1874 if d then 1875 redis.call('del', v) 1876 i = i + 1 1877 end 1715 1878 end 1716 1879 end 1717 end 1718 until 0 == cur 1719 return i 1880 until 0 == cur 1881 return i 1720 1882 LUA; 1721 1883 if ( version_compare( $this->redis_version(), '5', '<' ) && version_compare( $this->redis_version(), '3.2', '>=' ) ) { … … 1745 1907 */ 1746 1908 public function get( $key, $group = 'default', $force = false, &$found = null ) { 1747 $start_time = microtime( true );1748 1749 1909 $san_key = $this->sanitize_key_part( $key ); 1750 1910 $san_group = $this->sanitize_key_part( $group ); … … 1763 1923 return false; 1764 1924 } 1925 1926 $start_time = microtime( true ); 1765 1927 1766 1928 try { … … 2119 2281 }, $tx->{$method}() ); 2120 2282 2283 if ( count( $results ) !== count( $keys ) ) { 2284 $tx->discard(); 2285 2286 return array_fill_keys( $keys, false ); 2287 } 2288 2121 2289 $results = array_combine( $keys, $results ); 2122 2290 … … 2277 2445 public function stats() { 2278 2446 ?> 2279 <p>2280 <strong>Redis Status:</strong>2281 <?php echo $this->redis_status() ? 'Connected' : 'Not connected'; ?>2282 <br />2283 <strong>Redis Client:</strong>2284 <?php echo $this->diagnostics['client'] ?: 'Unknown'; ?>2285 <br />2286 <strong>Cache Hits:</strong>2287 <?php echo (int) $this->cache_hits; ?>2288 <br />2289 <strong>Cache Misses:</strong>2290 <?php echo (int) $this->cache_misses; ?>2291 <br />2292 <strong>Cache Size:</strong>2293 <?php echo number_format( strlen( serialize( $this->cache ) ) / 1024, 2 ); ?> KB2294 </p>2447 <p> 2448 <strong>Redis Status:</strong> 2449 <?php echo $this->redis_status() ? 'Connected' : 'Not connected'; ?> 2450 <br /> 2451 <strong>Redis Client:</strong> 2452 <?php echo $this->diagnostics['client'] ?: 'Unknown'; ?> 2453 <br /> 2454 <strong>Cache Hits:</strong> 2455 <?php echo (int) $this->cache_hits; ?> 2456 <br /> 2457 <strong>Cache Misses:</strong> 2458 <?php echo (int) $this->cache_misses; ?> 2459 <br /> 2460 <strong>Cache Size:</strong> 2461 <?php echo number_format_i18n( strlen( serialize( $this->cache ) ) / 1024, 2 ); ?> KB 2462 </p> 2295 2463 <?php 2296 2464 } … … 2684 2852 return false; 2685 2853 } 2686 // Or else fall through.2687 // No break!2854 // Or else fall through. 2855 // No break! 2688 2856 case 'a': 2689 2857 case 'O': … … 2713 2881 $this->ignored_groups = array_unique( array_merge( $this->ignored_groups, $this->global_groups ) ); 2714 2882 2715 if ( ! $this->fail_gracefully ) {2716 throw $exception;2717 }2718 2719 $this->errors[] = $exception->getMessage();2720 2721 2883 error_log( $exception ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log 2722 2884 2723 2885 if ( function_exists( 'do_action' ) ) { 2724 2886 /** 2725 * Fires on every cache error2887 * Fires when an object cache related error occurs. 2726 2888 * 2727 2889 * @since 1.5.0 2728 * @param \Exception $exception The exception triggered. 2890 * @param \Exception $exception The exception. 2891 * @param string $message The exception message. 2729 2892 */ 2730 do_action( 'redis_object_cache_error', $exception ); 2731 } 2893 do_action( 'redis_object_cache_error', $exception, $exception->getMessage() ); 2894 } 2895 2896 if ( ! $this->fail_gracefully ) { 2897 $this->show_error_and_die( $exception ); 2898 } 2899 2900 $this->errors[] = $exception->getMessage(); 2901 } 2902 2903 /** 2904 * Show Redis connection error screen, or load custom `/redis-error.php`. 2905 * 2906 * @return void 2907 */ 2908 protected function show_error_and_die( Exception $exception ) { 2909 wp_load_translations_early(); 2910 2911 add_filter( 'pre_determine_locale', function () { 2912 return defined( 'WPLANG' ) ? WPLANG : 'en_US'; 2913 } ); 2914 2915 // Load custom DB error template, if present. 2916 if ( file_exists( WP_CONTENT_DIR . '/redis-error.php' ) ) { 2917 require_once WP_CONTENT_DIR . '/redis-error.php'; 2918 die(); 2919 } 2920 2921 $verbose = wp_installing() 2922 || defined( 'WP_ADMIN' ) 2923 || ( defined( 'WP_DEBUG' ) && WP_DEBUG ); 2924 2925 $message = '<h1>' . __( 'Error establishing a Redis connection', 'redis-cache' ) . "</h1>\n"; 2926 2927 if ( $verbose ) { 2928 $message .= "<p><code>" . $exception->getMessage() . "</code></p>\n"; 2929 2930 $message .= '<p>' . sprintf( 2931 // translators: %s = Formatted wp-config.php file name. 2932 __( 'WordPress is unable to establish a connection to Redis. This means that the connection information in your %s file are incorrect, or that the Redis server is not reachable.', 'redis-cache' ), 2933 '<code>wp-config.php</code>' 2934 ) . "</p>\n"; 2935 2936 $message .= "<ul>\n"; 2937 $message .= '<li>' . __( 'Is the correct Redis host and port set?', 'redis-cache' ) . "</li>\n"; 2938 $message .= '<li>' . __( 'Is the Redis server running?', 'redis-cache' ) . "</li>\n"; 2939 $message .= "</ul>\n"; 2940 2941 $message .= '<p>' . sprintf( 2942 // translators: %s = Link to installation instructions. 2943 __( 'If you need help, please read the <a href="%s">installation instructions</a>.', 'redis-cache' ), 2944 'https://github.com/rhubarbgroup/redis-cache/blob/develop/INSTALL.md' 2945 ) . "</p>\n"; 2946 } 2947 2948 $message .= '<p>' . sprintf( 2949 // translators: %1$s = Formatted object-cache.php file name, %2$s = Formatted wp-content directory name. 2950 __( 'To disable Redis, delete the %1$s file in the %2$s directory.', 'redis-cache' ), 2951 '<code>object-cache.php</code>', 2952 '<code>/wp-content/</code>' 2953 ) . "</p>\n"; 2954 2955 wp_die( $message ); 2732 2956 } 2733 2957 -
spinupwp/trunk/readme.txt
r2812614 r3029656 3 3 Tags: cache, caching, performance 4 4 Requires at least: 4.7 5 Tested up to: 6. 15 Tested up to: 6.4 6 6 Requires PHP: 7.1 7 Stable tag: 1. 5.17 Stable tag: 1.6 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 87 87 == Changelog == 88 88 89 = 1.6 (2024-01-31) = 90 * New: Add "Purge this URL" option to our Cache menu in the WordPress nav bar. 91 * New: Cache key customization. /props quimcastella 92 * Improvement: Increase default cache purge timeout limit from 1 to 5 seconds. 93 * Improvement: PHP 8.1 compatibility. /props afragen 94 * Bug Fix: Page cache not cleared when clearing object cache fails. 95 89 96 = 1.5.1 (2022-11-05) = 90 97 * Ensure SpinupWP page caching is correctly detected in Site Health -
spinupwp/trunk/src/Cache.php
r2774192 r3029656 52 52 } 53 53 54 if ( $this->is_page_cache_enabled() && ! is_admin() ) { 55 $this->admin_bar->add_item( __( 'Purge this URL', 'spinupwp' ), 'purge-url' ); 56 } 57 54 58 add_action( 'spinupwp_purge_object_cache', array( $this, 'purge_object_cache' ) ); 55 59 add_action( 'spinupwp_purge_page_cache', array( $this, 'purge_page_cache' ) ); 60 add_action( 'spinupwp_purge_url', array( $this, 'purge_url' ) ); 56 61 add_action( 'admin_init', array( $this, 'handle_manual_purge_action' ) ); 57 62 add_action( 'transition_post_status', array( $this, 'purge_post_on_update' ), 10, 3 ); … … 74 79 $action = filter_input( INPUT_GET, 'spinupwp_action' ); 75 80 76 if ( ! $action || ! in_array( $action, array( 'purge-all', 'purge-object', 'purge-page' ) ) ) {81 if ( ! $action || ! in_array( $action, array( 'purge-all', 'purge-object', 'purge-page', 'purge-url' ) ) ) { 77 82 return; 78 83 } … … 83 88 84 89 if ( 'purge-all' === $action ) { 85 $purge = $this->purge_object_cache() && $this->purge_page_cache(); 90 $purge_object_cache = $this->purge_object_cache(); 91 $purge_page_cache = $this->purge_page_cache(); 92 93 $purge = $purge_object_cache && $purge_page_cache; 86 94 $type = 'all'; 87 95 } … … 95 103 $purge = $this->purge_page_cache(); 96 104 $type = 'page'; 105 } 106 107 if ( 'purge-url' === $action ) { 108 $url = $_SERVER['HTTP_REFERER']; 109 $purge = $this->purge_url($url); 110 $type = 'url'; 97 111 } 98 112 … … 288 302 */ 289 303 public function purge_url( $url ) { 290 $path = $this->get_cache_path_for_url( $url ); 291 $result = $this->delete( $path ); 292 293 do_action( 'spinupwp_url_purged', $url, $result ); 294 295 return $result; 296 } 297 298 /** 299 * Get's the cache file path for a given URL. 300 * 304 $cache_paths = $this->get_cache_paths_for_url( $url ); 305 306 $all_deleted = true; 307 foreach ($cache_paths as $path) { 308 $deleted = $this->delete( $path ); 309 do_action( 'spinupwp_url_purged', $url, $deleted ); 310 $all_deleted &= $deleted; 311 } 312 313 return $all_deleted; 314 } 315 316 /** 317 * Gets the cache file paths for a given URL. 318 * 301 319 * Must be using the default Nginx cache options (levels=1:2) 302 * and (fastcgi_cache_key "$scheme$request_method$host$request_uri").303 320 * https://www.digitalocean.com/community/tutorials/how-to-setup-fastcgi-caching-with-nginx-on-your-vps#purging-the-cache 304 321 * 305 322 * @param string $url 306 323 * 307 * @return string 308 */ 309 private function get_cache_path_for_url( $url ) { 324 * @return array 325 */ 326 private function get_cache_paths_for_url( $url ) { 327 $cache_keys = $this->get_cache_keys_for_url( $url ); 328 329 $cache_paths = array(); 330 foreach ($cache_keys as $key) { 331 $hashed_key = md5($key); 332 $path = substr( $hashed_key, - 1 ) . '/' . substr( $hashed_key, - 3, 2 ) . '/' . $hashed_key; 333 $cache_paths[] = trailingslashit( $this->cache_path ) . $path; 334 } 335 336 return $cache_paths; 337 } 338 339 /** 340 * Gets the cache keys for a given URL. 341 * 342 * It defaults to a single key: (fastcgi_cache_key "$scheme$request_method$host$request_uri"), 343 * but it can be modified with spinupwp_cache_key_components filter. 344 * This must match the Nginx configuration. 345 * 346 * @param string $url 347 * 348 * @return array 349 */ 350 private function get_cache_keys_for_url( $url ) { 351 // Default cache key 310 352 $parsed_url = parse_url( trailingslashit( $url ) ); 311 $cache_key = md5( $parsed_url['scheme'] . 'GET' . $parsed_url['host'] . $parsed_url['path'] ); 312 $cache_path = substr( $cache_key, - 1 ) . '/' . substr( $cache_key, - 3, 2 ) . '/' . $cache_key; 313 314 return trailingslashit( $this->cache_path ) . $cache_path; 353 $cache_keys = array($parsed_url['scheme'] . 'GET' . $parsed_url['host'] . $parsed_url['path']); 354 355 // Allow the cache keys to be modified 356 $cache_keys = apply_filters('spinupwp_cache_keys_for_url', $cache_keys, $url); 357 358 return $cache_keys; 315 359 } 316 360 … … 324 368 */ 325 369 private function delete( $path, $recursive = false ) { 326 if ( file_exists( $path ) && is_writable( $path ) ) {370 if ( null !== $path && file_exists( $path ) && is_writable( $path ) ) { 327 371 require_once( ABSPATH . '/wp-admin/includes/file.php' ); 328 372
Note: See TracChangeset
for help on using the changeset viewer.