| @@ -6,14 +6,14 @@ | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | namespace ElasticPress\Feature\Search; |
| 9 | 9 | |
| 10 | -use ElasticPress\Feature; | |
| 10 | +use ElasticPress\Elasticsearch; | |
| 11 | +use ElasticPress\FeatureRequirementsStatus; | |
| 11 | 12 | use ElasticPress\Features; |
| 12 | 13 | use ElasticPress\Indexables; |
| 13 | -use ElasticPress\Elasticsearch; | |
| 14 | -use ElasticPress\FeatureRequirementsStatus; | |
| 15 | -use ElasticPress\Utils as Utils; | |
| 14 | +use ElasticPress\REST; | |
| 15 | +use ElasticPress\Utils; | |
| 16 | 16 | |
| 17 | 17 | if ( ! defined( 'ABSPATH' ) ) { |
| 18 | 18 | exit; // Exit if accessed directly. |
| 19 | 19 | } |
| @@ -82,15 +82,17 @@ | ||
| 82 | 82 | * |
| 83 | 83 | * @return FeatureRequirementsStatus |
| 84 | 84 | */ |
| 85 | 85 | public function requirements_status() { |
| 86 | + $status = new FeatureRequirementsStatus( 0, null, $this ); | |
| 86 | 87 | $search = $this->get_search_feature(); |
| 87 | 88 | |
| 88 | 89 | if ( ! $search->is_active() ) { |
| 89 | - return new FeatureRequirementsStatus( 2, esc_html__( 'This feature requires the "Post Search" feature to be enabled', 'elasticpress' ) ); | |
| 90 | + $status->code = 2; | |
| 91 | + $status->message = esc_html__( 'This feature requires the "Post Search" feature to be enabled', 'elasticpress' ); | |
| 90 | 92 | } |
| 91 | 93 | |
| 92 | - return new FeatureRequirementsStatus( 0 ); | |
| 94 | + return $status; | |
| 93 | 95 | } |
| 94 | 96 | |
| 95 | 97 | /** |
| 96 | 98 | * Setup Feature Functionality |
| @@ -97,9 +99,9 @@ | ||
| 97 | 99 | * |
| 98 | 100 | * @return bool |
| 99 | 101 | */ |
| 100 | 102 | public function setup() { |
| 101 | - if ( (bool) $this->requirements_status()->code ) { | |
| 103 | + if ( (bool) $this->requirements_status()->get_code() ) { | |
| 102 | 104 | return false; |
| 103 | 105 | } |
| 104 | 106 | |
| 105 | 107 | // Register a post type to hold the synonyms post. |
| @@ -108,18 +110,14 @@ | ||
| 108 | 110 | // Setup the UI. |
| 109 | 111 | add_action( 'admin_menu', [ $this, 'admin_menu' ], 50 ); |
| 110 | 112 | add_action( 'admin_enqueue_scripts', [ $this, 'scripts' ] ); |
| 111 | 113 | |
| 112 | - // Handle the update synonyms action. | |
| 113 | - $action = $this->get_action(); | |
| 114 | - add_action( "admin_post_$action", [ $this, 'handle_update_synonyms' ] ); | |
| 115 | - | |
| 116 | - // Handle the admin notices. | |
| 117 | - add_action( 'admin_notices', [ $this, 'admin_notices' ] ); | |
| 118 | - | |
| 119 | 114 | // Add the synonyms to the elasticsearch query. |
| 120 | 115 | add_filter( 'ep_config_mapping', [ $this, 'add_search_synonyms' ], 20, 2 ); |
| 121 | 116 | |
| 117 | + // Register REST routes. | |
| 118 | + add_action( 'rest_api_init', [ $this, 'setup_endpoint' ] ); | |
| 119 | + | |
| 122 | 120 | return true; |
| 123 | 121 | } |
| 124 | 122 | |
| 125 | 123 | /** |
| @@ -133,31 +131,46 @@ | ||
| 133 | 131 | } |
| 134 | 132 | |
| 135 | 133 | wp_enqueue_script( |
| 136 | 134 | 'ep_synonyms_scripts', |
| 137 | - EP_URL . 'dist/js/synonyms-script.min.js', | |
| 135 | + EP_URL . 'dist/js/synonyms-script.js', | |
| 138 | 136 | Utils\get_asset_info( 'synonyms-script', 'dependencies' ), |
| 139 | 137 | Utils\get_asset_info( 'synonyms-script', 'version' ), |
| 140 | 138 | true |
| 141 | 139 | ); |
| 142 | 140 | |
| 141 | + wp_set_script_translations( 'ep_synonyms_scripts', 'elasticpress' ); | |
| 142 | + | |
| 143 | 143 | wp_enqueue_style( 'wp-edit-post' ); |
| 144 | 144 | |
| 145 | 145 | wp_enqueue_style( |
| 146 | + 'ep_synonyms_scripts', | |
| 147 | + EP_URL . 'dist/css/synonyms-script.css', | |
| 148 | + [ 'wp-components', 'wp-edit-post' ], | |
| 149 | + Utils\get_asset_info( 'synonyms-styles', 'version' ), | |
| 150 | + 'all' | |
| 151 | + ); | |
| 152 | + | |
| 153 | + wp_enqueue_style( | |
| 146 | 154 | 'ep_synonyms_styles', |
| 147 | - EP_URL . 'dist/css/synonyms-styles.min.css', | |
| 155 | + EP_URL . 'dist/css/synonyms-styles.css', | |
| 148 | 156 | Utils\get_asset_info( 'synonyms-styles', 'dependencies' ), |
| 149 | 157 | Utils\get_asset_info( 'synonyms-styles', 'version' ), |
| 150 | 158 | 'all' |
| 151 | 159 | ); |
| 152 | 160 | |
| 161 | + $api_url = rest_url( 'elasticpress/v1/synonyms' ); | |
| 162 | + $sync_url = Utils\get_sync_url(); | |
| 163 | + | |
| 153 | 164 | wp_localize_script( |
| 154 | 165 | 'ep_synonyms_scripts', |
| 155 | 166 | 'epSynonyms', |
| 156 | - array( | |
| 157 | - 'i18n' => $this->get_localized_strings(), | |
| 158 | - 'data' => $this->get_localized_data(), | |
| 159 | - ) | |
| 167 | + [ | |
| 168 | + 'apiUrl' => esc_url_raw( $api_url ), | |
| 169 | + 'defaultIsSolr' => $this->synonyms_editor_mode() === 'advanced', | |
| 170 | + 'defaultSolr' => $this->get_synonyms_raw(), | |
| 171 | + 'syncUrl' => esc_url_raw( $sync_url ), | |
| 172 | + ] | |
| 160 | 173 | ); |
| 161 | 174 | } |
| 162 | 175 | |
| 163 | 176 | /** |
| @@ -169,9 +182,9 @@ | ||
| 169 | 182 | add_submenu_page( |
| 170 | 183 | 'elasticpress', |
| 171 | 184 | esc_html__( 'ElasticPress Synonyms', 'elasticpress' ), |
| 172 | 185 | esc_html__( 'Synonyms', 'elasticpress' ), |
| 173 | - 'manage_options', | |
| 186 | + Utils\get_capability( 'synonyms' ), | |
| 174 | 187 | 'elasticpress-synonyms', |
| 175 | 188 | [ $this, 'admin_page' ] |
| 176 | 189 | ); |
| 177 | 190 | } |
| @@ -185,12 +198,9 @@ | ||
| 185 | 198 | include EP_PATH . '/includes/partials/header.php'; |
| 186 | 199 | |
| 187 | 200 | ?> |
| 188 | 201 | <div class="wrap"> |
| 189 | - <form action="<?php echo esc_url( $this->get_form_action() ); ?>" method="POST"> | |
| 190 | - <?php $this->form_hidden_fields(); ?> | |
| 191 | - <div id="synonym-root"></div> | |
| 192 | - </form> | |
| 202 | + <div id="ep-synonyms"></div> | |
| 193 | 203 | </div> |
| 194 | 204 | <?php |
| 195 | 205 | } |
| 196 | 206 | |
| @@ -197,10 +207,13 @@ | ||
| 197 | 207 | /** |
| 198 | 208 | * Admin notices. |
| 199 | 209 | * |
| 200 | 210 | * @return void |
| 211 | + * @deprecated 5.1.0 | |
| 201 | 212 | */ |
| 202 | 213 | public function admin_notices() { |
| 214 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::admin_notices', '5.1.0' ); | |
| 215 | + | |
| 203 | 216 | if ( ! $this->is_synonym_page() ) { |
| 204 | 217 | return; |
| 205 | 218 | } |
| 206 | 219 | |
| @@ -246,9 +259,9 @@ | ||
| 246 | 259 | 'publicly_queryable' => false, |
| 247 | 260 | 'show_ui' => false, |
| 248 | 261 | 'show_in_menu' => false, |
| 249 | 262 | 'query_var' => true, |
| 250 | - 'capability_type' => 'post', | |
| 263 | + 'capabilities' => Utils\get_post_map_capabilities( 'synonyms' ), | |
| 251 | 264 | 'has_archive' => false, |
| 252 | 265 | 'hierarchical' => false, |
| 253 | 266 | 'menu_position' => 100, |
| 254 | 267 | 'supports' => [ 'title' ], |
| @@ -307,9 +320,9 @@ | ||
| 307 | 320 | public function get_synonyms() { |
| 308 | 321 | $synonyms_raw = $this->get_synonyms_raw(); |
| 309 | 322 | $synonyms = array_values( |
| 310 | 323 | array_filter( |
| 311 | - array_map( [ $this, 'validate_synonym' ], explode( PHP_EOL, $synonyms_raw ) ) | |
| 324 | + array_map( [ $this, 'validate_synonym' ], preg_split( '/\r\n|\r|\n/', $synonyms_raw ) ) | |
| 312 | 325 | ) |
| 313 | 326 | ); |
| 314 | 327 | |
| 315 | 328 | /** |
| @@ -376,10 +389,10 @@ | ||
| 376 | 389 | return $mapping; |
| 377 | 390 | } |
| 378 | 391 | |
| 379 | 392 | // Ensure we have analyzers and that it is an array. |
| 380 | - if ( ! isset( $mapping['settings']['analysis']['analyzer']['default']['filter'] ) | |
| 381 | - || ! is_array( $mapping['settings']['analysis']['analyzer']['default']['filter'] ) | |
| 393 | + if ( ! isset( $mapping['settings']['analysis']['analyzer']['default_search']['filter'] ) | |
| 394 | + || ! is_array( $mapping['settings']['analysis']['analyzer']['default_search']['filter'] ) | |
| 382 | 395 | ) { |
| 383 | 396 | return $mapping; |
| 384 | 397 | } |
| 385 | 398 | |
| @@ -386,12 +399,14 @@ | ||
| 386 | 399 | // Create a custom synonym filter for EP. |
| 387 | 400 | $mapping['settings']['analysis']['filter'][ $filter_name ] = $this->get_synonym_filter(); |
| 388 | 401 | |
| 389 | 402 | // Tell the analyzer to use our newly created filter. |
| 390 | - $mapping['settings']['analysis']['analyzer']['default']['filter'] = array_values( | |
| 391 | - array_merge( | |
| 392 | - [ $filter_name ], | |
| 393 | - $mapping['settings']['analysis']['analyzer']['default']['filter'] | |
| 403 | + $mapping['settings']['analysis']['analyzer']['default_search']['filter'] = $this->maybe_change_filter_position( | |
| 404 | + array_values( | |
| 405 | + array_merge( | |
| 406 | + [ $filter_name ], | |
| 407 | + $mapping['settings']['analysis']['analyzer']['default_search']['filter'], | |
| 408 | + ) | |
| 394 | 409 | ) |
| 395 | 410 | ); |
| 396 | 411 | |
| 397 | 412 | return $mapping; |
| @@ -400,13 +415,17 @@ | ||
| 400 | 415 | /** |
| 401 | 416 | * Handles updating the synonym list. |
| 402 | 417 | * |
| 403 | 418 | * @return void |
| 419 | + * @deprecated 5.1.0 | |
| 404 | 420 | */ |
| 405 | 421 | public function handle_update_synonyms() { |
| 422 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::handle_update_synonyms', '5.1.0' ); | |
| 423 | + | |
| 406 | 424 | $nonce = filter_input( INPUT_POST, $this->get_nonce_field(), FILTER_SANITIZE_SPECIAL_CHARS ); |
| 407 | 425 | $referer = filter_input( INPUT_POST, '_wp_http_referer', FILTER_SANITIZE_URL ); |
| 408 | 426 | $post_id = false; |
| 427 | + $update = false; | |
| 409 | 428 | |
| 410 | 429 | if ( wp_verify_nonce( $nonce, $this->get_nonce_action() ) ) { |
| 411 | 430 | $synonyms = filter_input( INPUT_POST, $this->get_synonym_field(), FILTER_CALLBACK, [ 'options' => 'wp_strip_all_tags' ] ); |
| 412 | 431 | $mode = filter_input( INPUT_POST, 'synonyms_editor_mode', FILTER_SANITIZE_SPECIAL_CHARS ); |
| @@ -457,13 +476,18 @@ | ||
| 457 | 476 | */ |
| 458 | 477 | public function update_synonyms() { |
| 459 | 478 | return array_reduce( |
| 460 | 479 | $this->get_affected_indices(), |
| 461 | - function( $success, $index ) { | |
| 480 | + function ( $success, $index ) { | |
| 462 | 481 | $filter = $this->get_synonym_filter(); |
| 463 | 482 | $mapping = Elasticsearch::factory()->get_mapping( $index ); |
| 464 | - $filters = $mapping[ $index ]['settings']['index']['analysis']['analyzer']['default']['filter']; | |
| 465 | 483 | |
| 484 | + if ( empty( $mapping ) || empty( $mapping[ $index ] ) ) { | |
| 485 | + return false; | |
| 486 | + } | |
| 487 | + | |
| 488 | + $filters = (array) $mapping[ $index ]['settings']['index']['analysis']['analyzer']['default_search']['filter']; | |
| 489 | + | |
| 466 | 490 | /* |
| 467 | 491 | * Due to limitations in Elasticsearch, we can't remove the filter and analyzer |
| 468 | 492 | * once set on the index settings and synonyms array can't be empty. So we set a |
| 469 | 493 | * fallback synonyms array here if the user supplied synonym array is empty. |
| @@ -475,13 +499,15 @@ | ||
| 475 | 499 | // Construct the synonym filter. |
| 476 | 500 | $setting['index']['analysis']['filter']['ep_synonyms_filter'] = $filter; |
| 477 | 501 | |
| 478 | 502 | // Add the analyzer. |
| 479 | - $setting['index']['analysis']['analyzer']['default']['filter'] = array_values( | |
| 480 | - array_unique( | |
| 481 | - array_merge( | |
| 482 | - [ $this->get_synonym_filter_name() ], | |
| 483 | - $filters | |
| 503 | + $setting['index']['analysis']['analyzer']['default_search']['filter'] = $this->maybe_change_filter_position( | |
| 504 | + array_values( | |
| 505 | + array_unique( | |
| 506 | + array_merge( | |
| 507 | + [ $this->get_synonym_filter_name() ], | |
| 508 | + $filters | |
| 509 | + ) | |
| 484 | 510 | ) |
| 485 | 511 | ) |
| 486 | 512 | ); |
| 487 | 513 | |
| @@ -507,9 +533,9 @@ | ||
| 507 | 533 | $indices = apply_filters( 'ep_synonyms_affected_indices', $this->affected_indices ); |
| 508 | 534 | |
| 509 | 535 | return array_filter( |
| 510 | 536 | array_map( |
| 511 | - function( $index ) { | |
| 537 | + function ( $index ) { | |
| 512 | 538 | $indexable = Indexables::factory()->get( $index ); |
| 513 | 539 | return $indexable ? $indexable->get_index_name() : false; |
| 514 | 540 | }, |
| 515 | 541 | $indices |
| @@ -558,10 +584,13 @@ | ||
| 558 | 584 | * Get form action for admin page. |
| 559 | 585 | * |
| 560 | 586 | * @access protected |
| 561 | 587 | * @return string The admin post form action url. |
| 588 | + * @deprecated 5.1.0 | |
| 562 | 589 | */ |
| 563 | 590 | public function get_form_action() { |
| 591 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_form_action', '5.1.0' ); | |
| 592 | + | |
| 564 | 593 | return esc_url_raw( admin_url( 'admin-post.php' ) ); |
| 565 | 594 | } |
| 566 | 595 | |
| 567 | 596 | /** |
| @@ -567,10 +596,13 @@ | ||
| 567 | 596 | /** |
| 568 | 597 | * Render admin page form hidden fields. |
| 569 | 598 | * |
| 570 | 599 | * @return void |
| 600 | + * @deprecated 5.1.0 | |
| 571 | 601 | */ |
| 572 | 602 | public function form_hidden_fields() { |
| 603 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_form_action', '5.1.0', ); | |
| 604 | + | |
| 573 | 605 | wp_nonce_field( $this->get_nonce_action(), $this->get_nonce_field() ); |
| 574 | 606 | ?> |
| 575 | 607 | <input type="hidden" name="action" value="<?php echo esc_attr( $this->get_action() ); ?>" /> |
| 576 | 608 | <?php |
| @@ -579,10 +611,13 @@ | ||
| 579 | 611 | /** |
| 580 | 612 | * Get nonce action for admin page form. |
| 581 | 613 | * |
| 582 | 614 | * @return string |
| 615 | + * @deprecated 5.1.0 | |
| 583 | 616 | */ |
| 584 | 617 | public function get_nonce_action() { |
| 618 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_form_action', '5.1.0', ); | |
| 619 | + | |
| 585 | 620 | return $this->get_action(); |
| 586 | 621 | } |
| 587 | 622 | |
| 588 | 623 | /** |
| @@ -588,10 +623,13 @@ | ||
| 588 | 623 | /** |
| 589 | 624 | * Get nonce field for admin page form. |
| 590 | 625 | * |
| 591 | 626 | * @return string |
| 627 | + * @deprecated 5.1.0 | |
| 592 | 628 | */ |
| 593 | 629 | public function get_nonce_field() { |
| 630 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_nonce_field', '5.1.0', ); | |
| 631 | + | |
| 594 | 632 | return 'ep_synonyms_nonce'; |
| 595 | 633 | } |
| 596 | 634 | |
| 597 | 635 | /** |
| @@ -597,10 +635,13 @@ | ||
| 597 | 635 | /** |
| 598 | 636 | * Get synonym field name for admin page form. |
| 599 | 637 | * |
| 600 | 638 | * @return string |
| 639 | + * @deprecated 5.1.0 | |
| 601 | 640 | */ |
| 602 | 641 | public function get_synonym_field() { |
| 642 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_synonym_field', '5.1.0', ); | |
| 643 | + | |
| 603 | 644 | return 'ep_synonyms'; |
| 604 | 645 | } |
| 605 | 646 | |
| 606 | 647 | /** |
| @@ -606,10 +647,13 @@ | ||
| 606 | 647 | /** |
| 607 | 648 | * Get the action slug for admin page form. |
| 608 | 649 | * |
| 609 | 650 | * @return string |
| 651 | + * @deprecated 5.1.0 | |
| 610 | 652 | */ |
| 611 | 653 | public function get_action() { |
| 654 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_action', '5.1.0', ); | |
| 655 | + | |
| 612 | 656 | return 'ep_synonyms_update'; |
| 613 | 657 | } |
| 614 | 658 | |
| 615 | 659 | /** |
| @@ -633,13 +677,18 @@ | ||
| 633 | 677 | * @return string |
| 634 | 678 | */ |
| 635 | 679 | public function example_synonym_list( $as_array = false ) { |
| 636 | 680 | $lines = [ |
| 637 | - __( '# Defined sets ( equivalent synonyms).', 'elasticpress' ), | |
| 638 | - 'sneakers, tennis shoes, trainers, runners', | |
| 681 | + __( '# Defined synonyms.', 'elasticpress' ), | |
| 682 | + 'runner, running shoe, sneaker, tennis shoe, trainer', | |
| 639 | 683 | '', |
| 640 | - __( '# Defined alternatives (explicit mappings).', 'elasticpress' ), | |
| 641 | - 'shoes => sneaker, sandal, boots, high heels', | |
| 684 | + __( '# Defined hyponyms.', 'elasticpress' ), | |
| 685 | + 'blue => blue, aqua, azure, cerulean, cyan, ultramarine', | |
| 686 | + '', | |
| 687 | + __( '# Defined replacements.', 'elasticpress' ), | |
| 688 | + 'supposably => supposedly', | |
| 689 | + 'flustrated => flustered, frustrated', | |
| 690 | + 'intensive purposes => intents and purposes', | |
| 642 | 691 | ]; |
| 643 | 692 | |
| 644 | 693 | return $as_array ? $lines : implode( PHP_EOL, $lines ); |
| 645 | 694 | } |
| @@ -647,10 +696,13 @@ | ||
| 647 | 696 | /** |
| 648 | 697 | * Gets localized strings for use on the front end. |
| 649 | 698 | * |
| 650 | 699 | * @return array |
| 700 | + * @deprecated 5.1.0 | |
| 651 | 701 | */ |
| 652 | 702 | public function get_localized_strings() { |
| 703 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_localized_strings', '5.1.0' ); | |
| 704 | + | |
| 653 | 705 | return array( |
| 654 | 706 | 'pageHeading' => __( 'Manage Synonyms', 'elasticpress' ), |
| 655 | 707 | 'pageDescription' => __( 'Synonyms enable more flexible search results that show relevant results even without an exact match. Synonyms can be defined as a sets where all words are synonyms for each other, or as alternatives where searches for the primary word will also match the rest, but no vice versa.', 'elasticpress' ), |
| 656 | 708 | 'pageToggleAdvanceText' => __( 'Switch to Advanced Text Editor', 'elasticpress' ), |
| @@ -685,10 +737,13 @@ | ||
| 685 | 737 | /** |
| 686 | 738 | * Get data to export to the frontend with localization strings. |
| 687 | 739 | * |
| 688 | 740 | * @return array |
| 741 | + * @deprecated 5.1.0 | |
| 689 | 742 | */ |
| 690 | 743 | public function get_localized_data() { |
| 744 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::get_localized_strings', '5.1.0' ); | |
| 745 | + | |
| 691 | 746 | $data = array( |
| 692 | 747 | 'sets' => array(), |
| 693 | 748 | 'alternatives' => array(), |
| 694 | 749 | 'initialMode' => $this->synonyms_editor_mode(), |
| @@ -769,10 +824,13 @@ | ||
| 769 | 824 | * |
| 770 | 825 | * @param string $token The synonym token to prepare. |
| 771 | 826 | * @param boolean $primary Whether this string is the primary term of an alternative. |
| 772 | 827 | * @return array |
| 828 | + * @deprecated 5.1.0 | |
| 773 | 829 | */ |
| 774 | 830 | public static function prepare_localized_token( $token, $primary = false ) { |
| 831 | + _deprecated_function( 'ElasticPress\Feature\Search\Synonyms::prepare_localized_token', '5.1.0' ); | |
| 832 | + | |
| 775 | 833 | return array( |
| 776 | 834 | 'label' => trim( sanitize_text_field( $token ) ), |
| 777 | 835 | 'value' => trim( sanitize_text_field( $token ) ), |
| 778 | 836 | 'primary' => $primary, |
| @@ -799,9 +857,9 @@ | ||
| 799 | 857 | * |
| 800 | 858 | * @param string $content The content post. |
| 801 | 859 | * @return int|WP_Error |
| 802 | 860 | */ |
| 803 | - private function update_synonym_post( $content ) { | |
| 861 | + public function update_synonym_post( $content ) { | |
| 804 | 862 | $synonym_post_id = $this->get_synonym_post_id(); |
| 805 | 863 | |
| 806 | 864 | if ( ! $synonym_post_id ) { |
| 807 | 865 | return $synonym_post_id; |
| @@ -814,6 +872,34 @@ | ||
| 814 | 872 | 'post_type' => self::POST_TYPE_NAME, |
| 815 | 873 | ], |
| 816 | 874 | true |
| 817 | 875 | ); |
| 876 | + } | |
| 877 | + | |
| 878 | + /** | |
| 879 | + * Setup REST endpoints | |
| 880 | + * | |
| 881 | + * @since 5.1.0 | |
| 882 | + */ | |
| 883 | + public function setup_endpoint() { | |
| 884 | + $controller = new REST\Synonyms(); | |
| 885 | + $controller->register_routes(); | |
| 886 | + } | |
| 887 | + | |
| 888 | + /** | |
| 889 | + * Change the position of the lowercase filter to the beginning of the array. | |
| 890 | + * | |
| 891 | + * @since 5.1.0 | |
| 892 | + * @param array $filters Array of filters. | |
| 893 | + * @return array | |
| 894 | + */ | |
| 895 | + protected function maybe_change_filter_position( array $filters ): array { | |
| 896 | + $lowercase_filter = array_search( 'lowercase', $filters, true ); | |
| 897 | + | |
| 898 | + if ( false !== $lowercase_filter ) { | |
| 899 | + unset( $filters[ $lowercase_filter ] ); | |
| 900 | + array_unshift( $filters, 'lowercase' ); | |
| 901 | + } | |
| 902 | + | |
| 903 | + return $filters; | |
| 818 | 904 | } |
| 819 | 905 | } |