Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save felthy/9673477d1fd1ef8a703a0c377336bd6c to your computer and use it in GitHub Desktop.
Save felthy/9673477d1fd1ef8a703a0c377336bd6c to your computer and use it in GitHub Desktop.
PHP - Wordpress - Search - wordpress custom search function that encompasses ACF/advanced custom fields and taxonomies and split expression before request. Updated to use wpdb prepare() and esc_like().
<?php
/*
##############################
########### Search ###########
##############################
Included are steps to help make this script easier for other to follow
All you have to do is add custom ACF post types into Step 1 and custom taxonomies into Step 10
[list_searcheable_acf list all the custom fields we want to include in our search query]
@return [array] [list of custom fields]
*/
/*
* [advanced_custom_search search that encompasses ACF/advanced custom fields and taxonomies and split expression before request]
* @param [query-part/string] $search [the initial "where" part of the search query]
* @param [object] $wp_query []
* @return [query-part/string] $search [the "where" part of the search query as we customized]
* modified from gist: https://gist.github.com/FutureMedia/9581381/73afa809f38527d57f4213581eeae6a8e5a1340a
* see https://vzurczak.wordpress.com/2013/06/15/extend-the-default-wordpress-search/
* credits to Vincent Zurczak for the base query structure/spliting tags section and Sjouw for comment cleanup
*/
function advanced_custom_search( $search, &$wp_query ) {
global $wpdb;
if (empty($search)) {
return $search;
}
// AND (((wp_posts.post_title LIKE '%venenatis%') OR (wp_posts.post_excerpt LIKE '%venenatis%') OR (wp_posts.post_content LIKE '%venenatis%'))) AND (wp_posts.post_password = '')
// 1- get search expression
$terms = $wp_query->query_vars['s'];
// 2- explode search expression to get search terms
$exploded = preg_split('|\s+|', $terms);
if ($exploded === FALSE || count($exploded) == 0) {
$exploded = array(0 => $terms);
}
// 3- setup search variable as a string
$search = '';
$params = array();
// 4- a list of advanced custom fields you want to search content in
$list_searcheable_acf = array(
"your",
"acf",
"non-repeater",
"field-names",
"here",
"repeater" => array(
"repeater-sub-field1",
"repeater-sub-field2"
)
);
// 5- search through tags, inject each into SQL query
foreach ($exploded as $tag) {
$s = '%' . $wpdb->esc_like($tag) . '%';
$search .= "
AND (
({$wpdb->posts}.post_title LIKE '%s')
OR ({$wpdb->posts}.post_excerpt LIKE '%s')
OR ({$wpdb->posts}.post_content LIKE '%s')
" .
// 8- Adds to $search DB data from custom post types
"OR EXISTS (
SELECT * FROM {$wpdb->postmeta}
WHERE post_id = {$wpdb->posts}.ID
AND (";
$params []= $s;
$params []= $s;
$params []= $s;
// 5b - reads through $list_searcheable_acf array to see which custom post types you want to include in the search string
$metaStatements = array();
foreach ($list_searcheable_acf as $key => $searcheable_acf) {
if (is_array($searcheable_acf)) {
foreach ($searcheable_acf as $repeater_acf) {
array_push($metaStatements, "(meta_key LIKE '" . $key . "_%%_" . $repeater_acf . "' AND meta_value LIKE '%s')");
$params []= $s;
}
} else {
array_push($metaStatements, "(meta_key = '" . $searcheable_acf . "' AND meta_value LIKE '%s')");
$params []= $s;
}
}
$search .= join($metaStatements, "\n OR ");
$search .= ")
) " .
// 6- Adds to $search DB data from comments
"OR EXISTS (
SELECT * FROM {$wpdb->comments}
WHERE comment_post_ID = {$wpdb->posts}.ID
AND comment_content LIKE '%s'
) " .
// 7 - Adds to $search DB data from taxonomies
"OR EXISTS (
SELECT * FROM {$wpdb->terms}
INNER JOIN {$wpdb->term_taxonomy}
ON {$wpdb->term_taxonomy}.term_id = {$wpdb->terms}.term_id
INNER JOIN {$wpdb->term_relationships}
ON {$wpdb->term_relationships}.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id " .
// 7b- Add custom taxonomies here
"WHERE (
taxonomy = 'your'
OR taxonomy = 'custom'
OR taxonomy = 'taxonomies'
OR taxonomy = 'here'
)
AND object_id = {$wpdb->posts}.ID
AND {$wpdb->terms}.name LIKE '%s'
)" .
")";
$params []= $s;
$params []= $s;
}
return $wpdb->prepare($search, $params);
} // closes function advanced_custom_search
// 8- use add_filter to put advanced_custom_search into the posts_search results
add_filter( 'posts_search', 'advanced_custom_search', 500, 2 );
@Garconis
Copy link

I clicked through about 5 different "forks" to find yours. Works great!

@Garconis
Copy link

Garconis commented Sep 13, 2017

Any idea how to return results only if all fields are present in the search? E.g, if I search for "Jane Doe", it shows results of people with just "Jane". It should only return results if the field(s) have "Jane Doe".

Edit: Hmm. Nevermind. It seemed to be using "OR" if I had the Taxonomy block removed. If I add it back in, it seems to use "AND".

@chrisnajman
Copy link

chrisnajman commented Jan 24, 2018

Hi - this works - thanks! However, the site I built uses a Flexible content field containing (among other things) repeaters and nested repeaters. Any clues as to how to modify your script to include these? I also need to target nested repeater fields (outside of a Flexible Content field).

UPDATE: WP Plugin 'Search Everything' was recommend to me - I installed it and it works for all my fields.

@Macuzzin
Copy link

Awesome - thank you! Works perfectly including repeaters. Does anyone know how to amend the code to include nested repeaters in the search?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment