Failed Conditions
Pull Request — master (#1)
by Jonathan
13:20 queued 01:26
created

FileDriver::getAllClassNames()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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