Failed Conditions
Push — master ( ec2bd1...5afe97 )
by Jonathan
41s
created

FileDriver::initialize()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4.0119

Importance

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