Failed Conditions
Pull Request — 1.3.x (#71)
by Grégoire
02:49
created

FileDriver   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Test Coverage

Coverage 88%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 20
eloc 42
c 1
b 0
f 0
dl 0
loc 172
ccs 44
cts 50
cp 0.88
rs 10

9 Methods

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