Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Facet returns no result for a term having accent characters #3031

Merged
merged 15 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions includes/classes/Feature/Facets/FacetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,23 @@ abstract public function get_filter_name() : string;
* @return string The filter name.
*/
abstract public function get_filter_type() : string;

/**
* Get the facet sanitize function.
*
* @return string The function name.
*/
public function get_sanitize_callback() : string {

/**
* Filter the facet filter sanitize callback.
*
* @hook ep_facet_default_sanitize_callback
* @since 4.4.0
* @param {string} Facet filter sanitize callback
* @return {string} New facet filter sanitize callback
*/
return apply_filters( 'ep_facet_default_sanitize_callback', 'sanitize_text_field' );
}

}
23 changes: 11 additions & 12 deletions includes/classes/Feature/Facets/Facets.php
Original file line number Diff line number Diff line change
Expand Up @@ -371,29 +371,28 @@ public function get_aggs( $response, $query, $query_args, $query_object ) {
public function get_selected() {
$allowed_args = $this->get_allowed_query_args();

$filters = [];
$filter_names = [];
$filters = [];
$filter_names = [];
$sanitize_callbacks = [];
foreach ( $this->types as $type_obj ) {
$filter_type = $type_obj->get_filter_type();

$filters[ $filter_type ] = [];
$filter_names[ $filter_type ] = $type_obj->get_filter_name();
$filters[ $filter_type ] = [];
$filter_names[ $filter_type ] = $type_obj->get_filter_name();
$sanitize_callbacks[ $filter_type ] = $type_obj->get_sanitize_callback();
}

foreach ( $_GET as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification
$key = sanitize_key( $key );
if ( is_array( $value ) ) {
$value = array_map( 'sanitize_text_field', $value );
} else {
$value = sanitize_text_field( $value );
}

foreach ( $filter_names as $filter_type => $filter_name ) {
if ( 0 === strpos( $key, $filter_name ) ) {
$facet = str_replace( $filter_name, '', $key );
$facet = str_replace( $filter_name, '', $key );
$sanitize_callback = $sanitize_callbacks[ $filter_type ];
$terms = explode( ',', trim( $value, ',' ) );

$filters[ $filter_type ][ $facet ] = array(
'terms' => array_fill_keys( array_map( 'trim', explode( ',', trim( $value, ',' ) ) ), true ),
'terms' => array_fill_keys( array_map( $sanitize_callback, $terms ), true ),
);
}
}
Expand Down Expand Up @@ -441,7 +440,7 @@ public function build_query_url( $filters ) {
}
}

$query_string = http_build_query( $query_param );
$query_string = build_query( $query_param );

/**
* Filter facet query string
Expand Down
18 changes: 18 additions & 0 deletions includes/classes/Feature/Facets/Types/Taxonomy/FacetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,24 @@ public function get_filter_type() : string {
return apply_filters( 'ep_facet_filter_type', 'taxonomies' );
}

/**
* Get the facet sanitize function.
*
* @return string The function name.
*/
public function get_sanitize_callback() : string {

/**
* Filter the facet filter sanitize callback.
*
* @hook ep_facet_meta_sanitize_callback
* @since 4.4.0
* @param {string} Facet filter sanitize callback
* @return {string} New facet filter sanitize callback
*/
return apply_filters( 'ep_facet_sanitize_callback', 'sanitize_title' );
}

/**
* Get all taxonomies that could be selected for a facet.
*
Expand Down
13 changes: 8 additions & 5 deletions tests/cypress/integration/features/facets.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ describe('Facets Feature', () => {
* item as checked, and all articles being displayed should have the
* selected category.
*/
cy.url().should('include', 'ep_meta_filter_meta_field_1=Meta+Value+%281%29+-+20');
cy.url().should('include', 'ep_meta_filter_meta_field_1=Meta%20Value%20(1)%20-%2020');
cy.get('@firstBlock')
.contains('.term', 'Meta Value (1) - 20')
.find('.ep-checkbox')
Expand All @@ -435,8 +435,8 @@ describe('Facets Feature', () => {
* should be filtered by both selections.
*/
cy.get('@secondBlock').contains('.term', 'Meta Value (2) - 20').click();
cy.url().should('include', 'ep_meta_filter_meta_field_1=Meta+Value+%281%29+-+20');
cy.url().should('include', 'ep_meta_filter_meta_field_2=Meta+Value+%282%29+-+20');
cy.url().should('include', 'ep_meta_filter_meta_field_1=Meta%20Value%20(1)%20-%2020');
cy.url().should('include', 'ep_meta_filter_meta_field_2=Meta%20Value%20(2)%20-%2020');
cy.url().should('not.include', 'page/2');
cy.get('@firstBlock')
.contains('.term', 'Meta Value (1) - 20')
Expand All @@ -455,8 +455,11 @@ describe('Facets Feature', () => {
* facets active.
*/
cy.get('@secondBlock').contains('.term', 'Meta Value (2) - 20').click();
cy.url().should('not.include', 'ep_meta_filter_meta_field_2=Meta+Value+%282%29+-+20');
cy.url().should('include', 'ep_meta_filter_meta_field_1=Meta+Value+%281%29+-+20');
cy.url().should(
'not.include',
'ep_meta_filter_meta_field_2=Meta%20Value%20(2)%20-%2020',
);
cy.url().should('include', 'ep_meta_filter_meta_field_1=Meta%20Value%20(1)%20-%2020');
cy.get('@secondBlock')
.contains('a[aria-disabled="true"]', 'Meta Value (2) - 19')
.should('exist');
Expand Down
20 changes: 16 additions & 4 deletions tests/php/features/TestFacet.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ public function testGetSelected() {
$this->assertSelectedTax( [ 'dolor' => true ], 'taxonomy', $selected );
$this->assertArrayHasKey( 'post_type', $selected );
$this->assertSame( 'posttype', $selected['post_type'] );

// test for a term having accents characters in it.
$term = $this->factory->category->create_and_get(
array(
'name' => 'غير-مصنف',
)
);
parse_str( "post_type=posttype&ep_filter_taxonomy={$term->slug}", $_GET );
$selected = $facet_feature->get_selected();
$this->assertSelectedTax( array( $term->slug => true ), 'taxonomy', $selected );
$this->assertArrayHasKey( 'post_type', $selected );
$this->assertSame( 'posttype', $selected['post_type'] );
}

/**
Expand Down Expand Up @@ -120,16 +132,16 @@ public function testBuildQueryUrl() {
]
];

$this->assertEquals( '/?ep_filter_category=augue%2Cconsectetur', $facet_feature->build_query_url( $filters ) );
$this->assertEquals( '/?ep_filter_category=augue,consectetur', $facet_feature->build_query_url( $filters ) );

// test when search parameter is empty.
$filters['s'] = '';
$this->assertEquals( '/?ep_filter_category=augue%2Cconsectetur&s=', $facet_feature->build_query_url( $filters ) );
$this->assertEquals( '/?ep_filter_category=augue,consectetur&s=', $facet_feature->build_query_url( $filters ) );

$_SERVER['REQUEST_URI'] = 'test/page/1';

$filters['s'] = 'dolor';
$this->assertEquals( 'test/?ep_filter_category=augue%2Cconsectetur&s=dolor', $facet_feature->build_query_url( $filters ) );
$this->assertEquals( 'test/?ep_filter_category=augue,consectetur&s=dolor', $facet_feature->build_query_url( $filters ) );

/**
* Test the `ep_facet_query_string` filter.
Expand All @@ -151,7 +163,7 @@ public function testBuildQueryUrl() {
return 'ep_custom_filter_';
};
add_filter( 'ep_facet_filter_name', $change_ep_facet_filter_name );
$this->assertEquals( 'test/?ep_custom_filter_category=augue%2Cconsectetur&s=dolor', $facet_feature->build_query_url( $filters ) );
$this->assertEquals( 'test/?ep_custom_filter_category=augue,consectetur&s=dolor', $facet_feature->build_query_url( $filters ) );
remove_filter( 'ep_facet_filter_name', $change_ep_facet_filter_name );
}

Expand Down
34 changes: 34 additions & 0 deletions tests/php/features/TestFacetTypeMeta.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,38 @@ public function testInvalidateMetaValuesCache() {
public function testInvalidateMetaValuesCacheAfterBulk() {
$this->markTestIncomplete();
}

/**
* Test get_sanitize_callback method.
*
* @since 4.4.0
* @group facets
*/
public function testGetSanitizeCallback() {

$facet_feature = Features::factory()->get_registered_feature( 'facets' );
$test_meta = 'This is s test meta';
felipeelia marked this conversation as resolved.
Show resolved Hide resolved

parse_str( "ep_meta_filter_new_meta_key_1={$test_meta}", $_GET );
$selected = $facet_feature->get_selected();

// test sanitize_text_field runs by default on taxonomy facets
$expected_result = sanitize_text_field( $test_meta );
$this->assertArrayHasKey( $expected_result, $selected['meta']['new_meta_key_1']['terms'] );

$sanitize_function = function() {
return 'sanitize_title';
};
felipeelia marked this conversation as resolved.
Show resolved Hide resolved

// modify the sanitize callback.
add_filter( 'ep_facet_default_sanitize_callback', $sanitize_function );

$selected = $facet_feature->get_selected();

// test sanitize_text_field runs when filter is applied.
$expected_result = sanitize_title( $test_meta );
$this->assertArrayHasKey( $expected_result, $selected['meta']['new_meta_key_1']['terms'] );

remove_filter( 'ep_facet_default_sanitize_callback', $sanitize_function );
}
}
34 changes: 34 additions & 0 deletions tests/php/features/TestFacetTypeTaxonomy.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,38 @@ public function testAddQueryFilters() {
];
$this->assertSame( $expected, $new_filters );
}

/**
* Test get_sanitize_callback method.
*
* @since 4.4.0
* @group facets
*/
public function testGetSanitizeCallback() {

$facet_feature = Features::factory()->get_registered_feature( 'facets' );
$test_taxonomy = 'This is a test taxonomy';

parse_str( "ep_filter_taxonomy={$test_taxonomy}", $_GET );
$selected = $facet_feature->get_selected();

// test sanitize_title runs by default on taxonomy facets
$expected_result = sanitize_title( $test_taxonomy );
$this->assertArrayHasKey( $expected_result, $selected['taxonomies']['taxonomy']['terms'] );

$sanitize_function = function() {
return 'sanitize_text_field';
};
felipeelia marked this conversation as resolved.
Show resolved Hide resolved

// modify the sanitize callback.
add_filter( 'ep_facet_sanitize_callback', $sanitize_function );

$selected = $facet_feature->get_selected();

// test sanitize_text_field runs when filter is applied.
$expected_result = sanitize_text_field( $test_taxonomy );
$this->assertArrayHasKey( $expected_result, $selected['taxonomies']['taxonomy']['terms'] );

remove_filter( 'ep_facet_sanitize_callback', $sanitize_function );
}
}