<?php
namespace Doctrine\Common\Annotations;
class FileCacheReader implements Reader {
private $reader;
private $dir;
private $debug;
private $loadedAnnotations = array();
public function __construct(Reader $reader, $cacheDir, $debug = false) {
$this->reader = $reader;
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir));
}
if (!is_writable($cacheDir)) {
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));
}
$this->dir = rtrim($cacheDir, '\\/');
$this->debug = $debug;
}
public function getClassAnnotations(\ReflectionClass $class) {
$key = $class
->getName();
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php';
if (!file_exists($path)) {
$annot = $this->reader
->getClassAnnotations($class);
$this
->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug && false !== ($filename = $class
->getFilename()) && filemtime($path) < filemtime($filename)) {
@unlink($path);
$annot = $this->reader
->getClassAnnotations($class);
$this
->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = (include $path);
}
public function getPropertyAnnotations(\ReflectionProperty $property) {
$class = $property
->getDeclaringClass();
$key = $class
->getName() . '$' . $property
->getName();
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php';
if (!file_exists($path)) {
$annot = $this->reader
->getPropertyAnnotations($property);
$this
->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug && false !== ($filename = $class
->getFilename()) && filemtime($path) < filemtime($filename)) {
unlink($path);
$annot = $this->reader
->getPropertyAnnotations($property);
$this
->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = (include $path);
}
public function getMethodAnnotations(\ReflectionMethod $method) {
$class = $method
->getDeclaringClass();
$key = $class
->getName() . '#' . $method
->getName();
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php';
if (!file_exists($path)) {
$annot = $this->reader
->getMethodAnnotations($method);
$this
->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug && false !== ($filename = $class
->getFilename()) && filemtime($path) < filemtime($filename)) {
unlink($path);
$annot = $this->reader
->getMethodAnnotations($method);
$this
->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = (include $path);
}
private function saveCacheFile($path, $data) {
file_put_contents($path, '<?php return unserialize(' . var_export(serialize($data), true) . ');');
}
public function getClassAnnotation(\ReflectionClass $class, $annotationName) {
$annotations = $this
->getClassAnnotations($class);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) {
$annotations = $this
->getMethodAnnotations($method);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) {
$annotations = $this
->getPropertyAnnotations($property);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
public function clearLoadedAnnotations() {
$this->loadedAnnotations = array();
}
}