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/utils.php +134 -36 4.7.05.3.5 View file →
@@ -53,49 +53,68 @@
53 53
54 54 /**
55 55 * Get WP capability needed for a user to interact with ElasticPress in the admin
56 56 *
57 - * @since 4.5.0
57 + * @since 4.5.0, 5.1.0 added $context
58 + * @param string $context Context for the capability. Defaults to empty string.
58 59 * @return string
59 60 */
60 -function get_capability() : string {
61 +function get_capability( string $context = '' ): string {
61 62 /**
62 63 * Filter the WP capability needed to interact with ElasticPress in the admin
63 64 *
64 - * @since 4.5.0
65 + * Example:
66 + * ```
67 + * add_filter(
68 + * 'ep_capability',
69 + * function ( $cacapability, $context ) {
70 + * return ( 'synonyms' === $context ) ?
71 + * 'manage_elasticpress_synonyms' :
72 + * $cacapability;
73 + * },
74 + * 10,
75 + * 2
76 + * );
77 + * ```
78 + *
79 + * @since 4.5.0, 5.1.0 added $context
65 80 * @hook ep_capability
66 - * @param {bool} $capability Capability name. Defaults to `'elasticpress_manage'`
67 - * @return {bool} New capability value
81 + * @param {string} $capability Capability name. Defaults to `'manage_elasticpress'`
82 + * @param {string} $context Additional context
83 + * @return {string} New capability value
68 84 */
69 - return apply_filters( 'ep_capability', 'manage_elasticpress' );
85 + return apply_filters( 'ep_capability', 'manage_elasticpress', $context );
70 86 }
71 87
72 88 /**
73 89 * Get WP capability needed for a user to interact with ElasticPress in the network admin
74 90 *
75 - * @since 4.5.0
91 + * @since 4.5.0, 5.1.0 added $context
92 + * @param string $context Context for the capability. Defaults to empty string.
76 93 * @return string
77 94 */
78 -function get_network_capability() : string {
95 +function get_network_capability( string $context = '' ): string {
79 96 /**
80 97 * Filter the WP capability needed to interact with ElasticPress in the network admin
81 98 *
82 - * @since 4.5.0
99 + * @since 4.5.0, 5.1.0 added $context
83 100 * @hook ep_network_capability
84 - * @param {bool} $capability Capability name. Defaults to `'manage_network_elasticpress'`
85 - * @return {bool} New capability value
101 + * @param {string} $capability Capability name. Defaults to `'manage_network_elasticpress'`
102 + * @param {string} $context Additional context
103 + * @return {string} New capability value
86 104 */
87 - return apply_filters( 'ep_network_capability', 'manage_network_elasticpress' );
105 + return apply_filters( 'ep_network_capability', 'manage_network_elasticpress', $context );
88 106 }
89 107
90 108 /**
91 109 * Get mapped capabilities for post types
92 110 *
93 - * @since 4.5.0
111 + * @since 4.5.0, 5.1.0 added $context
112 + * @param string $context Context for the capability. Defaults to empty string.
94 113 * @return array
95 114 */
96 -function get_post_map_capabilities() : array {
97 - $capability = get_capability();
115 +function get_post_map_capabilities( string $context = '' ): array {
116 + $capability = get_capability( $context );
98 117
99 118 return [
100 119 'edit_post' => $capability,
101 120 'edit_posts' => $capability,
@@ -165,9 +184,11 @@
165 184 * @since 2.6
166 185 * @return bool
167 186 */
168 187 function is_epio() {
169 - return filter_var( preg_match( '#elasticpress\.io#i', get_host() ), FILTER_VALIDATE_BOOLEAN );
188 + $has_url = filter_var( preg_match( '#elasticpress\.io#i', get_host() ), FILTER_VALIDATE_BOOLEAN );
189 + $has_env_var = '1' === getenv( 'IS_EPIO_ENVIRONMENT' );
190 + return $has_url || $has_env_var;
170 191 }
171 192
172 193 /**
173 194 * Determine if we should index a blog/site
@@ -182,8 +203,12 @@
182 203 }
183 204
184 205 $site = get_site( $blog_id );
185 206
207 + if ( empty( $site ) ) {
208 + return false;
209 + }
210 +
186 211 $is_indexable = get_site_meta( $site['blog_id'], 'ep_indexable', true );
187 212
188 213 return 'no' !== $is_indexable && ! $site['deleted'] && ! $site['archived'] && ! $site['spam'];
189 214 }
@@ -281,8 +306,12 @@
281 306 */
282 307 function get_site( $site_id ) {
283 308 $site = \get_site( $site_id );
284 309
310 + if ( ! $site instanceof \WP_Site ) {
311 + return [];
312 + }
313 +
285 314 return [
286 315 'blog_id' => $site->blog_id,
287 316 'domain' => $site->domain,
288 317 'path' => $site->path,
@@ -417,9 +446,9 @@
417 446 break;
418 447 }
419 448
420 449 foreach ( $all_terms as $key => $term ) {
421 - $iteration_id++;
450 + ++$iteration_id;
422 451
423 452 if ( ! isset( $term->children ) ) {
424 453 $term->children = [];
425 454 }
@@ -444,18 +473,17 @@
444 473 $terms_tree[ strtolower( $term->name ) ] = $term;
445 474 }
446 475
447 476 unset( $all_terms[ $key ] );
448 - } else {
449 - if ( ! empty( $terms_map[ $term->parent ] ) && isset( $terms_map[ $term->parent ]->level ) ) {
477 + } elseif ( ! empty( $terms_map[ $term->parent ] ) && isset( $terms_map[ $term->parent ]->level ) ) {
450 478
451 - if ( empty( $orderby ) ) {
452 - $terms_map[ $term->parent ]->children[] = $term;
453 - } elseif ( 'count' === $orderby ) {
454 - $terms_map[ $term->parent ]->children[ ( ( $term->count * 10000000 ) + $iteration_id ) ] = $term;
455 - } elseif ( 'name' === $orderby ) {
456 - $terms_map[ $term->parent ]->children[ $term->name ] = $term;
457 - }
479 + if ( empty( $orderby ) ) {
480 + $terms_map[ $term->parent ]->children[] = $term;
481 + } elseif ( 'count' === $orderby ) {
482 + $terms_map[ $term->parent ]->children[ ( ( $term->count * 10000000 ) + $iteration_id ) ] = $term;
483 + } elseif ( 'name' === $orderby ) {
484 + $terms_map[ $term->parent ]->children[ $term->name ] = $term;
485 + }
458 486
459 487 $parent_level = ( $terms_map[ $term->parent ]->level ) ? $terms_map[ $term->parent ]->level : 0;
460 488
461 489 $term->level = $parent_level + 1;
@@ -461,9 +489,8 @@
461 489 $term->level = $parent_level + 1;
462 490 $term->parent_term = $terms_map[ $term->parent ];
463 491
464 492 unset( $all_terms[ $key ] );
465 - }
466 493 }
467 494 }
468 495 }
469 496
@@ -576,9 +603,8 @@
576 603 }
577 604 }
578 605
579 606 return $index_status;
580 -
581 607 }
582 608
583 609 /**
584 610 * Use the correct update option function depending on the context (multisite or not)
@@ -601,9 +627,9 @@
601 627 *
602 628 * @since 3.6.0
603 629 * @param string $option Name of the option to get.
604 630 * @param mixed $default_value Default value.
605 - * @return bool
631 + * @return mixed
606 632 */
607 633 function get_option( $option, $default_value = false ) {
608 634 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
609 635 return \get_site_option( $option, $default_value );
@@ -655,9 +681,9 @@
655 681 $types = [ 'admin', 'ajax', 'public', 'rest' ];
656 682 }
657 683
658 684 $is_admin_request = is_admin();
659 - $is_ajax_request = defined( 'DOING_AJAX' ) && DOING_AJAX;
685 + $is_ajax_request = wp_doing_ajax();
660 686 $is_rest_request = defined( 'REST_REQUEST' ) && REST_REQUEST;
661 687 $is_integrated_admin_request = false;
662 688 $is_integrated_ajax_request = false;
663 689 $is_integrated_public_request = false;
@@ -747,15 +773,19 @@
747 773 /**
748 774 * Return the Sync Page URL.
749 775 *
750 776 * @since 4.4.0
751 - * @param boolean $do_sync Whether the link should or should not start a resync.
777 + * @param boolean|string $do_sync Whether the link should or should not start a resync. Pass a string to store the reason of the resync.
752 778 * @return string
753 779 */
754 -function get_sync_url( bool $do_sync = false ) : string {
780 +function get_sync_url( $do_sync = false ): string {
755 781 $page = 'admin.php?page=elasticpress-sync';
756 782 if ( $do_sync ) {
757 783 $page .= '&do_sync';
784 + if ( is_string( $do_sync ) ) {
785 + $page .= '=' . rawurlencode( $do_sync );
786 + }
787 + $page .= '&ep_sync_nonce=' . wp_create_nonce( 'ep_sync_nonce' );
758 788 }
759 789 return ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) ?
760 790 network_admin_url( $page ) :
761 791 admin_url( $page );
@@ -761,8 +791,18 @@
761 791 admin_url( $page );
762 792 }
763 793
764 794 /**
795 + * Check if the `do_sync` parameter is set and the nonce is valid.
796 + *
797 + * @since 5.1.2
798 + * @return boolean
799 + */
800 +function isset_do_sync_parameter(): bool {
801 + return isset( $_GET['do_sync'] ) && ! empty( $_GET['ep_sync_nonce'] ) && wp_verify_nonce( sanitize_key( $_GET['ep_sync_nonce'] ), 'ep_sync_nonce' );
802 +}
803 +
804 +/**
765 805 * Generate a common prefix to be used while generating a request ID.
766 806 *
767 807 * Uses the return of `get_index_prefix()` by default.
768 808 *
@@ -788,9 +828,9 @@
788 828 *
789 829 * @since 4.5.0
790 830 * @return string
791 831 */
792 -function generate_request_id() : string {
832 +function generate_request_id(): string {
793 833 $uuid = str_replace( '-', '', wp_generate_uuid4() );
794 834
795 835 /**
796 836 * Filter the ID generated to identify a request.
@@ -809,9 +849,9 @@
809 849 * @since 4.6.0
810 850 * @param mixed $response The Elasticsearch response
811 851 * @return string
812 852 */
813 -function get_elasticsearch_error_reason( $response ) : string {
853 +function get_elasticsearch_error_reason( $response ): string {
814 854 if ( is_string( $response ) ) {
815 855 return $response;
816 856 }
817 857
@@ -826,10 +866,17 @@
826 866 if ( ! empty( $response['result']['error'] ) && ! empty( $response['result']['error']['root_cause'][0]['reason'] ) ) {
827 867 return (string) $response['result']['error']['root_cause'][0]['reason'];
828 868 }
829 869
830 - if ( ! empty( $response['result']['errors'] ) && ! empty( $response['result']['items'] ) && ! empty( $response['result']['items'][0]['index']['error']['reason'] ) ) {
831 - return (string) $response['result']['items'][0]['index']['error']['reason'];
870 + if ( ! empty( $response['result']['errors'] ) && ! empty( $response['result']['items'] ) ) {
871 + $error = '';
872 + foreach ( $response['result']['items'] as $item ) {
873 + if ( ! empty( $item['index']['error']['reason'] ) ) {
874 + $error = $item['index']['error']['reason'];
875 + break;
876 + }
877 + }
878 + return $error;
832 879 }
833 880
834 881 return '';
835 882 }
@@ -877,5 +924,56 @@
877 924 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
878 925 return \delete_site_transient( $transient );
879 926 }
880 927 return \delete_transient( $transient );
928 +}
929 +
930 +/**
931 + * Whether we are in the top level admin context or not.
932 + *
933 + * In a single site, the top level admin context would be `is_admin()`,
934 + * in a multisite, it would be `is_network_admin()`.
935 + *
936 + * @since 5.0.0
937 + * @return boolean
938 + */
939 +function is_top_level_admin_context() {
940 + $is_network = defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK;
941 + return $is_network ? is_network_admin() : is_admin();
942 +}
943 +
944 +/**
945 + * Safely resolve the post type(s) for a taxonomy query.
946 + *
947 + * Guards against null queried objects, missing taxonomy properties,
948 + * deregistered taxonomies, and non-post-type object types that would
949 + * otherwise cause unexpected behavior when chaining
950 + * get_queried_object()->taxonomy through get_taxonomy().
951 + *
952 + * @since 5.3.3
953 + *
954 + * @param \WP_Query|null $query Optional. WP_Query instance. Defaults to the global query.
955 + * @return array Registered post type names on success, empty array otherwise.
956 + */
957 +function get_post_types_for_tax_query( ?\WP_Query $query = null ): array {
958 + global $wp_query;
959 +
960 + if ( null === $query ) {
961 + $query = $wp_query;
962 + }
963 +
964 + if ( ! $query instanceof \WP_Query || ! $query->is_tax() ) {
965 + return [];
966 + }
967 +
968 + $queried_object = $query->get_queried_object();
969 + if ( ! $queried_object || ! isset( $queried_object->taxonomy ) ) {
970 + return [];
971 + }
972 +
973 + $taxonomy_object = get_taxonomy( $queried_object->taxonomy );
974 + if ( ! $taxonomy_object || ! is_array( $taxonomy_object->object_type ) ) {
975 + return [];
976 + }
977 +
978 + return array_values( array_filter( $taxonomy_object->object_type, 'post_type_exists' ) );
881 979 }