/** * Builds a map relating the database field alias (the alias in the SELECT statement) and the * actual entity field (as in JOINED_ENTITY.field or FROM_ENTITY.field) in order to use them * within the WHERE statement. * * @param Query $query * * @return array */ protected function buildSelectFieldMap(Query $query) { $selectFieldsMap = []; $requiredFields = $this->requiredFieldsExtractor->extractRequiredFields($query); $joins = $this->joinsGenerator->generate($query); foreach ($this->queryBuilderDataSourceFields as $element) { if (!in_array($element->getUniqueName(), $requiredFields, true)) { continue; } if (is_null($element->getDatabaseFilterQueryField())) { continue; } $fieldIdentifier = $element->getDatabaseSelectAlias(); if (is_array($fieldIdentifier)) { $fieldIdentifier = str_replace('.', '_', $element->getDatabaseFilterQueryField()); } $fieldParts = explode('.', $element->getDatabaseFilterQueryField()); if (count($fieldParts) === 1) { $selectFieldsMap[$fieldIdentifier] = $this->fromAlias . '.' . array_slice($fieldParts, -1, 1)[0]; } else { $joinField = implode('.', array_slice($fieldParts, 0, -1)); foreach ($joins as $path => $join) { if ($path == $joinField) { $selectFieldsMap[$fieldIdentifier] = $join->getAlias() . '.' . array_slice($fieldParts, -1, 1)[0]; break; } } } } return $selectFieldsMap; }
/** * Gets the fully generated query builder. Will autogenerate select and * join statements as needed. * * This function is cached, and will only be generated once per execution. * * @param Query $query * * @return QueryBuilder|null */ public function buildQueryBuilder(Query $query, $entityClass) { $queryBuilder = $this->entityManager->createQueryBuilder(); $queryBuilder->from($entityClass, $this->getFromAlias()); $select = $this->selectGenerator->generate($query); $event = new GenerateSelectsEvent($select, $this->getFromAlias()); $this->dataSource->getEventDispatcher()->dispatch(DoctrineDriver::EVENT_GENERATE_SELECTS, $event); $select = $event->select; $queryBuilder->add('select', $select); $joins = $this->joinGenerator->generate($query); $event = new GenerateJoinsEvent($this->getFromAlias(), $joins); $this->dataSource->getEventDispatcher()->dispatch(DoctrineDriver::EVENT_GENERATE_JOINS, $event); $joins = $event->joins; foreach ($joins as $join) { $queryBuilder->leftJoin($join->getJoin(), $join->getAlias(), $join->getConditionType(), $join->getCondition(), $join->getIndexBy()); } $this->filterer->filter($queryBuilder, $query->getFilter(), $this->selectGenerator->getUniqueNameToSelectFieldMap($query)); $this->sorter->sort($queryBuilder, $query->getSort(), $this->selectGenerator->getUniqueNameToSelectFieldMap($query)); $this->paginator->paginate($queryBuilder, $query->getPagination(), $this->dataSource->getFields()); $this->dataSource->getEventDispatcher()->dispatch(DoctrineDriver::EVENT_POST_GENERATE_QUERY_BUILDER, new PostGenerateQueryBuilderEvent($queryBuilder, $this->getFromAlias())); return $queryBuilder; }