private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, bool $forceEager, string $parentAlias, array $propertyMetadataOptions = [], bool $wasLeftJoin = false, int &$joinCount = 0)
{
if ($joinCount > $this->maxJoins) {
throw new RuntimeException('The total number of joined relations has exceeded the specified maximum. Raise the limit if necessary.');
}
$entityManager = $queryBuilder->getEntityManager();
$classMetadata = $entityManager->getClassMetadata($resourceClass);
foreach ($classMetadata->associationMappings as $association => $mapping) {
try {
$propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $association, $propertyMetadataOptions);
} catch (PropertyNotFoundException $propertyNotFoundException) {
//skip properties not found
continue;
} catch (ResourceClassNotFoundException $resourceClassNotFoundException) {
//skip associations that are not resource classes
continue;
}
if (false === $forceEager && ClassMetadataInfo::FETCH_EAGER !== $mapping['fetch']) {
continue;
}
if (false === $propertyMetadata->isReadableLink() || false === $propertyMetadata->isReadable()) {
continue;
}
$isNullable = $mapping['joinColumns'][0]['nullable'] ?? true;
if (false !== $wasLeftJoin || true === $isNullable) {
$method = 'leftJoin';
} else {
$method = 'innerJoin';
}
$associationAlias = $queryNameGenerator->generateJoinAlias($association);
$queryBuilder->{$method}(sprintf('%s.%s', $parentAlias, $association), $associationAlias);
++$joinCount;
try {
$this->addSelect($queryBuilder, $mapping['targetEntity'], $associationAlias, $propertyMetadataOptions);
} catch (ResourceClassNotFoundException $resourceClassNotFoundException) {
continue;
}
$this->joinRelations($queryBuilder, $queryNameGenerator, $mapping['targetEntity'], $forceEager, $associationAlias, $propertyMetadataOptions, $method === 'leftJoin', $joinCount);
}
}