Term begins with a letter

I had a template that relied on

$terms = get_terms( "ingredient", array( 'name__like' => $letter ) );

Read More

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?

Related posts

4 comments

  1. 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 ) )
    
  2. 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.

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

Comments are closed.