-
-
Save fiskhandlarn/f6f86c99e59f62d72ac2ce10be12dc1a to your computer and use it in GitHub Desktop.
<?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 | |
I also updated this work to include XSS and SQL injection projection | |
[list_searcheable_acf list all the custom fields we want to include in our search query] | |
@return [array] [list of custom fields] | |
*/ | |
// Define list of ACF fields you want to search through - do NOT include taxonomies here | |
function list_searcheable_acf(){ | |
$list_searcheable_acf = array( "your", | |
"acf", | |
"non-repeater", | |
"field-names", | |
"here", | |
"repeater" => array( "repeater-sub-field1", | |
"repeater-sub-field2" ) | |
); | |
return $list_searcheable_acf; | |
} | |
/* | |
* [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; | |
} | |
// 1- get search expression | |
$terms_raw = $wp_query->query_vars[ 's' ]; | |
// 2- check search term for XSS attacks | |
$terms_xss_cleared = strip_tags($terms_raw); | |
// 3- do another check for SQL injection, use WP esc_sql | |
$terms = esc_sql($terms_xss_cleared); | |
// 4- explode search expression to get search terms | |
$exploded = explode( ' ', $terms ); | |
if( $exploded === FALSE || count( $exploded ) == 0 ) { | |
$exploded = array( 0 => $terms ); | |
} | |
// 5- setup search variable as a string | |
$search = ''; | |
// 6- get searcheable_acf, a list of advanced custom fields you want to search content in | |
$list_searcheable_acf = list_searcheable_acf(); | |
// 7- get custom table prefixes, thanks to Brian Douglas @bmdinteractive on github for this improvement | |
$table_prefix = $wpdb->prefix; | |
// 8- search through tags, inject each into SQL query | |
foreach( $exploded as $tag ) { | |
$search .= " | |
AND ( | |
(".$table_prefix."posts.post_title LIKE '%$tag%') | |
OR (".$table_prefix."posts.post_excerpt LIKE '%$tag%') | |
OR (".$table_prefix."posts.post_content LIKE '%$tag%') | |
". | |
// 9- Adds to $search DB data from custom post types | |
"OR EXISTS ( | |
SELECT * FROM ".$table_prefix."postmeta | |
WHERE post_id = ".$table_prefix."posts.ID | |
AND ("; | |
// 9b - 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 '%$tag%')" ); | |
} | |
} | |
else { | |
array_push( $metaStatements, "(meta_key = '" . $searcheable_acf . "' AND meta_value LIKE '%$tag%')" ); | |
} | |
} | |
$search .= join( $metaStatements, "\n OR " ); | |
$search .= ") | |
)". | |
// 10- Adds to $search DB data from comments | |
"OR EXISTS ( | |
SELECT * FROM ".$table_prefix."comments | |
WHERE comment_post_ID = ".$table_prefix."posts.ID | |
AND comment_content LIKE '%$tag%' | |
)". | |
// 11 - Adds to $search DB data from taxonomies | |
"OR EXISTS ( | |
SELECT * FROM ".$table_prefix."terms | |
INNER JOIN ".$table_prefix."term_taxonomy | |
ON ".$table_prefix."term_taxonomy.term_id = ".$table_prefix."terms.term_id | |
INNER JOIN ".$table_prefix."term_relationships | |
ON ".$table_prefix."term_relationships.term_taxonomy_id = ".$table_prefix."term_taxonomy.term_taxonomy_id". | |
// 11b- Add custom taxonomies here | |
" WHERE ( | |
taxonomy = 'your' | |
OR taxonomy = 'custom' | |
OR taxonomy = 'taxonomies' | |
OR taxonomy = 'here' | |
) | |
AND object_id = ".$table_prefix."posts.ID | |
AND ".$table_prefix."terms.name LIKE '%$tag%' | |
)". | |
")"; // closes $search | |
} // closes foreach | |
return $search; | |
} // closes function advanced_custom_search | |
// 12- use add_filter to put advanced_custom_search into the posts_search results | |
add_filter( 'posts_search', 'advanced_custom_search', 500, 2 ); |
Could it be this?
array_push( $metaStatements, "(meta_key LIKE '" . $key . "_%_" . $repeater_acf . "' AND meta_value LIKE '%$tag%')" );
array_push( $metaStatements, "(meta_key LIKE '" . $key . "_%_" . $group_acf . "' AND meta_value LIKE '%$tag%')" );
For search inside "groups" in AFC? (otherwise it doesn't return any content in my case).
Could someone please give me an example of how this works?
$return_array = advanced_custom_search("12345", $WP_query);
//nothing comes out
print_r($return_array);
//spits out a query but I don't understand where to go from here.
echo $WP_query;
//where do I put the $WP_query?
echo WP_Query($WP_query);
@ac0ua Not sure what you're trying to achieve, but $wp_query
is supplied by the filter: https://gist.github.com/fiskhandlarn/f6f86c99e59f62d72ac2ce10be12dc1a#file-custom-search-acf-wordpress-php-L125
@fiskhandlarn
names of custom fields
$list_searcheable_acf = array( "services_short_description", "header_basic_heading", "header_basic_subhead", "menu_items" => array( "menu_item", "menu_submenu", "submenu_items" ), );
I am also using the MAMP stack for MACs, I say this because I am used to XXAMP sometimes there are obscure security setting that may get in my way.
Sorry I am new to WP and I feel like I am trying to do something advanced. Okay so the SQL query is returned by "advanced_custom_search("ac0ua", $WP_Query);"
togenter when I use this URL.com/search/?search=ac0ua (The URL was originally setup to use 's' but s was not working for me. I used 'search' instead query_var.)
Okay I got this far I have an
- SQL query
- the query has a bunch of lines with "LIKE %acoua%"
- all my custom fields in the array and are showing up in the returned SQL
Where is this query designed to run? I have tried to use phpmyadmin by selecting my DB and clicking the SQL tab and pasting it into the textarea, but I get an error.
Unrecognized statement type. (near "AND" at position 0)
@ac0ua
I haven't used this gist in a couple of years so I'm not sure if the resulting SQL is correct with current WP version and/or any plugins you may be using. Maybe there is a plugin with active development that solves this wanted behaviour nowadays?
The resulting SQL is run by WP itself, but if the SQL statement is malformed it won't work. I would start by analyzing the whole SQL statement (i.e. echo $search
just before it's returned). Good luck. :)
Works perfectly.
Thanks!