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 +182 -111 4.7.15.3.5 View file →
@@ -51,14 +51,10 @@
51 51 */
52 52 public function __construct() {
53 53 $this->slug = 'search';
54 54
55 - $this->title = esc_html__( 'Post Search', 'elasticpress' );
55 + $this->group = 'core-search';
56 56
57 - $this->summary = __( 'Instantly find the content you’re looking for. The first time.', 'elasticpress' );
58 -
59 - $this->docs_url = __( 'https://elasticpress.zendesk.com/hc/en-us/articles/360050447492-Configuring-ElasticPress-via-the-Plugin-Dashboard#post-search', 'elasticpress' );
60 -
61 57 $this->requires_install_reindex = false;
62 58
63 59 $this->default_settings = [
64 60 'decaying_enabled' => '1',
@@ -73,8 +69,29 @@
73 69 parent::__construct();
74 70 }
75 71
76 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 + /**
77 94 * We need to delay search setup up since it will fire after protected content and protected
78 95 * content filters into the search setup
79 96 *
80 97 * @since 2.2
@@ -79,10 +96,11 @@
79 96 *
80 97 * @since 2.2
81 98 */
82 99 public function setup() {
100 + Indexables::factory()->activate( 'post' );
101 +
83 102 add_action( 'init', [ $this, 'search_setup' ] );
84 - add_filter( 'ep_sanitize_feature_settings', [ $this, 'sanitize_highlighting_settings' ] );
85 103
86 104 // Set up weighting sub-module
87 105 $this->weighting = new Weighting();
88 106 $this->weighting->setup();
@@ -106,8 +124,9 @@
106 124 add_filter( 'ep_highlighting_tag', [ $this, 'get_highlighting_tag' ] );
107 125 add_action( 'ep_highlighting_pre_add_highlight', [ $this, 'allow_excerpt_html' ] );
108 126
109 127 add_action( 'init', [ $this, 'register_meta' ], 20 );
128 + add_filter( 'ep_prepare_meta_allowed_keys', [ $this, 'add_exclude_from_search' ] );
110 129 add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_block_editor_assets' ] );
111 130 add_filter( 'ep_post_filters', [ $this, 'exclude_posts_from_search' ], 10, 3 );
112 131 add_action( 'post_submitbox_misc_actions', [ $this, 'output_exclude_from_search_setting' ] );
113 132 add_action( 'edit_post', [ $this, 'save_exclude_from_search_meta' ] );
@@ -123,9 +142,9 @@
123 142 */
124 143 public function enqueue_scripts() {
125 144 $settings = $this->get_settings();
126 145
127 - if ( true !== $settings['highlight_enabled'] ) {
146 + if ( '1' !== $settings['highlight_enabled'] ) {
128 147 return;
129 148 }
130 149
131 150 wp_enqueue_style(
@@ -158,9 +177,9 @@
158 177
159 178 // get current config
160 179 $settings = $this->get_settings();
161 180
162 - if ( true !== $settings['highlight_enabled'] ) {
181 + if ( '1' !== $settings['highlight_enabled'] ) {
163 182 return $formatted_args;
164 183 }
165 184
166 185 if ( empty( $args['s'] ) ) {
@@ -236,9 +255,18 @@
236 255 $formatted_args['highlight']['fields'][ $field ] = [
237 256 'pre_tags' => [ $opening_tag ],
238 257 'post_tags' => [ $closing_tag ],
239 258 'type' => 'plain',
240 - '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 ),
241 269 ];
242 270 }
243 271
244 272 return $formatted_args;
@@ -256,9 +284,9 @@
256 284 }
257 285
258 286 $settings = $this->get_settings();
259 287
260 - if ( ! empty( $settings['highlight_excerpt'] ) && true === $settings['highlight_excerpt'] ) {
288 + if ( ! empty( $settings['highlight_excerpt'] ) && '1' === $settings['highlight_excerpt'] ) {
261 289 remove_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
262 290 add_filter( 'get_the_excerpt', [ $this, 'ep_highlight_excerpt' ], 10, 2 );
263 291 add_filter( 'ep_highlighting_fields', [ $this, 'ep_highlight_add_excerpt_field' ] );
264 292 }
@@ -273,16 +301,20 @@
273 301 *
274 302 * @return string $text the new excerpt
275 303 */
276 304 public function ep_highlight_excerpt( $text, $post ) {
277 -
278 305 $settings = $this->get_settings();
279 306
280 307 // reproduces wp_trim_excerpt filter, preserving the excerpt_more and excerpt_length filters
281 308 if ( '' === $text ) {
282 309 $text = get_the_content( '', false, $post );
310 +
311 + $text = strip_shortcodes( $text );
312 + $text = excerpt_remove_blocks( $text );
313 +
283 314 $text = apply_filters( 'the_content', $text );
284 315 $text = str_replace( '\]\]\>', ']]&gt;', $text );
316 +
285 317 $text = strip_tags( $text, '<' . esc_html( $settings['highlight_tag'] ) . '>' );
286 318
287 319 // use the defined length, if already applied...
288 320 $excerpt_length = apply_filters( 'excerpt_length', 55 );
@@ -288,11 +320,14 @@
288 320 $excerpt_length = apply_filters( 'excerpt_length', 55 );
289 321
290 322 // use defined excerpt_more filter if it is used
291 323 $excerpt_more = apply_filters( 'excerpt_more', $text );
292 -
293 324 $excerpt_more = $excerpt_more !== $text ? $excerpt_more : '[&hellip;]';
294 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 + */
295 330 $words = explode( ' ', $text, $excerpt_length + 1 );
296 331 if ( count( $words ) > $excerpt_length ) {
297 332 array_pop( $words );
298 333 array_push( $words, $excerpt_more );
@@ -329,26 +364,8 @@
329 364 return $tag;
330 365 }
331 366
332 367 /**
333 - * Sanitizes our highlighting settings.
334 - *
335 - * @param array $settings Array of current settings
336 - * @return mixed
337 - */
338 - public function sanitize_highlighting_settings( $settings ) {
339 - if ( ! empty( $settings['search']['highlight_excerpt'] ) ) {
340 - $settings['search']['highlight_excerpt'] = (bool) $settings['search']['highlight_excerpt'];
341 - }
342 -
343 - if ( ! empty( $settings['search']['highlight_enabled'] ) ) {
344 - $settings['search']['highlight_enabled'] = (bool) $settings['search']['highlight_enabled'];
345 - }
346 -
347 - return $settings;
348 - }
349 -
350 - /**
351 368 * Returns searchable post types for the current site
352 369 *
353 370 * @since 1.9
354 371 * @return mixed|void
@@ -414,9 +431,9 @@
414 431 */
415 432 public function is_decaying_enabled( $args = [] ) {
416 433 $settings = $this->get_settings();
417 434
418 - $is_decaying_enabled = (bool) $settings['decaying_enabled'];
435 + $is_decaying_enabled = $settings['decaying_enabled'] && '0' !== $settings['decaying_enabled'];
419 436
420 437 /**
421 438 * Filter to modify decaying
422 439 *
@@ -551,20 +568,8 @@
551 568 return $formatted_args;
552 569 }
553 570
554 571 /**
555 - * Output feature box long text
556 - *
557 - * @since 3.0
558 - */
559 - public function output_feature_box_long() {
560 - ?>
561 - <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>
562 -
563 - <?php
564 - }
565 -
566 - /**
567 572 * Enable integration on search queries
568 573 *
569 574 * @param bool $enabled Original enabled value
570 575 * @param WP_Query $query WP Query
@@ -600,72 +605,8 @@
600 605 return apply_filters( 'ep_integrate_search_queries', $enabled, $query );
601 606 }
602 607
603 608 /**
604 - * Display decaying settings on dashboard.
605 - *
606 - * @since 2.4
607 - */
608 - public function output_feature_box_settings() {
609 - $settings = $this->get_settings();
610 - ?>
611 - <div class="field">
612 - <div class="field-name status"><?php esc_html_e( 'Weight results by date', 'elasticpress' ); ?></div>
613 - <div class="input-wrap">
614 - <label><input name="settings[decaying_enabled]" type="radio" <?php checked( (bool) $settings['decaying_enabled'] ); ?> value="1"><?php esc_html_e( 'Enabled', 'elasticpress' ); ?></label><br>
615 - <label><input name="settings[decaying_enabled]" type="radio" <?php checked( ! (bool) $settings['decaying_enabled'] ); ?> value="0"><?php esc_html_e( 'Disabled', 'elasticpress' ); ?></label><br>
616 - <?php
617 - /**
618 - * Fires after the default Weight results by date settings
619 - *
620 - * @since 4.6.0
621 - * @hook ep_weight_settings_after_search
622 - * @param {array} $settings settings array
623 - */
624 - do_action( 'ep_weight_settings_after_search', $settings );
625 - ?>
626 - </div>
627 - </div>
628 - <div class="field">
629 - <div class="field-name status"><?php esc_html_e( 'Highlighting status', 'elasticpress' ); ?></div>
630 - <div class="input-wrap">
631 - <label><input name="settings[highlight_enabled]" type="radio" <?php checked( (bool) $settings['highlight_enabled'] ); ?> value="1"><?php esc_html_e( 'Enabled', 'elasticpress' ); ?></label><br>
632 - <label><input name="settings[highlight_enabled]" type="radio" <?php checked( ! (bool) $settings['highlight_enabled'] ); ?> value="0"><?php esc_html_e( 'Disabled', 'elasticpress' ); ?></label>
633 - <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>
634 - </div>
635 - </div>
636 - <div class="field">
637 - <label for="highlight-tag" class="field-name status"><?php echo esc_html_e( 'Highlight tag ', 'elasticpress' ); ?></label>
638 - <div class="input-wrap">
639 - <select id="highlight-tag" name="settings[highlight_tag]">
640 - <?php
641 - foreach ( self::$default_highlight_tags as $option ) :
642 - echo '<option value="' . esc_attr( $option ) . '" ' . selected( $option, $settings['highlight_tag'] ) . '>' . esc_html( $option ) . '</option>';
643 - endforeach;
644 - ?>
645 - </select>
646 - </div>
647 - </div>
648 -
649 - <div class="field">
650 - <div class="field-name status"><?php esc_html_e( 'Excerpt highlighting', 'elasticpress' ); ?></div>
651 - <div class="input-wrap">
652 - <label><input name="settings[highlight_excerpt]" type="radio" <?php checked( (bool) $settings['highlight_excerpt'] ); ?> value="1"><?php esc_html_e( 'Enabled', 'elasticpress' ); ?></label><br>
653 - <label><input name="settings[highlight_excerpt]" type="radio" <?php checked( ! (bool) $settings['highlight_excerpt'] ); ?> value="0"><?php esc_html_e( 'Disabled', 'elasticpress' ); ?></label>
654 - <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>
655 - </div>
656 - </div>
657 -
658 - <?php if ( ! defined( 'EP_IS_NETWORK' ) || ! EP_IS_NETWORK ) : ?>
659 - <br class="clear">
660 - <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>
661 - <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>
662 - <?php endif; ?>
663 -
664 - <?php
665 - }
666 -
667 - /**
668 609 * Registers post meta for exclude from search feature.
669 610 */
670 611 public function register_meta() {
671 612 register_post_meta(
@@ -679,8 +620,20 @@
679 620 );
680 621 }
681 622
682 623 /**
624 + * Add ep_exclude_from_search to the allowed meta fields list.
625 + *
626 + * @since 5.0.0
627 + * @param array $keys List of allowed meta fields
628 + * @return array
629 + */
630 + public function add_exclude_from_search( $keys ) {
631 + $keys[] = 'ep_exclude_from_search';
632 + return $keys;
633 + }
634 +
635 + /**
683 636 * Enqueue block editor assets.
684 637 */
685 638 public function enqueue_block_editor_assets() {
686 639 global $post;
@@ -688,15 +641,21 @@
688 641 if ( ! $post instanceof \WP_Post ) {
689 642 return;
690 643 }
691 644
645 + if ( ! $post->post_type || ! post_type_supports( $post->post_type, 'custom-fields' ) ) {
646 + return;
647 + }
648 +
692 649 wp_enqueue_script(
693 650 'ep-search-editor',
694 - EP_URL . '/dist/js/search-editor-script.js',
651 + EP_URL . 'dist/js/search-editor-script.js',
695 652 Utils\get_asset_info( 'search-editor-script', 'dependencies' ),
696 653 Utils\get_asset_info( 'search-editor-script', 'version' ),
697 654 true
698 655 );
656 +
657 + wp_set_script_translations( 'ep-search-editor', 'elasticpress' );
699 658 }
700 659
701 660 /**
702 661 * Exclude posts based on ep_exclude_from_search post meta.
@@ -705,9 +664,14 @@
705 664 * @param array $args WP Query args
706 665 * @param WP_Query $query WP Query object
707 666 */
708 667 public function exclude_posts_from_search( $filters, $args, $query ) {
709 - $bypass_exclusion_from_search = is_admin() || ! $query->is_search();
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 +
710 674 /**
711 675 * Filter whether the exclusion from the "exclude from search" checkbox should be applied
712 676 *
713 677 * @since 4.4.0
@@ -715,9 +679,14 @@
715 679 * @param {bool} $bypass_exclusion_from_search True means all posts will be returned
716 680 * @param {WP_Query} $query WP Query
717 681 * @return {bool} New $bypass_exclusion_from_search value
718 682 */
719 - if ( apply_filters( 'ep_bypass_exclusion_from_search', $bypass_exclusion_from_search, $query ) ) {
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 + ) ) {
720 689 return $filters;
721 690 }
722 691
723 692 $filters[] = [
@@ -783,9 +752,8 @@
783 752 update_post_meta( $post_id, 'ep_exclude_from_search', true );
784 753 } else {
785 754 delete_post_meta( $post_id, 'ep_exclude_from_search' );
786 755 }
787 -
788 756 }
789 757
790 758 /**
791 759 * If WP_Query has unsupported orderby, skip ES query integration and use the WP query instead.
@@ -819,6 +787,109 @@
819 787 return true;
820 788 }
821 789
822 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 + }
823 894 }
824 895 }