From ca7222929a125314fa25756392f0645228bb85c2 Mon Sep 17 00:00:00 2001 From: Coby Tamayo Date: Fri, 30 Aug 2019 15:40:29 -0700 Subject: [PATCH] #108 SupportsAdvancedSearch bugfixes --- cypress/integration/search.spec.js | 3 +- lib/Conifer/Post/SupportsAdvancedSearch.php | 75 ++++++++++++++++----- test/themes/search-test-theme/functions.php | 2 +- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/cypress/integration/search.spec.js b/cypress/integration/search.spec.js index 478d6f0..4da98ed 100644 --- a/cypress/integration/search.spec.js +++ b/cypress/integration/search.spec.js @@ -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') @@ -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) }) }) diff --git a/lib/Conifer/Post/SupportsAdvancedSearch.php b/lib/Conifer/Post/SupportsAdvancedSearch.php index 5ea498d..9207132 100644 --- a/lib/Conifer/Post/SupportsAdvancedSearch.php +++ b/lib/Conifer/Post/SupportsAdvancedSearch.php @@ -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); @@ -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'])) { @@ -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 ''; @@ -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 '(' @@ -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); } diff --git a/test/themes/search-test-theme/functions.php b/test/themes/search-test-theme/functions.php index c7c525e..57575b7 100644 --- a/test/themes/search-test-theme/functions.php +++ b/test/themes/search-test-theme/functions.php @@ -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([