PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | jetpack_vendor/automattic/jetpack-search/src/initializers/class-initializer.php +119 -9 12.5.2 → 16.3-beta View file →
@@ -7,8 +7,9 @@
7 7
8 8 namespace Automattic\Jetpack\Search;
9 9
10 10 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
11 +use Automattic\Jetpack\Status\Host;
11 12 use WP_Error;
12 13 /**
13 14 * Base class for the initializer pattern.
14 15 */
@@ -14,8 +15,24 @@
14 15 */
15 16 class Initializer {
16 17
17 18 /**
19 + * Whether a block-driven experience owns the search results this request
20 + * — Embedded, or the experimental blocks Overlay. Set to `true` in
21 + * `init_search_blocks()` only when the `jetpack_search_blocks_enabled`
22 + * gate is on AND the saved experience is one of those (the Overlay arm
23 + * additionally requires `jetpack_search_overlay_block_template_enabled`).
24 + * In those experiences both Classic and Instant Search are suppressed, so
25 + * `init_search()` returns falsy by design; `init()` reads this flag to
26 + * treat that as a no-op rather than a real failure. Anchoring on the
27 + * actually-wired-up state (not a filter read) prevents the abort carve-out
28 + * from being bypassed on a site that doesn't have Search Blocks registered.
29 + *
30 + * @var bool
31 + */
32 + private static $block_search_active = false;
33 +
34 + /**
18 35 * Initialize the search package.
19 36 *
20 37 * The method is called from the `Config` class.
21 38 */
@@ -53,8 +70,15 @@
53 70 do_action( 'jetpack_search_abort', 'inactive', null );
54 71 return;
55 72 }
56 73
74 + // Register the Search 3.0 Interactivity API blocks. Connection +
75 + // plan are already guaranteed by the abort above; this call only
76 + // layers the Phase 1 feature flag on top, mirroring how
77 + // `init_search()` layers `is_instant_search_enabled` on top of
78 + // the same upstream gate.
79 + static::init_search_blocks();
80 +
57 81 $blog_id = Helper::get_wpcom_site_id();
58 82 if ( ! $blog_id ) {
59 83 /** This filter is documented in search/src/initalizers/class-initalizer.php */
60 84 do_action( 'jetpack_search_abort', 'no_blog_id', null );
@@ -66,10 +90,19 @@
66 90 do_action( 'jetpack_search_abort', 'module_inactive', null );
67 91 return;
68 92 }
69 93
70 - // Initialize search package.
71 - if ( ! static::init_search( $blog_id ) ) {
94 + // Initialize search package. The block-driven experiences (Embedded /
95 + // blocks Overlay) intentionally skip both instant and classic init
96 + // (Search_Blocks owns the UI), so a falsy return there is by design —
97 + // not an abort. Anything else falsy is a real failure. Anchor on the
98 + // actually-wired-up flag (set in `init_search_blocks()` only when the
99 + // blocks gate passed) rather than a filter read, so flipping a filter
100 + // without the blocks gate can never bypass the abort.
101 + $initialized = static::init_search( $blog_id )
102 + || self::$block_search_active;
103 +
104 + if ( ! $initialized ) {
72 105 /** This filter is documented in search/src/initalizers/class-initalizer.php */
73 106 do_action( 'jetpack_search_abort', 'jetpack_search_init_search', null );
74 107 return;
75 108 }
@@ -85,13 +118,16 @@
85 118 /**
86 119 * Extra tweaks to make Jetpack Search play well with others.
87 120 */
88 121 public static function include_compatibility_files() {
89 - if ( class_exists( 'Jetpack' ) ) {
122 + // WordPress.com Simple defines its own unrelated `Jetpack` class, so the class name
123 + // alone does not mean the Jetpack plugin, and this shim would fatal there.
124 + if ( class_exists( 'Jetpack' ) && ! ( new Host() )->is_wpcom_simple() ) {
90 125 require_once Package::get_installed_path() . 'compatibility/jetpack.php';
91 126 }
92 127 require_once Package::get_installed_path() . 'compatibility/search-0.15.2.php';
93 128 require_once Package::get_installed_path() . 'compatibility/search-0.17.0.php';
129 + require_once Package::get_installed_path() . 'compatibility/unsupported-browsers.php';
94 130 }
95 131
96 132 /**
97 133 * Init functionality required for connection.
@@ -97,14 +133,78 @@
97 133 * Init functionality required for connection.
98 134 */
99 135 protected static function init_before_connection() {
100 136 // Set up Search API endpoints.
101 - add_action( 'rest_api_init', array( new REST_Controller(), 'register_rest_routes' ) );
137 + add_action( 'rest_api_init', array( REST_Controller::class, 'register' ) );
102 138 // The dashboard has to be initialized before connection.
103 139 ( new Dashboard() )->init_hooks();
140 + ( new AI_Answers() )->init();
104 141 }
105 142
106 143 /**
144 + * Register the Search 3.0 Interactivity API blocks on this request,
145 + * gated by the Phase 1 feature flag.
146 + *
147 + * Called from `init()` after the upstream connection + Search-plan
148 + * abort, so on entry the site is guaranteed to be connected and on a
149 + * plan that supports Search (paid plans or the free
150 + * `jetpack_search_free` product). The remaining gate is the
151 + * feature-flag opt-in.
152 + *
153 + * Sits before the blog_id and module-active checks because admins
154 + * should be able to configure Search blocks in the editor regardless
155 + * of which runtime experience is enabled — matching how Instant
156 + * Search layers its own opt-in on top of the same connection + plan
157 + * gate further down in `init_search()`.
158 + */
159 + protected static function init_search_blocks() {
160 + /**
161 + * Filter whether the Jetpack Search 3.0 Interactivity API blocks are enabled.
162 + *
163 + * Necessary but not sufficient on its own — registration also
164 + * requires the site to be connected and on a plan that supports
165 + * Search (paid plans or the free `jetpack_search_free` product).
166 + *
167 + * @param bool $enabled Default true.
168 + */
169 + if ( ! apply_filters( 'jetpack_search_blocks_enabled', true ) ) {
170 + return;
171 + }
172 +
173 + Search_Blocks::init();
174 +
175 + // When the Search blocks own the front-end results (Embedded / blocks
176 + // Overlay), Classic Search would otherwise run a server-side
177 + // Elasticsearch query plus a WP_Query to hydrate the posts on every
178 + // search request — work the blocks immediately discard. Suppress it so
179 + // it never runs, the same way Instant Search replaces Classic;
180 + // `Search_Blocks::filter__posts_pre_query` then short-circuits the
181 + // remaining core database search. With both handlers gone `init_search()`
182 + // returns false by design, so this flag tells `init()` not to treat that
183 + // as an abort.
184 + //
185 + // Front-end only, matching the `posts_pre_query` registration guard:
186 + // leaving Classic Search to initialize normally in wp-admin keeps the
187 + // change scoped to the search page and avoids dropping admin-side hooks.
188 + if ( ! is_admin() && Search_Blocks::owns_search_results() ) {
189 + add_filter( 'jetpack_search_classic_search_enabled', '__return_false' );
190 + self::$block_search_active = true;
191 + }
192 +
193 + // Experimental block-template overlay (available by default, opt-in
194 + // via the Experience Selector; see
195 + // `Search_Blocks::is_block_template_overlay_enabled()`): bypass the
196 + // preact `SearchApp` so it doesn't race the block overlay for
197 + // `?s=`, popstate, and theme search-trigger selectors. Suppressing
198 + // at the init filter is cleaner than dequeuing post-enqueue. Gated on
199 + // the overlay path specifically — Embedded never enables Instant Search,
200 + // so there is nothing to suppress there.
201 + if ( Search_Blocks::is_block_template_overlay_enabled() ) {
202 + add_filter( 'jetpack_search_init_instant_search', '__return_false' );
203 + }
204 + }
205 +
206 + /**
107 207 * Init the search package.
108 208 *
109 209 * @param int $blog_id WPCOM blog ID.
110 210 */
@@ -111,13 +211,22 @@
111 211 protected static function init_search( $blog_id ) {
112 212 // We could provide CLI to enable search/instant search, so init them regardless of whether the module is active or not.
113 213 static::init_cli();
114 214
115 - $success = false;
116 - if ( ( new Module_Control() )->is_instant_search_enabled() ) {
215 + $success = false;
216 + $is_instant_search_enabled = ( new Module_Control() )->is_instant_search_enabled();
217 + if ( $is_instant_search_enabled ) {
117 218 // Enable Instant search experience.
118 219 $success = static::init_instant_search( $blog_id );
119 - } else {
220 + }
221 + /**
222 + * Filter whether classic search should be enabled. By this stage, search module would be enabled already.
223 + *
224 + * @since 0.39.6
225 + * @param boolean initial value whether classic search is enabled.
226 + * @param boolean filtered result whether classic search is enabled.
227 + */
228 + if ( apply_filters( 'jetpack_search_classic_search_enabled', ! $is_instant_search_enabled ) ) {
120 229 // Enable the classic search experience.
121 230 $success = static::init_classic_search( $blog_id );
122 231 }
123 232
@@ -152,9 +261,9 @@
152 261 new Settings();
153 262 // Instantiate "Customberg", the live search configuration interface.
154 263 Customberg::instance();
155 264 // Enable configuring instant search within the Customizer iff it's not using a block theme.
156 - if ( ! function_exists( 'wp_is_block_theme' ) || ( function_exists( 'wp_is_block_theme' ) && ! wp_is_block_theme() ) ) {
265 + if ( ! wp_is_block_theme() ) {
157 266 new Customizer();
158 267 }
159 268 return true;
160 269 }
@@ -174,9 +283,10 @@
174 283 */
175 284 if ( ! apply_filters( 'jetpack_search_init_classic_search', true ) ) {
176 285 return;
177 286 }
178 - Classic_Search::initialize( $blog_id );
287 + Inline_Search::get_instance_maybe_fallback_to_classic( $blog_id );
288 +
179 289 return true;
180 290 }
181 291
182 292 /**