Failed Conditions
Pull Request — master (#7688)
by Gabriel
09:23
created

FileDriver   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Test Coverage

Coverage 50%

Importance

Changes 0
Metric Value
eloc 40
c 0
b 0
f 0
dl 0
loc 160
ccs 24
cts 48
cp 0.5
rs 10
wmc 20

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getLocator() 0 3 1
A setLocator() 0 3 1
A setGlobalBasename() 0 3 1
A getGlobalBasename() 0 3 1
A initialize() 0 10 4
A getAllClassNames() 0 13 3
A isTransient() 0 11 3
A __construct() 0 6 2
A getElement() 0 18 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Mapping\Driver;
6
7
use Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator;
8
use Doctrine\Common\Persistence\Mapping\Driver\FileLocator;
9
use Doctrine\Common\Persistence\Mapping\MappingException;
10
use function array_keys;
11
use function array_merge;
12
use function is_file;
13
use function str_replace;
14
15
/**
16
 * Base driver for file-based metadata drivers.
17
 *
18
 * A file driver operates in a mode where it loads the mapping files of individual
19
 * classes on demand. This requires the user to adhere to the convention of 1 mapping
20
 * file per class and the file names of the mapping files must correspond to the full
21
 * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'.
22
 */
23
abstract class FileDriver implements MappingDriver
24
{
25
    /** @var FileLocator */
26
    protected $locator;
27
28
    /** @var mixed[]|null */
29
    protected $classCache;
30
31
    /** @var string|null */
32
    protected $globalBasename;
33
34
    /**
35
     * Initializes a new FileDriver that looks in the given path(s) for mapping
36
     * documents and operates in the specified operating mode.
37
     *
38
     * @param string|string[]|FileLocator $locator       A FileLocator or one/multiple paths
39
     *                                                   where mapping documents can be found.
40
     * @param string|null                 $fileExtension
41
     */
42 38
    public function __construct($locator, $fileExtension = null)
43
    {
44 38
        if ($locator instanceof FileLocator) {
45 4
            $this->locator = $locator;
46
        } else {
47 34
            $this->locator = new DefaultFileLocator((array) $locator, $fileExtension);
48
        }
49 38
    }
50
51
    /**
52
     * Retrieves the locator used to discover mapping files by className.
53
     *
54
     * @return FileLocator
55
     */
56 4
    public function getLocator()
57
    {
58 4
        return $this->locator;
59
    }
60
61
    /**
62
     * Sets the locator used to discover mapping files by className.
63
     */
64
    public function setLocator(FileLocator $locator)
65
    {
66
        $this->locator = $locator;
67
    }
68
69
    /**
70
     * Sets the global basename.
71
     *
72
     * @param string $file
73
     */
74
    public function setGlobalBasename($file)
75
    {
76
        $this->globalBasename = $file;
77
    }
78
79
    /**
80
     * Retrieves the global basename.
81
     *
82
     * @return string|null
83
     */
84
    public function getGlobalBasename()
85
    {
86
        return $this->globalBasename;
87
    }
88
89
    /**
90
     * Gets the element of schema meta data for the class from the mapping file.
91
     * This will lazily load the mapping file if it is not loaded yet.
92
     *
93
     * @param string $className
94
     *
95
     * @return mixed[] The element of schema meta data.
96
     *
97
     * @throws MappingException
98
     */
99 33
    public function getElement($className)
100
    {
101 33
        if ($this->classCache === null) {
102 26
            $this->initialize();
103
        }
104
105 33
        if (isset($this->classCache[$className])) {
106
            return $this->classCache[$className];
107
        }
108
109 33
        $result = $this->loadMappingFile($this->locator->findMappingFile($className));
110 33
        if (! isset($result[$className])) {
111
            throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->locator->getFileExtension());
112
        }
113
114 33
        $this->classCache[$className] = $result[$className];
115
116 33
        return $result[$className];
117
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122 8
    public function isTransient($className) : bool
123
    {
124 8
        if ($this->classCache === null) {
125 7
            $this->initialize();
126
        }
127
128 8
        if (isset($this->classCache[$className])) {
129 4
            return false;
130
        }
131
132 7
        return ! $this->locator->fileExists($className);
133
    }
134
135
    /**
136
     * {@inheritDoc}
137
     */
138
    public function getAllClassNames() : array
139
    {
140
        if ($this->classCache === null) {
141
            $this->initialize();
142
        }
143
144
        if (! $this->classCache) {
145
            return (array) $this->locator->getAllClassNames($this->globalBasename);
146
        }
147
148
        return array_merge(
149
            array_keys($this->classCache),
150
            (array) $this->locator->getAllClassNames($this->globalBasename)
151
        );
152
    }
153
154
    /**
155
     * Loads a mapping file with the given name and returns a map
156
     * from class/entity names to their corresponding file driver elements.
157
     *
158
     * @param string $file The mapping file to load.
159
     *
160
     * @return mixed[]
161
     */
162
    abstract protected function loadMappingFile($file);
163
164
    /**
165
     * Initializes the class cache from all the global files.
166
     *
167
     * Using this feature adds a substantial performance hit to file drivers as
168
     * more metadata has to be loaded into memory than might actually be
169
     * necessary. This may not be relevant to scenarios where caching of
170
     * metadata is in place, however hits very hard in scenarios where no
171
     * caching is used.
172
     */
173 33
    protected function initialize()
174
    {
175 33
        $this->classCache = [];
176 33
        if ($this->globalBasename !== null) {
177
            foreach ($this->locator->getPaths() as $path) {
178
                $file = $path . '/' . $this->globalBasename . $this->locator->getFileExtension();
179
                if (is_file($file)) {
180
                    $this->classCache = array_merge(
181
                        $this->classCache,
182
                        $this->loadMappingFile($file)
183
                    );
184
                }
185
            }
186
        }
187 33
    }
188
}
189