← All changes
|
includes/classes/Feature/SearchOrdering/SearchOrdering.php
+36
-131
4.7.2
→
5.3.5
View file →
| @@ -10,8 +10,9 @@ | ||
| 10 | 10 | use ElasticPress\Feature; |
| 11 | 11 | use ElasticPress\FeatureRequirementsStatus; |
| 12 | 12 | use ElasticPress\Features; |
| 13 | 13 | use ElasticPress\Indexables; |
| 14 | +use ElasticPress\REST; | |
| 14 | 15 | use ElasticPress\Utils; |
| 15 | 16 | |
| 16 | 17 | if ( ! defined( 'ABSPATH' ) ) { |
| 17 | 18 | exit; // Exit if accessed directly. |
| @@ -50,17 +51,29 @@ | ||
| 50 | 51 | */ |
| 51 | 52 | public function __construct() { |
| 52 | 53 | $this->slug = 'searchordering'; |
| 53 | 54 | |
| 54 | - $this->title = esc_html__( 'Custom Search Results', 'elasticpress' ); | |
| 55 | + $this->group = 'core-search'; | |
| 55 | 56 | |
| 56 | - $this->summary = __( 'Insert specific posts into search results for specific search queries.', 'elasticpress' ); | |
| 57 | + $this->requires_install_reindex = false; | |
| 57 | 58 | |
| 58 | - $this->docs_url = __( 'https://elasticpress.zendesk.com/hc/en-us/articles/360050447492-Configuring-ElasticPress-via-the-Plugin-Dashboard#custom-search-results', 'elasticpress' ); | |
| 59 | + $this->requires_feature = 'search'; | |
| 59 | 60 | |
| 60 | - $this->requires_install_reindex = false; | |
| 61 | + parent::__construct(); | |
| 62 | + } | |
| 61 | 63 | |
| 62 | - parent::__construct(); | |
| 64 | + /** | |
| 65 | + * Sets i18n strings. | |
| 66 | + * | |
| 67 | + * @return void | |
| 68 | + * @since 5.2.0 | |
| 69 | + */ | |
| 70 | + public function set_i18n_strings(): void { | |
| 71 | + $this->title = esc_html__( 'Custom Search Results', 'elasticpress' ); | |
| 72 | + | |
| 73 | + $this->summary = '<p>' . __( 'Selected posts will be inserted into search results in the specified position.', 'elasticpress' ) . '</p>'; | |
| 74 | + | |
| 75 | + $this->docs_url = __( 'https://www.elasticpress.io/resources/articles/configuring-elasticpress-via-the-plugin-dashboard/#custom-search-results', 'elasticpress' ); | |
| 63 | 76 | } |
| 64 | 77 | |
| 65 | 78 | /** |
| 66 | 79 | * Setup Feature Functionality |
| @@ -71,9 +84,13 @@ | ||
| 71 | 84 | |
| 72 | 85 | /** Search Feature @var Feature\Search\Search $search */ |
| 73 | 86 | $search = $features->get_registered_feature( 'search' ); |
| 74 | 87 | |
| 75 | - if ( ! $search->is_active() && $this->is_active() ) { | |
| 88 | + if ( ! Utils\is_site_indexable() ) { | |
| 89 | + return false; | |
| 90 | + } | |
| 91 | + | |
| 92 | + if ( ( ! $search->is_active() && $this->is_active() ) ) { | |
| 76 | 93 | $features->deactivate_feature( $this->slug ); |
| 77 | 94 | return false; |
| 78 | 95 | } |
| 79 | 96 | |
| @@ -173,32 +190,13 @@ | ||
| 173 | 190 | * Requires the search feature to be activated |
| 174 | 191 | * |
| 175 | 192 | * @return FeatureRequirementsStatus |
| 176 | 193 | */ |
| 177 | - public function requirements_status() { | |
| 178 | - /** Features Class @var Features $features */ | |
| 179 | - $features = Features::factory(); | |
| 180 | - | |
| 181 | - /** Search Feature @var Feature\Search\Search $search */ | |
| 182 | - $search = $features->get_registered_feature( 'search' ); | |
| 183 | - | |
| 184 | - if ( ! $search->is_active() ) { | |
| 185 | - return new FeatureRequirementsStatus( 2, esc_html__( 'This feature requires the "Post Search" feature to be enabled', 'elasticpress' ) ); | |
| 186 | - } | |
| 187 | - | |
| 188 | - return parent::requirements_status(); | |
| 194 | + public function requirements_status(): FeatureRequirementsStatus { | |
| 195 | + return new FeatureRequirementsStatus( 0, null, $this ); | |
| 189 | 196 | } |
| 190 | 197 | |
| 191 | 198 | /** |
| 192 | - * Output feature box long | |
| 193 | - */ | |
| 194 | - public function output_feature_box_long() { | |
| 195 | - ?> | |
| 196 | - <p><?php esc_html_e( 'Selected posts will be inserted into search results in the specified position.', 'elasticpress' ); ?></p> | |
| 197 | - <?php | |
| 198 | - } | |
| 199 | - | |
| 200 | - /** | |
| 201 | 199 | * Adds this taxonomy as one of the taxonomies to index |
| 202 | 200 | * |
| 203 | 201 | * @param array $taxonomies Current indexable taxonomies |
| 204 | 202 | * |
| @@ -217,9 +215,9 @@ | ||
| 217 | 215 | add_submenu_page( |
| 218 | 216 | 'elasticpress', |
| 219 | 217 | esc_html__( 'Custom Results', 'elasticpress' ), |
| 220 | 218 | esc_html__( 'Custom Results', 'elasticpress' ), |
| 221 | - Utils\get_capability(), | |
| 219 | + Utils\get_capability( 'search-ordering' ), | |
| 222 | 220 | 'edit.php?post_type=' . self::POST_TYPE_NAME |
| 223 | 221 | ); |
| 224 | 222 | } |
| 225 | 223 | |
| @@ -270,11 +268,8 @@ | ||
| 270 | 268 | /** |
| 271 | 269 | * Registers the pointer post type for the injected results |
| 272 | 270 | */ |
| 273 | 271 | public function register_post_type() { |
| 274 | - $is_network = defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK; | |
| 275 | - $menu = $is_network ? null : false; | |
| 276 | - | |
| 277 | 272 | $labels = array( |
| 278 | 273 | 'name' => esc_html_x( 'Custom Search Results', 'post type general name', 'elasticpress' ), |
| 279 | 274 | 'singular_name' => esc_html_x( 'Custom Search Result', 'post type singular name', 'elasticpress' ), |
| 280 | 275 | 'menu_name' => esc_html_x( 'Custom Search Results', 'admin menu', 'elasticpress' ), |
| @@ -296,18 +291,18 @@ | ||
| 296 | 291 | 'description' => esc_html__( 'Posts to inject into search results', 'elasticpress' ), |
| 297 | 292 | 'public' => false, |
| 298 | 293 | 'publicly_queryable' => false, |
| 299 | 294 | 'show_ui' => true, |
| 300 | - 'show_in_menu' => $menu, | |
| 295 | + 'show_in_menu' => false, | |
| 301 | 296 | 'query_var' => true, |
| 302 | 297 | 'rewrite' => array( 'slug' => 'ep-pointer' ), |
| 303 | - 'capabilities' => Utils\get_post_map_capabilities(), | |
| 298 | + 'capabilities' => Utils\get_post_map_capabilities( 'search-ordering' ), | |
| 304 | 299 | 'has_archive' => false, |
| 305 | 300 | 'hierarchical' => false, |
| 306 | 301 | 'menu_position' => 100, |
| 307 | 302 | 'supports' => [ 'title' ], |
| 308 | 303 | 'register_meta_box_cb' => [ $this, 'register_meta_box' ], |
| 309 | - 'menu_icon' => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNzMgNzEuMyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNzMgNzEuMzsiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGQ9Ik0zNi41LDQuN0MxOS40LDQuNyw1LjYsMTguNiw1LjYsMzUuN2MwLDEwLDQuNywxOC45LDEyLjEsMjQuNWw0LjUtNC41YzAuMS0wLjEsMC4xLTAuMiwwLjItMC4zbDAuNy0wLjdsNi40LTYuNGMyLjEsMS4yLDQuNSwxLjksNy4xLDEuOWM4LDAsMTQuNS02LjUsMTQuNS0xNC41cy02LjUtMTQuNS0xNC41LTE0LjVTMjIsMjcuNiwyMiwzNS42YzAsMi44LDAuOCw1LjMsMi4xLDcuNWwtNi40LDYuNGMtMi45LTMuOS00LjYtOC43LTQuNi0xMy45YzAtMTIuOSwxMC41LTIzLjQsMjMuNC0yMy40czIzLjQsMTAuNSwyMy40LDIzLjRTNDkuNCw1OSwzNi41LDU5Yy0yLjEsMC00LjEtMC4zLTYtMC44bC0wLjYsMC42bC01LjIsNS40YzMuNiwxLjUsNy42LDIuMywxMS44LDIuM2MxNy4xLDAsMzAuOS0xMy45LDMwLjktMzAuOVM1My42LDQuNywzNi41LDQuN3oiLz48L3N2Zz4=', | |
| 304 | + 'menu_icon' => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNzMgNzEuMyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNzMgNzEuMzsiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGQ9Ik0zNi41LDQuN0MxOS40LDQuNyw1LjYsMTguNiw1LjYsMzUuN2MwLDEwLDQuNywxOC45LDEyLjEsMjQuNWw0LjUtNC41YzAuMS0wLjEsMC4xLTAuMiwwLjItMC4zbDAuNy0wLjdsNi40LTYuNGMyLjEsMS4yLDQuNSwxLjksNy4xLDEuOWM4LDAsMTQuNS02LjUsMTQuNS0xNC41cy02LjUtMTQuNS0xNC41LTE0LjVTMjIsMjcuNiwyMiwzNS42YzAsMi44LDAuOCw1LjMsMi4xLDcuNWwtNi40LDYuNGMtMi45LTMuOS00LjYtOC43LTQuNi0xMy45YzAtMTIuOSwxMC41LTIzLjQsMjMuNC0yMy40czIzLjQsMTAuNSwyMy40LDIzLjRTNDkuNCw1OSwzNi41LDU5Yy0yLjEsMC00LjEtMC4zLTYtMC44bC0wLjYsMC42bC01LjIsNS40YzMuNiwxLjUsNy42LDIuMywxMS44LDIuM2MxNy4xLDAsMzAuOS0xMy45LDMwLjktMzAuOVM1My42LDQuNywzNi41LDQuN3oiIGZpbGw9IiNhN2FhYWQiLz48L3N2Zz4=', | |
| 310 | 305 | ); |
| 311 | 306 | |
| 312 | 307 | register_post_type( self::POST_TYPE_NAME, $args ); |
| 313 | 308 | |
| @@ -332,8 +327,9 @@ | ||
| 332 | 327 | 'show_ui' => false, |
| 333 | 328 | 'show_admin_column' => false, |
| 334 | 329 | 'query_var' => false, |
| 335 | 330 | 'rewrite' => false, |
| 331 | + 'public' => false, | |
| 336 | 332 | ); |
| 337 | 333 | |
| 338 | 334 | /** Features Class @var Features $features */ |
| 339 | 335 | $features = Features::factory(); |
| @@ -496,8 +492,9 @@ | ||
| 496 | 492 | if ( intval( $order_data['order'] ) <= $posts_per_page ) { |
| 497 | 493 | $final_order_data[] = [ |
| 498 | 494 | 'ID' => intval( $order_data['ID'] ), |
| 499 | 495 | 'order' => intval( $order_data['order'] ), |
| 496 | + 'type' => ! empty( $order_data['type'] ) ? sanitize_text_field( $order_data['type'] ) : 'reordered', | |
| 500 | 497 | ]; |
| 501 | 498 | } else { |
| 502 | 499 | $previous_post_ids[ intval( $order_data['ID'] ) ] = true; |
| 503 | 500 | } |
| @@ -657,15 +654,14 @@ | ||
| 657 | 654 | |
| 658 | 655 | $to_inject = array(); |
| 659 | 656 | |
| 660 | 657 | foreach ( $posts as $key => &$post ) { |
| 661 | - if ( isset( $post->terms ) && isset( $post->terms[ self::TAXONOMY_NAME ] ) ) { | |
| 662 | - foreach ( $post->terms[ self::TAXONOMY_NAME ] as $current_term ) { | |
| 658 | + $terms = is_string( $post->terms ) ? json_decode( wp_specialchars_decode( $post->terms, ENT_QUOTES ), true ) : (array) $post->terms; | |
| 659 | + if ( isset( $terms[ self::TAXONOMY_NAME ] ) ) { | |
| 660 | + foreach ( $terms[ self::TAXONOMY_NAME ] as $current_term ) { | |
| 663 | 661 | if ( strtolower( $current_term['name'] ) === $search_query ) { |
| 664 | 662 | $to_inject[ $current_term['term_order'] ] = $post; |
| 665 | - | |
| 666 | 663 | unset( $posts[ $key ] ); |
| 667 | - | |
| 668 | 664 | break; |
| 669 | 665 | } |
| 670 | 666 | } |
| 671 | 667 | } |
| @@ -693,103 +689,13 @@ | ||
| 693 | 689 | /** |
| 694 | 690 | * Registers the API endpoint for searching from the admin interface |
| 695 | 691 | */ |
| 696 | 692 | public function rest_api_init() { |
| 697 | - register_rest_route( | |
| 698 | - 'elasticpress/v1', | |
| 699 | - 'pointer_search', | |
| 700 | - [ | |
| 701 | - 'methods' => 'GET', | |
| 702 | - 'callback' => [ $this, 'handle_pointer_search' ], | |
| 703 | - 'permission_callback' => function() { | |
| 704 | - return current_user_can( Utils\get_capability() ); | |
| 705 | - }, | |
| 706 | - 'args' => [ | |
| 707 | - 's' => [ | |
| 708 | - 'validate_callback' => function ( $param ) { | |
| 709 | - return ! empty( $param ); | |
| 710 | - }, | |
| 711 | - 'required' => true, | |
| 712 | - ], | |
| 713 | - ], | |
| 714 | - ] | |
| 715 | - ); | |
| 716 | - | |
| 717 | - register_rest_route( | |
| 718 | - 'elasticpress/v1', | |
| 719 | - 'pointer_preview', | |
| 720 | - [ | |
| 721 | - 'methods' => 'GET', | |
| 722 | - 'callback' => [ $this, 'handle_pointer_preview' ], | |
| 723 | - 'permission_callback' => function() { | |
| 724 | - return current_user_can( Utils\get_capability() ); | |
| 725 | - }, | |
| 726 | - 'args' => [ | |
| 727 | - 's' => [ | |
| 728 | - 'validate_callback' => function ( $param ) { | |
| 729 | - return ! empty( $param ); | |
| 730 | - }, | |
| 731 | - 'required' => true, | |
| 732 | - ], | |
| 733 | - ], | |
| 734 | - ] | |
| 735 | - ); | |
| 693 | + $controller = new REST\SearchOrdering(); | |
| 694 | + $controller->register_routes(); | |
| 736 | 695 | } |
| 737 | 696 | |
| 738 | 697 | /** |
| 739 | - * Handles the search for posts from the admin interface for the post type | |
| 740 | - * | |
| 741 | - * @param \WP_REST_Request $request Rest request | |
| 742 | - * | |
| 743 | - * @return array | |
| 744 | - */ | |
| 745 | - public function handle_pointer_search( $request ) { | |
| 746 | - $search = $request->get_param( 's' ); | |
| 747 | - | |
| 748 | - /** Features Class @var Features $features */ | |
| 749 | - $features = Features::factory(); | |
| 750 | - | |
| 751 | - /** Search Feature @var Feature\Search\Search $search */ | |
| 752 | - $search_feature = $features->get_registered_feature( 'search' ); | |
| 753 | - | |
| 754 | - $post_types = $search_feature->get_searchable_post_types(); | |
| 755 | - | |
| 756 | - $query = new \WP_Query( | |
| 757 | - [ | |
| 758 | - 'post_type' => $post_types, | |
| 759 | - 'post_status' => 'publish', | |
| 760 | - 's' => $search, | |
| 761 | - ] | |
| 762 | - ); | |
| 763 | - | |
| 764 | - return $query->posts; | |
| 765 | - } | |
| 766 | - | |
| 767 | - /** | |
| 768 | - * Handles the search preview on the pointer edit screen | |
| 769 | - * | |
| 770 | - * @param \WP_REST_Request $request Rest request | |
| 771 | - * | |
| 772 | - * @return array | |
| 773 | - */ | |
| 774 | - public function handle_pointer_preview( $request ) { | |
| 775 | - remove_filter( 'ep_searchable_post_types', [ $this, 'searchable_post_types' ] ); | |
| 776 | - | |
| 777 | - $search = $request->get_param( 's' ); | |
| 778 | - | |
| 779 | - $query = new \WP_Query( | |
| 780 | - [ | |
| 781 | - 's' => $search, | |
| 782 | - 'exclude_pointers' => true, | |
| 783 | - ] | |
| 784 | - ); | |
| 785 | - | |
| 786 | - add_filter( 'ep_searchable_post_types', [ $this, 'searchable_post_types' ] ); | |
| 787 | - | |
| 788 | - return $query->posts; | |
| 789 | - } | |
| 790 | - | |
| 791 | - /** | |
| 792 | 698 | * Removes taxonomy terms from the references posts when a pointer is deleted or trashed |
| 793 | 699 | * |
| 794 | 700 | * @param int $post_id Post ID that is being deleted |
| 795 | 701 | */ |
| @@ -889,6 +795,5 @@ | ||
| 889 | 795 | } |
| 890 | 796 | |
| 891 | 797 | return $admin_title; |
| 892 | 798 | } |
| 893 | - | |
| 894 | 799 | } |