-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix missing application of search filters
- Loading branch information
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 184 additions & 0 deletions
184
wp-content/themes/humanity-theme/includes/features/search/class-search-results.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?php | ||
|
||
declare( strict_types = 1 ); | ||
|
||
namespace Amnesty; | ||
|
||
use WP_Query; | ||
use WP_Tax_Query; | ||
use WP_Term; | ||
|
||
new Search_Results(); | ||
|
||
/** | ||
* Search results modifications | ||
*/ | ||
class Search_Results { | ||
|
||
/** | ||
* Bind hooks | ||
*/ | ||
public function __construct() { | ||
add_action( 'pre_get_posts', [ $this, 'boot' ], 9 ); | ||
} | ||
|
||
/** | ||
* Undocumented function | ||
* | ||
* @param \WP_Query $query the main query object | ||
* | ||
* @return void | ||
*/ | ||
public function boot( WP_Query $query ): void { | ||
if ( $this->should_filter_search( $query ) ) { | ||
add_filter( 'posts_request', [ $this, 'filter_posts_request' ], 10, 2 ); | ||
} | ||
} | ||
|
||
/** | ||
* Rewrite search query SQL if documents are to be searched for | ||
* | ||
* @param string $sql the existing SQL query | ||
* @param \WP_Query $query the Query object | ||
* | ||
* @return string | ||
*/ | ||
public function filter_posts_request( string $sql, WP_Query $query ): string { | ||
/** | ||
* The global db object | ||
* | ||
* @var \wpdb $wpdb the db object | ||
*/ | ||
global $wpdb; | ||
|
||
if ( ! $this->should_filter_search( $query ) ) { | ||
return $sql; | ||
} | ||
|
||
$custom_query = amnesty_get_searchpage_query_object( false ); | ||
|
||
return $wpdb->remove_placeholder_escape( $custom_query->get_sql() ); | ||
} | ||
|
||
/** | ||
* Build the JOIN/WHERE portion of the SQL query that | ||
* directly relates to the selected taxonomy terms. | ||
* | ||
* @param array<string,array<int,int>> $terms the taxonomy terms | ||
* | ||
* @return array<string,string> | ||
*/ | ||
final public function get_tax_query( array $terms ): array { | ||
global $wpdb; | ||
|
||
static $tax_query; | ||
|
||
if ( ! isset( $tax_query ) ) { | ||
$tax_query = new WP_Tax_Query( $this->build_tax_args( $terms ) ); | ||
$tax_query = $tax_query->get_sql( $wpdb->posts, 'id' ); | ||
} | ||
|
||
return $tax_query; | ||
} | ||
|
||
/** | ||
* Check whether the searchpage has active taxonomy filters | ||
* Build tax_query argument list for them, if so | ||
* | ||
* @param array<string,array<int,int>> $terms the taxonomy terms | ||
* | ||
* @return array<mixed> | ||
*/ | ||
final public function build_tax_args( array $terms ): array { | ||
$tax_query = []; | ||
|
||
foreach ( $terms as $taxonomy => $term_ids ) { | ||
$tax_query[] = [ | ||
'taxonomy' => $taxonomy, | ||
'field' => 'id', | ||
'terms' => $term_ids, | ||
]; | ||
} | ||
|
||
if ( empty( $tax_query ) ) { | ||
return $tax_query; | ||
} | ||
|
||
return [ | ||
'relation' => 'AND', | ||
...$tax_query, | ||
]; | ||
} | ||
|
||
/** | ||
* Retrieve term ids from request and convert to slugs | ||
* | ||
* @return array<string,array<int,string>> | ||
*/ | ||
final protected function term_ids_to_slugs(): array { | ||
$terms = []; | ||
|
||
foreach ( get_taxonomies( [ 'public' => true ] ) as $tax_name ) { | ||
$tax_qvar = query_var_to_array( "q{$tax_name}" ); | ||
|
||
if ( ! $tax_qvar ) { | ||
continue; | ||
} | ||
|
||
$objects = get_terms( | ||
[ | ||
'taxonomy' => $tax_name, | ||
'include' => $tax_qvar, | ||
] | ||
); | ||
|
||
$terms[ $tax_name ] = array_map( fn ( WP_Term $t ): string => $t->slug, $objects ); | ||
} | ||
|
||
return $terms; | ||
} | ||
|
||
/** | ||
* Convert list of taxonomy slugs to term ids | ||
* | ||
* @param array<string,array<int,string>> $term_list the list of tax=>terms slugs | ||
* | ||
* @return array<string,array<int,int>> | ||
*/ | ||
final protected function slugs_to_term_ids( array $term_list ): array { | ||
$terms = []; | ||
|
||
foreach ( $term_list as $tax_slug => $term_slugs ) { | ||
$objects = get_terms( | ||
[ | ||
'taxonomy' => $tax_slug, | ||
'slug' => $term_slugs, | ||
] | ||
); | ||
|
||
$terms[ $tax_slug ] = array_map( fn ( WP_Term $t ): int => $t->term_id, $objects ); | ||
} | ||
|
||
return $terms; | ||
} | ||
|
||
/** | ||
* Check whether we should add PDFs to the query | ||
* | ||
* @param \WP_Query $query the query to check | ||
* | ||
* @return bool | ||
*/ | ||
final protected function should_filter_search( WP_Query $query ): bool { | ||
if ( is_admin() || ! is_search() || ! $query->is_main_query() ) { | ||
return false; | ||
} | ||
|
||
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} |