private function parseCondition(array $levels, IMapper $mapper)
{
/** @var IDbStorageReflection $reflection */
$reflection = $mapper->getStorageReflection();
$expression = '';
$column = array_pop($levels);
$entityMD = $this->metadataStorage->get($mapper->getRepository()->getEntityClassNames()[0]);
foreach ($levels as $level) {
if (!$entityMD->hasProperty($level)) {
throw new InvalidArgumentException("Undefined property {$entityMD->className}::\${$level}.");
}
$propertyMD = $entityMD->getProperty($level);
if (!$propertyMD->relationshipRepository) {
throw new InvalidArgumentException("Entity {$entityMD->className}::\${$level} does not contain a relationship.");
}
$targetMapper = $this->model->getRepository($propertyMD->relationshipRepository)->getMapper();
$targetReflection = $targetMapper->getStorageReflection();
if ($propertyMD->relationshipType === PropertyMetadata::RELATIONSHIP_ONE_HAS_MANY) {
$table = $targetReflection->getStorageName();
$joinColumn = $targetReflection->convertEntityToStorageKey($propertyMD->relationshipProperty);
$expression .= ":{$table}({$joinColumn})";
} elseif ($propertyMD->relationshipType === PropertyMetadata::RELATIONSHIP_MANY_HAS_MANY) {
if ($propertyMD->relationshipIsMain) {
$expression .= ':' . $reflection->getManyHasManyStorageName($targetMapper);
$expression .= '.' . $reflection->getManyHasManyStoragePrimaryKeys($targetMapper)[1];
} else {
$expression .= ':' . $targetReflection->getManyHasManyStorageName($mapper);
$expression .= '.' . $targetReflection->getManyHasManyStoragePrimaryKeys($mapper)[0];
}
} else {
$expression .= '.' . $reflection->convertEntityToStorageKey($level);
}
$mapper = $targetMapper;
$reflection = $targetReflection;
$entityMD = $this->metadataStorage->get($mapper->getRepository()->getEntityClassNames()[0]);
}
// check if property exists
$entityMD->getProperty($column);
$column = $reflection->convertEntityToStorageKey($column);
return "{$expression}.{$column}";
}