Total Complexity | 91 |
Total Lines | 725 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like ClassSchema often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ClassSchema, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
35 | class ClassSchema |
||
36 | { |
||
37 | /** |
||
38 | * Available model types |
||
39 | */ |
||
40 | const MODELTYPE_ENTITY = 1; |
||
41 | const MODELTYPE_VALUEOBJECT = 2; |
||
42 | |||
43 | /** |
||
44 | * Name of the class this schema is referring to |
||
45 | * |
||
46 | * @var string |
||
47 | */ |
||
48 | protected $className; |
||
49 | |||
50 | /** |
||
51 | * Model type of the class this schema is referring to |
||
52 | * |
||
53 | * @var int |
||
54 | */ |
||
55 | protected $modelType = self::MODELTYPE_ENTITY; |
||
56 | |||
57 | /** |
||
58 | * Whether a repository exists for the class this schema is referring to |
||
59 | * |
||
60 | * @var bool |
||
61 | */ |
||
62 | protected $aggregateRoot = false; |
||
63 | |||
64 | /** |
||
65 | * The name of the property holding the uuid of an entity, if any. |
||
66 | * |
||
67 | * @var string |
||
68 | */ |
||
69 | protected $uuidPropertyName; |
||
70 | |||
71 | /** |
||
72 | * Properties of the class which need to be persisted |
||
73 | * |
||
74 | * @var array |
||
75 | */ |
||
76 | protected $properties = []; |
||
77 | |||
78 | /** |
||
79 | * The properties forming the identity of an object |
||
80 | * |
||
81 | * @var array |
||
82 | */ |
||
83 | protected $identityProperties = []; |
||
84 | |||
85 | /** |
||
86 | * Indicates if the class is a singleton or not. |
||
87 | * |
||
88 | * @var bool |
||
89 | */ |
||
90 | private $isSingleton; |
||
91 | |||
92 | /** |
||
93 | * @var array |
||
94 | */ |
||
95 | private $methods; |
||
96 | |||
97 | /** |
||
98 | * @var array |
||
99 | */ |
||
100 | private $tags = []; |
||
101 | |||
102 | /** |
||
103 | * @var array |
||
104 | */ |
||
105 | private $injectProperties = []; |
||
106 | |||
107 | /** |
||
108 | * @var array |
||
109 | */ |
||
110 | private $injectMethods = []; |
||
111 | |||
112 | /** |
||
113 | * Constructs this class schema |
||
114 | * |
||
115 | * @param string $className Name of the class this schema is referring to |
||
116 | * @throws \TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException |
||
117 | * @throws \ReflectionException |
||
118 | */ |
||
119 | public function __construct($className) |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * @param \ReflectionClass $reflectionClass |
||
150 | */ |
||
151 | protected function reflectProperties(\ReflectionClass $reflectionClass) |
||
152 | { |
||
153 | $annotationReader = new AnnotationReader(); |
||
154 | |||
155 | foreach ($reflectionClass->getProperties() as $reflectionProperty) { |
||
156 | $propertyName = $reflectionProperty->getName(); |
||
157 | |||
158 | $this->properties[$propertyName] = [ |
||
159 | 'default' => $reflectionProperty->isDefault(), |
||
160 | 'private' => $reflectionProperty->isPrivate(), |
||
161 | 'protected' => $reflectionProperty->isProtected(), |
||
162 | 'public' => $reflectionProperty->isPublic(), |
||
163 | 'static' => $reflectionProperty->isStatic(), |
||
164 | 'type' => null, // Extbase |
||
165 | 'elementType' => null, // Extbase |
||
166 | 'annotations' => [], |
||
167 | 'tags' => [] |
||
168 | ]; |
||
169 | |||
170 | $docCommentParser = new DocCommentParser(true); |
||
171 | $docCommentParser->parseDocComment($reflectionProperty->getDocComment()); |
||
172 | foreach ($docCommentParser->getTagsValues() as $tag => $values) { |
||
173 | $this->properties[$propertyName]['tags'][strtolower($tag)] = $values; |
||
174 | } |
||
175 | |||
176 | $this->properties[$propertyName]['annotations']['inject'] = false; |
||
177 | $this->properties[$propertyName]['annotations']['lazy'] = false; |
||
178 | $this->properties[$propertyName]['annotations']['transient'] = false; |
||
179 | $this->properties[$propertyName]['annotations']['type'] = null; |
||
180 | $this->properties[$propertyName]['annotations']['cascade'] = null; |
||
181 | $this->properties[$propertyName]['annotations']['dependency'] = null; |
||
182 | $this->properties[$propertyName]['annotations']['validators'] = []; |
||
183 | |||
184 | if ($docCommentParser->isTaggedWith('validate')) { |
||
185 | $this->properties[$propertyName]['annotations']['validators'] = $docCommentParser->getTagValues('validate'); |
||
186 | } |
||
187 | |||
188 | if ($annotationReader->getPropertyAnnotation($reflectionProperty, Lazy::class) instanceof Lazy) { |
||
189 | $this->properties[$propertyName]['annotations']['lazy'] = true; |
||
190 | } |
||
191 | |||
192 | if ($docCommentParser->isTaggedWith('lazy')) { |
||
193 | $this->properties[$propertyName]['annotations']['lazy'] = true; |
||
194 | trigger_error( |
||
195 | 'Tagging properties with @lazy is deprecated and will be removed in TYPO3 v10.0.', |
||
196 | E_USER_DEPRECATED |
||
197 | ); |
||
198 | } |
||
199 | |||
200 | if ($annotationReader->getPropertyAnnotation($reflectionProperty, Transient::class) instanceof Transient) { |
||
201 | $this->properties[$propertyName]['annotations']['transient'] = true; |
||
202 | } |
||
203 | |||
204 | if ($docCommentParser->isTaggedWith('transient')) { |
||
205 | $this->properties[$propertyName]['annotations']['transient'] = true; |
||
206 | trigger_error( |
||
207 | 'Tagging properties with @transient is deprecated and will be removed in TYPO3 v10.0.', |
||
208 | E_USER_DEPRECATED |
||
209 | ); |
||
210 | } |
||
211 | |||
212 | if ($propertyName !== 'settings' |
||
213 | && ($annotationReader->getPropertyAnnotation($reflectionProperty, Inject::class) instanceof Inject) |
||
214 | ) { |
||
215 | try { |
||
216 | $varValue = ltrim($docCommentParser->getTagValues('var')[0], '\\'); |
||
217 | $this->properties[$propertyName]['annotations']['inject'] = true; |
||
218 | $this->properties[$propertyName]['annotations']['type'] = $varValue; |
||
219 | $this->properties[$propertyName]['annotations']['dependency'] = $varValue; |
||
220 | |||
221 | $this->injectProperties[] = $propertyName; |
||
222 | } catch (\Exception $e) { |
||
|
|||
223 | } |
||
224 | } |
||
225 | |||
226 | if ($propertyName !== 'settings' && $docCommentParser->isTaggedWith('inject')) { |
||
227 | trigger_error( |
||
228 | 'Tagging properties with @inject is deprecated and will be removed in TYPO3 v10.0.', |
||
229 | E_USER_DEPRECATED |
||
230 | ); |
||
231 | try { |
||
232 | $varValues = $docCommentParser->getTagValues('var'); |
||
233 | $this->properties[$propertyName]['annotations']['inject'] = true; |
||
234 | $this->properties[$propertyName]['annotations']['type'] = ltrim($varValues[0], '\\'); |
||
235 | $this->properties[$propertyName]['annotations']['dependency'] = ltrim($varValues[0], '\\'); |
||
236 | |||
237 | if (!$reflectionProperty->isPublic()) { |
||
238 | trigger_error( |
||
239 | 'Using @inject with non-public properties is deprecated since TYPO3 v9.0 and will stop working in TYPO3 v10.0.', |
||
240 | E_USER_DEPRECATED |
||
241 | ); |
||
242 | } |
||
243 | |||
244 | $this->injectProperties[] = $propertyName; |
||
245 | } catch (\Exception $e) { |
||
246 | } |
||
247 | } |
||
248 | |||
249 | if ($docCommentParser->isTaggedWith('var') && !$docCommentParser->isTaggedWith('transient')) { |
||
250 | try { |
||
251 | $cascadeAnnotationValues = $docCommentParser->getTagValues('cascade'); |
||
252 | $this->properties[$propertyName]['annotations']['cascade'] = $cascadeAnnotationValues[0]; |
||
253 | } catch (\Exception $e) { |
||
254 | } |
||
255 | |||
256 | if ($this->properties[$propertyName]['annotations']['cascade'] !== null) { |
||
257 | trigger_error( |
||
258 | 'Tagging properties with @cascade is deprecated and will be removed in TYPO3 v10.0.', |
||
259 | E_USER_DEPRECATED |
||
260 | ); |
||
261 | } |
||
262 | |||
263 | if (($annotation = $annotationReader->getPropertyAnnotation($reflectionProperty, Cascade::class)) instanceof Cascade) { |
||
264 | /** @var Cascade $annotation */ |
||
265 | $this->properties[$propertyName]['annotations']['cascade'] = $annotation->value; |
||
266 | } |
||
267 | |||
268 | try { |
||
269 | $type = TypeHandlingUtility::parseType(implode(' ', $docCommentParser->getTagValues('var'))); |
||
270 | } catch (\Exception $e) { |
||
271 | $type = [ |
||
272 | 'type' => null, |
||
273 | 'elementType' => null |
||
274 | ]; |
||
275 | } |
||
276 | |||
277 | $this->properties[$propertyName]['type'] = $type['type'] ? ltrim($type['type'], '\\') : null; |
||
278 | $this->properties[$propertyName]['elementType'] = $type['elementType'] ? ltrim($type['elementType'], '\\') : null; |
||
279 | } |
||
280 | |||
281 | if ($docCommentParser->isTaggedWith('uuid')) { |
||
282 | $this->setUuidPropertyName($propertyName); |
||
283 | } |
||
284 | |||
285 | if ($docCommentParser->isTaggedWith('identity')) { |
||
286 | $this->markAsIdentityProperty($propertyName); |
||
287 | } |
||
288 | } |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * @param \ReflectionClass $reflectionClass |
||
293 | */ |
||
294 | protected function reflectMethods(\ReflectionClass $reflectionClass) |
||
295 | { |
||
296 | $annotationReader = new AnnotationReader(); |
||
297 | |||
298 | foreach ($reflectionClass->getMethods() as $reflectionMethod) { |
||
299 | $methodName = $reflectionMethod->getName(); |
||
300 | |||
301 | $this->methods[$methodName] = []; |
||
302 | $this->methods[$methodName]['private'] = $reflectionMethod->isPrivate(); |
||
303 | $this->methods[$methodName]['protected'] = $reflectionMethod->isProtected(); |
||
304 | $this->methods[$methodName]['public'] = $reflectionMethod->isPublic(); |
||
305 | $this->methods[$methodName]['static'] = $reflectionMethod->isStatic(); |
||
306 | $this->methods[$methodName]['abstract'] = $reflectionMethod->isAbstract(); |
||
307 | $this->methods[$methodName]['params'] = []; |
||
308 | $this->methods[$methodName]['tags'] = []; |
||
309 | $this->methods[$methodName]['annotations'] = []; |
||
310 | |||
311 | $docCommentParser = new DocCommentParser(true); |
||
312 | $docCommentParser->parseDocComment($reflectionMethod->getDocComment()); |
||
313 | |||
314 | $this->methods[$methodName]['annotations']['validators'] = []; |
||
315 | |||
316 | foreach ($docCommentParser->getTagsValues() as $tag => $values) { |
||
317 | if ($tag === 'ignorevalidation') { |
||
318 | trigger_error( |
||
319 | 'Tagging methods with @ignorevalidation is deprecated and will be removed in TYPO3 v10.0.', |
||
320 | E_USER_DEPRECATED |
||
321 | ); |
||
322 | } |
||
323 | if ($tag === 'validate') { |
||
324 | $this->methods[$methodName]['annotations']['validators'] = $values; |
||
325 | } |
||
326 | $this->methods[$methodName]['tags'][$tag] = array_map(function ($value) use ($tag) { |
||
327 | // not stripping the dollar sign for @validate annotations is just |
||
328 | // a quick fix for a regression introduced in 9.0.0. |
||
329 | // This exception to the rules will vanish once the resolving of |
||
330 | // validators will take place inside this class and not in the |
||
331 | // controller during runtime. |
||
332 | return $tag === 'validate' ? $value : ltrim($value, '$'); |
||
333 | }, $values); |
||
334 | } |
||
335 | |||
336 | foreach ($annotationReader->getMethodAnnotations($reflectionMethod) as $annotation) { |
||
337 | if ($annotation instanceof IgnoreValidation) { |
||
338 | $this->methods[$methodName]['tags']['ignorevalidation'][] = $annotation->argumentName; |
||
339 | } |
||
340 | } |
||
341 | |||
342 | $this->methods[$methodName]['description'] = $docCommentParser->getDescription(); |
||
343 | |||
344 | foreach ($reflectionMethod->getParameters() as $parameterPosition => $reflectionParameter) { |
||
345 | /* @var $reflectionParameter \ReflectionParameter */ |
||
346 | |||
347 | $parameterName = $reflectionParameter->getName(); |
||
348 | |||
349 | $this->methods[$methodName]['params'][$parameterName] = []; |
||
350 | $this->methods[$methodName]['params'][$parameterName]['position'] = $parameterPosition; // compat |
||
351 | $this->methods[$methodName]['params'][$parameterName]['byReference'] = $reflectionParameter->isPassedByReference(); // compat |
||
352 | $this->methods[$methodName]['params'][$parameterName]['array'] = $reflectionParameter->isArray(); // compat |
||
353 | $this->methods[$methodName]['params'][$parameterName]['optional'] = $reflectionParameter->isOptional(); |
||
354 | $this->methods[$methodName]['params'][$parameterName]['allowsNull'] = $reflectionParameter->allowsNull(); // compat |
||
355 | $this->methods[$methodName]['params'][$parameterName]['class'] = null; // compat |
||
356 | $this->methods[$methodName]['params'][$parameterName]['type'] = null; |
||
357 | $this->methods[$methodName]['params'][$parameterName]['nullable'] = $reflectionParameter->allowsNull(); |
||
358 | $this->methods[$methodName]['params'][$parameterName]['default'] = null; |
||
359 | $this->methods[$methodName]['params'][$parameterName]['hasDefaultValue'] = $reflectionParameter->isDefaultValueAvailable(); |
||
360 | $this->methods[$methodName]['params'][$parameterName]['defaultValue'] = null; // compat |
||
361 | $this->methods[$methodName]['params'][$parameterName]['dependency'] = null; // Extbase DI |
||
362 | |||
363 | if ($reflectionParameter->isDefaultValueAvailable()) { |
||
364 | $this->methods[$methodName]['params'][$parameterName]['default'] = $reflectionParameter->getDefaultValue(); |
||
365 | $this->methods[$methodName]['params'][$parameterName]['defaultValue'] = $reflectionParameter->getDefaultValue(); // compat |
||
366 | } |
||
367 | |||
368 | if (($reflectionType = $reflectionParameter->getType()) instanceof \ReflectionType) { |
||
369 | $this->methods[$methodName]['params'][$parameterName]['type'] = (string)$reflectionType; |
||
370 | $this->methods[$methodName]['params'][$parameterName]['nullable'] = $reflectionType->allowsNull(); |
||
371 | } |
||
372 | |||
373 | if (($parameterClass = $reflectionParameter->getClass()) instanceof \ReflectionClass) { |
||
374 | $this->methods[$methodName]['params'][$parameterName]['class'] = $parameterClass->getName(); |
||
375 | $this->methods[$methodName]['params'][$parameterName]['type'] = ltrim($parameterClass->getName(), '\\'); |
||
376 | } else { |
||
377 | $methodTagsAndValues = $this->methods[$methodName]['tags']; |
||
378 | if (isset($methodTagsAndValues['param'], $methodTagsAndValues['param'][$parameterPosition])) { |
||
379 | $explodedParameters = explode(' ', $methodTagsAndValues['param'][$parameterPosition]); |
||
380 | if (count($explodedParameters) >= 2) { |
||
381 | if (TypeHandlingUtility::isSimpleType($explodedParameters[0])) { |
||
382 | // ensure that short names of simple types are resolved correctly to the long form |
||
383 | // this is important for all kinds of type checks later on |
||
384 | $typeInfo = TypeHandlingUtility::parseType($explodedParameters[0]); |
||
385 | |||
386 | $this->methods[$methodName]['params'][$parameterName]['type'] = ltrim($typeInfo['type'], '\\'); |
||
387 | } else { |
||
388 | $this->methods[$methodName]['params'][$parameterName]['type'] = ltrim($explodedParameters[0], '\\'); |
||
389 | } |
||
390 | } |
||
391 | } |
||
392 | } |
||
393 | |||
394 | // Extbase DI |
||
395 | if ($reflectionParameter->getClass() instanceof \ReflectionClass |
||
396 | && ($reflectionMethod->isConstructor() || $this->hasInjectMethodName($reflectionMethod)) |
||
397 | ) { |
||
398 | $this->methods[$methodName]['params'][$parameterName]['dependency'] = $reflectionParameter->getClass()->getName(); |
||
399 | } |
||
400 | } |
||
401 | |||
402 | // Extbase |
||
403 | $this->methods[$methodName]['injectMethod'] = false; |
||
404 | if ($this->hasInjectMethodName($reflectionMethod) |
||
405 | && count($this->methods[$methodName]['params']) === 1 |
||
406 | && reset($this->methods[$methodName]['params'])['dependency'] !== null |
||
407 | ) { |
||
408 | $this->methods[$methodName]['injectMethod'] = true; |
||
409 | $this->injectMethods[] = $methodName; |
||
410 | } |
||
411 | } |
||
412 | } |
||
413 | |||
414 | /** |
||
415 | * Returns the class name this schema is referring to |
||
416 | * |
||
417 | * @return string The class name |
||
418 | */ |
||
419 | public function getClassName(): string |
||
420 | { |
||
421 | return $this->className; |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * Adds (defines) a specific property and its type. |
||
426 | * |
||
427 | * @param string $name Name of the property |
||
428 | * @param string $type Type of the property |
||
429 | * @param bool $lazy Whether the property should be lazy-loaded when reconstituting |
||
430 | * @param string $cascade Strategy to cascade the object graph. |
||
431 | * @deprecated |
||
432 | */ |
||
433 | public function addProperty($name, $type, $lazy = false, $cascade = '') |
||
434 | { |
||
435 | trigger_error( |
||
436 | 'This method will be removed in TYPO3 v10.0, properties will be automatically added on ClassSchema construction.', |
||
437 | E_USER_DEPRECATED |
||
438 | ); |
||
439 | $type = TypeHandlingUtility::parseType($type); |
||
440 | $this->properties[$name] = [ |
||
441 | 'type' => $type['type'], |
||
442 | 'elementType' => $type['elementType'], |
||
443 | 'lazy' => $lazy, |
||
444 | 'cascade' => $cascade |
||
445 | ]; |
||
446 | } |
||
447 | |||
448 | /** |
||
449 | * Returns the given property defined in this schema. Check with |
||
450 | * hasProperty($propertyName) before! |
||
451 | * |
||
452 | * @param string $propertyName |
||
453 | * @return array |
||
454 | */ |
||
455 | public function getProperty($propertyName) |
||
456 | { |
||
457 | return is_array($this->properties[$propertyName]) ? $this->properties[$propertyName] : []; |
||
458 | } |
||
459 | |||
460 | /** |
||
461 | * Returns all properties defined in this schema |
||
462 | * |
||
463 | * @return array |
||
464 | */ |
||
465 | public function getProperties() |
||
466 | { |
||
467 | return $this->properties; |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * Sets the model type of the class this schema is referring to. |
||
472 | * |
||
473 | * @param int $modelType The model type, one of the MODELTYPE_* constants. |
||
474 | * @throws \InvalidArgumentException |
||
475 | * @deprecated |
||
476 | */ |
||
477 | public function setModelType($modelType) |
||
478 | { |
||
479 | trigger_error( |
||
480 | 'This method will be removed in TYPO3 v10.0, modelType will be automatically set on ClassSchema construction.', |
||
481 | E_USER_DEPRECATED |
||
482 | ); |
||
483 | if ($modelType < self::MODELTYPE_ENTITY || $modelType > self::MODELTYPE_VALUEOBJECT) { |
||
484 | throw new \InvalidArgumentException('"' . $modelType . '" is an invalid model type.', 1212519195); |
||
485 | } |
||
486 | $this->modelType = $modelType; |
||
487 | } |
||
488 | |||
489 | /** |
||
490 | * Returns the model type of the class this schema is referring to. |
||
491 | * |
||
492 | * @return int The model type, one of the MODELTYPE_* constants. |
||
493 | * @deprecated |
||
494 | */ |
||
495 | public function getModelType() |
||
496 | { |
||
497 | trigger_error( |
||
498 | 'This method will be removed in TYPO3 v10.0.', |
||
499 | E_USER_DEPRECATED |
||
500 | ); |
||
501 | return $this->modelType; |
||
502 | } |
||
503 | |||
504 | /** |
||
505 | * Marks the class if it is root of an aggregate and therefore accessible |
||
506 | * through a repository - or not. |
||
507 | * |
||
508 | * @param bool $isRoot TRUE if it is the root of an aggregate |
||
509 | */ |
||
510 | public function setAggregateRoot($isRoot) |
||
511 | { |
||
512 | $this->aggregateRoot = $isRoot; |
||
513 | } |
||
514 | |||
515 | /** |
||
516 | * Whether the class is an aggregate root and therefore accessible through |
||
517 | * a repository. |
||
518 | * |
||
519 | * @return bool TRUE if it is managed |
||
520 | */ |
||
521 | public function isAggregateRoot(): bool |
||
522 | { |
||
523 | return $this->aggregateRoot; |
||
524 | } |
||
525 | |||
526 | /** |
||
527 | * If the class schema has a certain property. |
||
528 | * |
||
529 | * @param string $propertyName Name of the property |
||
530 | * @return bool |
||
531 | */ |
||
532 | public function hasProperty($propertyName): bool |
||
533 | { |
||
534 | return array_key_exists($propertyName, $this->properties); |
||
535 | } |
||
536 | |||
537 | /** |
||
538 | * Sets the property marked as uuid of an object with @uuid |
||
539 | * |
||
540 | * @param string $propertyName |
||
541 | * @throws \InvalidArgumentException |
||
542 | * @deprecated |
||
543 | */ |
||
544 | public function setUuidPropertyName($propertyName) |
||
545 | { |
||
546 | trigger_error( |
||
547 | 'Tagging properties with @uuid is deprecated and will be removed in TYPO3 v10.0.', |
||
548 | E_USER_DEPRECATED |
||
549 | ); |
||
550 | if (!array_key_exists($propertyName, $this->properties)) { |
||
551 | throw new \InvalidArgumentException('Property "' . $propertyName . '" must be added to the class schema before it can be marked as UUID property.', 1233863842); |
||
552 | } |
||
553 | $this->uuidPropertyName = $propertyName; |
||
554 | } |
||
555 | |||
556 | /** |
||
557 | * Gets the name of the property marked as uuid of an object |
||
558 | * |
||
559 | * @return string |
||
560 | * @deprecated |
||
561 | */ |
||
562 | public function getUuidPropertyName() |
||
563 | { |
||
564 | trigger_error( |
||
565 | 'Tagging properties with @uuid is deprecated and will be removed in TYPO3 v10.0.', |
||
566 | E_USER_DEPRECATED |
||
567 | ); |
||
568 | return $this->uuidPropertyName; |
||
569 | } |
||
570 | |||
571 | /** |
||
572 | * Marks the given property as one of properties forming the identity |
||
573 | * of an object. The property must already be registered in the class |
||
574 | * schema. |
||
575 | * |
||
576 | * @param string $propertyName |
||
577 | * @throws \InvalidArgumentException |
||
578 | * @deprecated |
||
579 | */ |
||
580 | public function markAsIdentityProperty($propertyName) |
||
581 | { |
||
582 | trigger_error( |
||
583 | 'Tagging properties with @identity is deprecated and will be removed in TYPO3 v10.0.', |
||
584 | E_USER_DEPRECATED |
||
585 | ); |
||
586 | if (!array_key_exists($propertyName, $this->properties)) { |
||
587 | throw new \InvalidArgumentException('Property "' . $propertyName . '" must be added to the class schema before it can be marked as identity property.', 1233775407); |
||
588 | } |
||
589 | if ($this->properties[$propertyName]['annotations']['lazy'] === true) { |
||
590 | throw new \InvalidArgumentException('Property "' . $propertyName . '" must not be makred for lazy loading to be marked as identity property.', 1239896904); |
||
591 | } |
||
592 | $this->identityProperties[$propertyName] = $this->properties[$propertyName]['type']; |
||
593 | } |
||
594 | |||
595 | /** |
||
596 | * Gets the properties (names and types) forming the identity of an object. |
||
597 | * |
||
598 | * @return array |
||
599 | * @see markAsIdentityProperty() |
||
600 | * @deprecated |
||
601 | */ |
||
602 | public function getIdentityProperties() |
||
603 | { |
||
604 | trigger_error( |
||
605 | 'Tagging properties with @identity is deprecated and will be removed in TYPO3 v10.0.', |
||
606 | E_USER_DEPRECATED |
||
607 | ); |
||
608 | return $this->identityProperties; |
||
609 | } |
||
610 | |||
611 | /** |
||
612 | * @return bool |
||
613 | */ |
||
614 | public function hasConstructor(): bool |
||
617 | } |
||
618 | |||
619 | /** |
||
620 | * @param string $name |
||
621 | * @return array |
||
622 | */ |
||
623 | public function getMethod(string $name): array |
||
624 | { |
||
625 | return $this->methods[$name] ?? []; |
||
626 | } |
||
627 | |||
628 | /** |
||
629 | * @return array |
||
630 | */ |
||
631 | public function getMethods(): array |
||
632 | { |
||
633 | return $this->methods; |
||
634 | } |
||
635 | |||
636 | /** |
||
637 | * @param \ReflectionMethod $reflectionMethod |
||
638 | * @return bool |
||
639 | */ |
||
640 | protected function hasInjectMethodName(\ReflectionMethod $reflectionMethod): bool |
||
641 | { |
||
642 | $methodName = $reflectionMethod->getName(); |
||
643 | if ($methodName === 'injectSettings' || !$reflectionMethod->isPublic()) { |
||
644 | return false; |
||
645 | } |
||
646 | |||
647 | if ( |
||
648 | strpos($reflectionMethod->getName(), 'inject') === 0 |
||
649 | ) { |
||
650 | return true; |
||
651 | } |
||
652 | |||
653 | return false; |
||
654 | } |
||
655 | |||
656 | /** |
||
657 | * @return bool |
||
658 | * @internal |
||
659 | */ |
||
660 | public function isModel(): bool |
||
661 | { |
||
662 | return $this->isEntity() || $this->isValueObject(); |
||
663 | } |
||
664 | |||
665 | /** |
||
666 | * @return bool |
||
667 | * @internal |
||
668 | */ |
||
669 | public function isEntity(): bool |
||
670 | { |
||
671 | return $this->modelType === static::MODELTYPE_ENTITY; |
||
672 | } |
||
673 | |||
674 | /** |
||
675 | * @return bool |
||
676 | * @internal |
||
677 | */ |
||
678 | public function isValueObject(): bool |
||
679 | { |
||
680 | return $this->modelType === static::MODELTYPE_VALUEOBJECT; |
||
681 | } |
||
682 | |||
683 | /** |
||
684 | * @return bool |
||
685 | */ |
||
686 | public function isSingleton(): bool |
||
687 | { |
||
688 | return $this->isSingleton; |
||
689 | } |
||
690 | |||
691 | /** |
||
692 | * @param string $methodName |
||
693 | * @return bool |
||
694 | */ |
||
695 | public function hasMethod(string $methodName): bool |
||
696 | { |
||
697 | return isset($this->methods[$methodName]); |
||
698 | } |
||
699 | |||
700 | /** |
||
701 | * @return array |
||
702 | */ |
||
703 | public function getTags(): array |
||
704 | { |
||
705 | return $this->tags; |
||
706 | } |
||
707 | |||
708 | /** |
||
709 | * @return bool |
||
710 | */ |
||
711 | public function hasInjectProperties(): bool |
||
712 | { |
||
713 | return count($this->injectProperties) > 0; |
||
714 | } |
||
715 | |||
716 | /** |
||
717 | * @return bool |
||
718 | */ |
||
719 | public function hasInjectMethods(): bool |
||
720 | { |
||
721 | return count($this->injectMethods) > 0; |
||
722 | } |
||
723 | |||
724 | /** |
||
725 | * @return array |
||
726 | */ |
||
727 | public function getInjectMethods(): array |
||
728 | { |
||
729 | $injectMethods = []; |
||
730 | foreach ($this->injectMethods as $injectMethodName) { |
||
731 | $injectMethods[$injectMethodName] = reset($this->methods[$injectMethodName]['params'])['dependency']; |
||
732 | } |
||
733 | |||
734 | return $injectMethods; |
||
735 | } |
||
736 | |||
737 | /** |
||
738 | * @return array |
||
739 | */ |
||
740 | public function getInjectProperties(): array |
||
748 | } |
||
749 | |||
750 | /** |
||
751 | * @return array |
||
752 | */ |
||
753 | public function getConstructorArguments(): array |
||
754 | { |
||
760 | } |
||
761 | } |
||
762 |