3
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
* This software consists of voluntary contributions made by many individuals
16
* and is licensed under the MIT license. For more information, see
17
* <http://www.doctrine-project.org>.
20
namespace Doctrine\Common\Persistence\Mapping\Driver;
22
use Doctrine\Common\Annotations\AnnotationReader;
23
use Doctrine\Common\Annotations\AnnotationRegistry;
24
use Doctrine\Common\Persistence\Mapping\MappingException;
27
* The AnnotationDriver reads the mapping metadata from docblock annotations.
30
* @author Benjamin Eberlei <kontakt@beberlei.de>
31
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
32
* @author Jonathan H. Wage <jonwage@gmail.com>
33
* @author Roman Borschel <roman@code-factory.org>
35
abstract class AnnotationDriver implements MappingDriver
38
* The AnnotationReader.
40
* @var AnnotationReader
45
* The paths where to look for mapping files.
49
protected $paths = array();
52
* The paths excluded from path where to look for mapping files.
56
protected $excludePaths = array();
59
* The file extension of mapping documents.
63
protected $fileExtension = '.php';
66
* Cache for AnnotationDriver#getAllClassNames().
70
protected $classNames;
73
* Name of the entity annotations as keys.
77
protected $entityAnnotationClasses = array();
80
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
81
* docblock annotations.
83
* @param AnnotationReader $reader The AnnotationReader to use, duck-typed.
84
* @param string|array|null $paths One or multiple paths where mapping classes can be found.
86
public function __construct($reader, $paths = null)
88
$this->reader = $reader;
90
$this->addPaths((array) $paths);
95
* Appends lookup paths to metadata driver.
101
public function addPaths(array $paths)
103
$this->paths = array_unique(array_merge($this->paths, $paths));
107
* Retrieves the defined metadata lookup paths.
111
public function getPaths()
117
* Append exclude lookup paths to metadata driver.
119
* @param array $paths
121
public function addExcludePaths(array $paths)
123
$this->excludePaths = array_unique(array_merge($this->excludePaths, $paths));
127
* Retrieve the defined metadata lookup exclude paths.
131
public function getExcludePaths()
133
return $this->excludePaths;
137
* Retrieve the current annotation reader
139
* @return AnnotationReader
141
public function getReader()
143
return $this->reader;
147
* Gets the file extension used to look for mapping files under.
151
public function getFileExtension()
153
return $this->fileExtension;
157
* Sets the file extension used to look for mapping files under.
159
* @param string $fileExtension The file extension to set.
163
public function setFileExtension($fileExtension)
165
$this->fileExtension = $fileExtension;
169
* Returns whether the class with the specified name is transient. Only non-transient
170
* classes, that is entities and mapped superclasses, should have their metadata loaded.
172
* A class is non-transient if it is annotated with an annotation
173
* from the {@see AnnotationDriver::entityAnnotationClasses}.
175
* @param string $className
179
public function isTransient($className)
181
$classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className));
183
foreach ($classAnnotations as $annot) {
184
if (isset($this->entityAnnotationClasses[get_class($annot)])) {
194
public function getAllClassNames()
196
if ($this->classNames !== null) {
197
return $this->classNames;
201
throw MappingException::pathRequired();
205
$includedFiles = array();
207
foreach ($this->paths as $path) {
208
if ( ! is_dir($path)) {
209
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
212
$iterator = new \RegexIterator(
213
new \RecursiveIteratorIterator(
214
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
215
\RecursiveIteratorIterator::LEAVES_ONLY
217
'/^.+' . preg_quote($this->fileExtension) . '$/i',
218
\RecursiveRegexIterator::GET_MATCH
221
foreach ($iterator as $file) {
222
$sourceFile = $file[0];
224
if ( ! preg_match('(^phar:)i', $sourceFile)) {
225
$sourceFile = realpath($sourceFile);
228
foreach ($this->excludePaths as $excludePath) {
229
$exclude = str_replace('\\', '/', realpath($excludePath));
230
$current = str_replace('\\', '/', $sourceFile);
232
if (strpos($current, $exclude) !== false) {
237
require_once $sourceFile;
239
$includedFiles[] = $sourceFile;
243
$declared = get_declared_classes();
245
foreach ($declared as $className) {
246
$rc = new \ReflectionClass($className);
247
$sourceFile = $rc->getFileName();
248
if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
249
$classes[] = $className;
253
$this->classNames = $classes;