Skip to content

Instantly share code, notes, and snippets.

@damianociarla
Created August 16, 2017 13:14
Show Gist options
  • Save damianociarla/7b4f9c4e2da3bc8c367cba4aa718e4ed to your computer and use it in GitHub Desktop.
Save damianociarla/7b4f9c4e2da3bc8c367cba4aa718e4ed to your computer and use it in GitHub Desktop.
Helps you not duplicate DQL parts in your queries
<?php
namespace Helper;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
class DoctrineQueryPart
{
/**
* Add join if not present
*
* @param QueryBuilder $qb Query build to apply the join
* @param string $fromTableAlias Start table alias
* @param string $field Name of the field
* @param string $toTableAlias Alias of the table represented by $field
* @param string $type Type of the join. inner|left
* @throws \UnexpectedValueException
*/
public static function addJoinIfNotExists(QueryBuilder $qb, string $fromTableAlias, string $field, string $toTableAlias, string $type = 'inner'): void
{
$joinParts = $qb->getDQLPart('join');
$join = $fromTableAlias.'.'.$field;
if (count($joinParts) > 0) {
if (!array_key_exists($fromTableAlias, $joinParts)) {
return;
}
foreach ($joinParts[$fromTableAlias] as $joinPart) {
if ($joinPart->getJoin() === $join) {
return;
}
}
}
switch ($type) {
case 'inner':
$qb->innerJoin($join, $toTableAlias);
break;
case 'left':
$qb->leftJoin($join, $toTableAlias);
break;
default:
throw new \UnexpectedValueException('Unexpected type');
break;
}
}
/**
* Add join on unmapped table if not present
*
* @param QueryBuilder $qb Query build to apply the join
* @param string $primaryTableAlias Main table Alias
* @param string $joinEntityClass Extended entity class to join. Namespace\Of\The\Entity::class
* @param string $joinTableAlias Alias of the table represented by $joinEntityClass
* @param string $condition DQL Condition to join the entity
* @param string $type Type of the join. inner|left
*/
public static function addUnmappedJoinIfNotExists(QueryBuilder $qb, string $primaryTableAlias, string $joinEntityClass, string $joinTableAlias, string $condition, string $type = 'inner'): void
{
$joinParts = $qb->getDQLPart('join');
if (count($joinParts) > 0) {
if (!array_key_exists($primaryTableAlias, $joinParts)) {
return;
}
/** @var \Doctrine\ORM\Query\Expr\Join $joinPart */
foreach ($joinParts[$primaryTableAlias] as $joinPart) {
if ($joinPart->getJoin() === $joinEntityClass && $joinPart->getAlias() === $joinTableAlias) {
return;
}
}
}
switch ($type) {
case 'inner':
$qb->innerJoin($joinEntityClass, $joinTableAlias, Join::WITH, $condition);
break;
case 'left':
$qb->leftJoin($joinEntityClass, $joinTableAlias, Join::WITH, $condition);
break;
default:
throw new \UnexpectedValueException('Unexpected type');
break;
}
}
/**
* Add select condition if not present
*
* @param QueryBuilder $qb Query build to apply the select
* @param string $select
*/
public static function addSelectIfNotExists(QueryBuilder $qb, string $select): void
{
/** @var \Doctrine\ORM\Query\Expr\Select[] $selectParts */
$selectParts = $qb->getDQLPart('select');
if (count($selectParts) > 0) {
foreach ($selectParts as $selectPart) {
foreach ($selectPart->getParts() as $existingSelect) {
if ($existingSelect === $select) {
return;
}
}
}
}
$qb->addSelect($select);
}
/**
* Add group by condition if not present
*
* @param QueryBuilder $qb Query build to apply the group by
* @param string $groupBy
*/
public static function addGroupByIfNotExists(QueryBuilder $qb, string $groupBy): void
{
/** @var \Doctrine\ORM\Query\Expr\GroupBy[] $groupByParts */
$groupByParts = $qb->getDQLPart('groupBy');
if (count($groupByParts) > 0) {
foreach ($groupByParts as $groupByPart) {
foreach ($groupByPart->getParts() as $existingGroupBy) {
if ($existingGroupBy === $groupBy) {
return;
}
}
}
}
$qb->addGroupBy($groupBy);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment