Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / common / lib / Doctrine / Common / Annotations / FileCacheReader.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\Annotations;
21
22
23 /**
24  * File cache reader for annotations.
25  *
26  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
27  * @author Benjamin Eberlei <kontakt@beberlei.de>
28  */
29 class FileCacheReader implements Reader
30 {
31     /**
32      * @var Reader
33      */
34     private $reader;
35
36     /**
37      * @var string
38      */
39     private $dir;
40
41     /**
42      * @var bool
43      */
44     private $debug;
45
46     /**
47      * @var array
48      */
49     private $loadedAnnotations = array();
50
51     /**
52      * Constructor
53      *
54      * @param Reader $reader
55      * @param string $cacheDir
56      * @param bool $debug
57      *
58      * @throws \InvalidArgumentException
59      */
60     public function __construct(Reader $reader, $cacheDir, $debug = false)
61     {
62         $this->reader = $reader;
63         if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true)) {
64             throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir));
65         }
66         if (!is_writable($cacheDir)) {
67             throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $cacheDir));
68         }
69
70         $this->dir   = rtrim($cacheDir, '\\/');
71         $this->debug = $debug;
72     }
73
74     /**
75      * Retrieve annotations for class
76      *
77      * @param \ReflectionClass $class
78      * @return array
79      */
80     public function getClassAnnotations(\ReflectionClass $class)
81     {
82         $key = $class->getName();
83
84         if (isset($this->loadedAnnotations[$key])) {
85             return $this->loadedAnnotations[$key];
86         }
87
88         $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
89         if (!file_exists($path)) {
90             $annot = $this->reader->getClassAnnotations($class);
91             $this->saveCacheFile($path, $annot);
92             return $this->loadedAnnotations[$key] = $annot;
93         }
94
95         if ($this->debug
96             && (false !== $filename = $class->getFilename())
97             && filemtime($path) < filemtime($filename)) {
98             @unlink($path);
99
100             $annot = $this->reader->getClassAnnotations($class);
101             $this->saveCacheFile($path, $annot);
102             return $this->loadedAnnotations[$key] = $annot;
103         }
104
105         return $this->loadedAnnotations[$key] = include $path;
106     }
107
108     /**
109      * Get annotations for property
110      *
111      * @param \ReflectionProperty $property
112      * @return array
113      */
114     public function getPropertyAnnotations(\ReflectionProperty $property)
115     {
116         $class = $property->getDeclaringClass();
117         $key = $class->getName().'$'.$property->getName();
118
119         if (isset($this->loadedAnnotations[$key])) {
120             return $this->loadedAnnotations[$key];
121         }
122
123         $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
124         if (!file_exists($path)) {
125             $annot = $this->reader->getPropertyAnnotations($property);
126             $this->saveCacheFile($path, $annot);
127             return $this->loadedAnnotations[$key] = $annot;
128         }
129
130         if ($this->debug
131             && (false !== $filename = $class->getFilename())
132             && filemtime($path) < filemtime($filename)) {
133             unlink($path);
134
135             $annot = $this->reader->getPropertyAnnotations($property);
136             $this->saveCacheFile($path, $annot);
137             return $this->loadedAnnotations[$key] = $annot;
138         }
139
140         return $this->loadedAnnotations[$key] = include $path;
141     }
142
143     /**
144      * Retrieve annotations for method
145      *
146      * @param \ReflectionMethod $method
147      * @return array
148      */
149     public function getMethodAnnotations(\ReflectionMethod $method)
150     {
151         $class = $method->getDeclaringClass();
152         $key = $class->getName().'#'.$method->getName();
153
154         if (isset($this->loadedAnnotations[$key])) {
155             return $this->loadedAnnotations[$key];
156         }
157
158         $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
159         if (!file_exists($path)) {
160             $annot = $this->reader->getMethodAnnotations($method);
161             $this->saveCacheFile($path, $annot);
162             return $this->loadedAnnotations[$key] = $annot;
163         }
164
165         if ($this->debug
166             && (false !== $filename = $class->getFilename())
167             && filemtime($path) < filemtime($filename)) {
168             unlink($path);
169
170             $annot = $this->reader->getMethodAnnotations($method);
171             $this->saveCacheFile($path, $annot);
172             return $this->loadedAnnotations[$key] = $annot;
173         }
174
175         return $this->loadedAnnotations[$key] = include $path;
176     }
177
178     /**
179      * Save cache file
180      *
181      * @param string $path
182      * @param mixed $data
183      */
184     private function saveCacheFile($path, $data)
185     {
186         file_put_contents($path, '<?php return unserialize('.var_export(serialize($data), true).');');
187     }
188
189     /**
190      * Gets a class annotation.
191      *
192      * @param \ReflectionClass $class The ReflectionClass of the class from which
193      *                               the class annotations should be read.
194      * @param string $annotationName The name of the annotation.
195      *
196      * @return mixed The Annotation or NULL, if the requested annotation does not exist.
197      */
198     public function getClassAnnotation(\ReflectionClass $class, $annotationName)
199     {
200         $annotations = $this->getClassAnnotations($class);
201
202         foreach ($annotations as $annotation) {
203             if ($annotation instanceof $annotationName) {
204                 return $annotation;
205             }
206         }
207
208         return null;
209     }
210
211     /**
212      * Gets a method annotation.
213      *
214      * @param \ReflectionMethod $method
215      * @param string $annotationName The name of the annotation.
216      * @return mixed The Annotation or NULL, if the requested annotation does not exist.
217      */
218     public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
219     {
220         $annotations = $this->getMethodAnnotations($method);
221
222         foreach ($annotations as $annotation) {
223             if ($annotation instanceof $annotationName) {
224                 return $annotation;
225             }
226         }
227
228         return null;
229     }
230
231     /**
232      * Gets a property annotation.
233      *
234      * @param \ReflectionProperty $property
235      * @param string $annotationName The name of the annotation.
236      * @return mixed The Annotation or NULL, if the requested annotation does not exist.
237      */
238     public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
239     {
240         $annotations = $this->getPropertyAnnotations($property);
241
242         foreach ($annotations as $annotation) {
243             if ($annotation instanceof $annotationName) {
244                 return $annotation;
245             }
246         }
247
248         return null;
249     }
250
251     /**
252      * Clear stores annotations
253      */
254     public function clearLoadedAnnotations()
255     {
256         $this->loadedAnnotations = array();
257     }
258 }