最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Term begins with a letter

programmeradmin0浏览0评论

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 badges
Add a comment  | 

4 Answers 4

Reset to default 8

You 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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论