← All changes
|
includes/modules/ObjectCache/ObjectCacheModule.php
+68
-13
1.3.7
→
1.4.2
View file →
| @@ -19,8 +19,9 @@ | ||
| 19 | 19 | defined( 'ABSPATH' ) || exit; |
| 20 | 20 | |
| 21 | 21 | use XSpeed\Module; |
| 22 | 22 | use XSpeed\Object_Cache; |
| 23 | +use XSpeed\Object_Cache_Takeover; | |
| 23 | 24 | |
| 24 | 25 | final class ObjectCacheModule extends Module { |
| 25 | 26 | |
| 26 | 27 | public const SLUG = 'object-cache'; |
| @@ -62,14 +63,27 @@ | ||
| 62 | 63 | 'label' => __( 'Cache server', 'xspeed' ), |
| 63 | 64 | 'description' => __( 'The cache server your host provides. Ask your host if you are not sure.', 'xspeed' ), |
| 64 | 65 | ), |
| 65 | 66 | 'redis_host' => array( |
| 66 | - 'type' => 'string', | |
| 67 | - 'default' => '127.0.0.1', | |
| 68 | - 'constants' => array( 'XSPEED_OC_HOST', 'WP_REDIS_HOST' ), | |
| 69 | - 'label' => __( 'Redis host', 'xspeed' ), | |
| 70 | - 'description' => __( 'Address of the Redis server. Use 127.0.0.1 when Redis runs on the same server as your site.', 'xspeed' ), | |
| 71 | - 'dependsOn' => array( 'field' => 'backend', 'value' => 'redis' ), | |
| 67 | + 'type' => 'string', | |
| 68 | + 'default' => '127.0.0.1', | |
| 69 | + // WP_REDIS_PATH is Redis Object Cache's name for a unix socket, | |
| 70 | + // and it only means one when WP_REDIS_SCHEME says `unix` -- the | |
| 71 | + // same pair that plugin reads. It ranks above WP_REDIS_HOST | |
| 72 | + // because that plugin ignores the host once the scheme is unix, | |
| 73 | + // and hosts that write the pair often leave a stale host | |
| 74 | + // beside it. (#566) | |
| 75 | + 'constants' => array( 'XSPEED_OC_HOST', 'WP_REDIS_PATH', 'WP_REDIS_HOST' ), | |
| 76 | + 'constants_when' => array( | |
| 77 | + 'WP_REDIS_PATH' => array( | |
| 78 | + 'constant' => 'WP_REDIS_SCHEME', | |
| 79 | + 'is' => 'unix', | |
| 80 | + 'case_insensitive' => true, | |
| 81 | + ), | |
| 82 | + ), | |
| 83 | + 'label' => __( 'Redis host', 'xspeed' ), | |
| 84 | + 'description' => __( 'Address of the Redis server, or the path to its socket file if your host gave you one (for example /run/redis/redis.sock). Use 127.0.0.1 when Redis runs on the same server as your site.', 'xspeed' ), | |
| 85 | + 'dependsOn' => array( 'field' => 'backend', 'value' => 'redis' ), | |
| 72 | 86 | ), |
| 73 | 87 | 'redis_port' => array( |
| 74 | 88 | 'type' => 'int', |
| 75 | 89 | 'default' => 6379, |
| @@ -76,9 +90,9 @@ | ||
| 76 | 90 | 'min' => 1, |
| 77 | 91 | 'max' => 65535, |
| 78 | 92 | 'constants' => array( 'XSPEED_OC_PORT', 'WP_REDIS_PORT' ), |
| 79 | 93 | 'label' => __( 'Redis port', 'xspeed' ), |
| 80 | - 'description' => __( 'The default Redis port is 6379.', 'xspeed' ), | |
| 94 | + 'description' => __( 'The default Redis port is 6379. Not used when the host is a socket path.', 'xspeed' ), | |
| 81 | 95 | 'advanced' => true, |
| 82 | 96 | 'dependsOn' => array( 'field' => 'backend', 'value' => 'redis' ), |
| 83 | 97 | ), |
| 84 | 98 | 'redis_user' => array( |
| @@ -87,9 +101,11 @@ | ||
| 87 | 101 | // WP_REDIS_PASSWORD trails the dedicated names because in its |
| 88 | 102 | // array form -- how xCloud and Cloudways hand out ACL |
| 89 | 103 | // credentials -- it carries the username too. It is pair-only: |
| 90 | 104 | // as a plain string it is a password, never a username. |
| 91 | - 'constants' => array( 'XSPEED_OC_USER', 'WP_REDIS_USER', 'WP_REDIS_PASSWORD' ), | |
| 105 | + // WP_REDIS_USERNAME is Redis Object Cache's name for the same | |
| 106 | + // thing, and that plugin lets it win over the array form. (#566) | |
| 107 | + 'constants' => array( 'XSPEED_OC_USER', 'WP_REDIS_USERNAME', 'WP_REDIS_USER', 'WP_REDIS_PASSWORD' ), | |
| 92 | 108 | 'constants_pair_only' => array( 'WP_REDIS_PASSWORD' ), |
| 93 | 109 | 'constant_pair' => 'user', |
| 94 | 110 | 'label' => __( 'Redis username', 'xspeed' ), |
| 95 | 111 | 'description' => __( 'Only needed if your host gave you a Redis username along with the password. Leave blank otherwise.', 'xspeed' ), |
| @@ -659,9 +675,9 @@ | ||
| 659 | 675 | * probe recorded on save knows; until this it had no reader outside |
| 660 | 676 | * WP-CLI, so the panel kept saying "Redis ready" over a cache that |
| 661 | 677 | * stored nothing. (#398) |
| 662 | 678 | */ |
| 663 | - $detect = Object_Cache::detect(); | |
| 679 | + $detect = Object_Cache::detect( true ); | |
| 664 | 680 | $failure = self::live_write_failure(); |
| 665 | 681 | if ( null !== $failure ) { |
| 666 | 682 | $detect['write_probe'] = $failure; |
| 667 | 683 | } |
| @@ -748,12 +764,22 @@ | ||
| 748 | 764 | |
| 749 | 765 | public function rest_enable( \WP_REST_Request $request ) { |
| 750 | 766 | // Persist any settings sent with the enable call first, then act on them. |
| 751 | 767 | $body = $request->get_json_params(); |
| 768 | + // `takeover` is an action, not a setting: take it out before the body | |
| 769 | + // is saved as the settings row. Sent in the body rather than the query | |
| 770 | + // string because on plain permalinks the REST base already carries | |
| 771 | + // `?rest_route=`. (#686) | |
| 772 | + $takeover = is_array( $body ) && ! empty( $body['takeover'] ) | |
| 773 | + ? rest_sanitize_boolean( $body['takeover'] ) | |
| 774 | + : rest_sanitize_boolean( $request->get_param( 'takeover' ) ); | |
| 775 | + if ( is_array( $body ) ) { | |
| 776 | + unset( $body['takeover'] ); | |
| 777 | + } | |
| 752 | 778 | if ( is_array( $body ) && ! empty( $body ) ) { |
| 753 | 779 | \XSpeed\Settings_Manager::update( self::SLUG, $body ); |
| 754 | 780 | } |
| 755 | - $result = Object_Cache::enable( $this->get_settings() ); | |
| 781 | + $result = Object_Cache::enable( $this->get_settings(), array( 'takeover' => $takeover ) ); | |
| 756 | 782 | |
| 757 | 783 | if ( $result['ok'] && class_exists( '\\XSpeed\\Activity_Log' ) ) { |
| 758 | 784 | \XSpeed\Activity_Log::record( |
| 759 | 785 | 'object_cache_enabled', |
| @@ -764,9 +790,11 @@ | ||
| 764 | 790 | return rest_ensure_response( $result ); |
| 765 | 791 | } |
| 766 | 792 | |
| 767 | 793 | public function rest_disable( \WP_REST_Request $request ) { |
| 768 | - $result = Object_Cache::disable(); | |
| 794 | + $result = Object_Cache::disable( | |
| 795 | + array( 'restore' => rest_sanitize_boolean( $request->get_param( 'restore' ) ) ) | |
| 796 | + ); | |
| 769 | 797 | if ( $result['ok'] && class_exists( '\\XSpeed\\Activity_Log' ) ) { |
| 770 | 798 | \XSpeed\Activity_Log::record( |
| 771 | 799 | 'object_cache_disabled', |
| 772 | 800 | 'Object cache disabled.', |
| @@ -799,8 +827,20 @@ | ||
| 799 | 827 | 'type' => 'positional', |
| 800 | 828 | 'name' => 'value', |
| 801 | 829 | 'optional' => true, |
| 802 | 830 | ), |
| 831 | + array( | |
| 832 | + 'type' => 'flag', | |
| 833 | + 'name' => 'takeover', | |
| 834 | + 'description' => 'With enable: switch from the plugin that owns object-cache.php (backs it up, turns that plugin off, installs xSpeed, undoes everything on failure).', | |
| 835 | + 'optional' => true, | |
| 836 | + ), | |
| 837 | + array( | |
| 838 | + 'type' => 'flag', | |
| 839 | + 'name' => 'restore', | |
| 840 | + 'description' => 'With disable: put back the plugin xSpeed switched from.', | |
| 841 | + 'optional' => true, | |
| 842 | + ), | |
| 803 | 843 | ), |
| 804 | 844 | ), |
| 805 | 845 | ); |
| 806 | 846 | } |
| @@ -956,13 +996,28 @@ | ||
| 956 | 996 | $t = Object_Cache::test_connection( $this->get_settings() ); |
| 957 | 997 | $t['ok'] ? \WP_CLI::success( $t['message'] ) : \WP_CLI::error( $t['message'] ); |
| 958 | 998 | return; |
| 959 | 999 | case 'enable': |
| 960 | - $r = Object_Cache::enable( $this->get_settings() ); | |
| 1000 | + $r = Object_Cache::enable( | |
| 1001 | + $this->get_settings(), | |
| 1002 | + array( 'takeover' => ! empty( $assoc['takeover'] ) ) | |
| 1003 | + ); | |
| 1004 | + if ( ! $r['ok'] && ! empty( $r['needs_takeover'] ) && Object_Cache_Takeover::STRATEGY_REFUSE !== ( $r['owner']['strategy'] ?? '' ) ) { | |
| 1005 | + // This handler also answers MCP (through Cli_Bridge), where | |
| 1006 | + // the switch is an argument, not a flag. | |
| 1007 | + \WP_CLI::error( $r['message'] . ' To switch, run again with --takeover (MCP: takeover: true).' ); | |
| 1008 | + } | |
| 961 | 1009 | $r['ok'] ? \WP_CLI::success( $r['message'] ) : \WP_CLI::error( $r['message'] ); |
| 962 | 1010 | return; |
| 963 | 1011 | case 'disable': |
| 964 | - $r = Object_Cache::disable(); | |
| 1012 | + $r = Object_Cache::disable( array( 'restore' => ! empty( $assoc['restore'] ) ) ); | |
| 1013 | + // Disabling worked; a restore that could not complete is a | |
| 1014 | + // warning, not a failed command. | |
| 1015 | + if ( $r['ok'] && false === ( $r['restored'] ?? null ) ) { | |
| 1016 | + \WP_CLI::warning( $r['message'] ); | |
| 1017 | + \WP_CLI::success( 'Object cache disabled.' ); | |
| 1018 | + return; | |
| 1019 | + } | |
| 965 | 1020 | $r['ok'] ? \WP_CLI::success( $r['message'] ) : \WP_CLI::error( $r['message'] ); |
| 966 | 1021 | return; |
| 967 | 1022 | default: |
| 968 | 1023 | \WP_CLI::error( "Unknown action: $action" ); |