I’ve been playing around with code snippets which add meta data to admin searches.
The best snippet I’ve found was written by Stefano on this question.
However, it appears to have 1, annoying bug when searching non-meta terms.
Here are some grabs from my local dev install. I’ve printed the 2 MySQL queries onto the screen.
View of the single CPT post I’m using to test
This is the code working as expected and allowing me to search meta data from admin
Unfortunately the code creates duplicates on non-meta matches, in this case on post title
A grab showing the post status, post type and post ancestors of dupes
!A grab showing the post status, post type and post ancestors of dupes
Here is the code I’m running, it’s basically the same as Stefano’s, but with my crude attempts to make the query work.
/*
* Search custom fields from admin keyword searches
*/
function rel_search_join( $join ) {
global $pagenow, $wpdb;
if ( is_admin() && $pagenow == 'edit.php' && $_GET['post_type'] == 'listings' && $_GET['s'] != '') {
$join .= 'LEFT JOIN ' . $wpdb->postmeta . ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
}
echo '<br><strong>JOIN</strong>: ';
print_r ( $join );
echo '<br>';
return $join;
}
add_filter('posts_join', 'rel_search_join' );
function rel_search_where( $where ) {
global $pagenow, $wpdb;
if ( is_admin() && $pagenow == 'edit.php' && $_GET['post_type']=='listings' && $_GET['s'] != '' ) {
$where = preg_replace( "/(s*".$wpdb->posts.".post_titles+LIKEs*('[^']+')s*)/", "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
$where = str_replace( "OR wp_posts.post_status = 'pending'", "", $where );
$where = str_replace( "OR wp_posts.post_status = 'private'", "", $where );
$where = str_replace( "OR wp_posts.post_status = 'draft'", "", $where );
$where = str_replace( "OR wp_posts.post_status = 'future'", "", $where );
}
echo '<br><strong>WHERE</strong>: ';
print_r ( $where );
echo '<br>';
return $where;
}
add_filter( 'posts_where', 'rel_search_where' );
A
GROUP BY
statement can group your posts after theJOIN
. For WordPress you can use theposts_groupby
filter.Thanks for your work on this, folks. This code got me most of the way there, but using WP 3.8 I was getting a SQL non-unique table/alias error, so I made some changes. For it to work on my setup I had to set a $wpdb->postmeta alias that was used in the JOIN statement. I also check only check once to see if the hooks should be used so they don’t fire every time. Hope this helps someone!