I had a template that relied on
$terms = get_terms( "ingredient", array( 'name__like' => $letter ) );
to return all posts where the custom taxonomy ingredient
begins with $letter
.
The behaviour of name__like
was changed in WP 3.7 to a text search instead of beginning.
What function can I use to achieve the results I had before? Do I need a custom query?
I had a template that relied on
$terms = get_terms( "ingredient", array( 'name__like' => $letter ) );
to return all posts where the custom taxonomy ingredient
begins with $letter
.
The behaviour of name__like
was changed in WP 3.7 to a text search instead of beginning.
What function can I use to achieve the results I had before? Do I need a custom query?
Share Improve this question asked Nov 14, 2013 at 19:42 P_EnriqueP_Enrique 2343 silver badges9 bronze badges4 Answers
Reset to default 8You will need to filter the query, which you can do with the terms_clauses
hook. This is very similar to G-M's solution but does not require a prefix on your search string.
function old_style_name_like_wpse_123298($clauses) {
remove_filter('term_clauses','old_style_name_like_wpse_123298');
$pattern = '|(name LIKE )\'%(.+%)\'|';
$clauses['where'] = preg_replace($pattern,'$1 \'$2\'',$clauses['where']);
return $clauses;
}
add_filter('terms_clauses','old_style_name_like_wpse_123298');
// $letter = 'str'; // test
$terms = get_terms( "ingredient", array( 'name__like' => $letter ) )
This is a trick.
Prepend to the letter you want to search a strange string:
$letter = '§§§' . 'a'; // strange string plus the letter you want to search
Then apply a filter to terms_clauses
hook:
add_filter('terms_clauses', 'replace_name__like_for_ingredients', 10, 3);
$terms = get_terms( "ingredient", array( 'name__like' => $letter ) );
Finally use that function to remove the %
preceding the strange string and the strange string itself:
function replace_name__like_for_ingredient( $pieces, $taxonomies, $args ) {
if ( in_array('ingredient', $taxonomies) ) {
// replace the perc sign plus strange string with empty string so
// LIKE '%§§§a%' become LIKE 'a%'
$pieces['where'] = str_replace("%§§§", '', $pieces['where']);
}
return $pieces;
}
Untested.
I can't comment on the previous answers, so I'll add this note here in case anyone else faces this problem too: The above wasn't working for me, so I replaced:
$pattern = '|(name LIKE )\'%(.+%)\'|';
with
$pattern = '|(name LIKE )\'{.*?}(.+{.*?})\'|';
as suggested here: https://stackoverflow/questions/47840519/listing-custom-taxonomy-terms-by-first-letter-using-name-like-does-not-work-ev
Based on gmazaap's reply, I got this:
$terms_array = [
'taxonomy' => 'pa_myattr',
'name__like' => '§§§' . 'A'
];
$terms = get_terms($terms_array);
add_filter('terms_clauses', 'replace_name__like_for_product_attribute', 10, 3);
function replace_name__like_for_product_attribute($pieces, $taxonomies, $args)
{
if (in_array('pa_myattr', $taxonomies)) {
// replace the perc sign plus strange string with empty string so
// LIKE '{abc..}§§§a{abc...}' become LIKE 'A%'
$pieces['where'] = preg_replace('/(.* LIKE ).*§§§([A-Z])(.*)/', '$1\'$2$3', $pieces['where']);
}
return $pieces;
}
Tested with WordPress 5.2.2
Had to modify the regular str_replace with a preg_match because now WordPress seems to add something like a hash to protect SQL injections. Since this string seems to be random between queries the only solution is to use regex.