PluginProbe
ElasticPress / 5.0.2
ElasticPress v5.0.2
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 / Search / Weighting.php

Weighting.php in ElasticPress 5.0.2, at includes/classes/Feature/Search/Weighting.php

795 lines 23.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Weighting dashboard for ElasticPress
4 *
5 * @package elasticpress
6 */
7
8 namespace ElasticPress\Feature\Search;
9
10 use ElasticPress\Features;
11 use ElasticPress\Utils;
12
13 /**
14 * Controls search weighting and search fields dashboard
15 *
16 * @package ElasticPress\Feature\Search
17 */
18 class Weighting {
19
20 /**
21 * Sets up the weighting module
22 */
23 public function setup() {
24 /**
25 * Filter to disable loading of Search weighting engine.
26 *
27 * @hook ep_disable_search_weighting
28 * @since 4.0
29 * @param bool Whether to disable search weighting engine. Defaults to false.
30 * @return bool Whether to disable search weighting engine.
31 */
32 if ( apply_filters( 'ep_disable_search_weighting', false ) ) {
33 return;
34 }
35
36 add_action( 'admin_menu', [ $this, 'add_weighting_submenu_page' ], 15 );
37 add_filter( 'ep_formatted_args', [ $this, 'do_weighting' ], 20, 2 ); // After date decay, etc are injected
38 add_filter( 'ep_query_weighting_fields', [ $this, 'adjust_weight_for_cross_fields' ], 10, 5 );
39 add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
40 }
41
42 /**
43 * Returns a grouping of all the fields that support weighting for the post type
44 *
45 * @param string $post_type Post type
46 *
47 * @return array
48 */
49 public function get_weightable_fields_for_post_type( $post_type ) {
50 $fields = array(
51 'attributes' => array(
52 'label' => __( 'Attributes', 'elasticpress' ),
53 'children' => array(
54 'post_title' => array(
55 'key' => 'post_title',
56 'label' => 'Title',
57 ),
58 'post_content' => array(
59 'key' => 'post_content',
60 'label' => 'Content',
61 ),
62 'post_excerpt' => array(
63 'key' => 'post_excerpt',
64 'label' => 'Excerpt',
65 ),
66 'author_name' => array(
67 'key' => 'author_name',
68 'label' => 'Author',
69 ),
70 ),
71 ),
72 );
73
74 $public_taxonomies = get_taxonomies(
75 [
76 'public' => true,
77 ]
78 );
79
80 $post_type_taxonomies = get_object_taxonomies( $post_type );
81
82 $taxonomies = array_intersect( $public_taxonomies, $post_type_taxonomies );
83
84 if ( ! empty( $taxonomies ) ) {
85 $fields['taxonomies'] = [
86 'label' => __( 'Taxonomies', 'elasticpress' ),
87 'children' => [],
88 ];
89
90 foreach ( $taxonomies as $taxonomy ) {
91 $key = "terms.{$taxonomy}.name";
92 $taxonomy_object = get_taxonomy( $taxonomy );
93
94 $fields['taxonomies']['children'][ $key ] = [
95 'key' => $key,
96 'label' => $taxonomy_object->labels->name,
97 ];
98 }
99 }
100
101 $fields['ep_metadata'] = [
102 'label' => 'Metadata',
103 'children' => [],
104 ];
105
106 $empty_post = new \WP_Post( new \stdClass() );
107
108 $empty_post->post_type = $post_type;
109
110 /** This filter is documented in includes/classes/Indexable/Post/Post.php */
111 $allowed_protected_keys = apply_filters( 'ep_prepare_meta_allowed_protected_keys', [], $empty_post );
112
113 sort( $allowed_protected_keys, SORT_STRING );
114
115 /** This filter is documented in includes/classes/Indexable/Post/Post.php */
116 $excluded_public_keys = apply_filters( 'ep_prepare_meta_excluded_public_keys', [], $empty_post );
117
118 foreach ( $allowed_protected_keys as $meta_key ) {
119 $key = "meta.$meta_key.value";
120
121 if ( in_array( $key, $excluded_public_keys, true ) ) {
122 continue;
123 }
124
125 $required = in_array( $meta_key, $allowed_protected_keys, true );
126
127 $fields['ep_metadata']['children'][ $key ] = [
128 'key' => $key,
129 'label' => $meta_key,
130 'required' => $required,
131 ];
132 }
133
134 /**
135 * Filter weighting fields for a post type
136 *
137 * @hook ep_weighting_fields_for_post_type
138 * @param {array} $fields Current weighting fields
139 * @param {string} $post_type Current post type
140 * @return {array} New fields
141 */
142 return apply_filters( 'ep_weighting_fields_for_post_type', $fields, $post_type );
143 }
144
145 /**
146 * Get weightable fields for all searchable post types.
147 *
148 * @since 5.0.0
149 * @return array
150 */
151 public function get_weightable_fields() {
152 $weightable = array();
153 $post_types = Features::factory()->get_registered_feature( 'search' )->get_searchable_post_types();
154
155 foreach ( $post_types as $post_type ) {
156 $post_type_object = get_post_type_object( $post_type );
157 $post_type_labels = get_post_type_labels( $post_type_object );
158
159 $weightable_fields = $this->get_weightable_fields_for_post_type( $post_type );
160
161 $groups = [];
162 $fields = [];
163
164 foreach ( $weightable_fields as $group => $weightable_field ) {
165 $groups[] = [
166 'key' => $group,
167 'label' => $weightable_field['label'],
168 ];
169
170 foreach ( $weightable_field['children'] as $field ) {
171 $fields[] = [
172 'group' => $group,
173 'key' => $field['key'],
174 'label' => $field['label'],
175 'required' => isset( $field['required'] ) ? $field['required'] : false,
176 ];
177 }
178 }
179
180 $weightable[] = [
181 'key' => $post_type,
182 'label' => $post_type_labels->menu_name,
183 'groups' => $groups,
184 'fields' => $fields,
185 ];
186 }
187
188 return $weightable;
189 }
190
191 /**
192 * Returns default settings for any post type
193 *
194 * Defaults to title, content, excerpt, and author name enabled with zero weight
195 *
196 * @param string $post_type Post Type we need settings for
197 *
198 * @return array Defaults for post type
199 */
200 public function get_post_type_default_settings( $post_type ) {
201 $post_type_defaults = [
202 'post_title' => [
203 'enabled' => true,
204 'weight' => 1,
205 ],
206 'post_content' => [
207 'enabled' => true,
208 'weight' => 1,
209 ],
210 'post_excerpt' => [
211 'enabled' => true,
212 'weight' => 1,
213 ],
214 'author_name' => [
215 'enabled' => true,
216 'weight' => 1,
217 ],
218 ];
219
220 $post_type_taxonomies = get_object_taxonomies( $post_type );
221
222 /**
223 * Filter install status
224 *
225 * Previous behavior had post_tag and category enabled by default, so if this is supported on the post type
226 * we add them as enabled by default
227 *
228 * @hook ep_weighting_default_enabled_taxonomies
229 * @param {array} $enabled_taxonomies Taxonomies that should be enabled by default
230 * @param {string} $post_type Post type slug
231 * @return {array} New taxonomies
232 * @since 3.6.5
233 */
234 $enabled_by_default = apply_filters( 'ep_weighting_default_enabled_taxonomies', [ 'post_tag', 'category' ], $post_type );
235
236 foreach ( $enabled_by_default as $default_tax ) {
237 if ( in_array( $default_tax, $post_type_taxonomies, true ) ) {
238 $post_type_defaults[ 'terms.' . $default_tax . '.name' ] = [
239 'enabled' => true,
240 'weight' => 1,
241 ];
242 }
243 }
244
245 /**
246 * Filter weighting defaults for post type
247 *
248 * @hook ep_weighting_default_post_type_weights
249 * @param {array} $post_type_defaults Current weighting defaults
250 * @param {string} $post_type Current post type
251 * @return {array} New defaults
252 */
253 return apply_filters( 'ep_weighting_default_post_type_weights', $post_type_defaults, $post_type );
254 }
255
256 /**
257 * Returns the current weighting configuration
258 *
259 * @return array
260 */
261 public function get_weighting_configuration() {
262 /**
263 * Filter weighting configuration
264 *
265 * @hook ep_weighting_configuration
266 * @param {array} $config Current configuration
267 * @return {array} New configuration
268 */
269 return apply_filters( 'ep_weighting_configuration', get_option( 'elasticpress_weighting', [] ) );
270 }
271
272 /**
273 * Returns the current weighting configuration with defaults for any
274 * missing fields.
275 *
276 * @return array Current weighting configuration with defaults.
277 * @since 5.0.0
278 */
279 public function get_weighting_configuration_with_defaults() {
280 $search = Features::factory()->get_registered_feature( 'search' );
281
282 $post_types = $search->get_searchable_post_types();
283 $weighting = $this->get_weighting_configuration();
284
285 foreach ( $post_types as $post_type ) {
286 $current = isset( $weighting[ $post_type ] ) ? $weighting[ $post_type ] : [];
287 $defaults = $this->get_post_type_default_settings( $post_type );
288
289 $weighting[ $post_type ] = wp_parse_args( $current, $defaults );
290 }
291
292 return $weighting;
293 }
294
295 /**
296 * Returns the current meta mode.
297 *
298 * @return array
299 * @since 5.0.0
300 */
301 public function get_meta_mode() {
302 /**
303 * Filter meta management mode.
304 *
305 * Setting the meta mode to 'auto' will restore the pre-5.0.0 behavior
306 * of syncing all public meta fields, but without the ability to
307 * add fields to make them searchable through the UI. Weighting settings
308 * will need to be changed, and a sync performed, any time this value
309 * is changed.
310 *
311 * @hook ep_meta_mode
312 * @since 5.0.0
313 * @param string $ep_meta_mode Meta mode.
314 * @return string New meta mode.
315 */
316 return apply_filters( 'ep_meta_mode', 'manual' );
317 }
318
319 /**
320 * Adds the submenu page for controlling weighting
321 */
322 public function add_weighting_submenu_page() {
323 $menu_slug = ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK && ! Utils\is_top_level_admin_context() ) ?
324 'elasticpress' :
325 'elasticpress-weighting';
326
327 add_submenu_page(
328 'elasticpress',
329 esc_html__( 'ElasticPress Search Fields & Weighting', 'elasticpress' ),
330 esc_html__( 'Search Fields & Weighting', 'elasticpress' ),
331 Utils\get_capability(),
332 $menu_slug,
333 [ $this, 'render_settings_page' ]
334 );
335 }
336
337 /**
338 * Renders the settings page that controls weighting
339 */
340 public function render_settings_page() {
341 include EP_PATH . '/includes/partials/header.php'; ?>
342 <div class="wrap">
343 <div id="ep-weighting-screen"></div>
344 </div>
345 <?php
346 }
347
348 /**
349 * Recursively renders each settings section and its children.
350 *
351 * @param string $post_type Current post type we're rendering
352 * @param array $field Current field to render
353 * @param array $current_values Current stored weighting values
354 * @deprecated
355 */
356 public function render_settings_section( $post_type, $field, $current_values ) {
357 _doing_it_wrong(
358 __METHOD__,
359 esc_html( 'Weighting sections display are now handled via React components.' ),
360 'ElasticPress 5.0.0'
361 );
362 }
363
364 /**
365 * Handles processing the new weighting values and saving them
366 * to the elasticpress.io service.
367 *
368 * @deprecated
369 */
370 public function handle_save() {
371 _doing_it_wrong(
372 __METHOD__,
373 esc_html( 'Weighting settings are now updated using the REST API.' ),
374 'ElasticPress 5.0.0'
375 );
376 }
377
378 /**
379 * We need this method to test handle_save properly.
380 *
381 * @param string $redirect_url Redirect URL.
382 * @deprecated
383 */
384 protected function redirect( $redirect_url ) {
385 _doing_it_wrong(
386 __METHOD__,
387 esc_html( 'Weighting settings are now updated using the REST API, and do not redirect server-side.' ),
388 'ElasticPress 5.0.0'
389 );
390 }
391
392 /**
393 * Save weighting configuration for each searchable post_type.
394 *
395 * @param array $settings weighting settings
396 * @return void
397 * @since 3.4.1
398 * @deprecated
399 */
400 public function save_weighting_configuration( $settings ) {
401 _doing_it_wrong(
402 __METHOD__,
403 esc_html( 'Weighting sections display are now handled via React components.' ),
404 'ElasticPress 5.0.0'
405 );
406 }
407
408 /**
409 * Register REST routes.
410 *
411 * @return void
412 * @since 5.0.0
413 */
414 public function register_rest_routes() {
415 register_rest_route(
416 'elasticpress/v1',
417 'weighting',
418 [
419 'callback' => [ $this, 'update_weighting' ],
420 'methods' => 'POST',
421 'permission_callback' => function() {
422 return current_user_can( Utils\get_capability() );
423 },
424 ]
425 );
426 }
427
428 /**
429 * Handles processing the new weighting values and saving them.
430 *
431 * @param \WP_Rest_Request $request REST API request.
432 * @return array
433 * @since 5.0.0
434 */
435 public function update_weighting( $request = null ) {
436 $meta_mode = $this->get_meta_mode();
437 $weighting = $request->get_json_params();
438
439 $post_types = Features::factory()->get_registered_feature( 'search' )->get_searchable_post_types();
440
441 // Add default fields for post types not sent.
442 foreach ( $post_types as $post_type ) {
443 if ( ! isset( $weighting[ $post_type ] ) ) {
444 $weighting[ $post_type ] = [];
445 }
446 }
447
448 /**
449 * If metadata is not being managed manually, remove any custom
450 * fields that have not been registered as weightable fields.
451 */
452 if ( 'manual' !== $meta_mode ) {
453 foreach ( $weighting as $post_type => $fields ) {
454 $weightable_fields = $this->get_weightable_fields_for_post_type( $post_type );
455
456 foreach ( $fields as $key => $value ) {
457 $is_weightable = false;
458
459 foreach ( $weightable_fields as $group ) {
460 if ( isset( $group['children'][ $key ] ) ) {
461 $is_weightable = true;
462 continue;
463 }
464 }
465
466 if ( ! $is_weightable ) {
467 unset( $weighting[ $post_type ][ $key ] );
468 }
469 }
470 }
471 }
472
473 // Cleanup any post type sent (or added via filters) that does not exist.
474 foreach ( $weighting as $post_type => $fields ) {
475 if ( ! post_type_exists( $post_type ) ) {
476 unset( $weighting[ $post_type ] );
477 }
478 }
479
480 update_option( 'elasticpress_weighting', $weighting );
481
482 /**
483 * Fires right after the weighting configuration is saved.
484 *
485 * @since 3.5.x
486 * @hook ep_saved_weighting_configuration
487 */
488 do_action( 'ep_saved_weighting_configuration' );
489
490 return [
491 'data' => $weighting,
492 'success' => true,
493 ];
494 }
495
496 /**
497 * Iterates through arrays in the formatted args to find "fields" and injects weighting values
498 *
499 * @param array $fieldset Current subset of formatted ES args
500 * @param array $weights Weight configuration
501 */
502 public function recursively_inject_weights_to_fields( &$fieldset, $weights ) {
503 if ( ! is_array( $fieldset ) ) {
504 return;
505 }
506
507 if ( is_array( $fieldset ) && isset( $fieldset['fields'] ) ) {
508 // Add any fields to the search that aren't already in there (weighting handled in next step)
509 foreach ( $weights as $field => $settings ) {
510 if ( ! in_array( $field, $fieldset['fields'], true ) ) {
511 $fieldset['fields'][] = $field;
512 }
513 }
514
515 foreach ( $fieldset['fields'] as $key => $field ) {
516 if ( isset( $weights[ $field ] ) && false !== $weights[ $field ]['enabled'] ) {
517 $weight = (int) $weights[ $field ]['weight'];
518
519 if ( 0 !== $weight ) {
520 if ( 'author_name' === $field ) {
521 $field = 'post_author.display_name';
522 }
523
524 /**
525 * Filter fields and their weitghting as used in the Elasticsearch query.
526 *
527 * @hook ep_query_weighting_fields
528 * @param {string} $weighted_field The field and its weight as used in the ES query.
529 * @param {string} $field Field name
530 * @param {string} $weight Weight value
531 * @param {array} $fieldset Current subset of formatted ES args
532 * @param {array} $weights Weight configuration
533 * @return {array} New weighted field string
534 *
535 * @since 3.5.5
536 */
537 $fieldset['fields'][ $key ] = apply_filters(
538 'ep_query_weighting_fields',
539 "{$field}^{$weight}",
540 $field,
541 $weight,
542 $fieldset,
543 $weights
544 );
545 }
546 } else {
547 // this handles removing post_author.login field added in Post::format_args() if author search field has being disabled
548 if ( 'author_name' === $field ) {
549 $author_key = array_search( 'post_author.login', $fieldset['fields'], true );
550 if ( false !== $author_key ) {
551 unset( $fieldset['fields'][ $author_key ] );
552 }
553 }
554 unset( $fieldset['fields'][ $key ] );
555 }
556 // else: Leave anything that isn't explicitly disabled alone. Could have been added by search_fields, and if it is not present in the UI, we shouldn't touch it here
557
558 // If fieldset has fuzziness enabled and fuzziness is disabled for this field, unset the field
559 if ( isset( $fieldset['fuzziness'] ) && $fieldset['fuzziness'] && isset( $weights[ $field ]['fuzziness'] ) && false === $weights[ $field ]['fuzziness'] ) {
560 unset( $fieldset['fields'][ $key ] );
561 }
562 }
563
564 // Reindex the array
565 $fieldset['fields'] = array_values( $fieldset['fields'] );
566 } else {
567 foreach ( $fieldset as &$field ) {
568 $this->recursively_inject_weights_to_fields( $field, $weights );
569 }
570 }
571
572 // Most likely to occur with the ordering results not being allowed in fuzzy, and weighting turning off fields for this otherwise
573 if ( isset( $fieldset['fields'] ) && empty( $fieldset['fields'] ) ) {
574 $fieldset = null;
575 }
576 }
577
578 /**
579 * Determine if a post type has any fields enabled for search
580 *
581 * @param string $post_type Post Type
582 * @param array $args WP_Query args
583 * @return boolean true/false depending on any fields enabled == true
584 */
585 public function post_type_has_fields( $post_type, $args = [] ) {
586 $weight_config = $this->get_weighting_configuration();
587
588 /**
589 * Filter weighting configuration for search
590 *
591 * @hook ep_weighting_configuration_for_search
592 * @param {array} $weight_config Current weight config
593 * @param {array} $args WP Query arguments
594 * @return {array} New configuration
595 */
596 $weight_config = apply_filters( 'ep_weighting_configuration_for_search', $weight_config, $args );
597
598 if ( ! isset( $weight_config[ $post_type ] ) ) {
599 $weights = $this->get_post_type_default_settings( $post_type );
600 } else {
601 $weights = $weight_config[ $post_type ];
602 }
603
604 /**
605 * Filter fields considered in weighting
606 *
607 * Define keys which are irrelevant for this consideration, like `terms.ep_custom_result.name`.
608 *
609 * @hook ep_weighting_ignore_fields_in_consideration
610 * @param {array} $fields Current fields
611 * @return {array} New fields
612 */
613 $ignore_keys = apply_filters( 'ep_weighting_ignore_fields_in_consideration', [ 'terms.ep_custom_result.name' => true ] );
614 $fields = array_diff_key( $weights, $ignore_keys );
615
616 $found_enabled = false;
617 foreach ( $fields as $field ) {
618 if ( filter_var( $field['enabled'], FILTER_VALIDATE_BOOLEAN ) ) {
619 $found_enabled = true;
620 break;
621 }
622 }
623
624 return $found_enabled;
625 }
626
627 /**
628 * Adjusts the query for configured weighting values
629 *
630 * @param array $formatted_args Formatted ES args
631 * @param array $args WP_Query args
632 *
633 * @return array Formatted ES args
634 */
635 public function do_weighting( $formatted_args, $args ) {
636
637 /**
638 * If search fields is set on the query, we should use those instead of the weighting, since the query was
639 * overridden by some custom code
640 */
641 if ( isset( $args['search_fields'] ) && ! empty( $args['search_fields'] ) ) {
642 return $formatted_args;
643 }
644
645 $weight_config = $this->get_weighting_configuration();
646
647 /**
648 * Filter weighting configuration for search
649 *
650 * @hook ep_weighting_configuration_for_search
651 * @param {array} $weight_config Current weight config
652 * @param {array} $args WP Query arguments
653 * @return {array} New configuration
654 */
655 $weight_config = apply_filters( 'ep_weighting_configuration_for_search', $weight_config, $args );
656
657 $should_do_weighting = Utils\is_integrated_request( 'weighting', [ 'public', 'rest' ] ) && ! empty( $args['s'] );
658
659 /**
660 * Filter whether to enable weighting configuration
661 *
662 * @hook ep_enable_do_weighting
663 * @since 4.2.2
664 * @param {bool} Whether to enable weight config, defaults to true for search requests that are public or REST
665 * @param {array} $weight_config Current weight config
666 * @param {array} $args WP Query arguments
667 * @param {array} $formatted_args Formatted ES arguments
668 * @return {bool} Whether to use weighting configuration
669 */
670 if ( apply_filters( 'ep_enable_do_weighting', $should_do_weighting, $weight_config, $args, $formatted_args ) ) {
671 $formatted_args = $this->apply_weighting( $formatted_args, $args, $weight_config );
672 }
673
674 return $formatted_args;
675 }
676
677 /**
678 * Applies weighting based on ES args
679 *
680 * @since 4.2.2
681 * @param array $formatted_args Formatted ES args
682 * @param array $args WP_Query args
683 * @param array $weight_config Weight configuration to apply
684 *
685 * @return array $formatted_args Formatted ES args with weightings applied
686 */
687 protected function apply_weighting( $formatted_args, $args, $weight_config ) {
688 /*
689 * This section splits up the single query clause for all post types into separate nested clauses (one for each post type)
690 * which then get combined into one result set. By having separate clauses for each post type, we can then
691 * weight fields such as post_title per post type so that we can have fine grained control over weights by post
692 * type, rather than globally on the query
693 */
694 $new_query = [
695 'bool' => [
696 'should' => [],
697 ],
698 ];
699
700 // grab the query and keep track of whether or not it is nested in a function score
701 $function_score = isset( $formatted_args['query']['function_score'] );
702 $query = $function_score ? $formatted_args['query']['function_score']['query'] : $formatted_args['query'];
703
704 foreach ( (array) $args['post_type'] as $post_type ) {
705 if ( false === $this->post_type_has_fields( $post_type, $args ) ) {
706 continue;
707 }
708 // Copy the query, so we can set specific weight values
709 $current_query = $query;
710
711 if ( isset( $weight_config[ $post_type ] ) ) {
712 // Find all "fields" values and inject weights for the current post type
713 $this->recursively_inject_weights_to_fields( $current_query, $weight_config[ $post_type ] );
714 } else {
715 // Use the default values for the post type
716 $this->recursively_inject_weights_to_fields( $current_query, $this->get_post_type_default_settings( $post_type ) );
717 }
718
719 // Check for any segments with null fields from recursively_inject function and remove them
720 if ( isset( $current_query['bool'] ) && isset( $current_query['bool']['should'] ) ) {
721 foreach ( $current_query['bool']['should'] as $index => $current_bool_should ) {
722 if ( isset( $current_bool_should['multi_match'] ) && null === $current_bool_should['multi_match'] ) {
723 unset( $current_query['bool']['should'][ $index ] );
724 }
725 }
726 }
727
728 /**
729 * Filter weighting query for a post type
730 *
731 * @hook ep_weighted_query_for_post_type
732 * @param {array} $query Weighting query
733 * @param {string} $post_type Post type
734 * @param {array} $args WP Query arguments
735 * @return {array} New query
736 */
737 $new_query['bool']['should'][] = apply_filters(
738 'ep_weighted_query_for_post_type',
739 [
740 'bool' => [
741 'must' => [
742 $current_query,
743 ],
744 'filter' => [
745 [
746 'match' => [
747 'post_type.raw' => $post_type,
748 ],
749 ],
750 ],
751 ],
752 ],
753 $post_type,
754 $args
755 );
756 }
757
758 // put the new query back in the correct location
759 if ( $function_score ) {
760 $formatted_args['query']['function_score']['query'] = $new_query;
761 } else {
762 $formatted_args['query'] = $new_query;
763 }
764
765 /**
766 * Hook after weighting is added to Elasticsearch query
767 *
768 * @hook ep_weighting_added
769 * @param {array} $formatted_args Elasticsearch query
770 * @param {array} $args WP Query arguments
771 */
772 do_action( 'ep_weighting_added', $formatted_args, $args );
773
774 return $formatted_args;
775 }
776
777 /**
778 * Adjust weighting when the type is cross_fields, as it just works with weight = 1.
779 *
780 * @since 4.0.0
781 *
782 * @param string $weighted_field The field and its weight as used in the ES query.
783 * @param string $field Field name
784 * @param string $weight Weight value
785 * @param array $fieldset Current subset of formatted ES args
786 * @return array New weighted field string
787 */
788 public function adjust_weight_for_cross_fields( $weighted_field, $field, $weight, $fieldset ) {
789 if ( ! empty( $fieldset['type'] ) && 'cross_fields' === $fieldset['type'] ) {
790 $weighted_field = "{$field}^1";
791 }
792 return $weighted_field;
793 }
794 }
795