Search code examples
symfonydoctrinecriteria

Criteria expression on ArrayCollection is case sensitive


I have an ArrayCollection from Hashtag entity (database/table collation both set to utf8_bin_ci) which I want to match on a Criteria but it's not case insensitive.

I've tried 'contains', 'eq', 'startsWith', 'endsWith' expressions, but it returns null on matching, however it has many results without the Criteria matching.

If I add strtolower / strtoupper to $this->name property, it works in the specified case.

How can I make it case-insensitive the Criteria or the matching here?

  public function getHashtags($max = null) {
    $hashtags = $this->hashtags;
    $hashtags->getIterator();
    $crit = Criteria::create()
                    ->where(Criteria::expr()->contains('name', $this->name))
    if (!empty($max)) {
      $crit->setMaxResults($max);
    }

    return $hashtags->matching($crit);
  }

Solution

  • Your code calls getIterator(), which will prevent any database magic from ever happening, because it initializes the collection (which loads all entries), so your collation doesn't matter anyway.

    Also, the contains function uses strpos, which obviously is not case-insensitive.

    Since your code already pulls in all hashtags, just filter it already:

    $hashtags = array_filter(function(Hashtag $hashtag) {
        return stripos($this->name, $hashtag->getName());
    }, $this->hashtags);
    if(!empty($max)) {
        $hashtags = array_slice($hashtags, 0, $max, true); 
        // remove true, if you don't care about keys  ^, this preserves them
    }
    return $hashtags;