/** * Get join aliases that will produce non symmetric results * (many-to-one left join or one-to-many right join) * * @param Expr\From[] $fromStatements * @param array $joins * @param string $groupByAliases the aliases that was used in GROUP BY statement * * @return array */ protected function getNonSymmetricJoinAliases($fromStatements, $joins, $groupByAliases) { $aliases = []; $dependencies = $this->getNonSymmetricJoinDependencies($fromStatements, $joins); foreach ($dependencies as $alias => $joinInfo) { $join = $this->context->getJoinByAlias($alias); // skip joins that is not left joins or was not used in GROUP BY statement, // if it was a GROUP BY statement at all if ($join->getJoinType() !== Expr\Join::LEFT_JOIN || !empty($groupByAliases) && !in_array($alias, $groupByAliases, true)) { continue; } // if there is just association expression like `alias.fieldName` $parts = explode('.', $join->getJoin()); if (count($parts) === 2) { $associationType = $this->context->getAssociationType($parts[0], $parts[1]); if ($associationType & ClassMetadata::TO_MANY) { $aliases[] = $alias; } } else { // otherwise there is an entity name $joinEntityClass = $this->context->getEntityClassByAlias($join->getAlias()); $aliasToAssociation = []; // [alias => associationName, ...] $fields = $this->qbTools->getFields($join->getCondition()); foreach ($fields as $field) { $fieldParts = explode('.', $field); $aliasToAssociation[$fieldParts[0]] = $fieldParts[1]; } // for each alias the current join is depended (this alias is called as $dependeeAlias): // - resolve it's entity class // - check the relations foreach ($joinInfo[1] as $dependeeAlias) { $dependeeClass = $this->context->getEntityClassByAlias($dependeeAlias); $associationName = array_key_exists($dependeeAlias, $aliasToAssociation) ? $aliasToAssociation[$dependeeAlias] : $aliasToAssociation[$alias]; if ($this->isToManyAssociation($dependeeClass, $associationName, $joinEntityClass)) { $aliases[] = $alias; } } } } return array_unique($aliases); }
/** * @dataProvider fieldsDataProvider * @param string $condition * @param array $expected */ public function getFields($condition, $expected) { $tools = new QueryBuilderTools(); $this->assertEquals($expected, $tools->getFields($condition)); }