DriverFactory   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 10

Test Coverage

Coverage 60.98%

Importance

Changes 0
Metric Value
wmc 16
lcom 0
cbo 10
dl 0
loc 99
ccs 25
cts 41
cp 0.6098
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __invoke() 0 6 1
A createService() 0 4 1
A getOptionsClass() 0 4 1
C createDriver() 0 66 13
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DoctrineModule\Service;
6
7
use Doctrine\Common\Annotations;
8
use Doctrine\Persistence\Mapping\Driver\DefaultFileLocator;
9
use Doctrine\Persistence\Mapping\Driver\FileDriver;
10
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
11
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
12
use DoctrineModule\Options\Driver as DriverOptions;
13
use Interop\Container\ContainerInterface;
14
use InvalidArgumentException;
15
use Laminas\ServiceManager\ServiceLocatorInterface;
16
use function class_exists;
17
use function get_class;
18
use function interface_exists;
19
use function is_array;
20
use function is_subclass_of;
21
use function sprintf;
22
23
/**
24
 * MappingDriver ServiceManager factory
25
 *
26
 * @link    http://www.doctrine-project.org/
27
 */
28
class DriverFactory extends AbstractFactory
29
{
30
    /**
31
     * {@inheritDoc}
32
     *
33
     * @return MappingDriver
34
     */
35 2
    public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
36
    {
37 2
        $options = $this->getOptions($container, 'driver');
38
39 2
        return $this->createDriver($container, $options);
0 ignored issues
show
Compatibility introduced by
$options of type object<Laminas\Stdlib\AbstractOptions> is not a sub-type of object<DoctrineModule\Options\Driver>. It seems like you assume a child class of the class Laminas\Stdlib\AbstractOptions to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
40
    }
41
42
    /**
43
     * {@inheritDoc}
44
     *
45
     * @return MappingDriver
46
     */
47 2
    public function createService(ServiceLocatorInterface $container)
48
    {
49 2
        return $this($container, MappingDriver::class);
50
    }
51
52 2
    public function getOptionsClass() : string
53
    {
54 2
        return 'DoctrineModule\Options\Driver';
55
    }
56
57
    /**
58
     * @throws InvalidArgumentException
59
     */
60 2
    protected function createDriver(ContainerInterface $container, DriverOptions $options) : MappingDriver
61
    {
62 2
        $class = $options->getClass();
63
64 2
        if (! $class) {
65
            throw new InvalidArgumentException('Drivers must specify a class');
66
        }
67
68 2
        if (! class_exists($class)) {
69
            throw new InvalidArgumentException(sprintf('Driver with type "%s" could not be found', $class));
70
        }
71
72
        // Not all drivers (DriverChain) require paths.
73 2
        $paths = $options->getPaths();
74
75
        // Special options for AnnotationDrivers.
76 2
        if ($class === 'Doctrine\Persistence\Mapping\Driver\AnnotationDriver'
77 2
            || is_subclass_of($class, 'Doctrine\Persistence\Mapping\Driver\AnnotationDriver')
78
        ) {
79
            $reader = new Annotations\AnnotationReader();
80
            $reader = new Annotations\CachedReader(
81
                new Annotations\IndexedReader($reader),
82
                $container->get($options->getCache())
83
            );
84
            $driver = new $class($reader, $paths);
85
        } else {
86 2
            $driver = new $class($paths);
87
        }
88
89 2
        if ($options->getExtension() && $driver instanceof FileDriver) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $options->getExtension() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
90
            $locator = $driver->getLocator();
91
92
            if (get_class($locator) !== 'Doctrine\Persistence\Mapping\Driver\DefaultFileLocator') {
93
                throw new InvalidArgumentException(
94
                    sprintf(
95
                        'Discovered file locator for driver of type "%s" is an instance of "%s". This factory '
96
                        . 'supports only the DefaultFileLocator when an extension is set for the file locator',
97
                        get_class($driver),
98
                        get_class($locator)
99
                    )
100
                );
101
            }
102
103
            $driver->setLocator(new DefaultFileLocator($locator->getPaths(), $options->getExtension()));
104
        }
105
106
        // Extra post-create options for DriverChain.
107 2
        if ($driver instanceof MappingDriverChain && $options->getDrivers()) {
108 1
            $drivers = $options->getDrivers();
109
110 1
            if (! is_array($drivers)) {
111
                $drivers = [$drivers];
112
            }
113
114 1
            foreach ($drivers as $namespace => $driverName) {
115 1
                if ($driverName === null) {
116 1
                    continue;
117
                }
118
119 1
                $options = $this->getOptions($container, 'driver', $driverName);
120 1
                $driver->addDriver($this->createDriver($container, $options), $namespace);
0 ignored issues
show
Compatibility introduced by
$options of type object<Laminas\Stdlib\AbstractOptions> is not a sub-type of object<DoctrineModule\Options\Driver>. It seems like you assume a child class of the class Laminas\Stdlib\AbstractOptions to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
121
            }
122
        }
123
124 2
        return $driver;
125
    }
126
}
127
128
interface_exists(MappingDriver::class);
129