[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/zendframework/zend-code/src/Annotation/Parser/ -> GenericAnnotationParser.php (source)

   1  <?php
   2  /**
   3   * Zend Framework (http://framework.zend.com/)
   4   *
   5   * @link      http://github.com/zendframework/zf2 for the canonical source repository
   6   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
   7   * @license   http://framework.zend.com/license/new-bsd New BSD License
   8   */
   9  
  10  namespace Zend\Code\Annotation\Parser;
  11  
  12  use Traversable;
  13  use Zend\Code\Annotation\AnnotationInterface;
  14  use Zend\Code\Exception;
  15  use Zend\EventManager\EventInterface;
  16  
  17  use function array_search;
  18  use function class_exists;
  19  use function get_class;
  20  use function gettype;
  21  use function in_array;
  22  use function is_array;
  23  use function is_object;
  24  use function is_string;
  25  use function sprintf;
  26  use function str_replace;
  27  use function strtolower;
  28  use function trim;
  29  
  30  /**
  31   * Generic annotation parser
  32   *
  33   * Expects registration of AnnotationInterface instances. Such instances
  34   * will be passed annotation content to their initialize() method, which
  35   * they are then responsible for parsing.
  36   */
  37  class GenericAnnotationParser implements ParserInterface
  38  {
  39      /**
  40       * @var array
  41       */
  42      protected $aliases = [];
  43  
  44      /**
  45       * @var array
  46       */
  47      protected $annotationNames = [];
  48  
  49      /**
  50       * @var AnnotationInterface[]
  51       */
  52      protected $annotations = [];
  53  
  54      /**
  55       * Listen to onCreateAnnotation, and attempt to return an annotation object
  56       * instance.
  57       *
  58       * If the annotation class or alias is not registered, immediately returns
  59       * false. Otherwise, resolves the class, clones it, and, if any content is
  60       * present, calls {@link AnnotationInterface::initialize()} with the
  61       * content.
  62       *
  63       * @param  EventInterface $e
  64       * @return false|AnnotationInterface
  65       */
  66      public function onCreateAnnotation(EventInterface $e)
  67      {
  68          $class = $e->getParam('class', false);
  69          if (! $class || ! $this->hasAnnotation($class)) {
  70              return false;
  71          }
  72  
  73          $content = $e->getParam('content', '');
  74          $content = trim($content, '()');
  75  
  76          if ($this->hasAlias($class)) {
  77              $class = $this->resolveAlias($class);
  78          }
  79  
  80          $index      = array_search($class, $this->annotationNames);
  81          $annotation = $this->annotations[$index];
  82  
  83          $newAnnotation = clone $annotation;
  84          if ($content) {
  85              $newAnnotation->initialize($content);
  86          }
  87  
  88          return $newAnnotation;
  89      }
  90  
  91      /**
  92       * Register annotations
  93       *
  94       * @param  string|AnnotationInterface $annotation String class name of an
  95       *         AnnotationInterface implementation, or actual instance
  96       * @return void
  97       * @throws Exception\InvalidArgumentException
  98       */
  99      public function registerAnnotation($annotation)
 100      {
 101          $class = false;
 102          if (is_string($annotation) && class_exists($annotation)) {
 103              $class      = $annotation;
 104              $annotation = new $annotation();
 105          }
 106  
 107          if (! $annotation instanceof AnnotationInterface) {
 108              throw new Exception\InvalidArgumentException(sprintf(
 109                  '%s: expects an instance of %s\AnnotationInterface; received "%s"',
 110                  __METHOD__,
 111                  __NAMESPACE__,
 112                  is_object($annotation) ? get_class($annotation) : gettype($annotation)
 113              ));
 114          }
 115  
 116          $class = $class ?: get_class($annotation);
 117  
 118          if (in_array($class, $this->annotationNames)) {
 119              throw new Exception\InvalidArgumentException(sprintf(
 120                  'An annotation for this class %s already exists',
 121                  $class
 122              ));
 123          }
 124  
 125          $this->annotations[]     = $annotation;
 126          $this->annotationNames[] = $class;
 127      }
 128  
 129      /**
 130       * Register many annotations at once
 131       *
 132       * @param  array|Traversable $annotations
 133       * @throws Exception\InvalidArgumentException
 134       * @return GenericAnnotationParser
 135       */
 136      public function registerAnnotations($annotations)
 137      {
 138          if (! is_array($annotations) && ! $annotations instanceof Traversable) {
 139              throw new Exception\InvalidArgumentException(sprintf(
 140                  '%s: expects an array or Traversable; received "%s"',
 141                  __METHOD__,
 142                  is_object($annotations) ? get_class($annotations) : gettype($annotations)
 143              ));
 144          }
 145  
 146          foreach ($annotations as $annotation) {
 147              $this->registerAnnotation($annotation);
 148          }
 149  
 150          return $this;
 151      }
 152  
 153      /**
 154       * Checks if the manager has annotations for a class
 155       *
 156       * @param  string $class
 157       * @return bool
 158       */
 159      public function hasAnnotation($class)
 160      {
 161          if (in_array($class, $this->annotationNames)) {
 162              return true;
 163          }
 164  
 165          if ($this->hasAlias($class)) {
 166              return true;
 167          }
 168  
 169          return false;
 170      }
 171  
 172      /**
 173       * Alias an annotation name
 174       *
 175       * @param  string $alias
 176       * @param  string $class May be either a registered annotation name or another alias
 177       * @throws Exception\InvalidArgumentException
 178       * @return GenericAnnotationParser
 179       */
 180      public function setAlias($alias, $class)
 181      {
 182          if (! in_array($class, $this->annotationNames) && ! $this->hasAlias($class)) {
 183              throw new Exception\InvalidArgumentException(sprintf(
 184                  '%s: Cannot alias "%s" to "%s", as class "%s" is not currently a registered annotation or alias',
 185                  __METHOD__,
 186                  $alias,
 187                  $class,
 188                  $class
 189              ));
 190          }
 191  
 192          $alias = $this->normalizeAlias($alias);
 193          $this->aliases[$alias] = $class;
 194  
 195          return $this;
 196      }
 197  
 198      /**
 199       * Normalize an alias name
 200       *
 201       * @param  string $alias
 202       * @return string
 203       */
 204      protected function normalizeAlias($alias)
 205      {
 206          return strtolower(str_replace(['-', '_', ' ', '\\', '/'], '', $alias));
 207      }
 208  
 209      /**
 210       * Do we have an alias by the provided name?
 211       *
 212       * @param  string $alias
 213       * @return bool
 214       */
 215      protected function hasAlias($alias)
 216      {
 217          $alias = $this->normalizeAlias($alias);
 218  
 219          return isset($this->aliases[$alias]);
 220      }
 221  
 222      /**
 223       * Resolve an alias to a class name
 224       *
 225       * @param  string $alias
 226       * @return string
 227       */
 228      protected function resolveAlias($alias)
 229      {
 230          do {
 231              $normalized = $this->normalizeAlias($alias);
 232              $class      = $this->aliases[$normalized];
 233          } while ($this->hasAlias($class));
 234  
 235          return $class;
 236      }
 237  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1