示例#1
0
 /**
  * Returns a query builder that could be used for fetching the list of owner side entities
  * the specified $associationTargetClass associated with.
  * The $filters and $joins could be used to filter entities
  *
  * The resulting query would be something like this:
  * <code>
  * SELECT entity.entityId AS id, entity.entityClass AS entity, entity.entityTitle AS title FROM (
  *      SELECT [DISTINCT]
  *          target.id AS id,
  *          e.id AS entityId,
  *          {first_owner_entity_class} AS entityClass,
  *          {first_owner_title} AS entityTitle
  *      FROM {first_owner_entity_class} AS e
  *          INNER JOIN e.{target_field_name_for_first_owner} AS target
  *          {joins}
  *      WHERE {filters}
  *      UNION ALL
  *      SELECT [DISTINCT]
  *          target.id AS id,
  *          e.id AS entityId,
  *          {second_owner_entity_class} AS entityClass,
  *          {second_owner_title} AS entityTitle
  *      FROM {second_owner_entity_class} AS e
  *          INNER JOIN e.{target_field_name_for_second_owner} AS target
  *          {joins}
  *      WHERE {filters}
  *      UNION ALL
  *      ... select statements for other owners
  * ) entity
  * ORDER BY {orderBy}
  * LIMIT {limit} OFFSET {(page - 1) * limit}
  * </code>
  *
  * @param string        $associationTargetClass The FQCN of the entity that is the target side of the association
  * @param mixed|null    $filters                Criteria is used to filter entities which are association owners
  *                                              e.g. ['age' => 20, ...] or \Doctrine\Common\Collections\Criteria
  * @param array|null    $joins                  Additional associations required to filter owning side entities
  * @param array         $associationOwners      The list of fields responsible to store associations between
  *                                              the given target and association owners
  *                                              Array format: [owner_entity_class => field_name]
  * @param int|null      $limit                  The maximum number of items per page
  * @param int|null      $page                   The page number
  * @param string|null   $orderBy                The ordering expression for the result
  * @param callable|null $callback               A callback function which can be used to modify child queries
  *                                              function (QueryBuilder $qb, $ownerEntityClass)
  *
  * @return SqlQueryBuilder
  */
 public function getMultiAssociationOwnersQueryBuilder($associationTargetClass, $filters, $joins, $associationOwners, $limit = null, $page = null, $orderBy = null, $callback = null)
 {
     $em = $this->doctrineHelper->getEntityManager($associationTargetClass);
     $criteria = QueryUtils::normalizeCriteria($filters);
     $selectStmt = null;
     $subQueries = [];
     $targetIdFieldName = $this->doctrineHelper->getSingleEntityIdentifierFieldName($associationTargetClass);
     foreach ($associationOwners as $ownerClass => $fieldName) {
         $nameExpr = $this->entityNameResolver->getNameDQL($ownerClass, 'e');
         $subQb = $em->getRepository($ownerClass)->createQueryBuilder('e')->select(sprintf('target.%s AS id, e.id AS entityId, \'%s\' AS entityClass, ' . ($nameExpr ?: '\'\'') . ' AS entityTitle', $targetIdFieldName, str_replace('\'', '\'\'', $ownerClass)))->innerJoin('e.' . $fieldName, 'target');
         QueryUtils::applyJoins($subQb, $joins);
         $subQb->addCriteria($criteria);
         if (null !== $callback && is_callable($callback)) {
             call_user_func($callback, $subQb, $ownerClass);
         }
         $subQuery = $this->getAclHelper()->apply($subQb);
         $subQueries[] = QueryUtils::getExecutableSql($subQuery);
         if (empty($selectStmt)) {
             $mapping = QueryUtils::parseQuery($subQuery)->getResultSetMapping();
             $selectStmt = sprintf('entity.%s AS id, entity.%s AS entity, entity.%s AS title', QueryUtils::getColumnNameByAlias($mapping, 'entityId'), QueryUtils::getColumnNameByAlias($mapping, 'entityClass'), QueryUtils::getColumnNameByAlias($mapping, 'entityTitle'));
         }
     }
     $rsm = new ResultSetMapping();
     $rsm->addScalarResult('id', 'id', Type::INTEGER)->addScalarResult('entity', 'entity')->addScalarResult('title', 'title');
     $qb = new SqlQueryBuilder($em, $rsm);
     $qb->select($selectStmt)->from('(' . implode(' UNION ALL ', $subQueries) . ')', 'entity');
     if (null !== $limit) {
         $qb->setMaxResults($limit);
         if (null !== $page) {
             $qb->setFirstResult(QueryUtils::getPageOffset($page, $limit));
         }
     }
     if ($orderBy) {
         $qb->orderBy($orderBy);
     }
     return $qb;
 }
示例#2
0
 public function testApplyJoins()
 {
     $joins = ['emails' => null, 'phones', 'contacts' => [], 'accounts' => ['join' => 'accounts_field'], 'users' => ['join' => 'accounts.users_field', 'condition' => 'users.active = true', 'conditionType' => 'WITH'], 'products' => ['condition' => 'products.active = true']];
     $qb = $this->getMockBuilder('Doctrine\\ORM\\QueryBuilder')->disableOriginalConstructor()->getMock();
     $qb->expects($this->once())->method('distinct')->with(true);
     $qb->expects($this->once())->method('getRootAliases')->willReturn(['root_alias']);
     $qb->expects($this->at(2))->method('leftJoin')->with('root_alias.emails', 'emails');
     $qb->expects($this->at(3))->method('leftJoin')->with('root_alias.phones', 'phones');
     $qb->expects($this->at(4))->method('leftJoin')->with('root_alias.contacts', 'contacts');
     $qb->expects($this->at(5))->method('leftJoin')->with('root_alias.accounts_field', 'accounts');
     $qb->expects($this->at(6))->method('leftJoin')->with('accounts.users_field', 'users', 'WITH', 'users.active = true');
     $qb->expects($this->at(7))->method('leftJoin')->with('root_alias.products', 'products', 'WITH', 'products.active = true');
     QueryUtils::applyJoins($qb, $joins);
 }
示例#3
0
 /**
  * Applies the given joins for the query builder
  *
  * @param QueryBuilder $qb
  * @param array|null   $joins
  *
  * @deprecated since 1.9. Use QueryUtils::applyJoins instead
  */
 public function applyJoins(QueryBuilder $qb, $joins)
 {
     QueryUtils::applyJoins($qb, $joins);
 }
示例#4
0
 /**
  * Applies the given joins for the query builder
  *
  * @param QueryBuilder $qb
  * @param array|null   $joins
  */
 protected function applyJoins($qb, $joins)
 {
     QueryUtils::applyJoins($qb, $joins);
 }