Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/Bridges/NetteDI/DIRepositoryFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public function loadConfiguration(): ?array

public function beforeCompile(): ?array
{
$types = $this->builder->findByType(IRepository::class);
$repositories = [];
$types = $this->findRepositories();
$repositories = [];
$repositoriesMap = [];
foreach ($types as $serviceName => $serviceDefinition) {
$serviceName = (string) $serviceName;
Expand Down Expand Up @@ -88,4 +88,14 @@ protected function setupRepositoryLoader(array $repositoriesMap): void
'repositoryNamesMap' => $repositoriesMap,
]);
}


/**
* @return array<string, \Nette\DI\Definitions\Definition>
*/
protected function findRepositories(): array
{
return $this->builder->findByType(IRepository::class);
}

}
75 changes: 75 additions & 0 deletions src/Bridges/NetteDI/FilteredDIRepositoryFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php declare(strict_types = 1);

namespace Nextras\Orm\Bridges\NetteDI;


use Nette\DI\ContainerBuilder;
use Nette\DI\Definitions\FactoryDefinition;
use Nette\DI\Definitions\ServiceDefinition;
use Nextras\Orm\Entity\IEntity;
use Nextras\Orm\Exception\InvalidStateException;
use Nextras\Orm\Model\IModel;
use Nextras\Orm\Model\Model;
use Nextras\Orm\Repository\IRepository;
use ReflectionClass;


class FilteredDIRepositoryFinder extends DIRepositoryFinder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced this should be in Orm, it is a highly subjective use case. It would be ok to have it locally in your project, wouldn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, yes/maybe and no.

FilteredDIRepositoryFinder may be subjective and I don't insist this particular solution should be in Orm. I think however, that if Orm supports multiple solutions then it should also support auto-registering repositories that work with multiple solutions.

FilteredDIRepositoryFinder is just a proposal for a solution that works with minimal configuration because it reuses the model namespace.

{

/**
* @param class-string<IModel> $modelClass
*/
public function __construct(
private readonly string $modelClass,
private readonly ContainerBuilder $builder,
OrmExtension $extension
)
{
if ($this->modelClass === Model::class) {
throw new InvalidStateException('Your model has to inherit from ' . Model::class . '. Use compiler extension configuration - model key.');
}

parent::__construct($this->modelClass, $builder, $extension);
}


protected function findRepositories(): array
{
$reflection = new ReflectionClass($this->modelClass);
$modelClassNamespace = $reflection->getNamespaceName();

$types = $this->builder->findByType(IRepository::class);
$filteredTypes = [];

foreach ($types as $serviceName => $serviceDefinition) {
$serviceName = (string) $serviceName;

/** @var class-string<IRepository<IEntity>> $type */
$type = $serviceDefinition->getType();

$isSupportedDefinition =
$serviceDefinition instanceof FactoryDefinition ||
$serviceDefinition instanceof ServiceDefinition ||
$serviceDefinition instanceof \Nette\DI\ServiceDefinition;

if ($isSupportedDefinition === false) {
throw new InvalidStateException(
"It seems DI defined repository of type '$type' is not defined as one of supported DI services.
Orm can only work with ServiceDefinition or FactoryDefinition services.",
);
}

if ($type === null) {
continue;
}

if (str_starts_with($type, $modelClassNamespace)) {
$filteredTypes[$serviceName] = $serviceDefinition;
}
}

return $filteredTypes;
}

}
Loading