/** * @param string $alias * @param QueryOptimizationContext $context * * @return bool */ protected function isPrimaryItemLeftJoin($alias, QueryOptimizationContext $context) { $join = $context->getJoinByAlias($alias); if ($join->getJoinType() !== Expr\Join::LEFT_JOIN || !$join->getCondition()) { return false; } $className = $context->getEntityClassByAlias($alias); if (!is_a($className, 'Oro\\Bundle\\FormBundle\\Entity\\PrimaryItem', true)) { return false; } $condition = trim($join->getCondition()); $matchResult = preg_match(sprintf(self::PRIMARY_CONDITION_PATTERN, $alias), $condition, $matches); if (!$matchResult || $matches[0] !== $condition) { return false; } return $this->isTrueValue($matches['value'], $context); }
/** * 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); }