Passed
Push — add_typed_no_default_reflectio... ( 26533b...1005a7 )
by Benjamin
04:11
created

FileDriver::isTransient()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 10
cc 3
nc 4
nop 1
crap 3
1
<?php
2
3
namespace Doctrine\Persistence\Mapping\Driver;
4
5
use Doctrine\Persistence\Mapping\ClassMetadata;
6
use Doctrine\Persistence\Mapping\MappingException;
7
use function array_keys;
8
use function array_merge;
9
use function array_unique;
10
use function class_exists;
11
use function interface_exists;
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 ClassMetadata[]|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 12
    public function __construct($locator, $fileExtension = null)
43
    {
44 12
        if ($locator instanceof FileLocator) {
45 9
            $this->locator = $locator;
46
        } else {
47 3
            $this->locator = new DefaultFileLocator((array) $locator, $fileExtension);
48
        }
49 12
    }
50
51
    /**
52
     * Sets the global basename.
53
     *
54
     * @param string $file
55
     *
56
     * @return void
57
     */
58 6
    public function setGlobalBasename($file)
59
    {
60 6
        $this->globalBasename = $file;
61 6
    }
62
63
    /**
64
     * Retrieves the global basename.
65
     *
66
     * @return string|null
67
     */
68 1
    public function getGlobalBasename()
69
    {
70 1
        return $this->globalBasename;
71
    }
72
73
    /**
74
     * Gets the element of schema meta data for the class from the mapping file.
75
     * This will lazily load the mapping file if it is not loaded yet.
76
     *
77
     * @param string $className
78
     *
79
     * @return ClassMetadata The element of schema meta data.
80
     *
81
     * @throws MappingException
82
     */
83 4
    public function getElement($className)
84
    {
85 4
        if ($this->classCache === null) {
86 4
            $this->initialize();
87
        }
88
89 4
        if (isset($this->classCache[$className])) {
90 2
            return $this->classCache[$className];
91
        }
92
93 3
        $result = $this->loadMappingFile($this->locator->findMappingFile($className));
94 3
        if (! isset($result[$className])) {
95
            throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->locator->getFileExtension());
96
        }
97
98 3
        $this->classCache[$className] = $result[$className];
99
100 3
        return $result[$className];
101
    }
102
103
    /**
104
     * {@inheritDoc}
105
     */
106 3
    public function isTransient($className)
107
    {
108 3
        if ($this->classCache === null) {
109 3
            $this->initialize();
110
        }
111
112 3
        if (isset($this->classCache[$className])) {
113 1
            return false;
114
        }
115
116 3
        return ! $this->locator->fileExists($className);
117
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122 4
    public function getAllClassNames()
123
    {
124 4
        if ($this->classCache === null) {
125 3
            $this->initialize();
126
        }
127
128 4
        if (! $this->classCache) {
129 1
            return (array) $this->locator->getAllClassNames($this->globalBasename);
130
        }
131
132 3
        return array_unique(array_merge(
133 3
            array_keys($this->classCache),
134 3
            (array) $this->locator->getAllClassNames($this->globalBasename)
135
        ));
136
    }
137
138
    /**
139
     * Loads a mapping file with the given name and returns a map
140
     * from class/entity names to their corresponding file driver elements.
141
     *
142
     * @param string $file The mapping file to load.
143
     *
144
     * @return ClassMetadata[]
145
     */
146
    abstract protected function loadMappingFile($file);
147
148
    /**
149
     * Initializes the class cache from all the global files.
150
     *
151
     * Using this feature adds a substantial performance hit to file drivers as
152
     * more metadata has to be loaded into memory than might actually be
153
     * necessary. This may not be relevant to scenarios where caching of
154
     * metadata is in place, however hits very hard in scenarios where no
155
     * caching is used.
156
     *
157
     * @return void
158
     */
159 10
    protected function initialize()
160
    {
161 10
        $this->classCache = [];
162 10
        if ($this->globalBasename === null) {
163 5
            return;
164
        }
165
166 5
        foreach ($this->locator->getPaths() as $path) {
167 5
            $file = $path . '/' . $this->globalBasename . $this->locator->getFileExtension();
168 5
            if (! is_file($file)) {
169
                continue;
170
            }
171
172 5
            $this->classCache = array_merge(
173 5
                $this->classCache,
174 5
                $this->loadMappingFile($file)
175
            );
176
        }
177 5
    }
178
179
    /**
180
     * Retrieves the locator used to discover mapping files by className.
181
     *
182
     * @return FileLocator
183
     */
184
    public function getLocator()
185
    {
186
        return $this->locator;
187
    }
188
189
    /**
190
     * Sets the locator used to discover mapping files by className.
191
     */
192
    public function setLocator(FileLocator $locator)
193
    {
194
        $this->locator = $locator;
195
    }
196
}
197
198
class_exists(\Doctrine\Common\Persistence\Mapping\Driver\FileDriver::class);
199
interface_exists(FileLocator::class);
200