/** * @param JoinPointInterface $joinPoint The current join point * @return mixed * @Flow\Around("methodAnnotatedWith(TYPO3\Jobqueue\Common\Annotations\Defer)") */ public function queueMethodCallAsJob(JoinPointInterface $joinPoint) { if ($this->processingJob) { return $joinPoint->getAdviceChain()->proceed($joinPoint); } $deferAnnotation = $this->reflectionService->getMethodAnnotation($joinPoint->getClassName(), $joinPoint->getMethodName(), 'TYPO3\\Jobqueue\\Common\\Annotations\\Defer'); $queueName = $deferAnnotation->queueName; $job = new StaticMethodCallJob($joinPoint->getClassName(), $joinPoint->getMethodName(), $joinPoint->getMethodArguments()); $this->jobManager->queue($queueName, $job); return NULL; }
/** * @param string $model * @param object $context an arbitrary object which is available in all actions and nested functionality * @return array * @throws MissingModelTypeException * @throws \Exception */ protected function getProperties($model, $context = null) { if ($model === NULL) { throw new MissingModelTypeException('The "model" property has not been specified as parameter to the ViewHelper ' . get_class($this) . '.', 1452715128); } $classSchema = $this->reflectionService->getClassSchema($model); if ($classSchema === NULL) { throw new MissingModelTypeException('No class schema could be resolved for model ' . $model . '.', 1452715183); } $classSchema->getProperties(); $fields = []; foreach ($classSchema->getProperties() as $propertyName => $propertyDefinition) { if ($propertyName === 'Persistence_Object_Identifier') { continue; } /* @var $formFieldAnnotation FormField */ $formFieldAnnotation = $this->reflectionService->getPropertyAnnotation($model, $propertyName, FormField::class); $fields[$propertyName] = []; if ($formFieldAnnotation) { $fields[$propertyName] = get_object_vars($formFieldAnnotation); } $this->addDefaultsToFields($fields, $propertyName); } foreach (get_class_methods($model) as $methodName) { if (substr($methodName, 0, 3) === 'get') { $methodAnnotation = $this->reflectionService->getMethodAnnotation($model, $methodName, FormField::class); if ($methodAnnotation) { $propertyName = lcfirst(substr($methodName, 3)); $fields[$propertyName] = get_object_vars($methodAnnotation); $this->addDefaultsToFields($fields, $propertyName); } } } $generatorAnnotation = $this->reflectionService->getClassAnnotation($model, FieldGenerator::class); if ($generatorAnnotation !== NULL) { $generator = $this->objectManager->get($generatorAnnotation->className); if (!$generator instanceof FieldGeneratorInterface) { throw new \Exception('TODO: generator must implement FieldGeneratorInterface, ' . get_class($generator) . ' given.'); } foreach ($generator->generate($context) as $propertyName => $annotation) { $fields[$propertyName] = get_object_vars($annotation); $this->addDefaultsToFields($fields, $propertyName); } } return (new PositionalArraySorter($fields))->toArray(); }
/** * This function tries to find yet unmatched dependencies which need to be injected via "inject*" setter methods. * * @param array &$objectConfigurations * @return void * @throws \TYPO3\Flow\Object\Exception if an injected property is private */ protected function autowireProperties(array &$objectConfigurations) { foreach ($objectConfigurations as $objectConfiguration) { $className = $objectConfiguration->getClassName(); $properties = $objectConfiguration->getProperties(); $classMethodNames = get_class_methods($className); if (!is_array($classMethodNames)) { if (!class_exists($className)) { throw new \TYPO3\Flow\Object\Exception\UnknownClassException(sprintf('The class "%s" defined in the object configuration for object "%s", defined in package: %s, does not exist.', $className, $objectConfiguration->getObjectName(), $objectConfiguration->getPackageKey()), 1352371371); } else { throw new \TYPO3\Flow\Object\Exception\UnknownClassException(sprintf('Could not autowire properties of class "%s" because names of methods contained in that class could not be retrieved using get_class_methods().', $className), 1352386418); } } foreach ($classMethodNames as $methodName) { if (strlen($methodName) > 6 && substr($methodName, 0, 6) === 'inject' && $methodName[6] === strtoupper($methodName[6])) { $propertyName = lcfirst(substr($methodName, 6)); $autowiringAnnotation = $this->reflectionService->getMethodAnnotation($className, $methodName, 'TYPO3\\Flow\\Annotations\\Autowiring'); if ($autowiringAnnotation !== NULL && $autowiringAnnotation->enabled === FALSE) { continue; } if ($methodName === 'injectSettings') { $packageKey = $objectConfiguration->getPackageKey(); if ($packageKey !== NULL) { $properties[$propertyName] = new ConfigurationProperty($propertyName, $packageKey, ConfigurationProperty::PROPERTY_TYPES_SETTING); } } else { if (array_key_exists($propertyName, $properties)) { continue; } $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName); if (count($methodParameters) !== 1) { $this->systemLogger->log(sprintf('Could not autowire property %s because %s() expects %s instead of exactly 1 parameter.', "{$className}::{$propertyName}", $methodName, count($methodParameters) ?: 'none'), LOG_DEBUG); continue; } $methodParameter = array_pop($methodParameters); if ($methodParameter['class'] === NULL) { $this->systemLogger->log(sprintf('Could not autowire property %s because the method parameter in %s() contained no class type hint.', "{$className}::{$propertyName}", $methodName), LOG_DEBUG); continue; } $properties[$propertyName] = new ConfigurationProperty($propertyName, $methodParameter['class'], ConfigurationProperty::PROPERTY_TYPES_OBJECT); } } } foreach ($this->reflectionService->getPropertyNamesByAnnotation($className, 'TYPO3\\Flow\\Annotations\\Inject') as $propertyName) { if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) { $exceptionMessage = 'The property "' . $propertyName . '" in class "' . $className . '" must not be private when annotated for injection.'; throw new \TYPO3\Flow\Object\Exception($exceptionMessage, 1328109641); } if (!array_key_exists($propertyName, $properties)) { $objectName = trim(implode('', $this->reflectionService->getPropertyTagValues($className, $propertyName, 'var')), ' \\'); $properties[$propertyName] = new ConfigurationProperty($propertyName, $objectName, ConfigurationProperty::PROPERTY_TYPES_OBJECT); } } $objectConfiguration->setProperties($properties); } }
/** * This function tries to find yet unmatched dependencies which need to be injected via "inject*" setter methods. * * @param array &$objectConfigurations * @return void * @throws \TYPO3\Flow\Object\Exception if an injected property is private */ protected function autowireProperties(array &$objectConfigurations) { /** @var Configuration $objectConfiguration */ foreach ($objectConfigurations as $objectConfiguration) { $className = $objectConfiguration->getClassName(); $properties = $objectConfiguration->getProperties(); if ($className === '') { continue; } $classMethodNames = get_class_methods($className); if (!is_array($classMethodNames)) { if (!class_exists($className)) { throw new \TYPO3\Flow\Object\Exception\UnknownClassException(sprintf('The class "%s" defined in the object configuration for object "%s", defined in package: %s, does not exist.', $className, $objectConfiguration->getObjectName(), $objectConfiguration->getPackageKey()), 1352371371); } else { throw new \TYPO3\Flow\Object\Exception\UnknownClassException(sprintf('Could not autowire properties of class "%s" because names of methods contained in that class could not be retrieved using get_class_methods().', $className), 1352386418); } } foreach ($classMethodNames as $methodName) { if (isset($methodName[6]) && strpos($methodName, 'inject') === 0 && $methodName[6] === strtoupper($methodName[6])) { $propertyName = lcfirst(substr($methodName, 6)); $autowiringAnnotation = $this->reflectionService->getMethodAnnotation($className, $methodName, \TYPO3\Flow\Annotations\Autowiring::class); if ($autowiringAnnotation !== NULL && $autowiringAnnotation->enabled === FALSE) { continue; } if ($methodName === 'injectSettings') { $packageKey = $objectConfiguration->getPackageKey(); if ($packageKey !== NULL) { $properties[$propertyName] = new ConfigurationProperty($propertyName, array('type' => ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'path' => $packageKey), ConfigurationProperty::PROPERTY_TYPES_CONFIGURATION); } } else { if (array_key_exists($propertyName, $properties)) { continue; } $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName); if (count($methodParameters) !== 1) { $this->systemLogger->log(sprintf('Could not autowire property %s because %s() expects %s instead of exactly 1 parameter.', $className . '::' . $propertyName, $methodName, count($methodParameters) ?: 'none'), LOG_DEBUG); continue; } $methodParameter = array_pop($methodParameters); if ($methodParameter['class'] === NULL) { $this->systemLogger->log(sprintf('Could not autowire property %s because the method parameter in %s() contained no class type hint.', $className . '::' . $propertyName, $methodName), LOG_DEBUG); continue; } $properties[$propertyName] = new ConfigurationProperty($propertyName, $methodParameter['class'], ConfigurationProperty::PROPERTY_TYPES_OBJECT); } } } foreach ($this->reflectionService->getPropertyNamesByAnnotation($className, \TYPO3\Flow\Annotations\Inject::class) as $propertyName) { if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) { throw new \TYPO3\Flow\Object\Exception(sprintf('The property "%%s" in class "%s" must not be private when annotated for injection.', $propertyName, $className), 1328109641); } if (!array_key_exists($propertyName, $properties)) { /** @var Inject $injectAnnotation */ $injectAnnotation = $this->reflectionService->getPropertyAnnotation($className, $propertyName, \TYPO3\Flow\Annotations\Inject::class); // TODO: Should be removed with 3.2. Inject settings by Inject-Annotation is deprecated since 3.0. Injecting settings by annotation should be done using the InjectConfiguration annotation if ($injectAnnotation->setting !== NULL) { $packageKey = $injectAnnotation->package !== NULL ? $injectAnnotation->package : $objectConfiguration->getPackageKey(); $configurationPath = rtrim($packageKey . '.' . $injectAnnotation->setting, '.'); $properties[$propertyName] = new ConfigurationProperty($propertyName, array('type' => ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'path' => $configurationPath), ConfigurationProperty::PROPERTY_TYPES_CONFIGURATION); } else { $objectName = trim(implode('', $this->reflectionService->getPropertyTagValues($className, $propertyName, 'var')), ' \\'); $configurationProperty = new ConfigurationProperty($propertyName, $objectName, ConfigurationProperty::PROPERTY_TYPES_OBJECT, NULL, $injectAnnotation->lazy); $properties[$propertyName] = $configurationProperty; } } } foreach ($this->reflectionService->getPropertyNamesByAnnotation($className, \TYPO3\Flow\Annotations\InjectConfiguration::class) as $propertyName) { if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) { throw new \TYPO3\Flow\Object\Exception(sprintf('The property "%s" in class "%s" must not be private when annotated for configuration injection.', $propertyName, $className), 1416765599); } if (array_key_exists($propertyName, $properties)) { continue; } /** @var InjectConfiguration $injectConfigurationAnnotation */ $injectConfigurationAnnotation = $this->reflectionService->getPropertyAnnotation($className, $propertyName, \TYPO3\Flow\Annotations\InjectConfiguration::class); if ($injectConfigurationAnnotation->type === ConfigurationManager::CONFIGURATION_TYPE_SETTINGS) { $packageKey = $injectConfigurationAnnotation->package !== NULL ? $injectConfigurationAnnotation->package : $objectConfiguration->getPackageKey(); $configurationPath = rtrim($packageKey . '.' . $injectConfigurationAnnotation->path, '.'); } else { if ($injectConfigurationAnnotation->package !== NULL) { throw new \TYPO3\Flow\Object\Exception(sprintf('The InjectConfiguration annotation for property "%s" in class "%s" specifies a "package" key for configuration type "%s", but this is only supported for injection of "Settings".', $propertyName, $className, $injectConfigurationAnnotation->type), 1420811958); } $configurationPath = $injectConfigurationAnnotation->path; } $properties[$propertyName] = new ConfigurationProperty($propertyName, array('type' => $injectConfigurationAnnotation->type, 'path' => $configurationPath), ConfigurationProperty::PROPERTY_TYPES_CONFIGURATION); } $objectConfiguration->setProperties($properties); } }