Completed
Push — master ( c11d86...d758ed )
by Gianluca
13:50
created

DriverFactory::__invoke()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 3
crap 1
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace DoctrineModule\Service;
21
22
use Interop\Container\ContainerInterface;
23
use InvalidArgumentException;
24
use Doctrine\Common\Annotations;
25
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
26
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
27
use Doctrine\Common\Persistence\Mapping\Driver\FileDriver;
28
use Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator;
29
use DoctrineModule\Options\Driver as DriverOptions;
30
use Zend\ServiceManager\ServiceLocatorInterface;
31
32
/**
33
 * MappingDriver ServiceManager factory
34
 *
35
 * @license MIT
36
 * @link    http://www.doctrine-project.org/
37
 * @author  Kyle Spraggs <[email protected]>
38
 */
39
class DriverFactory extends AbstractFactory
40
{
41
    /**
42
     * {@inheritDoc}
43
     * @return MappingDriver
44
     */
45 2
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
46
    {
47
        /* @var $options DriverOptions */
48 2
        $options = $this->getOptions($container, 'driver');
49
50 2
        return $this->createDriver($container, $options);
51
    }
52
    /**
53
     * {@inheritDoc}
54
     * @return MappingDriver
55
     */
56 2
    public function createService(ServiceLocatorInterface $container)
57
    {
58 2
        return $this($container, MappingDriver::class);
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64 2
    public function getOptionsClass()
65
    {
66 2
        return 'DoctrineModule\Options\Driver';
67
    }
68
69
    /**
70
     * @param  ContainerInterface $container
71
     * @param  DriverOptions      $options
72
     * @throws InvalidArgumentException
73
     * @return MappingDriver
74
     */
75 2
    protected function createDriver(ContainerInterface $container, DriverOptions $options)
76
    {
77 2
        $class = $options->getClass();
78
79 2
        if (!$class) {
80
            throw new InvalidArgumentException('Drivers must specify a class');
81
        }
82
83 2
        if (!class_exists($class)) {
84
            throw new InvalidArgumentException(sprintf('Driver with type "%s" could not be found', $class));
85
        }
86
87
        // Not all drivers (DriverChain) require paths.
88 2
        $paths = $options->getPaths();
89
90
        // Special options for AnnotationDrivers.
91
        if ('Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver' === $class
92 2
            || is_subclass_of($class, 'Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver')
93 2
        ) {
94
            $reader = new Annotations\AnnotationReader;
95
            $reader = new Annotations\CachedReader(
96
                new Annotations\IndexedReader($reader),
97
                $container->get($options->getCache())
98
            );
99
            /* @var $driver MappingDriver */
100
            $driver = new $class($reader, $paths);
101
        } else {
102
            /* @var $driver MappingDriver */
103 2
            $driver = new $class($paths);
104
        }
105
106 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...
107
            /* @var $driver FileDriver */
108
            /* @var $locator \Doctrine\Common\Persistence\Mapping\Driver\FileLocator */
109
            $locator = $driver->getLocator();
110
111
            if (get_class($locator) === 'Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator') {
112 1
                $driver->setLocator(new DefaultFileLocator($locator->getPaths(), $options->getExtension()));
113
            } else {
114
                throw new InvalidArgumentException(
115
                    sprintf(
116
                        'Discovered file locator for driver of type "%s" is an instance of "%s". This factory '
117
                        . 'supports only the DefaultFileLocator when an extension is set for the file locator',
118
                        get_class($driver),
119
                        get_class($locator)
120
                    )
121
                );
122
            }
123
        }
124
125
        // Extra post-create options for DriverChain.
126 2
        if ($driver instanceof MappingDriverChain && $options->getDrivers()) {
127
            /* @var $driver \Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain */
128 1
            $drivers = $options->getDrivers();
129
130 1
            if (!is_array($drivers)) {
131
                $drivers = array($drivers);
132
            }
133
134 1
            foreach ($drivers as $namespace => $driverName) {
135 1
                if (null === $driverName) {
136 1
                    continue;
137
                }
138 1
                $options = $this->getOptions($container, 'driver', $driverName);
139 1
                $driver->addDriver($this->createDriver($container, $options), $namespace);
0 ignored issues
show
Compatibility introduced by
$options of type object<Zend\Stdlib\AbstractOptions> is not a sub-type of object<DoctrineModule\Options\Driver>. It seems like you assume a child class of the class Zend\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...
140 1
            }
141 1
        }
142
143 2
        return $driver;
144
    }
145
}
146