mirror of
https://github.com/torrentpier/torrentpier-lts.git
synced 2025-03-01 15:21:02 +03:00
225 lines
6.1 KiB
PHP
225 lines
6.1 KiB
PHP
<?php
|
|
/**
|
|
* Zend Framework (http://framework.zend.com/)
|
|
*
|
|
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
|
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
*/
|
|
|
|
namespace Zend\Code\Annotation\Parser;
|
|
|
|
use Traversable;
|
|
use Zend\Code\Annotation\AnnotationInterface;
|
|
use Zend\Code\Exception;
|
|
use Zend\EventManager\EventInterface;
|
|
|
|
/**
|
|
* Generic annotation parser
|
|
*
|
|
* Expects registration of AnnotationInterface instances. Such instances
|
|
* will be passed annotation content to their initialize() method, which
|
|
* they are then responsible for parsing.
|
|
*/
|
|
class GenericAnnotationParser implements ParserInterface
|
|
{
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $aliases = array();
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $annotationNames = array();
|
|
|
|
/**
|
|
* @var AnnotationInterface[]
|
|
*/
|
|
protected $annotations = array();
|
|
|
|
/**
|
|
* Listen to onCreateAnnotation, and attempt to return an annotation object
|
|
* instance.
|
|
*
|
|
* If the annotation class or alias is not registered, immediately returns
|
|
* false. Otherwise, resolves the class, clones it, and, if any content is
|
|
* present, calls {@link AnnotationInterface::initialize()} with the
|
|
* content.
|
|
*
|
|
* @param EventInterface $e
|
|
* @return false|AnnotationInterface
|
|
*/
|
|
public function onCreateAnnotation(EventInterface $e)
|
|
{
|
|
$class = $e->getParam('class', false);
|
|
if (!$class || !$this->hasAnnotation($class)) {
|
|
return false;
|
|
}
|
|
|
|
$content = $e->getParam('content', '');
|
|
$content = trim($content, '()');
|
|
|
|
if ($this->hasAlias($class)) {
|
|
$class = $this->resolveAlias($class);
|
|
}
|
|
|
|
$index = array_search($class, $this->annotationNames);
|
|
$annotation = $this->annotations[$index];
|
|
|
|
$newAnnotation = clone $annotation;
|
|
if ($content) {
|
|
$newAnnotation->initialize($content);
|
|
}
|
|
|
|
return $newAnnotation;
|
|
}
|
|
|
|
/**
|
|
* Register annotations
|
|
*
|
|
* @param string|AnnotationInterface $annotation String class name of an
|
|
* AnnotationInterface implementation, or actual instance
|
|
* @return GenericAnnotationParser
|
|
* @throws Exception\InvalidArgumentException
|
|
*/
|
|
public function registerAnnotation($annotation)
|
|
{
|
|
$class = false;
|
|
if (is_string($annotation) && class_exists($annotation)) {
|
|
$class = $annotation;
|
|
$annotation = new $annotation();
|
|
}
|
|
|
|
if (!$annotation instanceof AnnotationInterface) {
|
|
throw new Exception\InvalidArgumentException(sprintf(
|
|
'%s: expects an instance of %s\AnnotationInterface; received "%s"',
|
|
__METHOD__,
|
|
__NAMESPACE__,
|
|
(is_object($annotation) ? get_class($annotation) : gettype($annotation))
|
|
));
|
|
}
|
|
|
|
$class = $class ?: get_class($annotation);
|
|
|
|
if (in_array($class, $this->annotationNames)) {
|
|
throw new Exception\InvalidArgumentException(sprintf(
|
|
'An annotation for this class %s already exists',
|
|
$class
|
|
));
|
|
}
|
|
|
|
$this->annotations[] = $annotation;
|
|
$this->annotationNames[] = $class;
|
|
}
|
|
|
|
/**
|
|
* Register many annotations at once
|
|
*
|
|
* @param array|Traversable $annotations
|
|
* @throws Exception\InvalidArgumentException
|
|
* @return GenericAnnotationParser
|
|
*/
|
|
public function registerAnnotations($annotations)
|
|
{
|
|
if (!is_array($annotations) && !$annotations instanceof Traversable) {
|
|
throw new Exception\InvalidArgumentException(sprintf(
|
|
'%s: expects an array or Traversable; received "%s"',
|
|
__METHOD__,
|
|
(is_object($annotations) ? get_class($annotations) : gettype($annotations))
|
|
));
|
|
}
|
|
|
|
foreach ($annotations as $annotation) {
|
|
$this->registerAnnotation($annotation);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Checks if the manager has annotations for a class
|
|
*
|
|
* @param string $class
|
|
* @return bool
|
|
*/
|
|
public function hasAnnotation($class)
|
|
{
|
|
if (in_array($class, $this->annotationNames)) {
|
|
return true;
|
|
}
|
|
|
|
if ($this->hasAlias($class)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Alias an annotation name
|
|
*
|
|
* @param string $alias
|
|
* @param string $class May be either a registered annotation name or another alias
|
|
* @throws Exception\InvalidArgumentException
|
|
* @return GenericAnnotationParser
|
|
*/
|
|
public function setAlias($alias, $class)
|
|
{
|
|
if (!in_array($class, $this->annotationNames) && !$this->hasAlias($class)) {
|
|
throw new Exception\InvalidArgumentException(sprintf(
|
|
'%s: Cannot alias "%s" to "%s", as class "%s" is not currently a registered annotation or alias',
|
|
__METHOD__,
|
|
$alias,
|
|
$class,
|
|
$class
|
|
));
|
|
}
|
|
|
|
$alias = $this->normalizeAlias($alias);
|
|
$this->aliases[$alias] = $class;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Normalize an alias name
|
|
*
|
|
* @param string $alias
|
|
* @return string
|
|
*/
|
|
protected function normalizeAlias($alias)
|
|
{
|
|
return strtolower(str_replace(array('-', '_', ' ', '\\', '/'), '', $alias));
|
|
}
|
|
|
|
/**
|
|
* Do we have an alias by the provided name?
|
|
*
|
|
* @param string $alias
|
|
* @return bool
|
|
*/
|
|
protected function hasAlias($alias)
|
|
{
|
|
$alias = $this->normalizeAlias($alias);
|
|
|
|
return (isset($this->aliases[$alias]));
|
|
}
|
|
|
|
/**
|
|
* Resolve an alias to a class name
|
|
*
|
|
* @param string $alias
|
|
* @return string
|
|
*/
|
|
protected function resolveAlias($alias)
|
|
{
|
|
do {
|
|
$normalized = $this->normalizeAlias($alias);
|
|
$class = $this->aliases[$normalized];
|
|
} while ($this->hasAlias($class));
|
|
|
|
return $class;
|
|
}
|
|
}
|