PluginProbe
ElasticPress / 5.3.5
ElasticPress v5.3.5
5.3.5 5.3.4 3.6.5 3.6.6 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.7.0 4.7.1 4.7.2 5.0.0 5.0.1 5.0.2 All 108 releases
elasticpress / includes / classes / Feature / WooCommerce / WooCommerce.php

WooCommerce.php in ElasticPress 5.3.5, at includes/classes/Feature/WooCommerce/WooCommerce.php

640 lines 21.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ElasticPress WooCommerce feature
4 *
5 * @since 2.1
6 * @package elasticpress
7 */
8
9 namespace ElasticPress\Feature\WooCommerce;
10
11 use ElasticPress\Feature;
12 use ElasticPress\FeatureRequirementsStatus;
13 use ElasticPress\Utils;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * WooCommerce feature class
21 */
22 class WooCommerce extends Feature {
23 /**
24 * If enabled, receive the OrdersAutosuggest object instance
25 *
26 * @since 4.7.0
27 * @var null|OrdersAutosuggest
28 */
29 public $orders_autosuggest = null;
30
31 /**
32 * Receive the Products object instance
33 *
34 * @since 4.7.0
35 * @var null|Products
36 */
37 public $products = null;
38
39 /**
40 * Receive the Orders object instance
41 *
42 * @since 4.5.0
43 * @var null|Orders
44 */
45 public $orders = null;
46
47 /**
48 * Initialize feature setting it's config
49 *
50 * @since 3.0
51 */
52 public function __construct() {
53 $this->slug = 'woocommerce';
54
55 $this->group = 'woocommerce';
56
57 $this->requires_install_reindex = true;
58
59 $this->setting_requires_install_reindex = 'orders';
60
61 $this->available_during_installation = true;
62
63 $this->default_settings = [
64 'orders' => '0',
65 ];
66
67 $this->orders = new Orders( $this );
68 $this->products = new Products( $this );
69 $this->orders_autosuggest = new OrdersAutosuggest( $this );
70
71 parent::__construct();
72 }
73
74 /**
75 * Sets i18n strings.
76 *
77 * @return void
78 * @since 5.2.0
79 */
80 public function set_i18n_strings(): void {
81 $this->title = esc_html__( 'WooCommerce', 'elasticpress' );
82
83 $this->summary = '<p>' . __( 'Most caching and performance tools can’t keep up with the nearly infinite ways your visitors might filter or navigate your products. No matter how many products, filters, or customers you have, ElasticPress will keep your online store performing quickly. If used in combination with the Protected Content feature, ElasticPress will also accelerate order searches and back end product management.', 'elasticpress' ) . '</p>';
84
85 $this->docs_url = __( 'https://www.elasticpress.io/resources/articles/configuring-elasticpress-via-the-plugin-dashboard/#woocommerce', 'elasticpress' );
86 }
87
88 /**
89 * Setup all feature filters
90 *
91 * @since 2.1
92 */
93 public function setup() {
94 if ( ! function_exists( 'WC' ) ) {
95 return;
96 }
97
98 add_action( 'switch_blog', [ $this, 'setup_or_tear_down' ] );
99
100 add_filter( 'ep_integrate_search_queries', [ $this, 'disallow_coupons' ], 10, 2 );
101
102 $this->products->setup();
103 $this->orders->setup();
104 $this->orders_autosuggest->setup();
105 }
106
107 /**
108 * Setup or tear down the functionality depending on the plugin being active for the current site.
109 *
110 * If the site wasn't initialized yet (it does not have its database tables created) we skip it.
111 *
112 * @since 5.0.0
113 * @param int $blog_id Blog ID
114 * @return void
115 */
116 public function setup_or_tear_down( $blog_id ) {
117 include_once ABSPATH . 'wp-admin/includes/plugin.php';
118 if ( wp_is_site_initialized( $blog_id ) && \is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
119 $this->setup();
120 } else {
121 $this->tear_down();
122 }
123 }
124
125 /**
126 * Un-setup all feature filters
127 *
128 * @since 5.0.0
129 */
130 public function tear_down() {
131 remove_filter( 'ep_integrate_search_queries', [ $this, 'disallow_coupons' ] );
132
133 $this->products->tear_down();
134 $this->orders->tear_down();
135 $this->orders_autosuggest->tear_down();
136 }
137
138 /**
139 * Given a WP_Query object, return its search term (if any)
140 *
141 * This method also accounts for the `'search'` parameter used by
142 * WooCommerce, in addition to the regular `'s'` parameter.
143 *
144 * @param \WP_Query $query The WP_Query object
145 * @return string
146 */
147 public function get_search_term( \WP_Query $query ): string {
148 $search = $query->get( 'search' );
149 return ( ! empty( $search ) ) ? $search : $query->get( 's', '' );
150 }
151
152 /**
153 * Make search coupons don't go through ES
154 *
155 * @param bool $enabled Coupons enabled or not
156 * @param WP_Query $query WP Query
157 * @since 4.7.0
158 * @return bool
159 */
160 public function disallow_coupons( $enabled, $query ) {
161 if ( is_admin() ) {
162 return $enabled;
163 }
164
165 if ( 'shop_coupon' === $query->get( 'post_type' ) && empty( $query->query_vars['ep_integrate'] ) ) {
166 return false;
167 }
168
169 return $enabled;
170 }
171
172 /**
173 * Determine WC feature reqs status
174 *
175 * @since 2.2
176 * @return EP_Feature_Requirements_Status
177 */
178 public function requirements_status() {
179 $status = new FeatureRequirementsStatus( 0, null, $this );
180
181 if ( ! class_exists( 'WooCommerce' ) ) {
182 $status->code = 2;
183 $status->message = esc_html__( 'WooCommerce not installed.', 'elasticpress' );
184 }
185
186 return $status;
187 }
188
189 /**
190 * Determines whether or not ES should be integrating with the provided query
191 *
192 * @param \WP_Query $query Query we might integrate with
193 *
194 * @return bool
195 */
196 public function should_integrate_with_query( $query ) {
197 // Lets make sure this doesn't interfere with the CLI
198 if ( defined( 'WP_CLI' ) && WP_CLI ) {
199 return false;
200 }
201
202 if ( defined( 'WC_API_REQUEST' ) && WC_API_REQUEST ) {
203 return false;
204 }
205
206 if ( isset( $query->query_vars['ep_integrate'] ) && ! filter_var( $query->query_vars['ep_integrate'], FILTER_VALIDATE_BOOLEAN ) ) {
207 return false;
208 }
209
210 /**
211 * Filter to skip WP Query integration
212 *
213 * @hook ep_skip_query_integration
214 * @param {bool} $skip True to skip
215 * @param {WP_Query} $query WP Query to evaluate
216 * @return {bool} New skip value
217 */
218 if ( apply_filters( 'ep_skip_query_integration', false, $query ) ) {
219 return false;
220 }
221
222 if ( ! Utils\is_integrated_request( $this->slug ) ) {
223 return false;
224 }
225
226 /**
227 * Do nothing for single product queries
228 */
229 $product_name = $query->get( 'product', false );
230 if ( ! empty( $product_name ) || $query->is_single() ) {
231 return false;
232 }
233
234 /**
235 * ElasticPress does not yet support post_parent queries
236 */
237 $post_parent = $query->get( 'post_parent', false );
238 if ( ! empty( $post_parent ) ) {
239 return false;
240 }
241
242 /**
243 * If this is just a preview, let's not use Elasticsearch.
244 */
245 if ( $query->get( 'preview', false ) ) {
246 return false;
247 }
248
249 return true;
250 }
251
252 /**
253 * Set the `settings_schema` attribute
254 *
255 * @since 5.0.0
256 */
257 protected function set_settings_schema() {
258 /**
259 * Filters the WooCommerce Settings schema.
260 *
261 * @since 5.1.0
262 * @hook ep_woocommerce_settings_schema
263 * @param {array} $settings_schema WooCommerce feature settings schema
264 * @return {array} $settings_schema
265 */
266 $this->settings_schema = apply_filters( 'ep_woocommerce_settings_schema', $this->settings_schema );
267 }
268
269 /**
270 * DEPRECATED. Whether orders autosuggest is available or not
271 *
272 * @since 4.5.0
273 * @deprecated 5.1.0
274 * @return boolean
275 */
276 public function is_orders_autosuggest_available(): bool {
277 _deprecated_function( __METHOD__, '5.1.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders_autosuggest->is_available()" );
278 return $this->orders_autosuggest->is_available();
279 }
280
281 /**
282 * DEPRECATED. Whether orders autosuggest is enabled or not
283 *
284 * @since 4.5.0
285 * @deprecated 5.1.0
286 * @return boolean
287 */
288 public function is_orders_autosuggest_enabled(): bool {
289 _deprecated_function( __METHOD__, '5.1.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders_autosuggest->is_enabled()" );
290 return $this->orders_autosuggest->is_enabled();
291 }
292
293 /**
294 * DEPRECATED. Translate args to ElasticPress compat format. This is the meat of what the feature does
295 *
296 * @param \WP_Query $query WP Query
297 * @since 2.1
298 * @deprecated 4.7.0
299 */
300 public function translate_args( $query ) {
301 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->translate_args() OR \ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->translate_args()" );
302 $this->products->translate_args( $query );
303 $this->orders->translate_args( $query );
304 }
305
306 /**
307 * DEPRECATED. Fetch the ES related meta mapping for orderby
308 *
309 * @param array $meta_key The meta key to get the mapping for.
310 * @since 2.1
311 * @deprecated 4.7.0
312 * @return string The mapped meta key.
313 */
314 public function get_orderby_meta_mapping( $meta_key ) {
315 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->get_orderby_meta_mapping()" );
316 return $this->products->get_orderby_meta_mapping( $meta_key );
317 }
318
319 /**
320 * DEPRECATED. Remove the author_name from search fields.
321 *
322 * @param array $search_fields Array of search fields.
323 * @since 3.0
324 * @deprecated 4.7.0
325 * @return array
326 */
327 public function remove_author( $search_fields ) {
328 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->remove_author()" );
329 return $this->products->remove_author( $search_fields );
330 }
331
332 /**
333 * DEPRECATED. Index WooCommerce meta
334 *
335 * @param array $meta Existing post meta.
336 * @param array $post Post arguments array.
337 * @deprecated 4.7.0
338 * @since 2.1
339 * @return array
340 */
341 public function whitelist_meta_keys( $meta, $post ) {
342 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->allow_meta_keys() AND/OR \ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->allow_meta_keys()" );
343 return array_unique(
344 array_merge(
345 $this->products->allow_meta_keys( $meta ),
346 $this->orders->allow_meta_keys( $meta )
347 )
348 );
349 }
350
351 /**
352 * DEPRECATED. Index WooCommerce taxonomies
353 *
354 * @param array $taxonomies Index taxonomies array.
355 * @param array $post Post properties array.
356 * @deprecated 4.7.0
357 * @since 2.1
358 * @return array
359 */
360 public function whitelist_taxonomies( $taxonomies, $post ) {
361 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->sync_taxonomies()" );
362 return $this->products->sync_taxonomies( $taxonomies );
363 }
364
365 /**
366 * DEPRECATED. Returns the WooCommerce-oriented post types in admin that EP will search
367 *
368 * @since 4.4.0
369 * @deprecated 4.7.0
370 * @return mixed|void
371 */
372 public function get_admin_searchable_post_types() {
373 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->get_admin_searchable_post_types()" );
374 return $this->orders->get_admin_searchable_post_types();
375 }
376
377 /**
378 * DEPRECATED. Make search coupons don't go through ES
379 *
380 * @param bool $enabled Coupons enabled or not
381 * @param WP_Query $query WP Query
382 * @since 2.1
383 * @deprecated 4.7.0
384 * @return bool
385 */
386 public function blacklist_coupons( $enabled, $query ) {
387 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->disallow_coupons()" );
388 return $this->disallow_coupons( $enabled, $query );
389 }
390
391 /**
392 * DEPRECATED. Allow order creations on the front end to get synced
393 *
394 * @since 2.1
395 * @param bool $override Original order perms check value
396 * @deprecated 4.7.0
397 * @param int $post_id Post ID
398 * @return bool
399 */
400 public function bypass_order_permissions_check( $override, $post_id ) {
401 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->price_filter()" );
402 return $this->orders->bypass_order_permissions_check( $override, $post_id );
403 }
404
405 /**
406 * DEPRECATED. Sets WooCommerce meta search fields to an empty array if we are integrating the main query with ElasticSearch
407 *
408 * WooCommerce calls this action as part of its own callback on parse_query. We add this filter only if the query
409 * is integrated with ElasticSearch.
410 * If we were to always return array() on this filter, we'd break admin searches when WooCommerce module is activated
411 * without the Protected Content Module
412 *
413 * @deprecated 4.7.0
414 * @param \WP_Query $query Current query
415 */
416 public function maybe_hook_woocommerce_search_fields( $query ) {
417 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->maybe_hook_woocommerce_search_fields()" );
418 return $this->orders->maybe_hook_woocommerce_search_fields( $query );
419 }
420
421 /**
422 * DEPRECATED. Enhance WooCommerce search order by order id, email, phone number, name, etc..
423 * What this function does:
424 * 1. Reverse the woocommerce shop_order_search_custom_fields query
425 * 2. If the search key is integer and it is an Order Id, just query with post__in
426 * 3. If the search key is integer but not an order id ( might be phone number ), use ES to find it
427 *
428 * @param WP_Query $wp WP Query
429 * @deprecated 4.7.0
430 * @since 2.3
431 */
432 public function search_order( $wp ) {
433 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->search_order()" );
434 return $this->orders->search_order( $wp );
435 }
436
437 /**
438 * DEPRECATED. Add order items as a searchable string.
439 *
440 * This mimics how WooCommerce currently does in the order_itemmeta
441 * table. They combine the titles of the products and put them in a
442 * meta field called "Items".
443 *
444 * @since 2.4
445 *
446 * @param array $post_args Post arguments
447 * @param string|int $post_id Post id
448 * @deprecated 4.7.0
449 * @return array
450 */
451 public function add_order_items_search( $post_args, $post_id ) {
452 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->add_order_items_search()" );
453 return $this->orders->add_order_items_search( $post_args, $post_id );
454 }
455
456 /**
457 * DEPRECATED. Add WooCommerce Product Attributes to EP Facets.
458 *
459 * @param array $taxonomies Taxonomies array
460 * @deprecated 4.7.0
461 * @return array
462 */
463 public function add_product_attributes( $taxonomies = [] ) {
464 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->add_product_attributes()" );
465 return $this->products->add_product_attributes( $taxonomies );
466 }
467
468 /**
469 * DEPRECATED. Add WooCommerce Fields to the Weighting Dashboard.
470 *
471 * @since 3.x
472 * @deprecated 4.7.0
473 * @param array $fields Current weighting fields.
474 * @param string $post_type Current post type.
475 * @return array New fields.
476 */
477 public function add_product_attributes_to_weighting( $fields, $post_type ) {
478 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->add_product_attributes_to_weighting()" );
479 return $this->products->add_product_attributes_to_weighting( $fields, $post_type );
480 }
481
482 /**
483 * DEPRECATED. Add WooCommerce Fields to the default values of the Weighting Dashboard.
484 *
485 * @since 3.x
486 * @deprecated 4.7.0
487 * @param array $defaults Default values for the post type.
488 * @param string $post_type Current post type.
489 * @return array
490 */
491 public function add_product_default_post_type_weights( $defaults, $post_type ) {
492 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->add_product_default_post_type_weights()" );
493 return $this->products->add_product_default_post_type_weights( $defaults, $post_type );
494 }
495
496 /**
497 * DEPRECATED. Add WC post type to autosuggest
498 *
499 * @param array $post_types Array of post types (e.g. post, page).
500 * @since 2.6
501 * @deprecated 4.7.0
502 * @return array
503 */
504 public function suggest_wc_add_post_type( $post_types ) {
505 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->suggest_wc_add_post_type()" );
506 return $this->products->suggest_wc_add_post_type( $post_types );
507 }
508
509 /**
510 * DEPRECATED. Modifies main query to allow filtering by price with WooCommerce "Filter by price" widget.
511 *
512 * @param array $args ES args
513 * @param array $query_args WP_Query args
514 * @param WP_Query $query WP_Query object
515 * @since 3.2
516 * @deprecated 4.7.0
517 * @return array
518 */
519 public function price_filter( $args, $query_args, $query ) {
520 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->price_filter()" );
521 return $this->products->price_filter( $args, $query_args, $query );
522 }
523
524 /**
525 * DEPRECATED. Prevent order fields from being removed.
526 *
527 * When Protected Content is enabled, all posts with password have their content removed.
528 * This can't happen for orders, as the order key is added in that field.
529 *
530 * @see https://github.com/10up/ElasticPress/issues/2726
531 *
532 * @since 4.2.0
533 * @deprecated 4.7.0
534 * @param bool $skip Whether the password protected content should have their content, and meta removed
535 * @param array $post_args Post arguments
536 * @return bool
537 */
538 public function keep_order_fields( $skip, $post_args ) {
539 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->orders->keep_order_fields()" );
540 return $this->orders->keep_order_fields( $skip, $post_args );
541 }
542
543 /**
544 * DEPRECATED. Add a new `_variations_skus` meta field to the product to be indexed in Elasticsearch.
545 *
546 * @since 4.2.0
547 * @deprecated 4.7.0
548 * @param array $post_meta Post meta
549 * @param WP_Post $post Post object
550 * @return array
551 */
552 public function add_variations_skus_meta( $post_meta, $post ) {
553 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->add_variations_skus_meta()" );
554 return $this->products->add_variations_skus_meta( $post_meta, $post );
555 }
556
557 /**
558 * DEPRECATED. Integrate ElasticPress with the WooCommerce Admin Product List.
559 *
560 * WooCommerce uses its `WC_Admin_List_Table_Products` class to control that screen. This
561 * function adds all necessary hooks to bypass the default behavior and integrate with ElasticPress.
562 * By default, WC runs a SQL query to get the Product IDs that match the list criteria and passes
563 * that list of IDs to the main WP_Query. This integration changes that process to a single query, run
564 * by ElasticPress.
565 *
566 * @since 4.2.0
567 * @deprecated 4.7.0
568 * @param array $query_vars Query vars.
569 * @return array
570 */
571 public function admin_product_list_request_query( $query_vars ) {
572 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->admin_product_list_request_query()" );
573 return $this->products->admin_product_list_request_query( $query_vars );
574 }
575
576 /**
577 * DEPRECATED. Apply the necessary changes to WP_Query in WooCommerce Admin Product List.
578 *
579 * @param WP_Query $query The WP Query being executed.
580 * @deprecated 4.7.0
581 */
582 public function translate_args_admin_products_list( $query ) {
583 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->price_filter()" );
584 $this->products->translate_args_admin_products_list( $query );
585 }
586
587 /**
588 * DEPRECATED. Depending on the number of products display an admin notice in the custom sort screen for WooCommerce Products
589 *
590 * @since 4.4.0
591 * @deprecated 4.7.0
592 * @param array $notices Current ElasticPress admin notices
593 * @return array
594 */
595 public function maybe_display_notice_about_product_ordering( $notices ) {
596 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->maybe_display_notice_about_product_ordering()" );
597 return $this->products->maybe_display_notice_about_product_ordering( $notices );
598 }
599
600 /**
601 * DEPRECATED. Conditionally resync products after applying a custom order.
602 *
603 * @since 4.4.0
604 * @deprecated 4.7.0
605 * @param int $sorting_id ID of post dragged and dropped
606 * @param array $menu_orders Post IDs and their new menu_order value
607 */
608 public function action_sync_on_woocommerce_sort_single( $sorting_id, $menu_orders ) {
609 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->action_sync_on_woocommerce_sort_single()" );
610 return $this->products->action_sync_on_woocommerce_sort_single( $sorting_id, $menu_orders );
611 }
612
613 /**
614 * DEPRECATED. Add weight by date settings related to WooCommerce
615 *
616 * @since 4.6.0
617 * @deprecated 4.7.0
618 * @param array $settings Current settings.
619 */
620 public function add_weight_settings_search( $settings ) {
621 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->add_weight_settings_search()" );
622 $this->products->add_weight_settings_search( $settings );
623 }
624
625 /**
626 * DEPRECATED. Conditionally disable decaying by date based on WooCommerce Decay settings.
627 *
628 * @since 4.6.0
629 * @deprecated 4.7.0
630 * @param bool $is_decaying_enabled Whether decay by date is enabled or not
631 * @param array $settings Settings
632 * @param array $args WP_Query args
633 * @return bool
634 */
635 public function maybe_disable_decaying( $is_decaying_enabled, $settings, $args ) {
636 _deprecated_function( __METHOD__, '4.7.0', "\ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' )->products->maybe_disable_decaying()" );
637 return $this->products->maybe_disable_decaying( $is_decaying_enabled, $settings, $args );
638 }
639 }
640