These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * Copyright 2011 Johannes M. Schmitt <[email protected]> |
||
5 | * |
||
6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
7 | * you may not use this file except in compliance with the License. |
||
8 | * You may obtain a copy of the License at |
||
9 | * |
||
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
11 | * |
||
12 | * Unless required by applicable law or agreed to in writing, software |
||
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
15 | * See the License for the specific language governing permissions and |
||
16 | * limitations under the License. |
||
17 | */ |
||
18 | |||
19 | namespace JMS\DiExtraBundle\Metadata\Driver; |
||
20 | |||
21 | use JMS\DiExtraBundle\Annotation\MetadataProcessorInterface; |
||
22 | use JMS\DiExtraBundle\Annotation\SecurityFunction; |
||
23 | |||
24 | use JMS\DiExtraBundle\Annotation\AfterSetup; |
||
25 | |||
26 | use JMS\DiExtraBundle\Annotation\FormType; |
||
27 | |||
28 | use JMS\DiExtraBundle\Annotation\AbstractDoctrineListener; |
||
29 | use JMS\DiExtraBundle\Annotation\DoctrineListener; |
||
30 | use JMS\DiExtraBundle\Annotation\DoctrineMongoDBListener; |
||
31 | use JMS\DiExtraBundle\Annotation\Reference as AnnotReference; |
||
32 | use JMS\DiExtraBundle\Annotation\LookupMethod; |
||
33 | use JMS\DiExtraBundle\Annotation\Validator; |
||
34 | use JMS\DiExtraBundle\Annotation\InjectParams; |
||
35 | use JMS\DiExtraBundle\Exception\InvalidTypeException; |
||
36 | use JMS\DiExtraBundle\Annotation\Observe; |
||
37 | use Doctrine\Common\Annotations\Reader; |
||
38 | use JMS\DiExtraBundle\Annotation\Inject; |
||
39 | use JMS\DiExtraBundle\Annotation\Service; |
||
40 | use JMS\DiExtraBundle\Annotation\Tag; |
||
41 | use JMS\DiExtraBundle\Metadata\ClassMetadata; |
||
42 | use JMS\DiExtraBundle\Metadata\NamingStrategy; |
||
43 | use Metadata\Driver\DriverInterface; |
||
44 | use Symfony\Component\DependencyInjection\ContainerInterface; |
||
45 | use Symfony\Component\DependencyInjection\Reference; |
||
46 | |||
47 | class AnnotationDriver implements DriverInterface |
||
48 | { |
||
49 | private $reader; |
||
50 | private $namingStrategy; |
||
51 | |||
52 | public function __construct(Reader $reader, NamingStrategy $namingStrategy) |
||
53 | { |
||
54 | $this->reader = $reader; |
||
55 | $this->namingStrategy = $namingStrategy; |
||
56 | } |
||
57 | |||
58 | public function loadMetadataForClass(\ReflectionClass $class) |
||
59 | { |
||
60 | $metadata = new ClassMetadata($className = $class->getName()); |
||
61 | if (false !== $filename = $class->getFilename()) { |
||
62 | $metadata->fileResources[] = $filename; |
||
63 | } |
||
64 | |||
65 | // this is a bit of a hack, but avoids any timeout issues when a class |
||
66 | // is moved into one of the compiled classes files, and Doctrine |
||
67 | // Common 2.1 is used. |
||
68 | if (false !== strpos($filename, '/classes.php') |
||
69 | || false !== strpos($filename, '/bootstrap.php')) { |
||
70 | return null; |
||
71 | } |
||
72 | |||
73 | foreach ($this->reader->getClassAnnotations($class) as $annot) { |
||
74 | if ($annot instanceof Service) { |
||
75 | if (null === $annot->id) { |
||
76 | $metadata->id = $this->namingStrategy->classToServiceName($className); |
||
77 | } else { |
||
78 | $metadata->id = $annot->id; |
||
79 | } |
||
80 | |||
81 | $metadata->parent = $annot->parent; |
||
82 | $metadata->public = $annot->public; |
||
83 | $metadata->scope = $annot->scope; |
||
84 | $metadata->abstract = $annot->abstract; |
||
85 | $metadata->decorates = $annot->decorates; |
||
86 | $metadata->decoration_inner_name = $annot->decoration_inner_name; |
||
87 | $metadata->deprecated = $annot->deprecated; |
||
88 | } else if ($annot instanceof Tag) { |
||
89 | $metadata->tags[$annot->name][] = $annot->attributes; |
||
90 | } else if ($annot instanceof Validator) { |
||
91 | // automatically register as service if not done explicitly |
||
92 | if (null === $metadata->id) { |
||
93 | $metadata->id = $this->namingStrategy->classToServiceName($className); |
||
94 | } |
||
95 | |||
96 | $metadata->tags['validator.constraint_validator'][] = array( |
||
97 | 'alias' => $annot->alias, |
||
98 | ); |
||
99 | } else if ($annot instanceof AbstractDoctrineListener) { |
||
100 | if (null === $metadata->id) { |
||
101 | $metadata->id = $this->namingStrategy->classToServiceName($className); |
||
102 | } |
||
103 | |||
104 | foreach ($annot->events as $event) { |
||
105 | $metadata->tags[$annot->getTag()][] = array( |
||
106 | 'event' => $event, |
||
107 | 'connection' => $annot->connection ?: 'default', |
||
108 | 'lazy' => $annot->lazy, |
||
109 | 'priority' => $annot->priority, |
||
110 | ); |
||
111 | } |
||
112 | } else if ($annot instanceof FormType) { |
||
113 | if (null === $metadata->id) { |
||
114 | $metadata->id = $this->namingStrategy->classToServiceName($className); |
||
115 | } |
||
116 | |||
117 | $alias = $annot->alias; |
||
118 | |||
119 | // try to extract it from the class itself |
||
120 | if (null === $alias) { |
||
121 | $instance = unserialize(sprintf('O:%d:"%s":0:{}', strlen($className), $className)); |
||
122 | $alias = $instance->getName(); |
||
123 | } |
||
124 | |||
125 | $metadata->tags['form.type'][] = array( |
||
126 | 'alias' => $alias, |
||
127 | ); |
||
128 | View Code Duplication | } else if ($annot instanceof MetadataProcessorInterface) { |
|
129 | if (null === $metadata->id) { |
||
130 | $metadata->id = $this->namingStrategy->classToServiceName($className); |
||
131 | } |
||
132 | |||
133 | $annot->processMetadata($metadata); |
||
134 | } |
||
135 | } |
||
136 | |||
137 | $hasInjection = false; |
||
138 | foreach ($class->getProperties() as $property) { |
||
139 | if ($property->getDeclaringClass()->getName() !== $className) { |
||
140 | continue; |
||
141 | } |
||
142 | $name = $property->getName(); |
||
143 | |||
144 | foreach ($this->reader->getPropertyAnnotations($property) as $annot) { |
||
145 | if ($annot instanceof Inject) { |
||
146 | $hasInjection = true; |
||
147 | $metadata->properties[$name] = $this->convertReferenceValue($name, $annot); |
||
148 | } |
||
149 | } |
||
150 | } |
||
151 | |||
152 | foreach ($class->getMethods() as $method) { |
||
153 | if ($method->getDeclaringClass()->getName() !== $className) { |
||
154 | continue; |
||
155 | } |
||
156 | $name = $method->getName(); |
||
157 | |||
158 | foreach ($this->reader->getMethodAnnotations($method) as $annot) { |
||
159 | if ($annot instanceof Observe) { |
||
160 | $metadata->tags['kernel.event_listener'][] = array( |
||
161 | 'event' => $annot->event, |
||
162 | 'method' => $name, |
||
163 | 'priority' => $annot->priority, |
||
164 | ); |
||
165 | } else if ($annot instanceof SecurityFunction) { |
||
166 | $metadata->tags['security.expressions.function_evaluator'][] = array( |
||
167 | 'function' => $annot->function, |
||
168 | 'method' => $name, |
||
169 | ); |
||
170 | } else if ($annot instanceof InjectParams) { |
||
171 | $params = array(); |
||
172 | foreach ($method->getParameters() as $param) { |
||
173 | if (!isset($annot->params[$paramName = $param->getName()])) { |
||
174 | $params[] = $this->convertReferenceValue($paramName, new Inject(array('value' => null))); |
||
175 | continue; |
||
176 | } |
||
177 | |||
178 | $params[] = $this->convertReferenceValue($paramName, $annot->params[$paramName]); |
||
179 | } |
||
180 | |||
181 | if (!$params) { |
||
182 | continue; |
||
183 | } |
||
184 | |||
185 | $hasInjection = true; |
||
186 | |||
187 | if ('__construct' === $name) { |
||
188 | $metadata->arguments = $params; |
||
189 | } else { |
||
190 | $metadata->methodCalls[] = array($name, $params); |
||
191 | } |
||
192 | } else if ($annot instanceof LookupMethod) { |
||
193 | $hasInjection = true; |
||
194 | |||
195 | if ($method->isFinal()) { |
||
196 | throw new \RuntimeException(sprintf('The method "%s::%s" is marked as final and cannot be declared as lookup-method.', $className, $name)); |
||
197 | } |
||
198 | if ($method->isPrivate()) { |
||
199 | throw new \RuntimeException(sprintf('The method "%s::%s" is marked as private and cannot be declared as lookup-method.', $className, $name)); |
||
200 | } |
||
201 | if ($method->getParameters()) { |
||
202 | 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)); |
||
203 | } |
||
204 | |||
205 | $metadata->lookupMethods[$name] = $this->convertReferenceValue('get' === substr($name, 0, 3) ? substr($name, 3) : $name, $annot); |
||
206 | } else if ($annot instanceof AfterSetup) { |
||
207 | if (!$method->isPublic()) { |
||
208 | throw new \RuntimeException(sprintf('The init method "%s::%s" must be public.', $method->class, $method->name)); |
||
209 | } |
||
210 | |||
211 | $metadata->initMethod = $method->name; |
||
0 ignored issues
–
show
|
|||
212 | $metadata->initMethods[] = $method->name; |
||
213 | View Code Duplication | } else if ($annot instanceof MetadataProcessorInterface) { |
|
214 | if (null === $metadata->id) { |
||
215 | $metadata->id = $this->namingStrategy->classToServiceName($className); |
||
216 | } |
||
217 | |||
218 | $annot->processMetadata($metadata); |
||
219 | } |
||
220 | } |
||
221 | } |
||
222 | |||
223 | if (null == $metadata->id && !$hasInjection) { |
||
224 | return null; |
||
225 | } |
||
226 | |||
227 | return $metadata; |
||
228 | } |
||
229 | |||
230 | private function convertReferenceValue($name, AnnotReference $annot) |
||
231 | { |
||
232 | View Code Duplication | if (null === $annot->value) { |
|
233 | return new Reference($this->namingStrategy->classToServiceName($name), false !== $annot->required ? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE : ContainerInterface::NULL_ON_INVALID_REFERENCE, $annot->strict); |
||
234 | } |
||
235 | |||
236 | View Code Duplication | if (false === strpos($annot->value, '%')) { |
|
237 | return new Reference($annot->value, false !== $annot->required ? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE : ContainerInterface::NULL_ON_INVALID_REFERENCE, $annot->strict); |
||
238 | } |
||
239 | |||
240 | return $annot->value; |
||
241 | } |
||
242 | } |
||
243 |
This property has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.