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 +170 -89 4.3.05.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 }
@@ -342,9 +319,9 @@
342 319 $status->code = 2;
343 320 $status->message[] = __( 'The <a href="https://www.elastic.co/guide/en/elasticsearch/plugins/master/ingest-attachment.html">Ingest Attachment plugin</a> for Elasticsearch is not installed. To get the most out of ElasticPress, without the hassle of Elasticsearch management, check out <a href="https://elasticpress.io">ElasticPress.io</a> hosting.', 'elasticpress' );
344 321 } else {
345 322 $status->code = 1;
346 - $status->message[] = __( 'This feature modifies the default user experience for your visitors by adding popular document file types to search results. <strong>All supported documents</strong> uploaded to your media library will appear in search results.', 'elasticpress' );
323 + $status->message[] = __( 'This feature modifies the default user experience for your visitors by adding popular document file types to search results. All supported documents (PDFs and Microsoft Office) uploaded to your media library will appear in search results.', 'elasticpress' );
347 324 }
348 325
349 326 return $status;
350 327 }
@@ -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 }