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/ProtectedContent/ProtectedContent.php +172 -26 5.0.25.3.5 View file →
@@ -29,15 +29,10 @@
29 29 */
30 30 public function __construct() {
31 31 $this->slug = 'protected_content';
32 32
33 - $this->title = esc_html__( 'Protected Content', 'elasticpress' );
33 + $this->group = 'indexing-options';
34 34
35 - $this->summary = '<p>' . __( 'Syncs unpublished content — including private, draft, and scheduled posts — improving load times in places like the administrative dashboard where WordPress needs to include protected content in a query.', 'elasticpress' ) . '</p>' .
36 - '<p><em>' . __( 'We recommend using a secured Elasticsearch setup, such as ElasticPress.io, to prevent potential exposure of content not intended for the public.', 'elasticpress' ) . '</em></p>';
37 -
38 - $this->docs_url = __( 'https://elasticpress.zendesk.com/hc/en-us/articles/360050447492-Configuring-ElasticPress-via-the-Plugin-Dashboard#protected-content', 'elasticpress' );
39 -
40 35 $this->requires_install_reindex = true;
41 36
42 37 $this->available_during_installation = true;
43 38
@@ -44,8 +39,23 @@
44 39 parent::__construct();
45 40 }
46 41
47 42 /**
43 + * Sets i18n strings.
44 + *
45 + * @return void
46 + * @since 5.2.0
47 + */
48 + public function set_i18n_strings(): void {
49 + $this->title = esc_html__( 'Protected Content', 'elasticpress' );
50 +
51 + $this->summary = '<p>' . __( 'Syncs unpublished content — including private, draft, and scheduled posts — improving load times in places like the administrative dashboard where WordPress needs to include protected content in a query.', 'elasticpress' ) . '</p>' .
52 + '<p><em>' . __( 'We recommend using a secured Elasticsearch setup, such as ElasticPress.io, to prevent potential exposure of content not intended for the public.', 'elasticpress' ) . '</em></p>';
53 +
54 + $this->docs_url = __( 'https://www.elasticpress.io/resources/articles/configuring-elasticpress-via-the-plugin-dashboard/#protected-content', 'elasticpress' );
55 + }
56 +
57 + /**
48 58 * Setup all feature filters
49 59 *
50 60 * @since 2.1
51 61 */
@@ -63,8 +73,10 @@
63 73 if ( is_admin() ) {
64 74 add_filter( 'ep_admin_wp_query_integration', '__return_true' );
65 75 add_action( 'pre_get_posts', [ $this, 'integrate' ] );
66 76 add_filter( 'ep_post_query_db_args', [ $this, 'query_password_protected_posts' ] );
77 + add_filter( 'ep_set_sort', [ $this, 'maybe_change_sort' ] );
78 + add_filter( 'ep_post_formatted_args', [ $this, 'filter_private_posts_for_current_user' ], 10, 2 );
67 79 }
68 80
69 81 if ( Features::factory()->get_registered_feature( 'comments' )->is_active() ) {
70 82 add_filter( 'ep_indexable_comment_status', [ $this, 'get_comment_statuses' ] );
@@ -172,12 +184,10 @@
172 184 }
173 185 }
174 186
175 187 $query->set( 'ep_integrate', true );
176 - } else {
177 - if ( ! empty( $supported_post_types[ $post_type ] ) ) {
188 + } elseif ( ! empty( $supported_post_types[ $post_type ] ) ) {
178 189 $query->set( 'ep_integrate', true );
179 - }
180 190 }
181 191
182 192 /**
183 193 * Remove articles weighting by date in admin.
@@ -354,28 +364,14 @@
354 364 }
355 365 }
356 366
357 367 $comment_query->query_vars['ep_integrate'] = true;
358 - } else {
359 - if ( in_array( $comment_type, $supported_comment_types, true ) ) {
368 + } elseif ( in_array( $comment_type, $supported_comment_types, true ) ) {
360 369 $comment_query->query_vars['ep_integrate'] = true;
361 - }
362 370 }
363 -
364 371 }
365 372
366 373 /**
367 - * Output feature box long
368 - *
369 - * @since 2.1
370 - */
371 - public function output_feature_box_long() {
372 - ?>
373 - <p><?php echo wp_kses_post( __( 'Securely indexes unpublished content—including private, draft, and scheduled posts —improving load times in places like the administrative dashboard where WordPress needs to include protected content in a query. <em>We recommend using a secured Elasticsearch setup, such as ElasticPress.io, to prevent potential exposure of content not intended for the public.</em>', 'elasticpress' ) ); ?></p>
374 - <?php
375 - }
376 -
377 - /**
378 374 * Fetches all post statuses we need to index
379 375 *
380 376 * @since 2.1
381 377 * @param array $statuses Post statuses array
@@ -406,9 +402,9 @@
406 402 * @since 2.2
407 403 * @return FeatureRequirementsStatus
408 404 */
409 405 public function requirements_status() {
410 - $status = new FeatureRequirementsStatus( 1 );
406 + $status = new FeatureRequirementsStatus( 1, null, $this );
411 407
412 408 if ( ! Utils\is_epio() ) {
413 409 $status->message = __( "You aren't using <a href='https://elasticpress.io'>ElasticPress.io</a> so we can't be sure your Elasticsearch instance is secure.", 'elasticpress' );
414 410 }
@@ -423,8 +419,158 @@
423 419 * @param null|bool $new_skip Short-circuit flag
424 420 * @param bool $skip Current value of $skip
425 421 * @return bool
426 422 */
427 - public function sync_password_protected( $new_skip, bool $skip ) : bool {
423 + public function sync_password_protected( $new_skip, bool $skip ): bool {
428 424 return $skip;
425 + }
426 +
427 + /**
428 + * Maybe change the sort order for the WP Dashboard.
429 + *
430 + * If the admin user has enabled the setting to use the default WordPress sort order,
431 + * we will change the sort order to (somewhat) match the default WP behavior.
432 + *
433 + * @since 5.1.4
434 + *
435 + * @param array $default_sort The previous value of the `ep_set_sort` filter
436 + * @return array
437 + */
438 + public function maybe_change_sort( $default_sort ) {
439 + if ( ! function_exists( '\get_current_screen' ) ) {
440 + return $default_sort;
441 + }
442 +
443 + $screen = get_current_screen();
444 + if ( empty( $screen ) || 'edit' !== $screen->base ) {
445 + return $default_sort;
446 + }
447 +
448 + if ( ! $this->get_setting( 'use_default_wp_sort' ) ) {
449 + return $default_sort;
450 + }
451 +
452 + return [
453 + [ 'post_date' => [ 'order' => 'desc' ] ],
454 + [ 'post_title.sortable' => [ 'order' => 'asc' ] ],
455 + ];
456 + }
457 +
458 + /**
459 + * Filter private posts for current user.
460 + *
461 + * Private statuses (including custom ones from `get_post_stati( [ 'private' => true ] )`)
462 + * are never added to the all-authors clause. Users without `read_private_posts` can
463 + * still match their own private posts via the author-restricted clause below. Merging
464 + * a requested private status into the all-authors list would otherwise expose other
465 + * authors' private posts.
466 + *
467 + * @param array $formatted_args Formatted Elasticsearch query
468 + * @param array $args Query variables
469 + *
470 + * @return array
471 + */
472 + public function filter_private_posts_for_current_user( $formatted_args, $args ): array {
473 + $post_statuses = ! empty( $args['post_status'] ) ? $args['post_status'] : [];
474 + $post_statuses = is_string( $post_statuses ) ? explode( ',', $post_statuses ) : $post_statuses;
475 + $post_types = ! empty( $args['post_type'] ) ? (array) $args['post_type'] : [];
476 + $valid_post_types = array_filter( $post_types, 'post_type_exists' );
477 + $private_statuses = get_post_stati( [ 'private' => true ] );
478 +
479 + $base_statuses = array_merge(
480 + get_post_stati( [ 'public' => true ] ),
481 + get_post_stati(
482 + [
483 + 'protected' => true,
484 + 'show_in_admin_all_list' => true,
485 + ]
486 + ),
487 + $post_statuses
488 + );
489 + // Requested private statuses belong only in the capability or author clauses.
490 + $base_statuses = array_unique( array_diff( $base_statuses, $private_statuses ) );
491 +
492 + $post_types_with_capability = [];
493 + $post_types_without_capability = [];
494 +
495 + foreach ( $valid_post_types as $post_type ) {
496 + $post_type_object = get_post_type_object( $post_type );
497 +
498 + if ( empty( $post_type_object ) || empty( $post_type_object->cap->read_private_posts ) ) {
499 + continue;
500 + }
501 +
502 + $read_private_cap = $post_type_object->cap->read_private_posts;
503 +
504 + if ( current_user_can( $read_private_cap ) ) {
505 + $post_types_with_capability[] = $post_type;
506 + } else {
507 + $post_types_without_capability[] = $post_type;
508 + }
509 + }
510 +
511 + $should_clauses = [];
512 +
513 + if ( ! empty( $post_types_with_capability ) ) {
514 + $all_statuses = array_unique( array_merge( $base_statuses, $private_statuses ) );
515 +
516 + $should_clauses[] = [
517 + 'bool' => [
518 + 'must' => [
519 + [ 'terms' => [ 'post_type.raw' => array_values( $post_types_with_capability ) ] ],
520 + [ 'terms' => [ 'post_status' => array_values( $all_statuses ) ] ],
521 + ],
522 + ],
523 + ];
524 + }
525 +
526 + if ( ! empty( $post_types_without_capability ) ) {
527 + $should_clauses[] = [
528 + 'bool' => [
529 + 'must' => [
530 + [ 'terms' => [ 'post_type.raw' => array_values( $post_types_without_capability ) ] ],
531 + [ 'terms' => [ 'post_status' => array_values( $base_statuses ) ] ],
532 + ],
533 + ],
534 + ];
535 +
536 + if ( ! empty( $private_statuses ) ) {
537 + $should_clauses[] = [
538 + 'bool' => [
539 + 'must' => [
540 + [ 'terms' => [ 'post_type.raw' => array_values( $post_types_without_capability ) ] ],
541 + [ 'terms' => [ 'post_status' => array_values( $private_statuses ) ] ],
542 + [ 'term' => [ 'post_author.id' => get_current_user_id() ] ],
543 + ],
544 + ],
545 + ];
546 + }
547 + }
548 +
549 + if ( ! empty( $should_clauses ) ) {
550 + $formatted_args['post_filter']['bool']['should'] = array_merge(
551 + $formatted_args['post_filter']['bool']['should'] ?? [],
552 + $should_clauses
553 + );
554 + $formatted_args['post_filter']['bool']['minimum_should_match'] = 1;
555 + }
556 +
557 + return $formatted_args;
558 + }
559 +
560 + /**
561 + * Set the `settings_schema` attribute
562 + *
563 + * @since 5.1.4
564 + */
565 + protected function set_settings_schema() {
566 + $this->settings_schema = [
567 + [
568 + 'default' => '0',
569 + 'key' => 'use_default_wp_sort',
570 + 'help' => __( 'Enable to use WordPress default sort for searches inside the WP Dashboard.', 'elasticpress' ),
571 + 'label' => __( 'Use default WordPress sort on the WP Dashboard', 'elasticpress' ),
572 + 'type' => 'checkbox',
573 + ],
574 + ];
429 575 }
430 576 }