| @@ -26,11 +26,11 @@ | ||
| 26 | 26 | public const VERSION = '1.0.0'; |
| 27 | 27 | |
| 28 | 28 | public function ui_metadata(): array { |
| 29 | 29 | return array( |
| 30 | - 'label' => 'Migration', | |
| 30 | + 'label' => __( 'Migration', 'xspeed' ), | |
| 31 | 31 | 'icon' => 'Import', |
| 32 | - 'description' => 'Import settings from WP Rocket, W3 Total Cache, or WP Super Cache.', | |
| 32 | + 'description' => __( 'Import settings from WP Rocket, W3 Total Cache, or WP Super Cache.', 'xspeed' ), | |
| 33 | 33 | 'custom_panel' => 'MigrationPanel', |
| 34 | 34 | ); |
| 35 | 35 | } |
| 36 | 36 | |
| @@ -1133,8 +1133,21 @@ | ||
| 1133 | 1133 | */ |
| 1134 | 1134 | $network_wide = is_multisite() && is_plugin_active_for_network( $file ); |
| 1135 | 1135 | deactivate_plugins( $file, false, $network_wide ); |
| 1136 | 1136 | |
| 1137 | + /* | |
| 1138 | + * The source's teardown just rewrote the very state the detector | |
| 1139 | + * memoizes for the request -- WP Rocket truncates advanced-cache.php | |
| 1140 | + * to 0 bytes and W3TC strips WP_CACHE, both from inside the call | |
| 1141 | + * above. Without dropping the memo, restore_own_environment() asks a | |
| 1142 | + * report taken while the source still held the field, sees "foreign", | |
| 1143 | + * and refuses -- so the handover deactivated the source and then | |
| 1144 | + * declined to take over, which is the outcome #391 describes. | |
| 1145 | + */ | |
| 1146 | + if ( class_exists( '\\XSpeed\\Page_Cache_Detector' ) ) { | |
| 1147 | + \XSpeed\Page_Cache_Detector::invalidate(); | |
| 1148 | + } | |
| 1149 | + | |
| 1137 | 1150 | return ! is_plugin_active( $file ); |
| 1138 | 1151 | } |
| 1139 | 1152 | |
| 1140 | 1153 | /** |
| @@ -1150,11 +1163,18 @@ | ||
| 1150 | 1163 | * loads it without the constant, and the cache silently degrades to the |
| 1151 | 1164 | * slow in-PHP path — measured at 78ms vs 16ms TTFB on an otherwise |
| 1152 | 1165 | * identical request. |
| 1153 | 1166 | * |
| 1154 | - * Only runs when the user has caching ON, and only re-asserts what we | |
| 1155 | - * already own, so it cannot resurrect a cache the user turned off. | |
| 1156 | - * (#218, #219) | |
| 1167 | + * Runs at exactly one moment -- the user asked to import from another | |
| 1168 | + * plugin AND switch it off, and we just switched it off -- so it turns | |
| 1169 | + * caching ON rather than only re-asserting an existing setting. It used | |
| 1170 | + * to return early unless cache_enabled was already set, which it almost | |
| 1171 | + * never is here: the site was being cached by the plugin we just | |
| 1172 | + * deactivated. That is how a migration could end with the source gone | |
| 1173 | + * and nothing serving. (#218, #219, #391) | |
| 1174 | + * | |
| 1175 | + * Not a licence to trample: toggle() still refuses on an occupied field, | |
| 1176 | + * so a page cache we were not asked to replace is left alone. | |
| 1157 | 1177 | */ |
| 1158 | 1178 | private function restore_own_environment(): void { |
| 1159 | 1179 | if ( ! class_exists( '\\XSpeed\\Cache' ) || ! class_exists( '\\XSpeed\\Settings' ) ) { |
| 1160 | 1180 | return; |
| @@ -1159,13 +1179,20 @@ | ||
| 1159 | 1179 | if ( ! class_exists( '\\XSpeed\\Cache' ) || ! class_exists( '\\XSpeed\\Settings' ) ) { |
| 1160 | 1180 | return; |
| 1161 | 1181 | } |
| 1162 | 1182 | |
| 1163 | - $opts = \XSpeed\Settings::get(); | |
| 1164 | - if ( empty( $opts['cache_enabled'] ) ) { | |
| 1165 | - return; | |
| 1166 | - } | |
| 1167 | - | |
| 1183 | + /* | |
| 1184 | + * Turn caching ON, rather than only re-asserting it when it was | |
| 1185 | + * already on. This runs at exactly one moment: the user asked us to | |
| 1186 | + * import from another plugin AND switch it off, and we just did. A | |
| 1187 | + * handover that ends with the old cache gone and no new one is not a | |
| 1188 | + * handover -- and cache_enabled is nearly always empty here, because | |
| 1189 | + * the site was being cached by the plugin we just deactivated. That | |
| 1190 | + * early return is why #391 ended with nothing serving. | |
| 1191 | + * | |
| 1192 | + * toggle() still refuses if the field is genuinely occupied, so this | |
| 1193 | + * cannot trample a cache we were not asked to replace. | |
| 1194 | + */ | |
| 1168 | 1195 | \XSpeed\Cache::toggle( true ); |
| 1169 | 1196 | } |
| 1170 | 1197 | |
| 1171 | 1198 | public function cli_commands(): array { |
| @@ -1275,8 +1302,15 @@ | ||
| 1275 | 1302 | if ( $want_off && $imported_something && $still_on ) { |
| 1276 | 1303 | if ( $this->deactivate_source( $src ) ) { |
| 1277 | 1304 | \WP_CLI::log( sprintf( 'Deactivated %s.', $src ) ); |
| 1278 | 1305 | $still_on = false; |
| 1306 | + // Same handover the REST route performs. Without it | |
| 1307 | + // the CLI switched the source off and stopped there, | |
| 1308 | + // leaving the husk of its drop-in and no page cache | |
| 1309 | + // at all -- reported as "Success: Import complete." | |
| 1310 | + // CLI and REST must not disagree about what | |
| 1311 | + // --deactivate-source means. (#391) | |
| 1312 | + $this->restore_own_environment(); | |
| 1279 | 1313 | } else { |
| 1280 | 1314 | \WP_CLI::warning( sprintf( 'Could not deactivate %s.', $src ) ); |
| 1281 | 1315 | } |
| 1282 | 1316 | } |