Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / common / lib / Doctrine / Common / Persistence / Mapping / Driver / AnnotationDriver.php
1 <?php
2 /*
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.
14  *
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>.
18  */
19
20 namespace Doctrine\Common\Persistence\Mapping\Driver;
21
22 use Doctrine\Common\Cache\ArrayCache,
23     Doctrine\Common\Annotations\AnnotationReader,
24     Doctrine\Common\Annotations\AnnotationRegistry,
25     Doctrine\Common\Persistence\Mapping\MappingException;
26
27 /**
28  * The AnnotationDriver reads the mapping metadata from docblock annotations.
29  *
30  * @since 2.2
31  * @author Benjamin Eberlei <kontakt@beberlei.de>
32  * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
33  * @author Jonathan H. Wage <jonwage@gmail.com>
34  * @author Roman Borschel <roman@code-factory.org>
35  */
36 abstract class AnnotationDriver implements MappingDriver
37 {
38     /**
39      * The AnnotationReader.
40      *
41      * @var AnnotationReader
42      */
43     protected $reader;
44
45     /**
46      * The paths where to look for mapping files.
47      *
48      * @var array
49      */
50     protected $paths = array();
51
52     /**
53      * The file extension of mapping documents.
54      *
55      * @var string
56      */
57     protected $fileExtension = '.php';
58
59     /**
60      * Cache for AnnotationDriver#getAllClassNames()
61      *
62      * @var array
63      */
64     protected $classNames;
65
66     /**
67      * Name of the entity annotations as keys
68      *
69      * @var array
70      */
71     protected $entityAnnotationClasses = array();
72
73     /**
74      * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
75      * docblock annotations.
76      *
77      * @param AnnotationReader $reader The AnnotationReader to use, duck-typed.
78      * @param string|array $paths One or multiple paths where mapping classes can be found.
79      */
80     public function __construct($reader, $paths = null)
81     {
82         $this->reader = $reader;
83         if ($paths) {
84             $this->addPaths((array) $paths);
85         }
86     }
87
88     /**
89      * Append lookup paths to metadata driver.
90      *
91      * @param array $paths
92      */
93     public function addPaths(array $paths)
94     {
95         $this->paths = array_unique(array_merge($this->paths, $paths));
96     }
97
98     /**
99      * Retrieve the defined metadata lookup paths.
100      *
101      * @return array
102      */
103     public function getPaths()
104     {
105         return $this->paths;
106     }
107
108     /**
109      * Retrieve the current annotation reader
110      *
111      * @return AnnotationReader
112      */
113     public function getReader()
114     {
115         return $this->reader;
116     }
117
118     /**
119      * Get the file extension used to look for mapping files under
120      *
121      * @return string
122      */
123     public function getFileExtension()
124     {
125         return $this->fileExtension;
126     }
127
128     /**
129      * Set the file extension used to look for mapping files under
130      *
131      * @param string $fileExtension The file extension to set
132      * @return void
133      */
134     public function setFileExtension($fileExtension)
135     {
136         $this->fileExtension = $fileExtension;
137     }
138
139     /**
140      * Whether the class with the specified name is transient. Only non-transient
141      * classes, that is entities and mapped superclasses, should have their metadata loaded.
142      *
143      * A class is non-transient if it is annotated with an annotation
144      * from the {@see AnnotationDriver::entityAnnotationClasses}.
145      *
146      * @param string $className
147      * @return boolean
148      */
149     public function isTransient($className)
150     {
151         $classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className));
152
153         foreach ($classAnnotations as $annot) {
154             if (isset($this->entityAnnotationClasses[get_class($annot)])) {
155                 return false;
156             }
157         }
158         return true;
159     }
160
161     /**
162      * {@inheritDoc}
163      */
164     public function getAllClassNames()
165     {
166         if ($this->classNames !== null) {
167             return $this->classNames;
168         }
169
170         if (!$this->paths) {
171             throw MappingException::pathRequired();
172         }
173
174         $classes = array();
175         $includedFiles = array();
176
177         foreach ($this->paths as $path) {
178             if ( ! is_dir($path)) {
179                 throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
180             }
181
182             $iterator = new \RegexIterator(
183                 new \RecursiveIteratorIterator(
184                     new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
185                     \RecursiveIteratorIterator::LEAVES_ONLY
186                 ),
187                 '/^.+' . str_replace('.', '\.', $this->fileExtension) . '$/i',
188                 \RecursiveRegexIterator::GET_MATCH
189             );
190
191             foreach ($iterator as $file) {
192                 $sourceFile = realpath($file[0]);
193
194                 require_once $sourceFile;
195
196                 $includedFiles[] = $sourceFile;
197             }
198         }
199
200         $declared = get_declared_classes();
201
202         foreach ($declared as $className) {
203             $rc = new \ReflectionClass($className);
204             $sourceFile = $rc->getFileName();
205             if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
206                 $classes[] = $className;
207             }
208         }
209
210         $this->classNames = $classes;
211
212         return $classes;
213     }
214 }