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/Documents/Documents.php +169 -88 4.5.25.3.5 View file →
@@ -6,13 +6,13 @@
6 6 */
7 7
8 8 namespace ElasticPress\Feature\Documents;
9 9
10 -use ElasticPress\Feature as Feature;
11 -use ElasticPress\Elasticsearch as Elasticsearch;
12 -use ElasticPress\FeatureRequirementsStatus as FeatureRequirementsStatus;
13 -use ElasticPress\Indexables as Indexables;
14 -use ElasticPress\Utils as Utils;
10 +use ElasticPress\Elasticsearch;
11 +use ElasticPress\Feature;
12 +use ElasticPress\FeatureRequirementsStatus;
13 +use ElasticPress\Indexables;
14 +use ElasticPress\Utils;
15 15
16 16 /**
17 17 * Documents feature class.
18 18 */
@@ -24,17 +24,27 @@
24 24 */
25 25 public function __construct() {
26 26 $this->slug = 'documents';
27 27
28 - $this->title = esc_html__( 'Documents', 'elasticpress' );
28 + $this->group = 'indexing-options';
29 29
30 - $this->summary = __( 'Indexes text inside of popular file types, and adds those files types to search results.', 'elasticpress' );
30 + $this->requires_install_reindex = false;
31 31
32 - $this->docs_url = __( 'https://elasticpress.zendesk.com/hc/en-us/articles/360050447492-Configuring-ElasticPress-via-the-Plugin-Dashboard#documents', 'elasticpress' );
32 + parent::__construct();
33 + }
33 34
34 - $this->requires_install_reindex = false;
35 + /**
36 + * Sets i18n strings.
37 + *
38 + * @return void
39 + * @since 5.2.0
40 + */
41 + public function set_i18n_strings(): void {
42 + $this->title = esc_html__( 'Documents', 'elasticpress' );
35 43
36 - parent::__construct();
44 + $this->summary = '<p>' . __( 'Website search results will include popular document file types, using file names as well as their content. Supported file types include: ppt, pptx, doc, docx, xls, xlsx, pdf, csv, txt.', 'elasticpress' ) . '</p>';
45 +
46 + $this->docs_url = __( 'https://www.elasticpress.io/resources/articles/configuring-elasticpress-via-the-plugin-dashboard/#documents', 'elasticpress' );
37 47 }
38 48
39 49 /**
40 50 * Setup feature filters
@@ -59,8 +69,10 @@
59 69 add_filter( 'ep_term_suggest_post_status', [ $this, 'filter_autosuggest_post_status' ] );
60 70
61 71 add_filter( 'ep_weighting_fields_for_post_type', [ $this, 'filter_weightable_fields_for_post_type' ], 10, 2 );
62 72 add_filter( 'ep_weighting_default_post_type_weights', [ $this, 'filter_attachment_post_type_weights' ], 10, 2 );
73 +
74 + add_filter( 'ep_ajax_wp_query_integration', [ $this, 'maybe_enable_ajax_wp_query_integration' ] );
63 75 }
64 76
65 77 /**
66 78 * Add attachment post type to be searched. We used to search these by default.
@@ -95,9 +107,9 @@
95 107 * @since 2.3
96 108 * @return array
97 109 */
98 110 public function attachments_mapping( $mapping ) {
99 - if ( version_compare( Elasticsearch::factory()->get_elasticsearch_version(), '7.0', '<' ) ) {
111 + if ( version_compare( (string) Elasticsearch::factory()->get_elasticsearch_version(), '7.0', '<' ) ) {
100 112 $mapping['mappings']['post']['properties']['attachments'] = array(
101 113 'type' => 'object',
102 114 );
103 115 } else {
@@ -109,12 +121,9 @@
109 121 return $mapping;
110 122 }
111 123
112 124 /**
113 - * This is some complex logic to handle the front end search query. If we have a search query,
114 - * add the attachment post type to post_type and inherit to post_status. If post_status is not set,
115 - * we assume publish/inherit is wanted. post_type should always be set. We also add allowed mime types.
116 - * If mime types are already set, append.
125 + * Handle the search query
117 126 *
118 127 * @param WP_Query $query WP_Query to modify to search.
119 128 * @since 2.3
120 129 */
@@ -122,59 +131,23 @@
122 131 if ( ! Utils\is_integrated_request( $this->slug, [ 'public', 'ajax' ] ) ) {
123 132 return;
124 133 }
125 134
135 + // If not a search, return.
126 136 $s = $query->get( 's', false );
127 -
128 137 if ( empty( $s ) ) {
129 138 return;
130 139 }
131 140
132 - $post_status = $query->get( 'post_status', [] );
133 - $post_type = $query->get( 'post_type', [] );
134 - $mime_types = $query->get( 'post_mime_type', [] );
135 -
136 - if ( ! empty( $post_type ) ) {
137 - if ( 'any' !== $post_type ) {
138 - if ( is_string( $post_type ) ) {
139 - $post_type = explode( ' ', $post_type );
140 - $post_type[] = 'attachment';
141 -
142 - $query->set( 'post_type', array_unique( $post_type ) );
143 - }
144 - }
141 + // Return if attachments are not involved in the query.
142 + // If post_type is empty, attachments will be included automatically.
143 + $post_type = (array) $query->get( 'post_type', [] );
144 + if ( ! empty( $post_type ) && ! in_array( 'attachment', $post_type, true ) ) {
145 + return;
145 146 }
146 147
147 - if ( empty( $post_status ) ) {
148 - $post_status = array_values(
149 - get_post_stati(
150 - [
151 - 'public' => true,
152 - 'exclude_from_search' => false,
153 - ]
154 - )
155 - );
156 -
157 - // Add inherit for documents
158 - $post_status[] = 'inherit';
159 - } else {
160 - if ( is_string( $post_status ) ) {
161 - $post_status = explode( ' ', $post_status );
162 - }
163 -
164 - $post_status[] = 'inherit';
165 - }
166 -
167 - $query->set( 'post_status', array_unique( $post_status ) );
168 -
169 - if ( ! empty( $mime_types ) && is_string( $mime_types ) ) {
170 - $mime_types = explode( ' ', $mime_types );
171 - }
172 -
173 - $mime_types = array_merge( $mime_types, $this->get_allowed_ingest_mime_types() );
174 - $mime_types[] = ''; // This let's us query non-attachments as well as attachments.
175 -
176 - $query->set( 'post_mime_type', array_unique( array_values( $mime_types ) ) );
148 + $this->maybe_set_post_status( $query );
149 + $this->maybe_set_mime_type( $query );
177 150 }
178 151
179 152 /**
180 153 * Change Elasticsearch request path if processing attachment
@@ -189,27 +162,31 @@
189 162 if ( 'post' !== $type ) {
190 163 return $path;
191 164 }
192 165
193 - if ( 'attachment' === $post['post_type'] ) {
194 - if ( ! empty( $post['attachments'][0]['data'] ) && isset( $post['post_mime_type'] ) && in_array( $post['post_mime_type'], $this->get_allowed_ingest_mime_types(), true ) ) {
195 - $index = Indexables::factory()->get( 'post' )->get_index_name();
166 + if ( 'attachment' !== $post['post_type'] ) {
167 + return $path;
168 + }
196 169
197 - /**
198 - * Filter documents pipeline ID
199 - *
200 - * @hook ep_documents_pipeline_id
201 - * @param {string} $id Pipeline ID
202 - * @return {string} new ID
203 - */
204 - $pipeline_id = apply_filters( 'ep_documents_pipeline_id', Indexables::factory()->get( 'post' )->get_index_name() . '-attachment' );
170 + if ( empty( $post['attachments'][0]['data'] ) || ! isset( $post['post_mime_type'] ) || ! in_array( $post['post_mime_type'], $this->get_allowed_ingest_mime_types(), true ) ) {
171 + return $path;
172 + }
205 173
206 - if ( version_compare( Elasticsearch::factory()->get_elasticsearch_version(), '7.0', '<' ) ) {
207 - $path = trailingslashit( $index ) . 'post/' . $post['ID'] . '?pipeline=' . $pipeline_id;
208 - } else {
209 - $path = trailingslashit( $index ) . '_doc/' . $post['ID'] . '?pipeline=' . $pipeline_id;
210 - }
211 - }
174 + $index = Indexables::factory()->get( 'post' )->get_index_name();
175 +
176 + /**
177 + * Filter documents pipeline ID
178 + *
179 + * @hook ep_documents_pipeline_id
180 + * @param {string} $id Pipeline ID
181 + * @return {string} new ID
182 + */
183 + $pipeline_id = apply_filters( 'ep_documents_pipeline_id', Indexables::factory()->get( 'post' )->get_index_name() . '-attachment' );
184 +
185 + if ( version_compare( (string) Elasticsearch::factory()->get_elasticsearch_version(), '7.0', '<' ) ) {
186 + $path = trailingslashit( $index ) . 'post/' . $post['ID'] . '?pipeline=' . $pipeline_id;
187 + } else {
188 + $path = trailingslashit( $index ) . '_doc/' . $post['ID'] . '?pipeline=' . $pipeline_id;
212 189 }
213 190
214 191 return $path;
215 192 }
@@ -326,9 +303,9 @@
326 303 * @since 2.3
327 304 * @return mixed
328 305 */
329 306 public function requirements_status() {
330 - $status = new FeatureRequirementsStatus( 1 );
307 + $status = new FeatureRequirementsStatus( 1, null, $this );
331 308
332 309 if ( empty( Elasticsearch::factory()->get_elasticsearch_version( false ) ) ) {
333 310 return $status;
334 311 }
@@ -349,19 +326,8 @@
349 326 return $status;
350 327 }
351 328
352 329 /**
353 - * Output feature box long
354 - *
355 - * @since 2.3
356 - */
357 - public function output_feature_box_long() {
358 - ?>
359 - <p><?php esc_html_e( 'Website search results will include popular document file types, using file names as well as their content. Supported file types include: ppt, pptx, doc, docx, xls, xlsx, pdf.', 'elasticpress' ); ?></p>
360 - <?php
361 - }
362 -
363 - /**
364 330 * Make sure to create pipeline after activation
365 331 *
366 332 * @since 2.6
367 333 */
@@ -437,8 +403,10 @@
437 403 'xls' => 'application/vnd.ms-excel',
438 404 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
439 405 'doc' => 'application/msword',
440 406 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
407 + 'csv' => 'text/csv',
408 + 'txt' => 'text/plain',
441 409 )
442 410 );
443 411 }
444 412
@@ -515,6 +483,119 @@
515 483 ];
516 484 }
517 485
518 486 return $weights;
487 + }
488 +
489 + /**
490 + * Enable integration if we are in the media library admin ajax search
491 + *
492 + * @param bool $integrate Whether it should be integrated or not
493 + * @return bool
494 + */
495 + public function maybe_enable_ajax_wp_query_integration( $integrate ) {
496 + return ( $this->is_admin_ajax_search() && $this->is_media_library_ajax_enabled() ) ? true : $integrate;
497 + }
498 +
499 + /**
500 + * If post_status is not set, we assume publish/inherit is wanted.
501 + *
502 + * @param WP_Query $query WP_Query to modify to search.
503 + * @return void
504 + */
505 + protected function maybe_set_post_status( $query ) {
506 + $post_status = $query->get( 'post_status', [] );
507 +
508 + if ( empty( $post_status ) ) {
509 + $post_status = array_values(
510 + get_post_stati(
511 + [
512 + 'public' => true,
513 + 'exclude_from_search' => false,
514 + ]
515 + )
516 + );
517 +
518 + // Add inherit for documents
519 + $post_status[] = 'inherit';
520 + } else {
521 + if ( is_string( $post_status ) ) {
522 + $post_status = explode( ' ', $post_status );
523 + }
524 +
525 + $post_status[] = 'inherit';
526 + }
527 +
528 + $query->set( 'post_status', array_unique( $post_status ) );
529 + }
530 +
531 + /**
532 + * Add allowed mime types. If mime types are already set, append.
533 + *
534 + * @param WP_Query $query WP_Query to modify to search.
535 + * @return void
536 + */
537 + protected function maybe_set_mime_type( $query ) {
538 + /**
539 + * Mime types
540 + *
541 + * By default, we do not restrict results by mime types in the Media Library AJAX search,
542 + * otherwise images, and SVGs, for example, will not be returned.
543 + */
544 + $should_set_mime_types = ! $this->is_admin_ajax_search() || ! $this->is_media_library_ajax_enabled();
545 +
546 + /**
547 + * Filter whether mime type restriction should be applied to the current WP Query
548 + *
549 + * @since 5.1.0
550 + * @hook ep_documents_wp_query_set_mime_types
551 + * @param {bool} $should_set Whether to restrict this query with mime types or not
552 + * @param {WP_Query} $query WP Query object
553 + * @return {bool} New value
554 + */
555 + $should_set_mime_types = apply_filters( 'ep_documents_wp_query_set_mime_types', $should_set_mime_types, $query );
556 +
557 + if ( ! $should_set_mime_types ) {
558 + return;
559 + }
560 +
561 + // Set mime types
562 + $mime_types = $query->get( 'post_mime_type', [] );
563 +
564 + if ( ! empty( $mime_types ) && is_string( $mime_types ) ) {
565 + $mime_types = explode( ' ', $mime_types );
566 + }
567 +
568 + $mime_types = array_merge( $mime_types, $this->get_allowed_ingest_mime_types() );
569 + $mime_types[] = ''; // This let's us query non-attachments as well as attachments.
570 +
571 + $query->set( 'post_mime_type', array_unique( array_values( $mime_types ) ) );
572 + }
573 +
574 + /**
575 + * Whether the feature should work on the Media Library admin ajax request
576 + *
577 + * @return boolean
578 + */
579 + protected function is_media_library_ajax_enabled() {
580 + $protected_content = \ElasticPress\Features::factory()->get_registered_feature( 'protected_content' );
581 +
582 + /**
583 + * Filter whether the feature should work on the Media Library admin ajax request
584 + *
585 + * @since 5.1.0
586 + * @hook ep_documents_media_library_ajax_enabled
587 + * @param {bool} $enabled Whether to integrate or not
588 + * @return {bool} New value
589 + */
590 + return apply_filters( 'ep_documents_media_library_ajax_enabled', $protected_content->is_active() );
591 + }
592 +
593 + /**
594 + * Whether we are in the admin ajax search request for the media library
595 + *
596 + * @return boolean
597 + */
598 + protected function is_admin_ajax_search() {
599 + return wp_doing_ajax() && isset( $_REQUEST['action'] ) && 'query-attachments' === $_REQUEST['action']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
519 600 }
520 601 }