Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace App\Doctrine\ORM\Repository;
- use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
- use Doctrine\ORM\QueryBuilder;
- abstract class AbstractRepository extends ServiceEntityRepository
- {
- /**
- * Parses a nested array and adds expressions to a query builder
- *
- * Example Array:
- *
- * Input:
- *
- * $criteria = [
- * 'condition' => 'andX',
- * 'expressions' => [
- * [
- * 'propertyPath' => 'taskList.project.id',
- * 'operator' => 'eq',
- * 'value' => '1',
- * ],
- * [
- * 'propertyPath' => 'taskList.project.workspace.id',
- * 'operator' => 'eq',
- * 'value' => '1',
- * ],
- * ],
- * ];
- *
- * DQL:
- *
- * SELECT Task
- * FROM App\Entity\Task Task
- * INNER JOIN Task.taskList taskList
- * INNER JOIN Task.project taskList_project
- * INNER JOIN Task.workspace taskList_project_workspace
- * WHERE taskList_project.id = 1
- * AND taskList_project_workspace.id = 1
- *
- * @param QueryBuilder $qb
- * @param array $criteria
- * @param null $alias
- */
- public function filterByCriteria(QueryBuilder $qb, array $criteria, $alias = null)
- {
- $alias = $alias ?: $qb->getRootAliases()[0];
- $expressionBuilder = $this->getEntityManager()->getExpressionBuilder();
- $expressions = [];
- foreach ($criteria['expressions'] as $expression) {
- if (key_exists('condition', $expression)) {
- $expressions[] = $this->filterByCriteria($qb, $expression, $alias);
- } else {
- // Get the operator and value
- switch ($expression['operator']) {
- case 'eq':
- case 'neq':
- case 'lt':
- case 'lte':
- case 'gt':
- case 'gte':
- case 'between':
- case 'isNull':
- case 'isNotNull':
- break;
- case 'startsWith':
- $expression['operator'] = 'LIKE';
- $expression['value'] = $expression['value'] . '%';
- break;
- case 'endsWith':
- $expression['operator'] = 'LIKE';
- $expression['value'] = '%' . $expression['value'];
- break;
- case 'contains':
- $expression['operator'] = 'LIKE';
- $expression['value'] = '%' . $expression['value'] . '%';
- break;
- }
- // Explode the property path into it's parts
- $propertyPathParts = explode('.', $expression['propertyPath']);
- // Pop the property off the end
- $property = array_pop($propertyPathParts);
- /*
- * Property is a dot delimited list.
- * We need to make sure each alias is added
- * These next few lines add the joins if required
- *
- * - task.taskList -> `$qb->join(task.taskList taskList)`
- * - task.taskList.project -> `$qb->join(taskList.project taskList_project)`
- * - task.taskList.project.workspace -> `$qb->oin(taskList_project.workspace taskList_project_workspace)`
- */
- $joinAlias = $alias;
- foreach($propertyPathParts as $count => $propertyPart) {
- $join = sprintf('%s.%s', $alias, $propertyPart);
- $joinAlias = implode("_", array_slice($propertyPathParts, 0, $count+1));
- if(!in_array($joinAlias, $qb->getAllAliases())) {
- $qb->join($join, $joinAlias);
- }
- }
- // Now we have the final alias
- // Join the alias and the property together
- $expression['propertyPath'] = sprintf('%s.%s', $joinAlias, $property);
- // Create the arguments
- $expressionArguments = [$expression['propertyPath'], $expression['value']];
- // Create the expression
- $expressions[] = call_user_func_array(
- [$expressionBuilder, $expression['operator']],
- $expressionArguments
- );
- }
- }
- // Apply all the expressions
- $expression = call_user_func_array([
- $expressionBuilder,
- $criteria['condition'],
- ], $expressions);
- $qb->andWhere($expression);
- }
- }
Add Comment
Please, Sign In to add comment