diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8a565d25d2..087799d513 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -81,4 +81,4 @@ jobs: run: composer install - name: PHPCS check - run: './vendor/bin/phpcs . -q --report=checkstyle --runtime-set testVersion 7.0- | cs2pr' + run: './vendor/bin/phpcs . -q --report=checkstyle --runtime-set testVersion 7.4- | cs2pr' diff --git a/.lintstagedrc.json b/.lintstagedrc.json index c0154d6280..3b50825496 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -6,6 +6,6 @@ "10up-toolkit lint-js" ], "*.php": [ - "./vendor/bin/phpcs --extensions=php --runtime-set testVersion 7.0- -s" + "./vendor/bin/phpcs --extensions=php --runtime-set testVersion 7.4- -s" ] } \ No newline at end of file diff --git a/composer.json b/composer.json index b45a0b51db..fa85945388 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "brianhenryie/strauss": "^0.14.0" }, "scripts": { - "lint": "phpcs . -s --runtime-set testVersion 7.0-", + "lint": "phpcs . -s --runtime-set testVersion 7.4-", "lint-fix": "phpcbf .", "test": "phpunit", "test-single-site": "phpunit -c single-site.xml.dist", diff --git a/includes/classes/Feature.php b/includes/classes/Feature.php index 952b20a87a..5e8a7d0c3a 100644 --- a/includes/classes/Feature.php +++ b/includes/classes/Feature.php @@ -118,6 +118,14 @@ abstract class Feature { */ protected $is_visible = true; + /** + * Settings description + * + * @since 5.0.0 + * @var array + */ + protected $settings_schema = []; + /** * Run on every page load for feature to set itself up * @@ -503,4 +511,64 @@ public function is_available() : bool { */ return apply_filters( 'ep_feature_is_available', $this->is_visible && 2 !== $requirements_status->code, $this->slug, $this ); } + + /** + * Get a JSON representation of the feature + * + * @since 5.0.0 + * @return string + */ + public function get_json() { + $requirements_status = $this->requirements_status(); + + $feature_desc = [ + 'slug' => $this->slug, + 'title' => $this->get_title(), + 'shortTitle' => $this->get_short_title(), + 'summary' => $this->summary, + 'docsUrl' => $this->docs_url, + 'defaultSettings' => $this->default_settings, + 'order' => $this->order, + 'isAvailable' => $this->is_available(), + 'reqStatusCode' => $requirements_status->code, + 'reqStatusMessages' => $requirements_status->message, + 'settingsSchema' => $this->get_settings_schema(), + ]; + return wp_json_encode( $feature_desc ); + } + + /** + * Return the feature settings schema + * + * @since 5.0.0 + * @return array + */ + public function get_settings_schema() { + $req_status = $this->requirements_status(); + + $active = [ + 'default' => 0 === $req_status->code, + 'key' => 'active', + 'label' => __( 'Enabled', 'elasticpress' ), + 'requires_sync' => $this->requires_install_reindex, + 'type' => 'checkbox', + ]; + + $settings_schema = [ + $active, + ...$this->settings_schema, + ]; + + /** + * Filter the settings schema of a feature + * + * @hook ep_feature_is_available + * @since 5.0.0 + * @param {array} $settings_schema True if the feature is available + * @param {string} $feature_slug Feature slug + * @param {Feature} $feature Feature object + * @return {array} New $settings_schema value + */ + return apply_filters( 'ep_feature_settings_schema', $settings_schema, $this->slug, $this ); + } } diff --git a/includes/classes/Feature/Autosuggest/Autosuggest.php b/includes/classes/Feature/Autosuggest/Autosuggest.php index 4d53f8df2e..9c77ee0867 100644 --- a/includes/classes/Feature/Autosuggest/Autosuggest.php +++ b/includes/classes/Feature/Autosuggest/Autosuggest.php @@ -58,6 +58,8 @@ public function __construct() { $this->available_during_installation = true; + $this->set_settings_schema(); + parent::__construct(); } @@ -855,6 +857,76 @@ public function intercept_remote_request() { return true; } + /** + * Conditionally add EP.io information to the settings schema + * + * @since 5.0.0 + */ + protected function maybe_add_epio_settings_schema() { + $allowed_params = $this->epio_autosuggest_set_and_get(); + if ( empty( $allowed_params ) ) { + return; + } + + $epio_link = 'https://elasticpress.io'; + $epio_autosuggest_kb_link = 'https://elasticpress.zendesk.com/hc/en-us/articles/360055402791'; + $status_report_link = defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ? network_admin_url( 'admin.php?page=elasticpress-status-report' ) : admin_url( 'admin.php?page=elasticpress-status-report' ); + + $this->settings_schema[] = [ + 'default' => sprintf( + /* translators: 1: tag (ElasticPress.io); 2. ; 3: tag (KB article); 4. ; 5: tag (Site Health Debug Section); 6. ; */ + __( 'You are directly connected to %1$sElasticPress.io%2$s, ensuring the most performant Autosuggest experience. %3$sLearn more about what this means%4$s or %5$sclick here for debug information%6$s.', 'elasticpress' ), + '', + '', + '', + '', + '', + '' + ), + 'key' => 'epio', + 'label' => __( 'Connection', 'elasticpress' ), + 'type' => 'markup', + ]; + } + + /** + * Set the `settings_schema` attribute + * + * @since 5.0.0 + */ + protected function set_settings_schema() { + $this->settings_schema = [ + [ + 'default' => '.ep-autosuggest', + 'help' => __( 'Input additional selectors where you would like to include autosuggest separated by a comma. Example: .custom-selector, #custom-id, input[type="text"]', 'elasticpress' ), + 'key' => 'autosuggest_selector', + 'label' => __( 'Autosuggest Selector', 'elasticpress' ), + 'type' => 'text', + ], + [ + 'key' => 'trigger_ga_event', + 'help' => __( 'When enabled, a gtag tracking event is fired when an autosuggest result is clicked.', 'elasticpress' ), + 'label' => __( 'Google Analytics Events', 'elasticpress' ), + 'type' => 'checkbox', + ], + ]; + + if ( Utils\is_epio() ) { + $this->maybe_add_epio_settings_schema(); + return; + } + + $set_in_wp_config = defined( 'EP_AUTOSUGGEST_ENDPOINT' ) && EP_AUTOSUGGEST_ENDPOINT; + + $this->settings_schema[] = [ + 'readonly' => $set_in_wp_config, + 'help' => $set_in_wp_config ? __( 'This address will be exposed to the public.', 'elasticpress' ) : '', + 'key' => 'endpoint_url', + 'label' => __( 'Endpoint URL', 'elasticpress' ), + 'type' => 'url', + ]; + } + /** * DEPRECATED. Delete the cached query for autosuggest. * diff --git a/includes/classes/Feature/Comments/Comments.php b/includes/classes/Feature/Comments/Comments.php index 66feb2e782..aa341adca2 100644 --- a/includes/classes/Feature/Comments/Comments.php +++ b/includes/classes/Feature/Comments/Comments.php @@ -8,11 +8,11 @@ namespace ElasticPress\Feature\Comments; -use ElasticPress\Feature as Feature; -use ElasticPress\Indexables as Indexables; -use ElasticPress\Indexable as Indexable; -use ElasticPress\Features as Features; -use ElasticPress\FeatureRequirementsStatus as FeatureRequirementsStatus; +use ElasticPress\Feature; +use ElasticPress\FeatureRequirementsStatus; +use ElasticPress\Features; +use ElasticPress\Indexable; +use ElasticPress\Indexables; use ElasticPress\Utils; /** diff --git a/includes/classes/Feature/DidYouMean/DidYouMean.php b/includes/classes/Feature/DidYouMean/DidYouMean.php index 2c823ae516..b8dc541686 100644 --- a/includes/classes/Feature/DidYouMean/DidYouMean.php +++ b/includes/classes/Feature/DidYouMean/DidYouMean.php @@ -35,6 +35,8 @@ public function __construct() { 'search_behavior' => false, ]; + $this->set_settings_schema(); + parent::__construct(); } @@ -415,4 +417,35 @@ public function the_output( $query = null ) { echo wp_kses_post( $html ); } + + /** + * Set the `settings_schema` attribute + * + * @since 5.0.0 + */ + protected function set_settings_schema() { + $this->settings_schema = [ + [ + 'default' => false, + 'key' => 'search_behavior', + 'label' => __( 'Search behavior when no result is found', 'elasticpress' ), + 'options' => [ + [ + [ + 'label' => __( 'Display the top suggestion', 'elasticpress' ), + 'value' => 0, + ], + [ + 'label' => __( 'Display all the suggestions', 'elasticpress' ), + 'value' => 'list', + ], + [ + 'label' => __( 'Automatically redirect the user to the top suggestion', 'elasticpress' ), + 'value' => 'redirect', + ], + ], + ], + ], + ]; + } } diff --git a/includes/classes/Feature/Facets/Facets.php b/includes/classes/Feature/Facets/Facets.php index 159d365df3..b968f243cc 100644 --- a/includes/classes/Feature/Facets/Facets.php +++ b/includes/classes/Feature/Facets/Facets.php @@ -85,6 +85,8 @@ public function __construct() { } } + $this->set_settings_schema(); + parent::__construct(); } @@ -644,6 +646,29 @@ public function remove_facets_filter( $filters ) { return $filters; } + /** + * Set the `settings_schema` attribute + * + * @since 5.0.0 + */ + protected function set_settings_schema() { + $this->settings_schema[] = [ + 'key' => 'match_type', + 'label' => __( 'Match Type', 'elasticpress' ), + 'help' => __( '"All" will only show content that matches all filters. "Any" will show content that matches any filter.', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Show any content tagged to all selected terms', 'elasticpress' ), + 'value' => 'all', + ], + [ + 'label' => __( 'Show all content tagged to any selected term', 'elasticpress' ), + 'value' => 'any', + ], + ], + ]; + } + /** * Figure out if Facet widget can display on page. * diff --git a/includes/classes/Feature/InstantResults/InstantResults.php b/includes/classes/Feature/InstantResults/InstantResults.php index ebe2bdbb72..90013af2ec 100644 --- a/includes/classes/Feature/InstantResults/InstantResults.php +++ b/includes/classes/Feature/InstantResults/InstantResults.php @@ -7,12 +7,12 @@ namespace ElasticPress\Feature\InstantResults; -use ElasticPress\Elasticsearch as Elasticsearch; -use ElasticPress\Feature as Feature; +use ElasticPress\Elasticsearch; +use ElasticPress\Feature; use ElasticPress\FeatureRequirementsStatus; -use ElasticPress\Features as Features; -use ElasticPress\Indexables as Indexables; -use ElasticPress\Utils as Utils; +use ElasticPress\Features; +use ElasticPress\Indexables; +use ElasticPress\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. @@ -96,6 +96,8 @@ public function __construct() { $this->available_during_installation = true; + $this->set_settings_schema(); + parent::__construct(); } @@ -1050,4 +1052,123 @@ public function get_title() : string { /* translators: 1. elasticpress.io logo; */ return sprintf( esc_html__( 'Instant Results By %s', 'elasticpress' ), $this->get_epio_logo() ); } + + /** + * Set the `settings_schema` attribute + * + * @since 5.0.0 + */ + protected function set_settings_schema() { + $this->settings_schema = [ + [ + 'default' => 'mark', + 'help' => __( 'Highlight search terms in results with the selected HTML tag.', 'elasticpress' ), + 'key' => 'highlight_tag', + 'label' => __( 'Highlight tag', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'None', 'elasticpress' ), + 'value' => '', + ], + [ + 'label' => 'mark', + 'value' => 'mark', + ], + [ + 'label' => 'span', + 'value' => 'span', + ], + [ + 'label' => 'strong', + 'value' => 'strong', + ], + [ + 'label' => 'em', + 'value' => 'em', + ], + [ + 'label' => 'i', + 'value' => 'i', + ], + ], + 'type' => 'select', + ], + [ + 'default' => 'post_type,category,post_tag', + 'key' => 'facets', + 'label' => __( 'Filters', 'elasticpress' ), + 'options' => [ + [ + 'label' => 'post_type', + 'value' => 'post_type', + ], + [ + 'label' => 'category', + 'value' => 'category', + ], + [ + 'label' => 'post_tag', + 'value' => 'post_tag', + ], + ], + 'type' => 'multiple', + ], + [ + 'default' => 'all', + 'help' => __( '"All" will only show content that matches all filters. "Any" will show content that matches any filter.', 'elasticpress' ), + 'key' => 'match_type', + 'label' => __( 'Match Type', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Show any content tagged to all selected terms', 'elasticpress' ), + 'value' => 'all', + ], + [ + 'label' => __( 'Show all content tagged to any selected term', 'elasticpress' ), + 'value' => 'any', + ], + ], + 'type' => 'radio', + ], + [ + 'default' => '1', + 'help' => __( 'When enabled, it will show the term count in the instant results widget.', 'elasticpress' ), + 'key' => 'term_count', + 'label' => __( 'Term Count', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Enabled', 'elasticpress' ), + 'value' => '1', + ], + [ + 'label' => __( 'Disabled', 'elasticpress' ), + 'value' => '0', + ], + ], + 'type' => 'radio', + ], + [ + 'default' => get_option( 'posts_per_page', 6 ), + 'key' => 'per_page', + 'type' => 'hidden', + ], + [ + 'default' => '', + 'key' => 'search_behavior', + 'label' => __( 'Search behavior when no result is found', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Display the top suggestion', 'elasticpress' ), + 'value' => '0', + ], + [ + 'label' => __( 'Display all the suggestions', 'elasticpress' ), + 'value' => 'list', + ], + ], + 'requires_feature' => 'did-you-mean', + 'type' => 'radio', + ], + ]; + } } diff --git a/includes/classes/Feature/Search/Search.php b/includes/classes/Feature/Search/Search.php index 42a714830a..c01eaf7b41 100644 --- a/includes/classes/Feature/Search/Search.php +++ b/includes/classes/Feature/Search/Search.php @@ -70,6 +70,8 @@ public function __construct() { $this->available_during_installation = true; + $this->set_settings_schema(); + parent::__construct(); } @@ -821,4 +823,134 @@ public function skip_query_integration( $skip, $query ) { return $skip; } + + /** + * Set the `settings_schema` attribute + * + * @since 5.0.0 + */ + protected function set_settings_schema() { + $this->settings_schema = [ + [ + 'default' => '1', + 'key' => 'decaying_enabled', + 'label' => __( 'Weight results by date', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Enabled', 'elasticpress' ), + 'value' => '1', + ], + [ + 'label' => __( 'Disabled', 'elasticpress' ), + 'value' => '0', + ], + ], + 'type' => 'radio', + ], + [ + 'default' => '0', + 'help' => __( 'Wrap search terms in HTML tags in results for custom styling. The wrapping HTML tag comes with the "ep-highlight" class for easy styling.' ), + 'key' => 'highlight_enabled', + 'label' => __( 'Highlighting status', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Enabled', 'elasticpress' ), + 'value' => '1', + ], + [ + 'label' => __( 'Disabled', 'elasticpress' ), + 'value' => '0', + ], + ], + 'type' => 'radio', + ], + [ + 'default' => 'mark', + 'key' => 'highlight_tag', + 'label' => __( 'Highlight tag', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'None', 'elasticpress' ), + 'value' => '', + ], + [ + 'label' => 'mark', + 'value' => 'mark', + ], + [ + 'label' => 'span', + 'value' => 'span', + ], + [ + 'label' => 'strong', + 'value' => 'strong', + ], + [ + 'label' => 'em', + 'value' => 'em', + ], + [ + 'label' => 'i', + 'value' => 'i', + ], + ], + 'type' => 'select', + ], + [ + 'default' => '0', + 'help' => __( 'By default, WordPress strips HTML from content excerpts. Enable when using the_excerpt() to display search results.', 'elasticpress' ), + 'key' => 'highlight_excerpt', + 'label' => __( 'Excerpt highlighting', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Enabled', 'elasticpress' ), + 'value' => '1', + ], + [ + 'label' => __( 'Disabled', 'elasticpress' ), + 'value' => '0', + ], + ], + 'type' => 'radio', + ], + [ + 'default' => '.ep-autosuggest', + 'help' => __( 'Input additional selectors where you would like to include autosuggest separated by a comma. Example: .custom-selector, #custom-id, input[type="text"]', 'elasticpress' ), + 'key' => 'autosuggest_selector', + 'label' => __( 'Autosuggest Selector', 'elasticpress' ), + 'type' => 'text', + ], + [ + 'key' => 'trigger_ga_event', + 'help' => __( 'When enabled, a gtag tracking event is fired when an autosuggest result is clicked.', 'elasticpress' ), + 'label' => __( 'Google Analytics Events', 'elasticpress' ), + 'type' => 'checkbox', + ], + [ + 'default' => 'simple', + 'key' => 'synonyms_editor_mode', + 'type' => 'hidden', + ], + ]; + + if ( ! defined( 'EP_IS_NETWORK' ) || ! EP_IS_NETWORK ) { + $weighting_url = esc_url( admin_url( 'admin.php?page=elasticpress-weighting' ) ); + $synonyms_url = esc_url( admin_url( 'admin.php?page=elasticpress-synonyms' ) ); + + $text = sprintf( + '
', + $weighting_url, + __( 'Advanced fields and weighting settings', 'elasticpress' ), + $synonyms_url, + __( 'Add synonyms to your post searches', 'elasticpress' ), + ); + + $this->settings_schema[] = [ + 'default' => $text, + 'key' => 'additional_links', + 'label' => '', + 'type' => 'markup', + ]; + } + } } diff --git a/includes/classes/Feature/WooCommerce/Products.php b/includes/classes/Feature/WooCommerce/Products.php index b5b08217fa..a7c44b5789 100644 --- a/includes/classes/Feature/WooCommerce/Products.php +++ b/includes/classes/Feature/WooCommerce/Products.php @@ -58,6 +58,7 @@ public function setup() { // Settings for Weight results by date add_action( 'ep_weight_settings_after_search', [ $this, 'add_weight_settings_search' ] ); + add_filter( 'ep_feature_settings_schema', [ $this, 'add_weight_settings_search_schema' ], 10, 2 ); add_filter( 'ep_is_decaying_enabled', [ $this, 'maybe_disable_decaying' ], 10, 3 ); } @@ -1015,4 +1016,40 @@ public function add_taxonomy_attributes( array $attribute_taxonomies ) : array { } return $attribute_taxonomies; } + + /** + * Add weight by date settings related to WooCommerce + * + * @since 5.0.0 + * @param array $settings_schema Settings schema + * @param string $feature_slug Feature slug + * @return array New settings schema + */ + public function add_weight_settings_search_schema( $settings_schema, $feature_slug ) { + if ( 'search' !== $feature_slug ) { + return $settings_schema; + } + + foreach ( $settings_schema as &$setting_schema ) { + if ( 'decaying_enabled' !== $setting_schema['key'] ) { + continue; + } + + $setting_schema['options'] = array_merge( + $setting_schema['options'], + [ + [ + 'label' => __( 'Disabled for product only queries', 'elasticpress' ), + 'value' => 'disabled_only_products', + ], + [ + 'label' => __( 'Disabled for any query that includes products', 'elasticpress' ), + 'value' => 'disabled_includes_products', + ], + ] + ); + } + + return $settings_schema; + } } diff --git a/includes/classes/Feature/WooCommerce/WooCommerce.php b/includes/classes/Feature/WooCommerce/WooCommerce.php index e925273cba..4b6a72c9bd 100644 --- a/includes/classes/Feature/WooCommerce/WooCommerce.php +++ b/includes/classes/Feature/WooCommerce/WooCommerce.php @@ -74,6 +74,8 @@ public function __construct() { $this->products = new Products( $this ); $this->orders_autosuggest = new OrdersAutosuggest(); + $this->set_settings_schema(); + parent::__construct(); } @@ -294,6 +296,52 @@ public function is_orders_autosuggest_enabled() : bool { return $this->is_orders_autosuggest_available() && '1' === $this->get_setting( 'orders' ); } + /** + * Set the `settings_schema` attribute + * + * @since 5.0.0 + */ + protected function set_settings_schema() { + $available = $this->is_orders_autosuggest_available(); + + $epio_autosuggest_kb_link = 'https://elasticpress.zendesk.com/hc/en-us/articles/13374461690381-Configuring-ElasticPress-io-Order-Autosuggest'; + + $message = ( $available ) ? + /* translators: 1: tag (ElasticPress.io); 2. ; 3: tag (KB article); 4. ; */ + __( 'You are directly connected to %1$sElasticPress.io%2$s! Enable Orders Autosuggest to enhance Dashboard results and quickly find WooCommerce Orders. %3$sLearn More%4$s.', 'elasticpress' ) : + /* translators: 1: tag (ElasticPress.io); 2. ; 3: tag (KB article); 4. ; */ + __( 'Due to the sensitive nature of orders, this autosuggest feature is available only to %1$sElasticPress.io%2$s customers. %3$sLearn More%4$s.', 'elasticpress' ); + + $message = sprintf( + wp_kses( $message, 'ep-html' ), + '', + '', + '', + '' + ); + + $this->settings_schema = [ + [ + 'default' => '0', + 'readonly' => ! $available, + 'help' => $message, + 'key' => 'orders', + 'label' => __( 'Orders Autosuggest', 'elasticpress' ), + 'options' => [ + [ + 'label' => __( 'Enabled', 'elasticpress' ), + 'value' => '1', + ], + [ + 'label' => __( 'Disabled', 'elasticpress' ), + 'value' => '0', + ], + ], + 'type' => 'radio', + ], + ]; + } + /** * DEPRECATED. Translate args to ElasticPress compat format. This is the meat of what the feature does * diff --git a/tests/php/TestFeature.php b/tests/php/TestFeature.php new file mode 100644 index 0000000000..4ce925d386 --- /dev/null +++ b/tests/php/TestFeature.php @@ -0,0 +1,127 @@ +getMockForAbstractClass( '\ElasticPress\Feature' ); + $stub->slug = 'slug'; + $stub->title = 'title'; + $stub->short_title = 'short_title'; + $stub->summary = 'summary'; + $stub->docs_url = 'https://elasticpress.io/'; + $stub->default_settings = []; + $stub->order = 1; + + add_filter( + 'ep_feature_requirements_status', + function() { + return new \ElasticPress\FeatureRequirementsStatus( 2, 'Testing' ); + } + ); + + $expected = [ + 'slug' => 'slug', + 'title' => 'title', + 'shortTitle' => 'short_title', + 'summary' => 'summary', + 'docsUrl' => 'https://elasticpress.io/', + 'defaultSettings' => [], + 'order' => 1, + 'isAvailable' => false, // Set by status code 2 + 'reqStatusCode' => 2, + 'reqStatusMessages' => 'Testing', + 'settingsSchema' => [ + [ + 'default' => false, + 'key' => 'active', + 'label' => __( 'Enabled', 'elasticpress' ), + 'requires_sync' => false, + 'type' => 'checkbox', + ], + ], + ]; + + $this->assertSame( wp_json_encode( $expected ), $stub->get_json() ); + } + + /** + * Test get_settings_schema. + * + * @group feature + */ + public function test_get_settings_schema() { + $stub = $this->getMockForAbstractClass( '\ElasticPress\Feature' ); + + $reflection = new \ReflectionClass( $stub ); + $reflection_property = $reflection->getProperty( 'settings_schema' ); + $reflection_property->setAccessible( true ); + + $reflection_property->setValue( $stub, [ [ 'key' => 'test_1' ], [ 'key' => 'test_2' ] ] ); + + $settings_schema = $stub->get_settings_schema(); + + $this->assertIsArray( $settings_schema ); + $this->assertSame( + [ + [ + 'default' => true, + 'key' => 'active', + 'label' => __( 'Enabled', 'elasticpress' ), + 'requires_sync' => false, + 'type' => 'checkbox', + ], + [ 'key' => 'test_1' ], + [ 'key' => 'test_2' ], + ], + $settings_schema + ); + } + + /** + * Test the ep_feature_settings_schema filter. + * + * @group feature + */ + public function test_ep_feature_settings_schema_filter() { + $stub = $this->getMockForAbstractClass( '\ElasticPress\Feature' ); + $stub->slug = 'slug'; + + $change_settings_schema = function( $settings_schema, $feature_slug, $feature ) use ( $stub ) { + $this->assertSame( $feature_slug, 'slug' ); + $this->assertSame( $feature, $stub ); + $settings_schema[] = [ 'key' => 'new_field' ]; + return $settings_schema; + }; + add_filter( 'ep_feature_settings_schema', $change_settings_schema, 10, 3 ); + + $settings_schema = $stub->get_settings_schema(); + $this->assertSame( + [ + [ + 'default' => true, + 'key' => 'active', + 'label' => __( 'Enabled', 'elasticpress' ), + 'requires_sync' => false, + 'type' => 'checkbox', + ], + [ 'key' => 'new_field' ], + ], + $settings_schema + ); + } +} diff --git a/tests/php/features/TestAutosuggest.php b/tests/php/features/TestAutosuggest.php index 8e4880ea38..334de493b1 100644 --- a/tests/php/features/TestAutosuggest.php +++ b/tests/php/features/TestAutosuggest.php @@ -305,4 +305,20 @@ public function testRequirementsStatus() { $this->assertEquals( 2, count( $status->message ) ); } + /** + * Test Autosuggest settings schema + * + * @since 5.0.0 + * @group autosuggest + */ + public function test_get_settings_schema() { + $settings_schema = $this->get_feature()->get_settings_schema(); + + $settings_keys = wp_list_pluck( $settings_schema, 'key' ); + + $this->assertSame( + [ 'active', 'autosuggest_selector', 'trigger_ga_event', 'endpoint_url' ], + $settings_keys + ); + } } diff --git a/tests/php/features/TestDidYouMean.php b/tests/php/features/TestDidYouMean.php index d6675c6e9e..72e6c222f8 100644 --- a/tests/php/features/TestDidYouMean.php +++ b/tests/php/features/TestDidYouMean.php @@ -451,4 +451,22 @@ function() { $this->assertTrue( $query->elasticsearch_success ); $this->assertEmpty( $query->suggested_terms['options'] ); } + + /** + * Test Did You Mean settings schema + * + * @since 5.0.0 + * @group did-you-mean + */ + public function test_get_settings_schema() { + $instance = new \ElasticPress\Feature\DidYouMean\DidYouMean(); + $settings_schema = $instance->get_settings_schema(); + + $settings_keys = wp_list_pluck( $settings_schema, 'key' ); + + $this->assertSame( + [ 'active', 'search_behavior' ], + $settings_keys + ); + } } diff --git a/tests/php/features/TestFacet.php b/tests/php/features/TestFacet.php index 381ca387a7..f4a7fcf1f1 100644 --- a/tests/php/features/TestFacet.php +++ b/tests/php/features/TestFacet.php @@ -363,6 +363,23 @@ public function testGetAllowedQueryArgs() { $this->assertEqualsCanonicalizing( array_merge( $default_allowed_args, [ 'test' ] ), $facet_feature->get_allowed_query_args() ); } + /** + * Test Facets settings schema + * + * @since 5.0.0 + * @group facets + */ + public function test_get_settings_schema() { + $settings_schema = Features::factory()->get_registered_feature( 'facets' )->get_settings_schema(); + + $settings_keys = wp_list_pluck( $settings_schema, 'key' ); + + $this->assertSame( + [ 'active', 'match_type' ], + $settings_keys + ); + } + /** * Utilitary function for the testGetSelected test. * diff --git a/tests/php/features/TestInstantResults.php b/tests/php/features/TestInstantResults.php new file mode 100644 index 0000000000..8419544657 --- /dev/null +++ b/tests/php/features/TestInstantResults.php @@ -0,0 +1,31 @@ +get_registered_feature( 'instant-results' )->get_settings_schema(); + + $settings_keys = wp_list_pluck( $settings_schema, 'key' ); + + $this->assertSame( + [ 'active', 'highlight_tag', 'facets', 'match_type', 'term_count', 'per_page', 'search_behavior' ], + $settings_keys + ); + } +} diff --git a/tests/php/features/TestSearch.php b/tests/php/features/TestSearch.php index 8b92a64a84..6ca08fcf73 100644 --- a/tests/php/features/TestSearch.php +++ b/tests/php/features/TestSearch.php @@ -335,4 +335,23 @@ public function testExcerptSetting() { $this->assertTrue( $settings['highlight_excerpt'] ); } + + /** + * Test Search settings schema + * + * @since 5.0.0 + * @group search + */ + public function test_get_settings_schema() { + $settings_schema = \ElasticPress\Features::factory()->get_registered_feature( 'search' )->get_settings_schema(); + + $settings_keys = wp_list_pluck( $settings_schema, 'key' ); + + $expected = [ 'active', 'decaying_enabled', 'highlight_enabled', 'highlight_tag', 'highlight_excerpt', 'autosuggest_selector', 'trigger_ga_event', 'synonyms_editor_mode' ]; + if ( ! is_multisite() ) { + $expected[] = 'additional_links'; + } + + $this->assertSame( $expected, $settings_keys ); + } } diff --git a/tests/php/features/WooCommerce/TestWooCommerce.php b/tests/php/features/WooCommerce/TestWooCommerce.php index 886f90ba68..e3cdeee993 100644 --- a/tests/php/features/WooCommerce/TestWooCommerce.php +++ b/tests/php/features/WooCommerce/TestWooCommerce.php @@ -241,6 +241,24 @@ public function testIsOrdersAutosuggestEnabled() { $this->assertFalse( $woocommerce_feature->is_orders_autosuggest_enabled() ); } + /** + * Test WooCommerce settings schema + * + * @since 5.0.0 + * @group woocommerce + */ + public function test_get_settings_schema() { + $woocommerce_feature = ElasticPress\Features::factory()->get_registered_feature( 'woocommerce' ); + $settings_schema = $woocommerce_feature->get_settings_schema(); + + $settings_keys = wp_list_pluck( $settings_schema, 'key' ); + + $this->assertSame( + [ 'active', 'orders' ], + $settings_keys + ); + } + /** * Test the addition of variations skus to product meta * diff --git a/tests/php/features/WooCommerce/TestWooCommerceProduct.php b/tests/php/features/WooCommerce/TestWooCommerceProduct.php index b5e887f653..4d81ad066f 100644 --- a/tests/php/features/WooCommerce/TestWooCommerceProduct.php +++ b/tests/php/features/WooCommerce/TestWooCommerceProduct.php @@ -1111,4 +1111,26 @@ public function test_add_taxonomy_attributes() { $this->assertEquals( $sample_test, $query_filters ); } + + /** + * Test the `add_weight_settings_search_schema` method + * + * @since 5.0.0 + * @group woocommerce + * @group woocommerce-products + */ + public function test_add_weight_settings_search_schema() { + $settings_schema = \ElasticPress\Features::factory()->get_registered_feature( 'search' )->get_settings_schema(); + + $settings_keys = wp_list_pluck( $settings_schema, 'key' ); + + $this->assertContains( 'decaying_enabled', $settings_keys ); + + $decaying = wp_list_filter( $settings_schema, [ 'key' => 'decaying_enabled' ] ); + $decaying = reset( $decaying ); + + $options = wp_list_pluck( $decaying['options'], 'value' ); + $this->assertContains( 'disabled_only_products', $options ); + $this->assertContains( 'disabled_includes_products', $options ); + } }