private function buildTree()
{
uksort($this->eagerLoads, 'strcmp');
$di = DI::getDefault();
$mM = $di['modelsManager'];
$eagerLoads = $resolvedRelations = [];
foreach ($this->eagerLoads as $relationAliases => $queryConstraints) {
$nestingLevel = 0;
$relationAliases = explode('.', $relationAliases);
$nestingLevels = count($relationAliases);
do {
do {
$alias = $relationAliases[$nestingLevel];
$name = join('.', array_slice($relationAliases, 0, $nestingLevel + 1));
} while (isset($eagerLoads[$name]) && ++$nestingLevel);
if ($nestingLevel === 0) {
$parentClassName = $this->subjectClassName;
} else {
$parentName = join('.', array_slice($relationAliases, 0, $nestingLevel));
$parentClassName = $resolvedRelations[$parentName]->getReferencedModel();
if ($parentClassName[0] === '\\') {
ltrim($parentClassName, '\\');
}
}
if (!isset($resolvedRelations[$name])) {
$mM->load($parentClassName);
$relation = $mM->getRelationByAlias($parentClassName, $alias);
if (!$relation instanceof Relation) {
throw new \RuntimeException(sprintf('There is no defined relation for the model `%s` using alias `%s`', $parentClassName, $alias));
}
$resolvedRelations[$name] = $relation;
} else {
$relation = $resolvedRelations[$name];
}
$relType = $relation->getType();
if ($relType !== Relation::BELONGS_TO && $relType !== Relation::HAS_ONE && $relType !== Relation::HAS_MANY && $relType !== Relation::HAS_MANY_THROUGH) {
throw new \RuntimeException(sprintf('Unknown relation type `%s`', $relType));
}
if (is_array($relation->getFields()) || is_array($relation->getReferencedFields())) {
throw new \RuntimeException('Relations with composite keys are not supported');
}
$parent = $nestingLevel > 0 ? $eagerLoads[$parentName] : $this;
$constraints = $nestingLevel + 1 === $nestingLevels ? $queryConstraints : null;
$eagerLoads[$name] = new EagerLoad($relation, $constraints, $parent);
} while (++$nestingLevel < $nestingLevels);
}
return $eagerLoads;
}