| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 | 
							- <?php
 - 
 - /*
 -  * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
 -  *
 -  * Licensed under the Apache License, Version 2.0 (the "License");
 -  * you may not use this file except in compliance with the License.
 -  * You may obtain a copy of the License at
 -  *
 -  * http://www.apache.org/licenses/LICENSE-2.0
 -  *
 -  * Unless required by applicable law or agreed to in writing, software
 -  * distributed under the License is distributed on an "AS IS" BASIS,
 -  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 -  * See the License for the specific language governing permissions and
 -  * limitations under the License.
 -  */
 - 
 - namespace JMS\DiExtraBundle\Metadata\Driver;
 - 
 - use JMS\DiExtraBundle\Annotation\AfterSetup;
 - 
 - use JMS\DiExtraBundle\Annotation\FormType;
 - 
 - use JMS\DiExtraBundle\Annotation\DoctrineListener;
 - use JMS\DiExtraBundle\Annotation\Reference as AnnotReference;
 - use JMS\DiExtraBundle\Annotation\LookupMethod;
 - use JMS\DiExtraBundle\Annotation\Validator;
 - use JMS\DiExtraBundle\Annotation\InjectParams;
 - use JMS\DiExtraBundle\Exception\InvalidTypeException;
 - use JMS\DiExtraBundle\Annotation\Observe;
 - use Doctrine\Common\Annotations\Reader;
 - use JMS\DiExtraBundle\Annotation\Inject;
 - use JMS\DiExtraBundle\Annotation\Service;
 - use JMS\DiExtraBundle\Annotation\Tag;
 - use JMS\DiExtraBundle\Metadata\ClassMetadata;
 - use Metadata\Driver\DriverInterface;
 - use Symfony\Component\DependencyInjection\ContainerInterface;
 - use Symfony\Component\DependencyInjection\Reference;
 - 
 - class AnnotationDriver implements DriverInterface
 - {
 -     private $reader;
 - 
 -     public function __construct(Reader $reader)
 -     {
 -         $this->reader = $reader;
 -     }
 - 
 -     public function loadMetadataForClass(\ReflectionClass $class)
 -     {
 -         $metadata = new ClassMetadata($className = $class->getName());
 -         if (false !== $filename = $class->getFilename()) {
 -             $metadata->fileResources[] = $filename;
 -         }
 - 
 -         // this is a bit of a hack, but avoids any timeout issues when a class
 -         // is moved into one of the compiled classes files, and Doctrine
 -         // Common 2.1 is used.
 -         if (false !== strpos($filename, '/classes.php')
 -             || false !== strpos($filename, '/bootstrap.php')) {
 -             return null;
 -         }
 - 
 -         foreach ($this->reader->getClassAnnotations($class) as $annot) {
 -             if ($annot instanceof Service) {
 -                 if (null === $annot->id) {
 -                     $metadata->id = $this->generateId($className);
 -                 } else {
 -                     $metadata->id = $annot->id;
 -                 }
 - 
 -                 $metadata->parent = $annot->parent;
 -                 $metadata->public = $annot->public;
 -                 $metadata->scope = $annot->scope;
 -                 $metadata->abstract = $annot->abstract;
 -             } else if ($annot instanceof Tag) {
 -                 $metadata->tags[$annot->name][] = $annot->attributes;
 -             } else if ($annot instanceof Validator) {
 -                 // automatically register as service if not done explicitly
 -                 if (null === $metadata->id) {
 -                     $metadata->id = $this->generateId($className);
 -                 }
 - 
 -                 $metadata->tags['validator.constraint_validator'][] = array(
 -                     'alias' => $annot->alias,
 -                 );
 -             } else if ($annot instanceof DoctrineListener) {
 -                 if (null === $metadata->id) {
 -                     $metadata->id = $this->generateId($className);
 -                 }
 - 
 -                 foreach ($annot->events as $event) {
 -                     $metadata->tags['doctrine.event_listener'][] = array(
 -                         'event' => $event,
 -                         'connection' => $annot->connection ?: 'default',
 -                         'lazy' => $annot->lazy,
 -                         'priority' => $annot->priority,
 -                     );
 -                 }
 -             } else if ($annot instanceof FormType) {
 -                 if (null === $metadata->id) {
 -                     $metadata->id = $this->generateId($className);
 -                 }
 - 
 -                 $alias = $annot->alias;
 - 
 -                 // try to extract it from the class itself
 -                 if (null === $alias) {
 -                     $instance = unserialize(sprintf('O:%d:"%s":0:{}', strlen($className), $className));
 -                     $alias = $instance->getName();
 -                 }
 - 
 -                 $metadata->tags['form.type'][] = array(
 -                     'alias' => $alias,
 -                 );
 -             }
 -         }
 - 
 -         $hasInjection = false;
 -         foreach ($class->getProperties() as $property) {
 -             if ($property->getDeclaringClass()->getName() !== $className) {
 -                 continue;
 -             }
 -             $name = $property->getName();
 - 
 -             foreach ($this->reader->getPropertyAnnotations($property) as $annot) {
 -                 if ($annot instanceof Inject) {
 -                     $hasInjection = true;
 -                     $metadata->properties[$name] = $this->convertReferenceValue($name, $annot);
 -                 }
 -             }
 -         }
 - 
 -         foreach ($class->getMethods() as $method) {
 -             if ($method->getDeclaringClass()->getName() !== $className) {
 -                 continue;
 -             }
 -             $name = $method->getName();
 - 
 -             foreach ($this->reader->getMethodAnnotations($method) as $annot) {
 -                 if ($annot instanceof Observe) {
 -                     $metadata->tags['kernel.event_listener'][] = array(
 -                         'event' => $annot->event,
 -                         'method' => $name,
 -                         'priority' => $annot->priority,
 -                     );
 -                 } else if ($annot instanceof InjectParams) {
 -                     $params = array();
 -                     foreach ($method->getParameters() as $param) {
 -                         if (!isset($annot->params[$paramName = $param->getName()])) {
 -                             $params[] = $this->convertReferenceValue($paramName, new Inject(array('value' => null)));
 -                             continue;
 -                         }
 - 
 -                         $params[] = $this->convertReferenceValue($paramName, $annot->params[$paramName]);
 -                     }
 - 
 -                     if (!$params) {
 -                         continue;
 -                     }
 - 
 -                     $hasInjection = true;
 - 
 -                     if ('__construct' === $name) {
 -                         $metadata->arguments = $params;
 -                     } else {
 -                         $metadata->methodCalls[] = array($name, $params);
 -                     }
 -                 } else if ($annot instanceof LookupMethod) {
 -                     $hasInjection = true;
 - 
 -                     if ($method->isFinal()) {
 -                         throw new \RuntimeException(sprintf('The method "%s::%s" is marked as final and cannot be declared as lookup-method.', $className, $name));
 -                     }
 -                     if ($method->isPrivate()) {
 -                         throw new \RuntimeException(sprintf('The method "%s::%s" is marked as private and cannot be declared as lookup-method.', $className, $name));
 -                     }
 -                     if ($method->getParameters()) {
 -                         throw new \RuntimeException(sprintf('The method "%s::%s" must have a no-arguments signature if you want to use it as lookup-method.', $className, $name));
 -                     }
 - 
 -                     $metadata->lookupMethods[$name] = $this->convertReferenceValue('get' === substr($name, 0, 3) ? substr($name, 3) : $name, $annot);
 -                 } else if ($annot instanceof AfterSetup) {
 -                     if (!$method->isPublic()) {
 -                         throw new \RuntimeException(sprintf('The init method "%s::%s" must be public.', $method->class, $method->name));
 -                     }
 - 
 -                     $metadata->initMethod = $method->name;
 -                 }
 -             }
 -         }
 - 
 -         if (null == $metadata->id && !$hasInjection) {
 -             return null;
 -         }
 - 
 -         return $metadata;
 -     }
 - 
 -     private function convertReferenceValue($name, AnnotReference $annot)
 -     {
 -         if (null === $annot->value) {
 -             return new Reference($this->generateId($name), false !== $annot->required ? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE : ContainerInterface::NULL_ON_INVALID_REFERENCE);
 -         }
 - 
 -         if (false === strpos($annot->value, '%')) {
 -             return new Reference($annot->value, false !== $annot->required ? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE : ContainerInterface::NULL_ON_INVALID_REFERENCE);
 -         }
 - 
 -         return $annot->value;
 -     }
 - 
 -     private function generateId($name)
 -     {
 -         $name = preg_replace('/(?<=[a-zA-Z0-9])[A-Z]/', '_\\0', $name);
 - 
 -         return strtolower(strtr($name, '\\', '.'));
 -     }
 - }
 
 
  |