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
← All changes | includes/classes/Feature/Search/Search.php +362 -146 4.3.15.3.5 View file →
@@ -7,11 +7,12 @@
7 7 */
8 8
9 9 namespace ElasticPress\Feature\Search;
10 10
11 -use ElasticPress\Feature as Feature;
12 -use ElasticPress\Indexables as Indexables;
13 -use ElasticPress\Utils as Utils;
11 +use ElasticPress\Feature;
12 +use ElasticPress\Features;
13 +use ElasticPress\Indexables;
14 +use ElasticPress\Utils;
14 15
15 16 /**
16 17 * Search feature class
17 18 */
@@ -50,14 +51,10 @@
50 51 */
51 52 public function __construct() {
52 53 $this->slug = 'search';
53 54
54 - $this->title = esc_html__( 'Post Search', 'elasticpress' );
55 + $this->group = 'core-search';
55 56
56 - $this->summary = __( 'Instantly find the content you’re looking for. The first time.', 'elasticpress' );
57 -
58 - $this->docs_url = __( 'https://elasticpress.zendesk.com/hc/en-us/articles/360050447492-Configuring-ElasticPress-via-the-Plugin-Dashboard#post-search', 'elasticpress' );
59 -
60 57 $this->requires_install_reindex = false;
61 58
62 59 $this->default_settings = [
63 60 'decaying_enabled' => '1',
@@ -72,8 +69,29 @@
72 69 parent::__construct();
73 70 }
74 71
75 72 /**
73 + * Sets i18n strings.
74 + *
75 + * @return void
76 + * @since 5.2.0
77 + */
78 + public function set_i18n_strings(): void {
79 + $this->title = esc_html__( 'Post Search', 'elasticpress' );
80 +
81 + $this->summary = '<p>' . __( 'Instantly find the content you’re looking for. The first time.', 'elasticpress' ) . '</p>' .
82 + '<p>' . __( 'Overcome higher-end performance and functional limits posed by the traditional WordPress structured (SQL) database to deliver superior keyword search, instantly. ElasticPress indexes custom fields, tags, and other metadata to improve search results. Fuzzy matching accounts for misspellings and verb tenses.', 'elasticpress' ) . '</p>';
83 +
84 + $this->docs_url = __( 'https://www.elasticpress.io/resources/articles/configuring-elasticpress-via-the-plugin-dashboard/#post-search', 'elasticpress' );
85 +
86 + $this->field_group_map = [
87 + 'highlight_group' => [
88 + 'label' => esc_html__( 'Highlighting Options', 'elasticpress' ),
89 + ],
90 + ];
91 + }
92 +
93 + /**
76 94 * We need to delay search setup up since it will fire after protected content and protected
77 95 * content filters into the search setup
78 96 *
79 97 * @since 2.2
@@ -78,10 +96,11 @@
78 96 *
79 97 * @since 2.2
80 98 */
81 99 public function setup() {
100 + Indexables::factory()->activate( 'post' );
101 +
82 102 add_action( 'init', [ $this, 'search_setup' ] );
83 - add_filter( 'ep_sanitize_feature_settings', [ $this, 'sanitize_highlighting_settings' ] );
84 103
85 104 // Set up weighting sub-module
86 105 $this->weighting = new Weighting();
87 106 $this->weighting->setup();
@@ -103,8 +122,19 @@
103 122 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
104 123 add_filter( 'ep_formatted_args', [ $this, 'add_search_highlight_tags' ], 10, 2 );
105 124 add_filter( 'ep_highlighting_tag', [ $this, 'get_highlighting_tag' ] );
106 125 add_action( 'ep_highlighting_pre_add_highlight', [ $this, 'allow_excerpt_html' ] );
126 +
127 + add_action( 'init', [ $this, 'register_meta' ], 20 );
128 + add_filter( 'ep_prepare_meta_allowed_keys', [ $this, 'add_exclude_from_search' ] );
129 + add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_block_editor_assets' ] );
130 + add_filter( 'ep_post_filters', [ $this, 'exclude_posts_from_search' ], 10, 3 );
131 + add_action( 'post_submitbox_misc_actions', [ $this, 'output_exclude_from_search_setting' ] );
132 + add_action( 'edit_post', [ $this, 'save_exclude_from_search_meta' ] );
133 + add_filter( 'ep_skip_query_integration', [ $this, 'skip_query_integration' ], 10, 2 );
134 +
135 + add_action( 'attachment_submitbox_misc_actions', [ $this, 'output_exclude_from_search_setting' ], 15 );
136 + add_action( 'edit_attachment', [ $this, 'save_exclude_from_search_meta' ] );
107 137 }
108 138
109 139
110 140 /**
@@ -112,21 +142,15 @@
112 142 */
113 143 public function enqueue_scripts() {
114 144 $settings = $this->get_settings();
115 145
116 - if ( ! $settings ) {
117 - $settings = [];
118 - }
119 -
120 - $settings = wp_parse_args( $settings, $this->default_settings );
121 -
122 - if ( true !== $settings['highlight_enabled'] ) {
146 + if ( '1' !== $settings['highlight_enabled'] ) {
123 147 return;
124 148 }
125 149
126 150 wp_enqueue_style(
127 151 'searchterm-highlighting',
128 - EP_URL . 'dist/css/highlighting-styles.min.css',
152 + EP_URL . 'dist/css/highlighting-styles.css',
129 153 Utils\get_asset_info( 'highlighting-styles', 'dependencies' ),
130 154 Utils\get_asset_info( 'highlighting-styles', 'version' )
131 155 );
132 156 }
@@ -153,15 +177,9 @@
153 177
154 178 // get current config
155 179 $settings = $this->get_settings();
156 180
157 - if ( ! $settings ) {
158 - $settings = [];
159 - }
160 -
161 - $settings = wp_parse_args( $settings, $this->default_settings );
162 -
163 - if ( true !== $settings['highlight_enabled'] ) {
181 + if ( '1' !== $settings['highlight_enabled'] ) {
164 182 return $formatted_args;
165 183 }
166 184
167 185 if ( empty( $args['s'] ) ) {
@@ -237,9 +255,18 @@
237 255 $formatted_args['highlight']['fields'][ $field ] = [
238 256 'pre_tags' => [ $opening_tag ],
239 257 'post_tags' => [ $closing_tag ],
240 258 'type' => 'plain',
241 - 'number_of_fragments' => 0,
259 + /**
260 + * Filter the maximum number of fragments highlighted for a searched field.
261 + *
262 + * @since 4.7.2
263 + * @hook ep_highlight_number_of_fragments
264 + * @param {int} $max_fragments Maximum number of fragments for field.
265 + * @param {string} $field Search field being setup.
266 + * @return {int} New maximum number of fragments to highlight for the searched field.
267 + */
268 + 'number_of_fragments' => apply_filters( 'ep_highlight_number_of_fragments', 0, $field ),
242 269 ];
243 270 }
244 271
245 272 return $formatted_args;
@@ -255,23 +282,13 @@
255 282 if ( ! Utils\is_integrated_request( 'highlighting', [ 'public' ] ) ) {
256 283 return;
257 284 }
258 285
259 - if ( empty( $_GET['s'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
260 - return;
261 - }
262 -
263 286 $settings = $this->get_settings();
264 287
265 - if ( ! $settings ) {
266 - $settings = [];
267 - }
268 -
269 - $settings = wp_parse_args( $settings, $this->default_settings );
270 -
271 - if ( ! empty( $settings['highlight_excerpt'] ) && true === $settings['highlight_excerpt'] ) {
288 + if ( ! empty( $settings['highlight_excerpt'] ) && '1' === $settings['highlight_excerpt'] ) {
272 289 remove_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
273 - add_filter( 'get_the_excerpt', [ $this, 'ep_highlight_excerpt' ] );
290 + add_filter( 'get_the_excerpt', [ $this, 'ep_highlight_excerpt' ], 10, 2 );
274 291 add_filter( 'ep_highlighting_fields', [ $this, 'ep_highlight_add_excerpt_field' ] );
275 292 }
276 293 }
277 294
@@ -278,26 +295,26 @@
278 295 /**
279 296 * Called by allow_excerpt_html
280 297 * logic for the excerpt filter allowing the currently selected tag.
281 298 *
282 - * @param string $text - excerpt string
283 - * @return string $text - the new excerpt
299 + * @param string $text excerpt string
300 + * @param WP_Post $post Post Object
301 + *
302 + * @return string $text the new excerpt
284 303 */
285 - public function ep_highlight_excerpt( $text ) {
286 -
304 + public function ep_highlight_excerpt( $text, $post ) {
287 305 $settings = $this->get_settings();
288 306
289 - if ( ! $settings ) {
290 - $settings = [];
291 - }
307 + // reproduces wp_trim_excerpt filter, preserving the excerpt_more and excerpt_length filters
308 + if ( '' === $text ) {
309 + $text = get_the_content( '', false, $post );
292 310
293 - $settings = wp_parse_args( $settings, $this->default_settings );
311 + $text = strip_shortcodes( $text );
312 + $text = excerpt_remove_blocks( $text );
294 313
295 - // reproduces wp_trim_excerpt filter, preserving the excerpt_more and excerpt_length filters
296 - if ( '' === $text ) {
297 - $text = get_the_content( '' );
298 314 $text = apply_filters( 'the_content', $text );
299 315 $text = str_replace( '\]\]\>', ']]&gt;', $text );
316 +
300 317 $text = strip_tags( $text, '<' . esc_html( $settings['highlight_tag'] ) . '>' );
301 318
302 319 // use the defined length, if already applied...
303 320 $excerpt_length = apply_filters( 'excerpt_length', 55 );
@@ -303,11 +320,14 @@
303 320 $excerpt_length = apply_filters( 'excerpt_length', 55 );
304 321
305 322 // use defined excerpt_more filter if it is used
306 323 $excerpt_more = apply_filters( 'excerpt_more', $text );
307 -
308 324 $excerpt_more = $excerpt_more !== $text ? $excerpt_more : '[&hellip;]';
309 325
326 + /**
327 + * WordPress would handle this using `wp_trim_words` but that removes all tags,
328 + * including the one used to highlight the search term.
329 + */
310 330 $words = explode( ' ', $text, $excerpt_length + 1 );
311 331 if ( count( $words ) > $excerpt_length ) {
312 332 array_pop( $words );
313 333 array_push( $words, $excerpt_more );
@@ -344,26 +364,8 @@
344 364 return $tag;
345 365 }
346 366
347 367 /**
348 - * Sanitizes our highlighting settings.
349 - *
350 - * @param array $settings Array of current settings
351 - * @return mixed
352 - */
353 - public function sanitize_highlighting_settings( $settings ) {
354 - if ( ! empty( $settings['search']['highlight_excerpt'] ) ) {
355 - $settings['search']['highlight_excerpt'] = (bool) $settings['search']['highlight_excerpt'];
356 - }
357 -
358 - if ( ! empty( $settings['search']['highlight_enabled'] ) ) {
359 - $settings['search']['highlight_enabled'] = (bool) $settings['search']['highlight_enabled'];
360 - }
361 -
362 - return $settings;
363 - }
364 -
365 - /**
366 368 * Returns searchable post types for the current site
367 369 *
368 370 * @since 1.9
369 371 * @return mixed|void
@@ -422,21 +424,28 @@
422 424
423 425 /**
424 426 * Returns true/false if decaying is/isn't enabled
425 427 *
428 + * @param array $args WP_Query args
429 + *
426 430 * @return bool
427 431 */
428 - public function is_decaying_enabled() {
432 + public function is_decaying_enabled( $args = [] ) {
429 433 $settings = $this->get_settings();
430 434
431 - $settings = wp_parse_args(
432 - $settings,
433 - [
434 - 'decaying_enabled' => true,
435 - ]
436 - );
435 + $is_decaying_enabled = $settings['decaying_enabled'] && '0' !== $settings['decaying_enabled'];
437 436
438 - return (bool) $settings['decaying_enabled'];
437 + /**
438 + * Filter to modify decaying
439 + *
440 + * @hook ep_is_decaying_enabled
441 + * @since 4.6.0
442 + * @param {bool} $is_decaying_enabled Whether decay by date is enabled or not
443 + * @param {array} $settings Settings
444 + * @param {array} $args WP_Query args
445 + * @return {bool} Decaying
446 + */
447 + return apply_filters( 'ep_is_decaying_enabled', $is_decaying_enabled, $settings, $args );
439 448 }
440 449
441 450 /**
442 451 * Weight more recent content in searches
@@ -449,11 +458,13 @@
449 458 public function weight_recent( $formatted_args, $args ) {
450 459 if ( empty( $args['s'] ) ) {
451 460 return $formatted_args;
452 461 }
453 - if ( ! $this->is_decaying_enabled() ) {
462 +
463 + if ( ! $this->is_decaying_enabled( $args ) ) {
454 464 return $formatted_args;
455 465 }
466 +
456 467 /**
457 468 * Filter search date weighting scale
458 469 *
459 470 * @hook epwr_decay_function
@@ -462,8 +473,9 @@
462 473 * @param {array} $args WP_Query arguments
463 474 * @return {string} New decay function
464 475 */
465 476 $decay_function = apply_filters( 'epwr_decay_function', 'exp', $formatted_args, $args );
477 +
466 478 /**
467 479 * Filter search date weighting field
468 480 *
469 481 * @hook epwr_decay_field
@@ -556,20 +568,8 @@
556 568 return $formatted_args;
557 569 }
558 570
559 571 /**
560 - * Output feature box long text
561 - *
562 - * @since 3.0
563 - */
564 - public function output_feature_box_long() {
565 - ?>
566 - <p><?php esc_html_e( 'Overcome higher-end performance and functional limits posed by the traditional WordPress structured (SQL) database to deliver superior keyword search, instantly. ElasticPress indexes custom fields, tags, and other metadata to improve search results. Fuzzy matching accounts for misspellings and verb tenses.', 'elasticpress' ); ?></p>
567 -
568 - <?php
569 - }
570 -
571 - /**
572 572 * Enable integration on search queries
573 573 *
574 574 * @param bool $enabled Original enabled value
575 575 * @param WP_Query $query WP Query
@@ -590,19 +590,8 @@
590 590 }
591 591
592 592 if ( method_exists( $query, 'is_search' ) && $query->is_search() && ! empty( $query->query_vars['s'] ) ) {
593 593 $enabled = true;
594 -
595 - /**
596 - * WordPress have to be version 4.6 or newer to have "fields" support
597 - * since it requires the "posts_pre_query" filter.
598 - *
599 - * @see WP_Query::get_posts
600 - */
601 - $fields = $query->get( 'fields' );
602 - if ( ! version_compare( get_bloginfo( 'version' ), '4.6', '>=' ) && ! empty( $fields ) ) {
603 - $enabled = false;
604 - }
605 594 }
606 595
607 596 /**
608 597 * Filter whether to enable integration on search queries or not.
@@ -616,64 +605,291 @@
616 605 return apply_filters( 'ep_integrate_search_queries', $enabled, $query );
617 606 }
618 607
619 608 /**
620 - * Display decaying settings on dashboard.
609 + * Registers post meta for exclude from search feature.
610 + */
611 + public function register_meta() {
612 + register_post_meta(
613 + '',
614 + 'ep_exclude_from_search',
615 + [
616 + 'show_in_rest' => true,
617 + 'single' => true,
618 + 'type' => 'boolean',
619 + ]
620 + );
621 + }
622 +
623 + /**
624 + * Add ep_exclude_from_search to the allowed meta fields list.
621 625 *
622 - * @since 2.4
626 + * @since 5.0.0
627 + * @param array $keys List of allowed meta fields
628 + * @return array
623 629 */
624 - public function output_feature_box_settings() {
625 - $settings = $this->get_settings();
630 + public function add_exclude_from_search( $keys ) {
631 + $keys[] = 'ep_exclude_from_search';
632 + return $keys;
633 + }
626 634
627 - if ( ! $settings ) {
628 - $settings = [];
635 + /**
636 + * Enqueue block editor assets.
637 + */
638 + public function enqueue_block_editor_assets() {
639 + global $post;
640 +
641 + if ( ! $post instanceof \WP_Post ) {
642 + return;
629 643 }
630 644
631 - $settings = wp_parse_args( $settings, $this->default_settings );
645 + if ( ! $post->post_type || ! post_type_supports( $post->post_type, 'custom-fields' ) ) {
646 + return;
647 + }
632 648
649 + wp_enqueue_script(
650 + 'ep-search-editor',
651 + EP_URL . 'dist/js/search-editor-script.js',
652 + Utils\get_asset_info( 'search-editor-script', 'dependencies' ),
653 + Utils\get_asset_info( 'search-editor-script', 'version' ),
654 + true
655 + );
656 +
657 + wp_set_script_translations( 'ep-search-editor', 'elasticpress' );
658 + }
659 +
660 + /**
661 + * Exclude posts based on ep_exclude_from_search post meta.
662 + *
663 + * @param array $filters Filters to be applied to the query
664 + * @param array $args WP Query args
665 + * @param WP_Query $query WP Query object
666 + */
667 + public function exclude_posts_from_search( $filters, $args, $query ) {
668 + if ( ! empty( $query->get( 'ep_skip_search_exclusion' ) ) ) {
669 + return $filters;
670 + }
671 +
672 + $bypass_exclusion_from_search = ( is_admin() && ! wp_doing_ajax() ) || ! $query->is_search();
673 +
674 + /**
675 + * Filter whether the exclusion from the "exclude from search" checkbox should be applied
676 + *
677 + * @since 4.4.0
678 + * @hook ep_bypass_exclusion_from_search
679 + * @param {bool} $bypass_exclusion_from_search True means all posts will be returned
680 + * @param {WP_Query} $query WP Query
681 + * @return {bool} New $bypass_exclusion_from_search value
682 + */
683 + if ( apply_filters_deprecated(
684 + 'ep_bypass_exclusion_from_search',
685 + [ $bypass_exclusion_from_search, $query ],
686 + 'ElasticPress 5.3.0',
687 + 'WP_Query->ep_skip_search_exclusion argument'
688 + ) ) {
689 + return $filters;
690 + }
691 +
692 + $filters[] = [
693 + 'bool' => [
694 + 'must_not' => [
695 + [
696 + 'terms' => [
697 + 'meta.ep_exclude_from_search.raw' => [ '1' ],
698 + ],
699 + ],
700 + ],
701 + ],
702 + ];
703 +
704 + return $filters;
705 + }
706 +
707 + /**
708 + * Outputs the checkbox to exclude a post from search.
709 + *
710 + * @param WP_POST $post Post object.
711 + */
712 + public function output_exclude_from_search_setting( $post ) {
713 + $searchable_post_types = $this->get_searchable_post_types();
714 + if ( ! in_array( $post->post_type, $searchable_post_types, true ) ) {
715 + return;
716 + }
633 717 ?>
634 - <div class="field">
635 - <div class="field-name status"><?php esc_html_e( 'Weight results by date', 'elasticpress' ); ?></div>
636 - <div class="input-wrap">
637 - <label><input name="settings[decaying_enabled]" type="radio" <?php checked( (bool) $settings['decaying_enabled'] ); ?> value="1"><?php esc_html_e( 'Enabled', 'elasticpress' ); ?></label><br>
638 - <label><input name="settings[decaying_enabled]" type="radio" <?php checked( ! (bool) $settings['decaying_enabled'] ); ?> value="0"><?php esc_html_e( 'Disabled', 'elasticpress' ); ?></label>
639 - </div>
718 + <div class="misc-pub-section">
719 + <input id="ep_exclude_from_search" name="ep_exclude_from_search" type="checkbox" value="1" <?php checked( get_post_meta( get_the_ID(), 'ep_exclude_from_search', true ) ); ?>>
720 + <label for="ep_exclude_from_search"><?php esc_html_e( 'Exclude from search results', 'elasticpress' ); ?></label>
721 + <p class="howto">
722 + <?php if ( 'attachment' === $post->post_type ) : ?>
723 + <?php esc_html_e( 'Excludes this media from the results of your site\'s search form while ElasticPress is active.', 'elasticpress' ); ?>
724 + <?php else : ?>
725 + <?php esc_html_e( 'Excludes this post from the results of your site\'s search form while ElasticPress is active.', 'elasticpress' ); ?>
726 + <?php endif; ?>
727 + </p>
728 + <?php wp_nonce_field( 'save-exclude-from-search', 'ep-exclude-from-search-nonce' ); ?>
640 729 </div>
641 - <div class="field">
642 - <div class="field-name status"><?php esc_html_e( 'Highlighting status', 'elasticpress' ); ?></div>
643 - <div class="input-wrap">
644 - <label><input name="settings[highlight_enabled]" type="radio" <?php checked( (bool) $settings['highlight_enabled'] ); ?> value="1"><?php esc_html_e( 'Enabled', 'elasticpress' ); ?></label><br>
645 - <label><input name="settings[highlight_enabled]" type="radio" <?php checked( ! (bool) $settings['highlight_enabled'] ); ?> value="0"><?php esc_html_e( 'Disabled', 'elasticpress' ); ?></label>
646 - <p class="field-description"><?php esc_html_e( 'Wrap search terms in HTML tags in results for custom styling. The wrapping HTML tag comes with the "ep-highlight" class for easy styling.' ); ?></p>
647 - </div>
648 - </div>
649 - <div class="field">
650 - <label for="highlight-tag" class="field-name status"><?php echo esc_html_e( 'Highlight tag ', 'elasticpress' ); ?></label>
651 - <div class="input-wrap">
652 - <select id="highlight-tag" name="settings[highlight_tag]">
653 - <?php
654 - foreach ( self::$default_highlight_tags as $option ) :
655 - echo '<option value="' . esc_attr( $option ) . '" ' . selected( $option, $settings['highlight_tag'] ) . '>' . esc_html( $option ) . '</option>';
656 - endforeach;
657 - ?>
658 - </select>
659 - </div>
660 - </div>
730 + <?php
731 + }
661 732
662 - <div class="field">
663 - <div class="field-name status"><?php esc_html_e( 'Excerpt highlighting', 'elasticpress' ); ?></div>
664 - <div class="input-wrap">
665 - <label><input name="settings[highlight_excerpt]" type="radio" <?php checked( (bool) $settings['highlight_excerpt'] ); ?> value="1"><?php esc_html_e( 'Enabled', 'elasticpress' ); ?></label><br>
666 - <label><input name="settings[highlight_excerpt]" type="radio" <?php checked( ! (bool) $settings['highlight_excerpt'] ); ?> value="0"><?php esc_html_e( 'Disabled', 'elasticpress' ); ?></label>
667 - <p class="field-description"><?php esc_html_e( 'By default, WordPress strips HTML from content excerpts. Enable when using the_excerpt() to display search results. ', 'elasticpress' ); ?></p>
668 - </div>
669 - </div>
733 + /**
734 + * Saves exclude from search meta.
735 + *
736 + * @param int $post_id The post ID.
737 + */
738 + public function save_exclude_from_search_meta( $post_id ) {
739 + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
740 + return;
741 + }
670 742
671 - <?php if ( ! defined( 'EP_IS_NETWORK' ) || ! EP_IS_NETWORK ) : ?>
672 - <br class="clear">
673 - <p><a href="<?php echo esc_url( admin_url( 'admin.php?page=elasticpress-weighting' ) ); ?>"><?php esc_html_e( 'Advanced fields and weighting settings', 'elasticpress' ); ?></a></p>
674 - <p><a href="<?php echo esc_url( admin_url( 'admin.php?page=elasticpress-synonyms' ) ); ?>"><?php esc_html_e( 'Add synonyms to your post searches', 'elasticpress' ); ?></a></p>
675 - <?php endif; ?>
743 + if ( ! isset( $_POST['ep-exclude-from-search-nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['ep-exclude-from-search-nonce'] ), 'save-exclude-from-search' ) ) {
744 + return;
745 + }
676 746
677 - <?php
747 + if ( ! current_user_can( 'edit_post', $post_id ) ) {
748 + return;
749 + }
750 +
751 + if ( isset( $_POST['ep_exclude_from_search'] ) ) {
752 + update_post_meta( $post_id, 'ep_exclude_from_search', true );
753 + } else {
754 + delete_post_meta( $post_id, 'ep_exclude_from_search' );
755 + }
756 + }
757 +
758 + /**
759 + * If WP_Query has unsupported orderby, skip ES query integration and use the WP query instead.
760 + *
761 + * @param bool $skip Whether to skip ES query integration
762 + * @param \WP_Query $query WP_Query object
763 + *
764 + * @since 4.5
765 + * @return bool
766 + */
767 + public function skip_query_integration( $skip, $query ) {
768 + if ( ! $query instanceof \WP_Query ) {
769 + return $skip;
770 + }
771 +
772 + $unsupported_orderby = [
773 + 'post__in',
774 + 'post_name__in',
775 + 'post_parent__in',
776 + 'parent',
777 + ];
778 +
779 + $orderby = is_string( $query->get( 'orderby' ) ) ? explode( ' ', $query->get( 'orderby' ) ) : $query->get( 'orderby', 'date' );
780 +
781 + $parse_orderby = array();
782 + foreach ( $orderby as $key => $value ) {
783 + $parse_orderby[] = is_string( $key ) ? $key : $value;
784 + }
785 +
786 + if ( array_intersect( $parse_orderby, $unsupported_orderby ) ) {
787 + return true;
788 + }
789 +
790 + return $skip;
791 + }
792 +
793 + /**
794 + * Set the `settings_schema` attribute
795 + *
796 + * @since 5.0.0
797 + */
798 + protected function set_settings_schema() {
799 + $this->settings_schema = [
800 + [
801 + 'default' => '1',
802 + 'key' => 'decaying_enabled',
803 + 'label' => __( 'Weighting by date', 'elasticpress' ),
804 + 'options' => [
805 + [
806 + 'label' => __( 'Don\'t weight results by date', 'elasticpress' ),
807 + 'value' => '0',
808 + ],
809 + [
810 + 'label' => __( 'Weight results by date', 'elasticpress' ),
811 + 'value' => '1',
812 + ],
813 + ],
814 + 'type' => 'radio',
815 + ],
816 + [
817 + 'default' => '0',
818 + 'help' => __( 'Enable to wrap search terms in HTML tags in results for custom styling. The wrapping HTML tag comes with the <code>ep-highlight</code> class for easy styling.', 'elasticpress' ),
819 + 'key' => 'highlight_enabled',
820 + 'label' => __( 'Highlight search terms', 'elasticpress' ),
821 + 'type' => 'checkbox',
822 + 'field_group_slug' => 'highlight_group',
823 + ],
824 + [
825 + 'default' => '0',
826 + 'help' => __( 'By default, WordPress strips HTML from content excerpts. Enable when using <code>the_excerpt()</code> to display search results.', 'elasticpress' ),
827 + 'key' => 'highlight_excerpt',
828 + 'label' => __( 'Highlight search terms in excerpts', 'elasticpress' ),
829 + 'type' => 'checkbox',
830 + 'field_group_slug' => 'highlight_group',
831 + ],
832 + [
833 + 'default' => 'mark',
834 + 'help' => __( 'Select the HTML tag used to highlight search terms.', 'elasticpress' ),
835 + 'key' => 'highlight_tag',
836 + 'label' => __( 'Highlight tag', 'elasticpress' ),
837 + 'options' => [
838 + [
839 + 'label' => 'mark',
840 + 'value' => 'mark',
841 + ],
842 + [
843 + 'label' => 'span',
844 + 'value' => 'span',
845 + ],
846 + [
847 + 'label' => 'strong',
848 + 'value' => 'strong',
849 + ],
850 + [
851 + 'label' => 'em',
852 + 'value' => 'em',
853 + ],
854 + [
855 + 'label' => 'i',
856 + 'value' => 'i',
857 + ],
858 + ],
859 + 'type' => 'select',
860 + 'requires_fields' => [
861 + 'relationship' => 'OR',
862 + 'conditions' => [
863 + 'highlight_enabled' => '1',
864 + 'highlight_excerpt' => '1',
865 + ],
866 + ],
867 + 'field_group_slug' => 'highlight_group',
868 + ],
869 + [
870 + 'default' => 'simple',
871 + 'key' => 'synonyms_editor_mode',
872 + 'type' => 'hidden',
873 + ],
874 + ];
875 +
876 + if ( ! defined( 'EP_IS_NETWORK' ) || ! EP_IS_NETWORK ) {
877 + $weighting_url = esc_url( admin_url( 'admin.php?page=elasticpress-weighting' ) );
878 + $synonyms_url = esc_url( admin_url( 'admin.php?page=elasticpress-synonyms' ) );
879 +
880 + $text = sprintf(
881 + '<p><a href="%1$s">%2$s</a></p><p><a href="%3$s">%4$s</a></p>',
882 + $weighting_url,
883 + __( 'Advanced fields and weighting settings', 'elasticpress' ),
884 + $synonyms_url,
885 + __( 'Add synonyms to your post searches', 'elasticpress' ),
886 + );
887 +
888 + $this->settings_schema[] = [
889 + 'key' => 'additional_links',
890 + 'label' => $text,
891 + 'type' => 'markup',
892 + ];
893 + }
678 894 }
679 895 }