Skip to content

Commit

Permalink
#108 SupportsAdvancedSearch bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Coby Tamayo committed Aug 30, 2019
1 parent 78f9a8a commit ca72229
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 19 deletions.
3 changes: 2 additions & 1 deletion cypress/integration/search.spec.js
Expand Up @@ -9,7 +9,6 @@ describe('Search', () => {
// search for "goo glue"
cy.visit('/?s=goo+glue')

cy.get('.search-results article').should('have.length', 8)
// posts with search term in title should come first
cy.get('article:nth-of-type(1) h2').should('have.text', 'A post about goo glue')
cy.get('article:nth-of-type(2) h2').should('have.text', 'A whole page about goo')
Expand All @@ -25,6 +24,8 @@ describe('Search', () => {
cy.get('.search-results').should('not.contain', 'This shouldn\'t either')
cy.get('.search-results').should('not.contain', 'Another Thing')
cy.get('.search-results').should('not.contain', 'Thing Draft')

cy.get('.search-results article').should('have.length', 8)
})
})

75 changes: 58 additions & 17 deletions lib/Conifer/Post/SupportsAdvancedSearch.php
Expand Up @@ -18,20 +18,42 @@ public static function configure_advanced_search(array $config) {
return $clauses;
}

// query by post_type
$queryingPostTypes = $query->query_vars['post_type'] ?? [];
if (!is_array($queryingPostTypes)) {
$queryingPostTypes = [$queryingPostTypes];
}

// customize only queries for post_types that appear in config
$searchCustomizations = array_filter(
$config,
function($searchConfig) use($queryingPostTypes) {
return !empty(array_intersect(
$queryingPostTypes,
$searchConfig['post_type']
));
});

if (empty($searchCustomizations)) {
// no advanced search customizations apply to this query
// TODO
//return $clauses;
}

// ->prepend_distinct
$clauses['fields'] = ' DISTINCT ' . $clauses['fields'];

// ->add_join('postmeta', 'posts.ID = postmeta.post_id')
$clauses['join'] .=
" LEFT JOIN {$wpdb->postmeta}"
. " ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id ) ";
" LEFT JOIN {$wpdb->postmeta} meta_search"
. " ON ( {$wpdb->posts}.ID = meta_search.post_id ) ";

// map -> wildcard
$terms = array_map(function(string $term) : string {
return "%{$term}%";
}, $query->query_vars['search_terms']);

$whereClauses = array_map(function(array $postTypeSearch) use($wpdb, $terms) {
$whereClauses = array_map(function(array $postTypeSearch) use($wpdb, $terms, $query, $clauses) {
$titleComparisons = array_map(function(string $term) use($wpdb) : string {
return $wpdb->prepare("{$wpdb->posts}.post_title LIKE %s", $term);
}, $terms);
Expand All @@ -47,14 +69,10 @@ public static function configure_advanced_search(array $config) {
}, $terms);
$contentClause = '(' . implode(' OR ', $contentComparisons) . ')';

$metaKeyComparisons = [
'(meta_key = "hello")',
'(meta_key LIKE "good%")',
];
$metaKeyComparisons = array_map(function($key) use($wpdb) : string {
if (is_string($key)) {

return $wpdb->prepare('(meta_key = %s)', $key);
return $wpdb->prepare('(meta_search.meta_key = %s)', $key);

} elseif (is_array($key) && isset($key['key'])) {

Expand All @@ -64,7 +82,7 @@ public static function configure_advanced_search(array $config) {
$op = '=';
}

return $wpdb->prepare("(meta_key {$op} %s)", $key['key']);
return $wpdb->prepare("(meta_search.meta_key {$op} %s)", $key['key']);
}

return '';
Expand All @@ -82,17 +100,38 @@ public static function configure_advanced_search(array $config) {
// put it all together
$searchClauses = [$titleClause, $excerptClause, $contentClause, $metaClause];

// TODO default to get_post_types() or similar
$postTypes = $postTypeSearch['post_type'] ?? ['post', 'page'];
// get post types from current query
$queryPostType = $query->query_vars['post_type'];

// support post_type wildcard "any"
if ($queryPostType === 'any') {
$queryPostType = get_post_types(['public' => true], 'names');
}

// ensure we have an array to map over
$postTypes = is_array($queryPostType)
? $queryPostType
: [$queryPostType];
$postTypeCriteria = array_map(function(string $type) use($wpdb) {
return $wpdb->prepare('%s', $type);
}, $postTypes);

// TODO default to get_post_statues() or similar
$postStatuses = $postTypeSearch['post_status'] ?? ['publish'];
$postStatusCriteria = array_map(function(string $type) use($wpdb) {
return $wpdb->prepare('%s', $type);
}, $postStatuses);
// get post status from current query
$queryStatuses = $postTypeSearch['post_status'] ?? ['publish'];
if ($queryStatuses === 'any') {
$queryStatusClause = '';
} else {
$postStatuses = is_array($queryStatuses)
? $queryStatuses
: [$queryStatuses];
$postStatusCriteria = array_map(function(string $type) use($wpdb) {
return $wpdb->prepare('%s', $type);
}, $postStatuses);

$queryStatusClause = ' AND wp_posts.post_status IN ('
. implode(', ', $postStatusCriteria)
. ')';
}

return
'('
Expand All @@ -101,13 +140,15 @@ public static function configure_advanced_search(array $config) {

. ' AND wp_posts.post_type IN (' . implode(', ', $postTypeCriteria) . ')'

. ' AND wp_posts.post_status IN (' . implode(', ', $postStatusCriteria) . ')'
. $queryStatusClause

. ')';
}, $config);

$clauses['where'] = ' AND (' . implode(' OR ', $whereClauses) . ')';

// defer to WP default orderby clause for now

return $clauses;
}, 10, 2);
}
Expand Down
2 changes: 1 addition & 1 deletion test/themes/search-test-theme/functions.php
Expand Up @@ -5,7 +5,7 @@

$site = new Site();
$site->configure(function () {
register_post_type('thing');
register_post_type('thing', ['public' => true]);
register_post_status('custom_status');

Post::configure_advanced_search([
Expand Down

0 comments on commit ca72229

Please sign in to comment.