From 2f597f8cb4bcb49eaee56feb83727709c0e3eaaa Mon Sep 17 00:00:00 2001 From: Felipe Elia Date: Wed, 5 Apr 2023 13:49:08 -0300 Subject: [PATCH] New ep_facet_should_check_if_allowed filter --- .../Feature/Facets/Types/Meta/FacetType.php | 27 +++++++- .../Facets/Types/MetaRange/FacetType.php | 23 ++++++- tests/php/features/TestFacetTypeMeta.php | 62 +++++++++++++++++++ tests/php/features/TestFacetTypeMetaRange.php | 60 ++++++++++++++++++ 4 files changed, 169 insertions(+), 3 deletions(-) diff --git a/includes/classes/Feature/Facets/Types/Meta/FacetType.php b/includes/classes/Feature/Facets/Types/Meta/FacetType.php index f6ac0a0516..ba53dd299a 100644 --- a/includes/classes/Feature/Facets/Types/Meta/FacetType.php +++ b/includes/classes/Feature/Facets/Types/Meta/FacetType.php @@ -209,12 +209,35 @@ public function add_query_filters( $filters ) { $feature = Features::factory()->get_registered_feature( 'facets' ); $selected_filters = $feature->get_selected(); + if ( empty( $selected_filters ) || empty( $selected_filters[ $this->get_filter_type() ] ) ) { return $filters; } - $meta_fields = $selected_filters[ $this->get_filter_type() ]; - $match_type = $feature->get_match_type(); + /** + * Filter if EP should only filter by fields selected in facets. Defaults to true. + * + * @since 4.5.1 + * @hook ep_facet_should_check_if_allowed + * @param {bool} $should_check Whether it should or not check fields + * @return {string} New value + */ + $should_check_if_allowed = apply_filters( 'ep_facet_should_check_if_allowed', true ); + if ( $should_check_if_allowed ) { + $allowed_meta_fields = $this->get_facets_meta_fields(); + + $meta_fields = array_filter( + $selected_filters[ $this->get_filter_type() ], + function ( $meta_field ) use ( $allowed_meta_fields ) { + return in_array( $meta_field, $allowed_meta_fields, true ); + }, + ARRAY_FILTER_USE_KEY + ); + } else { + $meta_fields = $selected_filters[ $this->get_filter_type() ]; + } + + $match_type = $feature->get_match_type(); foreach ( $meta_fields as $meta_field => $values ) { if ( 'any' === $match_type ) { diff --git a/includes/classes/Feature/Facets/Types/MetaRange/FacetType.php b/includes/classes/Feature/Facets/Types/MetaRange/FacetType.php index 23f6956039..9cab44d59c 100644 --- a/includes/classes/Feature/Facets/Types/MetaRange/FacetType.php +++ b/includes/classes/Feature/Facets/Types/MetaRange/FacetType.php @@ -96,7 +96,28 @@ public function add_query_filters( $filters, $query_args = [] ) { return $filters; } - $selected_range_filters = $all_selected_filters[ $this->get_filter_type() ]; + /** + * Filter if EP should only filter by fields selected in facets. Defaults to true. + * + * @since 4.5.1 + * @hook ep_facet_should_check_if_allowed + * @param {bool} $should_check Whether it should or not check fields + * @return {string} New value + */ + $should_check_if_allowed = apply_filters( 'ep_facet_should_check_if_allowed', true ); + if ( $should_check_if_allowed ) { + $allowed_meta_fields = $this->get_facets_meta_fields(); + + $selected_range_filters = array_filter( + $all_selected_filters[ $this->get_filter_type() ], + function ( $meta_field ) use ( $allowed_meta_fields ) { + return in_array( $meta_field, $allowed_meta_fields, true ); + }, + ARRAY_FILTER_USE_KEY + ); + } else { + $selected_range_filters = $all_selected_filters[ $this->get_filter_type() ]; + } $range_filters = []; foreach ( $selected_range_filters as $field_name => $values ) { diff --git a/tests/php/features/TestFacetTypeMeta.php b/tests/php/features/TestFacetTypeMeta.php index 8605f45f0a..caf3de0eeb 100644 --- a/tests/php/features/TestFacetTypeMeta.php +++ b/tests/php/features/TestFacetTypeMeta.php @@ -212,6 +212,12 @@ public function testAddQueryFilters() { $facet_feature = Features::factory()->get_registered_feature( 'facets' ); $facet_type = $facet_feature->types['meta']; + $allow_field = function ( $fields ) { + $fields[] = 'my_custom_field'; + return $fields; + }; + add_filter( 'ep_facet_meta_fields', $allow_field ); + parse_str( 'ep_meta_filter_my_custom_field=dolor,amet', $_GET ); $new_filters = $facet_type->add_query_filters( [] ); @@ -248,6 +254,62 @@ public function testAddQueryFilters() { $this->assertSame( $expected, $new_filters ); } + /** + * Test add_query_filters with not allowed parameters + * + * @since 4.5.1 + * @group facets + */ + public function testAddQueryFiltersWithNotAllowedParameters() { + $facet_feature = Features::factory()->get_registered_feature( 'facets' ); + $facet_type = $facet_feature->types['meta']; + + $allow_field = function ( $fields ) { + $fields[] = 'my_custom_field'; + return $fields; + }; + add_filter( 'ep_facet_meta_fields', $allow_field ); + + parse_str( 'ep_meta_filter_my_custom_field=dolor,amet&ep_meta_filter_not_allowed=1', $_GET ); + + $new_filters = $facet_type->add_query_filters( [] ); + $expected = [ + [ + 'term' => [ + 'meta.my_custom_field.raw' => 'dolor', + ], + ], + [ + 'term' => [ + 'meta.my_custom_field.raw' => 'amet', + ], + ], + ]; + $this->assertSame( $expected, $new_filters ); + + add_filter( 'ep_facet_should_check_if_allowed', '__return_false' ); + + $new_filters = $facet_type->add_query_filters( [] ); + $expected = [ + [ + 'term' => [ + 'meta.my_custom_field.raw' => 'dolor', + ], + ], + [ + 'term' => [ + 'meta.my_custom_field.raw' => 'amet', + ], + ], + [ + 'term' => [ + 'meta.not_allowed.raw' => 1, + ], + ], + ]; + $this->assertSame( $expected, $new_filters ); + } + /** * Test get_facets_meta_fields * diff --git a/tests/php/features/TestFacetTypeMetaRange.php b/tests/php/features/TestFacetTypeMetaRange.php index 3f2f1f33b5..d10c9402b2 100644 --- a/tests/php/features/TestFacetTypeMetaRange.php +++ b/tests/php/features/TestFacetTypeMetaRange.php @@ -91,6 +91,12 @@ public function testGetFilterType() { * @group facets */ public function testAddQueryFilters() { + $allow_field = function ( $fields ) { + $fields[] = 'my_custom_field'; + return $fields; + }; + add_filter( 'ep_facet_meta_range_fields', $allow_field ); + parse_str( 'ep_meta_range_filter_my_custom_field_min=5&ep_meta_range_filter_my_custom_field_max=25', $_GET ); $new_filters = $this->facet_type->add_query_filters( [] ); @@ -114,6 +120,60 @@ public function testAddQueryFilters() { $this->assertSame( [], $new_filters ); } + /** + * Test add_query_filters with not allowed parameters + * + * @since 4.5.1 + * @group facets + */ + public function testAddQueryFiltersWithNotAllowedParameters() { + $allow_field = function ( $fields ) { + $fields[] = 'my_custom_field'; + return $fields; + }; + add_filter( 'ep_facet_meta_range_fields', $allow_field ); + + parse_str( 'ep_meta_range_filter_my_custom_field_min=5&ep_meta_range_filter_my_custom_field_max=25&ep_meta_range_filter_not_allowed_min=5&ep_meta_range_filter_not_allowed_max=25', $_GET ); + + // Should not have `not_allowed` yet + $new_filters = $this->facet_type->add_query_filters( [] ); + $expected = [ + [ + 'range' => [ + 'meta.my_custom_field.double' => [ + 'gte' => floatval( 5 ), + 'lte' => floatval( 25 ), + ], + ], + ], + ]; + $this->assertSame( $expected, $new_filters ); + + add_filter( 'ep_facet_should_check_if_allowed', '__return_false' ); + + // As we are not checking, it should have `not_allowed` now + $new_filters = $this->facet_type->add_query_filters( [] ); + $expected = [ + [ + 'range' => [ + 'meta.my_custom_field.double' => [ + 'gte' => floatval( 5 ), + 'lte' => floatval( 25 ), + ], + ], + ], + [ + 'range' => [ + 'meta.not_allowed.double' => [ + 'gte' => floatval( 5 ), + 'lte' => floatval( 25 ), + ], + ], + ], + ]; + $this->assertSame( $expected, $new_filters ); + } + /** * Test set_wp_query_aggs *