[Doctrine] Add a like condition using DQL

Published on 2019-01-08 • Modified on 2019-01-08

The trick here is that the like must be in the where clause andWhere() whereas the wildcard character % must be passed to the setParameter() function.


<?php declare(strict_types=1);

namespace App\Entity;

/**
 * @method findOneBySlug(string $slug) ?Article
 */
class ArticleRepository extends BaseRepository
{
    public function findForLang(int $type, string $lang, string $keyword = null, ?int $maxResults = null): array
    {
        $qb = $this->createQueryBuilder('a')
            ->where('a.type = :type')
            ->setParameter('type', $type)
            ->andWhere('a.inLanguage LIKE :inLanguage')
            ->setParameter('inLanguage', '%'.$lang.'%')
            ->addOrderBy('a.datePublished', 'desc');

        if (null !== $keyword) {
            $qb->andWhere('a.keyword LIKE :keyword')
            ->setParameter('keyword', '%'.$keyword.'%');
        }

        if (null !== $maxResults) {
            $qb->setMaxResults($maxResults);
        }

        return $qb->getQuery()->execute();
    }
}
Bonus, the snippet to run this code: 🎉
<?php declare(strict_types=1);

namespace App\Controller\Snippet;

use App\Entity\Article;
use App\Repository\ArticleRepository;
use App\Repository\ArticleTypeRepository;

/**
 * I am using a PHP trait in order to isolate each snippet in a file.
 * This code should be called from a Symfony controller extending AbstractController (as of Symfony 4.2)
 * or Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Services are injected in the main controller constructor.
 *
 * @property ArticleRepository $articleRepo
 */
trait Snippet11Trait
{
    public function snippet11(): void
    {
        $articles = $this->articleRepo->findForLang(ArticleTypeRepository::TYPE_SNIPPET, 'en', 'DQL');
        $article = $articles[0] ?? null;

        if (!$article instanceof Article) {
            throw new \RuntimeException('No article was found.');
        }

        echo sprintf("Article: %s\n", $article->getName() ?? '');
        echo sprintf('Keywords: %s', $article->getKeyword() ?? '');

        // That's it! 😁
    }
}