PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.4.2
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.4.2
1.4.2 1.4.1 1.4.0 1.3.7 1.3.6 1.3.5 1.3.4 1.3.3 1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 All 36 releases
← All changes | includes/class-migration.php +51 -8 1.2.4 → 1.4.2 View file →
@@ -389,8 +389,12 @@
389 389 if ( empty( $servers ) || ! is_array( $servers ) ) {
390 390 continue;
391 391 }
392 392 $first = (string) ( $servers[0] ?? '' );
393 + // A Redis socket imports whole, so there is nothing to warn about.
394 + if ( 'redis' === $engine && '' !== Redis_Client::socket_path( $first ) ) {
395 + continue;
396 + }
393 397 if ( ! preg_match( '#^([a-z][a-z0-9+.-]*)://#i', $first, $m ) ) {
394 398 continue;
395 399 }
396 400 $notes[] = sprintf(
@@ -678,8 +682,22 @@
678 682 private const OPTIONAL_FOR_HANDOVER = array(
679 683 'object-cache',
680 684 'cdn',
681 685 'preloader',
686 + /*
687 + * `cache` is optional for the HANDOVER decision specifically, and it
688 + * has to be, because the source itself is usually why it failed: the
689 + * source holds advanced-cache.php, so page cache cannot apply, so we
690 + * refuse to deactivate the source, so it keeps holding the drop-in.
691 + * That loop is what left sites with no cache at all (#391).
692 + *
693 + * Deactivating first and enabling after is the resolution -- see
694 + * MigrationModule::restore_own_environment(), which now turns caching
695 + * on once the field is free. A cache failure is still reported to the
696 + * user either way; it just no longer vetoes the switch-off the notice
697 + * already promised.
698 + */
699 + 'cache',
682 700 );
683 701
684 702 /**
685 703 * Is it safe to switch the source plugin off?
@@ -730,10 +748,14 @@
730 748 if ( ! class_exists( __NAMESPACE__ . '\\Object_Cache' ) ) {
731 749 return $result;
732 750 }
733 751
734 - $opts = (array) Settings_Manager::get( 'object-cache' );
735 - $state = Object_Cache::enable( $opts );
752 + $opts = (array) Settings_Manager::get( 'object-cache' );
753 + // An import IS the user switching away from the source plugin, so it
754 + // takes the same switch path: the source's own object cache is turned
755 + // off through its settings (or the plugin deactivated) before ours goes
756 + // in, instead of being overwritten while it stays on. (#686)
757 + $state = Object_Cache::enable( $opts, array( 'takeover' => true ) );
736 758
737 759 $result['ok'] = ! empty( $state['ok'] );
738 760 $result['object_cache_ready'] = ! empty( $state['ok'] );
739 761 if ( empty( $state['ok'] ) ) {
@@ -801,8 +823,11 @@
801 823 'lazy_images' => ! empty( $r['lazyload'] ),
802 824 'lazy_iframes' => ! empty( $r['lazyload_iframes'] ),
803 825 'lazy_videos' => ! empty( $r['lazyload_youtube'] ),
804 826 );
827 + if ( ! empty( $r['lazyload_css_bg_img'] ) ) {
828 + $patch['lazy']['lazy_background_images'] = true;
829 + }
805 830
806 831 // Separate Mobile Cache — do NOT import this as ON. WP Rocket's
807 832 // "separate cache files for mobile" is frequently left on by habit even
808 833 // when the site serves identical HTML to every device, and xSpeed's
@@ -823,8 +848,19 @@
823 848 $patch['preloader']['sitemap_urls'] = array_values( array_filter( array_map( 'strval', $r['sitemap_preload_url'] ) ) );
824 849 }
825 850 }
826 851
852 + // Bloat — WP Rocket's "Disable Emoji" and "Disable WordPress embeds".
853 + $bloat = array_filter(
854 + array(
855 + 'disable_emojis' => ! empty( $r['emoji'] ),
856 + 'disable_oembed' => ! empty( $r['embeds'] ),
857 + )
858 + );
859 + if ( $bloat ) {
860 + $patch['bloat'] = $bloat;
861 + }
862 +
827 863 // CDN — WP Rocket stores CDN hosts in cdn_cnames (array).
828 864 if ( ! empty( $r['cdn'] ) && ! empty( $r['cdn_cnames'] ) && is_array( $r['cdn_cnames'] ) ) {
829 865 $first = (string) ( $r['cdn_cnames'][0] ?? '' );
830 866 if ( '' !== $first ) {
@@ -1037,8 +1073,16 @@
1037 1073 // drop-in's WP_REDIS_HOST, so the imported object cache could
1038 1074 // never connect. A managed Redis on TLS is the common case.
1039 1075 // Bracketed IPv6 is left alone — stream_socket_client() wants
1040 1076 // the brackets. (#224)
1077 + // W3TC writes a unix socket as `unix:/path`. Split on the
1078 + // colon like a host:port, it imported host "unix" and port 0.
1079 + // A socket carries no port, so only the host is set. (#566)
1080 + $socket = 'redis' === $engine ? Redis_Client::socket_path( $first ) : '';
1081 + if ( '' !== $socket ) {
1082 + $patch['object-cache']['redis_host'] = $socket;
1083 + $first = '';
1084 + }
1041 1085 $first = (string) preg_replace( '#^[a-z][a-z0-9+.-]*://#i', '', $first );
1042 1086 $separator = strrpos( $first, ':' );
1043 1087 if ( false !== $separator ) {
1044 1088 $host = substr( $first, 0, $separator );
@@ -1458,15 +1502,14 @@
1458 1502 $patch['fonts'] = array( 'font_display_swap' => true );
1459 1503 }
1460 1504
1461 1505 // ── Disable bloat ─────────────────────────────────────────────
1462 - // Only map the one LiteSpeed "remove" toggle with a clean xSpeed
1463 - // equivalent: removing the emoji + oEmbed scripts ≈ disable_oembed.
1464 - // (LiteSpeed's optm-emoji_rm strips the wp-emoji + wp-embed pair.)
1465 - // jQuery-migrate / dashicons / XML-RPC / RSS / REST aren't
1466 - // LiteSpeed-managed, so we don't guess at them.
1506 + // optm-emoji_rm is LiteSpeed's only bloat toggle. It used to map to
1507 + // disable_oembed, which turned oEmbed off unasked and left emojis on
1508 + // (#217, #532). jQuery-migrate / dashicons / XML-RPC / RSS / REST
1509 + // aren't LiteSpeed-managed, so we don't guess at them.
1467 1510 if ( $on( 'optm-emoji_rm' ) ) {
1468 - $patch['bloat'] = array( 'disable_oembed' => true );
1511 + $patch['bloat'] = array( 'disable_emojis' => true );
1469 1512 }
1470 1513
1471 1514 // ── Browser cache (LiteSpeed: cache-browser) ──────────────────
1472 1515 if ( $on( 'cache-browser' ) ) {