Skip to content

Commit

Permalink
Merge pull request #1689 from 10up/feature/1687-post-type-enhancements
Browse files Browse the repository at this point in the history
Feature/post type enhancements
  • Loading branch information
felipeelia authored Jun 28, 2021
2 parents b7744dc + f5625b9 commit 3c3ff85
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 28 deletions.
38 changes: 37 additions & 1 deletion assets/js/autosuggest.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,27 @@ function init() {
}
};

/**
* Get the searched post types from the search form.
*
* @param {HTMLFormElement} form - form containing the search input field
* @returns {Array} - post types
* @since 3.6.0
*/
function getPostTypesFromForm(form) {
const data = new FormData(form);

if (data.has('post_type')) {
return data.getAll('post_type').slice(-1);
}

if (data.has('post_type[]')) {
return data.getAll('post_type[]');
}

return [];
}

/**
* Calls the ajax request, and outputs the results.
* Called by the handleKeyup callback, debounced.
Expand All @@ -584,6 +605,7 @@ function init() {
const fetchResults = async (input) => {
const searchText = input.value;
const placeholder = 'ep_autosuggest_placeholder';
const postTypes = getPostTypesFromForm(input.form);

// retrieves the PHP-genereated query to pass to ElasticSearch
const queryJSON = getJsonQuery();
Expand All @@ -595,7 +617,21 @@ function init() {
if (searchText.length >= 2) {
setFormIsLoading(true, input);

const query = buildSearchQuery(searchText, placeholder, queryJSON);
let query = buildSearchQuery(searchText, placeholder, queryJSON);

if (postTypes.length > 0) {
query = JSON.parse(query);

if (typeof query.post_filter.bool.must !== 'undefined') {
query.post_filter.bool.must.push({
terms: {
'post_type.raw': postTypes,
},
});
}

query = JSON.stringify(query);
}

// fetch the results
const response = await esSearch(query, searchText);
Expand Down
2 changes: 1 addition & 1 deletion dist/js/admin-script.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/autosuggest-script.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/dashboard-script.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/facets-script.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/ordering-script.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/related-posts-block-script.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/stats-script.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/synonyms-script.min.js

Large diffs are not rendered by default.

53 changes: 41 additions & 12 deletions includes/classes/Feature/Facets/Facets.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ public function get_selected() {
'taxonomies' => [],
);

$allowed_args = $this->get_allowed_query_args();

foreach ( $_GET as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification
if ( 0 === strpos( $key, 'filter_' ) ) {
$taxonomy = str_replace( 'filter_', '', $key );
Expand All @@ -397,6 +399,10 @@ public function get_selected() {
'terms' => array_fill_keys( array_map( 'trim', explode( ',', trim( $value, ',' ) ) ), true ),
);
}

if ( in_array( $key, $allowed_args, true ) ) {
$filters[ $key ] = $value;
}
}

return $filters;
Expand All @@ -410,36 +416,39 @@ public function get_selected() {
* @return string
*/
public function build_query_url( $filters ) {
$query_string = '';

$s = get_search_query();

if ( ! empty( $s ) ) {
$query_string .= 's=' . $s;
}
$query_param = array();

if ( ! empty( $filters['taxonomies'] ) ) {
$tax_filters = $filters['taxonomies'];

foreach ( $tax_filters as $taxonomy => $filter ) {
if ( ! empty( $filter['terms'] ) ) {
if ( ! empty( $query_string ) ) {
$query_string .= '&';
}
$query_param[ 'filter_' . $taxonomy ] = implode( ',', array_keys( $filter['terms'] ) );
}
}
}

$allowed_args = $this->get_allowed_query_args();

$query_string .= 'filter_' . $taxonomy . '=' . implode( ',', array_keys( $filter['terms'] ) );
if ( ! empty( $filters ) ) {
foreach ( $filters as $filter => $value ) {
if ( ! empty( $value ) && in_array( $filter, $allowed_args, true ) ) {
$query_param[ $filter ] = $value;
}
}
}

$query_string = http_build_query( $query_param );

/**
* Filter facet query string
*
* @hook ep_facet_query_string
* @param {string} $query_string Current query string
* @param {array} $query_param Query parameters
* @return {string} New query string
*/
$query_string = apply_filters( 'ep_facet_query_string', $query_string );
$query_string = apply_filters( 'ep_facet_query_string', $query_string, $query_param );

$url = $_SERVER['REQUEST_URI'];
$pagination = strpos( $url, '/page' );
Expand Down Expand Up @@ -485,4 +494,24 @@ public function output_feature_box_long() {
</p>
<?php
}

/**
* Returns allowed query args for facets
*
* @return mixed|void
* @since 3.6.0
*/
public function get_allowed_query_args() {
$args = array( 's', 'post_type' );

/**
* Filter allowed query args
*
* @hook ep_facet_allowed_query_args
* @since 3.6.0
* @param {array} $args Post types
* @return {array} New post types
*/
return apply_filters( 'ep_facet_allowed_query_args', $args );
}
}
72 changes: 65 additions & 7 deletions tests/php/features/TestFacet.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,49 @@ public function tearDown() {
parent::tearDown();
}


/**
* Test the `get_selected` method
*
* @since 3.6.0
* @group facets
*
*/
public function testGetSelected() {
$facet_feature = Features::factory()->get_registered_feature( 'facets' );

parse_str( 'filter_taxonomy=dolor', $_GET );
$selected = $facet_feature->get_selected();
$this->assertSelectedTax( [ 'dolor' => true ], 'taxonomy', $selected );

parse_str( 'filter_taxonomy=dolor,sit', $_GET );
$selected = $facet_feature->get_selected();
$this->assertSelectedTax( [ 'dolor' => true, 'sit' => true ], 'taxonomy', $selected );

parse_str( 'filter_taxonomy=dolor,sit&filter_othertax=amet', $_GET );
$selected = $facet_feature->get_selected();

$this->assertIsArray( $selected );
$this->assertIsArray( $selected['taxonomies'] );
$this->assertCount( 2, $selected['taxonomies'] );
$this->assertArrayHasKey( 'taxonomy', $selected['taxonomies'] );
$this->assertArrayHasKey( 'othertax', $selected['taxonomies'] );
$this->assertSame( [ 'dolor' => true, 'sit' => true ], $selected['taxonomies']['taxonomy']['terms'] );
$this->assertSame( [ 'amet' => true ], $selected['taxonomies']['othertax']['terms'] );

parse_str( 's=searchterm&filter_taxonomy=dolor', $_GET );
$selected = $facet_feature->get_selected();
$this->assertSelectedTax( [ 'dolor' => true ], 'taxonomy', $selected );
$this->assertArrayHasKey( 's', $selected );
$this->assertSame( 'searchterm', $selected['s'] );

parse_str( 'post_type=posttype&filter_taxonomy=dolor', $_GET );
$selected = $facet_feature->get_selected();
$this->assertSelectedTax( [ 'dolor' => true ], 'taxonomy', $selected );
$this->assertArrayHasKey( 'post_type', $selected );
$this->assertSame( 'posttype', $selected['post_type'] );
}

/**
* Test build query URL
*
Expand All @@ -54,10 +97,10 @@ public function testBuildQueryUrl() {

$this->assertEquals( '/?filter_category=augue', $facet_feature->build_query_url( $filters ) );

set_query_var( 's', 'dolor' );
$this->assertEquals( '/?s=dolor&filter_category=augue', $facet_feature->build_query_url( $filters ) );
$filters['s'] = 'dolor';
$this->assertEquals( '/?filter_category=augue&s=dolor', $facet_feature->build_query_url( $filters ) );

set_query_var( 's', '' );
unset( $filters['s'] );
$filters = [
'taxonomies' => [
'category' => [
Expand All @@ -69,13 +112,28 @@ public function testBuildQueryUrl() {
]
];

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

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

set_query_var( 's', 'dolor' );
$this->assertEquals( 'test/?s=dolor&filter_category=augue,consectetur', $facet_feature->build_query_url( $filters ) );

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

/**
* Utilitary function for the testGetSelected test.
*
* Private as it is super specific and not likely to be extended.
*
* @param array $terms Array of terms as they should be in the $selected array.
* @param string $taxonomy Taxonomy slug
* @param array $selected Array of selected terms.
*/
private function assertSelectedTax( $terms, $taxonomy, $selected ) {
$this->assertIsArray( $selected );
$this->assertIsArray( $selected['taxonomies'] );
$this->assertCount( 1, $selected['taxonomies'] );
$this->assertArrayHasKey( $taxonomy, $selected['taxonomies'] );
$this->assertSame( $terms, $selected['taxonomies'][ $taxonomy ]['terms'] );
}
}

0 comments on commit 3c3ff85

Please sign in to comment.