public
Last active

Adds FIND_IN_SET support as a comparison operator for WordPress meta_query. Include this in a plugin, in the theme's functions.php file, or as a separate file that is loaded using require() or include() before your call to WP_Query. As @Otto42 points out, you might not want to use this in a plugin that you plan to distribute given the WordPress' teams interest in supporting other databases beyond MySQL at some time in the distant future.

  • Download Gist
find-in-set.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
<?php
/**
* Class Add_Find_In_Set_Compare_To_Meta_Query
*/
class Add_Find_In_Set_Compare_To_Meta_Query {
 
/**
*
*/
function __construct() {
add_action( 'posts_where', array( $this, 'posts_where' ), 10, 2 );
}
 
/**
* Adds value 'find_in_set' to meta query 'compare' var for WP_Query
*
* query['meta_query'][{n}]['compare'] => 'find_in_set'
* @example This will find in set where _related_post_ids is a string of comma separated post IDs.
*
* $query = new WP_Query( array(
* 'posts_per_page' => -1,
* 'post_type' => 'post'
* 'meta_query' => array(
* array(
* 'key' => '_related_post_ids',
* 'value' => $related_post->ID,
* 'compare' => 'find_in_set',
* )
* ),
* );
*
* @param array $where
* @param object $query
*
* @return array
*/
function posts_where( $where, $query ) {
global $wpdb;
foreach( $query->meta_query->queries as $index => $meta_query ) {
if ( isset( $meta_query['compare'] ) && 'find_in_set' == strtolower( $meta_query['compare'] ) ) {
$regex = "#\(({$wpdb->postmeta}.meta_key = '" . preg_quote( $meta_query['key'] ) . "')" .
" AND (CAST\({$wpdb->postmeta}.meta_value AS CHAR\)) = ('" . preg_quote( $meta_query['value'] ) . "')\)#";
/**
* Replace the compare '=' with compare 'find_in_set'
*/
$where = preg_replace( $regex, "($1 AND FIND_IN_SET($3,$2))", $where );
}
}
return $where;
}
 
}
new Add_Find_In_Set_Compare_To_Meta_Query();

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.