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

WIP: Experiment: Advanced search qualifiers #87

Open
wants to merge 14 commits into
base: trunk
Choose a base branch
from
Open
5 changes: 5 additions & 0 deletions source/wp-content/themes/wporg-developer/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@
require __DIR__ . '/inc/admin.php';
}

/**
* Custom class for modifying search queries.
*/
require __DIR__ . '/inc/advanced-search-filters.php';

/**
* Set the content width based on the theme's design and stylesheet.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

class Advanced_Search_Filters {

public static function init() {
add_filter( 'the_posts', array( __CLASS__, 'modify_search' ), 10, 2 );
}

/**
* Returns a tax query array for appending wp-parse-source-file taxonomy searches
*
* @param string $name
* @return array
*/
public static function get_file_tax_query( $name ) {
// Get the tax IDs first
$tax_ids = get_terms(
array(
'taxonomy' => 'wp-parser-source-file',
'name__like' => $name,
'fields' => 'ids',
)
);

return array(
'taxonomy' => 'wp-parser-source-file',
'terms' => $tax_ids,
);
}

/**
* Returns a tax query array for appending wp-parser-since taxonomy searches
*
* @param string $term
* @return array
*/
public static function get_version_tax_query( $term ) {
return array(
'taxonomy' => 'wp-parser-since',
'field' => 'name',
'terms' => $term,
);
}

/**
* Returns a post type string. wp-parser-{post_type}
*
* @param string $post_type_partial
* @return string
*/
public static function get_post_type_string( $post_type_partial ) {
return 'wp-parser-' . strtolower( $post_type_partial );
}

/**
* Modifies the query if user has used advanced search filters
*
* @param \WP_Query $query
* @return void
*/
public static function modify_query( $query ) {
$post_types = array();
$tax_queries = array();

// Clean up keyword.
$keyword = trim( $query->get( 's' ) );

// Split on spaces.
$groups = explode( ' ', $keyword );

// Loop through groups
foreach ( $groups as $group ) {
// Check if {qualifier}:{keyword} is used.
$split = explode( ':', $group );

// We have no qualifier.
if ( ! isset( $split[1] ) ||
empty( $split[0] ) || // Missing a qualifier. Ie: :init
$split[1][0] == ':' // Searching for a class method. Ie: {Class}::init()
) {

// If user has '()' at end of a search string, assume they want a specific function/method.
$s = htmlentities( $split[0] );
if ( str_contains( $s, '(' ) ) {
// Modify the search query to omit the parentheses.
$keyword = str_replace( array( '()', '(' ), '', $keyword );

// Restrict search to function-like content.
$post_types[] = 'wp-parser-function';
$post_types[] = 'wp-parser-method';
}

continue;
}

switch ( strtolower( $split[0] ) ) {
case 'type':
$type = self::get_post_type_string( $split[1] );

if ( in_array( $type, DevHub\get_parsed_post_types() ) ) {
$post_types[] = $type;
// Remove everything from the query.
$keyword = str_replace( $group, '', $keyword );
}

break;
case 'file':
$tax_queries[] = self::get_file_tax_query( $split[1] );

// Remove everything from the query.
$keyword = str_replace( $group, '', $keyword );
break;
case 'version':
$tax_queries[] = self::get_version_tax_query( $split[1] );

// Remove everything from the query.
$keyword = str_replace( $group, '', $keyword );
break;
}
}

// Add relevant tax queries
$query->set( 'tax_query', array_unique( array_merge( $query->get( 'tax_query' ) ?: array(), $tax_queries ), SORT_REGULAR ) );

// Add relevant post_types
$query->set( 'post_type', array_unique( array_merge( $query->get( 'post_type' ) ?: array(), $post_types ), SORT_REGULAR ) );

// Reset the keyword
$query->set( 's', $keyword );
}

/**
* Reset the keyword back to the original keyword after we retrieve the posts.
* We need to because we removed parts in modify_query().
*
* @param WP_Post[] $posts
* @param WP_Query $query
* @return WP_Post[]
*/
public static function modify_search( $posts, $query ) {
// Reset the keyword so we don't lose the qualifiers

if ( isset( $query->query['s'] ) ) {
$query->set( 's', $query->query['s'] );
}

return $posts;
}
}

Advanced_Search_Filters::init();
11 changes: 1 addition & 10 deletions source/wp-content/themes/wporg-developer/inc/search.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,7 @@ public static function pre_get_posts( $query ) {
// Just to make sure. post type should already be set.
$query->set( 'post_type', wporg_get_current_handbook() );
} else {
// If user has '()' at end of a search string, assume they want a specific function/method.
$s = htmlentities( $query->get( 's' ) );
if ( '()' === substr( $s, -2 ) || '(' == substr( $s, -1 ) ) {
// Enable exact search.
$query->set( 'exact', true );
// Modify the search query to omit the parentheses.
$query->set( 's', trim( $s, '()' ) );
// Restrict search to function-like content.
$query->set( 'post_type', array( 'wp-parser-function', 'wp-parser-method' ) );
}
Advanced_Search_Filters::modify_query( $query );
}

// Get post types (if used, or set above)
Expand Down