EntityRepositoryFactory   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 35
c 1
b 0
f 0
dl 0
loc 86
rs 10
wmc 7

2 Methods

Rating   Name   Duplication   Size   Complexity  
A generateCustomClassName() 0 9 1
B __invoke() 0 52 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\LaminasEntity\Factory\Repository;
6
7
use Arp\DoctrineEntityRepository\EntityRepository;
8
use Arp\DoctrineEntityRepository\EntityRepositoryInterface;
9
use Arp\DoctrineEntityRepository\Persistence\PersistService;
10
use Arp\DoctrineEntityRepository\Query\QueryService;
11
use Arp\Entity\EntityInterface;
12
use Arp\EventDispatcher\Listener\ListenerProvider;
13
use Arp\LaminasFactory\AbstractFactory;
14
use Arp\LaminasFactory\Exception\ServiceNotCreatedException;
15
use Interop\Container\ContainerInterface;
16
use Psr\Log\LoggerInterface;
17
use Psr\Log\NullLogger;
18
19
/**
20
 * @author  Alex Patterson <[email protected]>
21
 * @package Arp\LaminasEntity\Factory\Repository
22
 */
23
final class EntityRepositoryFactory extends AbstractFactory
24
{
25
    /**
26
     * @var string
27
     */
28
    private string $defaultClassName = EntityRepository::class;
29
30
    /**
31
     * @param ContainerInterface $container
32
     * @param string             $requestedName
33
     * @param array|null         $options
34
     *
35
     * @return EntityRepositoryInterface
36
     *
37
     * @throws ServiceNotCreatedException
38
     */
39
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
40
    {
41
        $options = $options ?? $this->getServiceOptions($container, $requestedName, 'entity_repositories');
42
43
        $className = $options['class_name'] ?? null;
44
        $entityName = $options['entity_name'] ?? $requestedName;
45
46
        if (! is_a($entityName, EntityInterface::class, true)) {
47
            throw new ServiceNotCreatedException(
48
                sprintf(
49
                    'The \'entity_name\' configuration option must reference a class ' .
50
                    'of type \'%s\' : \'%s\' provided for service \'%s\'',
51
                    EntityInterface::class,
52
                    $entityName,
53
                    $requestedName
54
                )
55
            );
56
        }
57
58
        // Attempt to automatically find a value custom repository or otherwise fallback to the default.
59
        if (null === $className) {
60
            $customClassName = $this->generateCustomClassName($entityName);
61
            $className = $this->defaultClassName;
62
63
            if (null !== $customClassName && class_exists($customClassName)) {
64
                $className = $customClassName;
65
            }
66
        }
67
68
        if (! is_a($className, EntityRepositoryInterface::class, true)) {
69
            throw new ServiceNotCreatedException(
70
                sprintf(
71
                    'The \'class_name\' option must be of type \'%s\'; \'%s\' provided for entity repository \'%s\'',
72
                    EntityRepositoryInterface::class,
73
                    $className,
74
                    $requestedName
75
                )
76
            );
77
        }
78
79
        $queryService = $container->build(QueryService::class, ['entity_name' => $entityName]);
0 ignored issues
show
Bug introduced by
The method build() does not exist on Interop\Container\ContainerInterface. It seems like you code against a sub-type of Interop\Container\ContainerInterface such as Laminas\ServiceManager\ServiceLocatorInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

79
        /** @scrutinizer ignore-call */ 
80
        $queryService = $container->build(QueryService::class, ['entity_name' => $entityName]);
Loading history...
80
81
        $listenerProvider = $options['listener_provider'] ?? ListenerProvider::class;
82
        $persistService = $container->build(
83
            PersistService::class,
84
            ['entity_name' => $entityName, 'listener_provider' => $listenerProvider]
85
        );
86
87
        /** @var LoggerInterface $logger */
88
        $logger = $this->getService($container, $options['logger'] ?? NullLogger::class, $requestedName);
89
90
        return new $className($entityName, $queryService, $persistService, $logger);
91
    }
92
93
    /**
94
     * @todo Current logic needs rethink; reflection?
95
     *
96
     * @param string $entityName
97
     *
98
     * @return string
99
     */
100
    private function generateCustomClassName(string $entityName): string
101
    {
102
        //$reflectionClass = new \ReflectionClass($entityName);
103
        //$reflectionClass->getShortName();
104
105
        $parts = explode('\\', $entityName);
106
        $entity = array_pop($parts);
107
108
        return sprintf('%s\\Repository\\%sRepository', implode('\\', $parts), $entity);
109
    }
110
}
111