Пример #1
0
 /**
  * Builds PHP code which calls the original (ie. parent) method after the added code has been executed.
  *
  * @param string $fullClassName Fully qualified name of the original class
  * @param string $methodName Name of the original method
  * @return string PHP code
  */
 protected function buildCallParentMethodCode($fullClassName, $methodName)
 {
     if (!$this->reflectionService->hasMethod($fullClassName, $methodName)) {
         return '';
     }
     return "parent::" . $methodName . "(" . $this->buildMethodParametersCode($fullClassName, $methodName, FALSE) . ");\n";
 }
Пример #2
0
 /**
  * If mandatory constructor arguments have not been defined yet, this function tries to autowire
  * them if possible.
  *
  * @param array &$objectConfigurations
  * @return void
  * @throws \TYPO3\FLOW3\Object\Exception\UnresolvedDependenciesException
  */
 protected function autowireArguments(array &$objectConfigurations)
 {
     foreach ($objectConfigurations as $objectConfiguration) {
         $className = $objectConfiguration->getClassName();
         $arguments = $objectConfiguration->getArguments();
         if ($this->reflectionService->hasMethod($className, '__construct')) {
             foreach ($this->reflectionService->getMethodParameters($className, '__construct') as $parameterName => $parameterInformation) {
                 $debuggingHint = '';
                 $index = $parameterInformation['position'] + 1;
                 if (!isset($arguments[$index])) {
                     if ($parameterInformation['optional'] === TRUE) {
                         $defaultValue = isset($parameterInformation['defaultValue']) ? $parameterInformation['defaultValue'] : NULL;
                         $arguments[$index] = new ConfigurationArgument($index, $defaultValue, ConfigurationArgument::ARGUMENT_TYPES_STRAIGHTVALUE);
                     } elseif ($parameterInformation['class'] !== NULL && isset($objectConfigurations[$parameterInformation['class']])) {
                         $arguments[$index] = new ConfigurationArgument($index, $parameterInformation['class'], ConfigurationArgument::ARGUMENT_TYPES_OBJECT);
                     } elseif ($parameterInformation['allowsNull'] === TRUE) {
                         $arguments[$index] = new ConfigurationArgument($index, NULL, ConfigurationArgument::ARGUMENT_TYPES_STRAIGHTVALUE);
                     } elseif (interface_exists($parameterInformation['class'])) {
                         $debuggingHint = sprintf('No default implementation for the required interface %s was configured, therefore no specific class name could be used for this dependency. ', $parameterInformation['class']);
                     }
                     $autowiringAnnotation = $this->reflectionService->getMethodAnnotation($className, '__construct', 'TYPO3\\FLOW3\\Annotations\\Autowiring');
                     if (isset($arguments[$index]) && ($objectConfiguration->getAutowiring() === Configuration::AUTOWIRING_MODE_OFF || $autowiringAnnotation !== NULL && $autowiringAnnotation->enabled === FALSE)) {
                         $arguments[$index]->setAutowiring(Configuration::AUTOWIRING_MODE_OFF);
                         $arguments[$index]->set($index, NULL);
                     }
                     if (!isset($arguments[$index]) && $objectConfiguration->getScope() === Configuration::SCOPE_SINGLETON) {
                         throw new \TYPO3\FLOW3\Object\Exception\UnresolvedDependenciesException(sprintf('Could not autowire required constructor argument $%s for singleton class %s. %sCheck the type hint of that argument and your Objects.yaml configuration.', $parameterName, $className, $debuggingHint), 1298629392);
                     }
                 }
             }
         }
         $objectConfiguration->setArguments($arguments);
     }
 }
Пример #3
0
 /**
  * Builds code which registers the lifecycle shutdown method, if any.
  *
  * @param \TYPO3\FLOW3\Object\Configuration\Configuration $objectConfiguration
  * @return string
  */
 protected function buildLifecycleShutdownCode(\TYPO3\FLOW3\Object\Configuration\Configuration $objectConfiguration)
 {
     $lifecycleShutdownMethodName = $objectConfiguration->getLifecycleShutdownMethodName();
     if (!$this->reflectionService->hasMethod($objectConfiguration->getClassName(), $lifecycleShutdownMethodName)) {
         return '';
     }
     return "\n" . '		\\TYPO3\\FLOW3\\Core\\Bootstrap::$staticObjectManager->registerShutdownObject($this, \'' . $lifecycleShutdownMethodName . '\');' . PHP_EOL;
 }
Пример #4
0
 /**
  * Builds methods for a single AOP proxy class for the specified class.
  *
  * @param string $targetClassName Name of the class to create a proxy class file for
  * @param array &$aspectContainers The array of aspect containers from the AOP Framework
  * @return boolean TRUE if the proxy class could be built, FALSE otherwise.
  */
 public function buildProxyClass($targetClassName, array &$aspectContainers)
 {
     $interfaceIntroductions = $this->getMatchingInterfaceIntroductions($aspectContainers, $targetClassName);
     $introducedInterfaces = $this->getInterfaceNamesFromIntroductions($interfaceIntroductions);
     $propertyIntroductions = $this->getMatchingPropertyIntroductions($aspectContainers, $targetClassName);
     $methodsFromTargetClass = $this->getMethodsFromTargetClass($targetClassName);
     $methodsFromIntroducedInterfaces = $this->getIntroducedMethodsFromInterfaceIntroductions($interfaceIntroductions, $targetClassName);
     $interceptedMethods = array();
     $this->addAdvicedMethodsToInterceptedMethods($interceptedMethods, array_merge($methodsFromTargetClass, $methodsFromIntroducedInterfaces), $targetClassName, $aspectContainers);
     $this->addIntroducedMethodsToInterceptedMethods($interceptedMethods, $methodsFromIntroducedInterfaces);
     if (count($interceptedMethods) < 1 && count($introducedInterfaces) < 1) {
         return FALSE;
     }
     $proxyClass = $this->compiler->getProxyClass($targetClassName);
     if ($proxyClass === FALSE) {
         return FALSE;
     }
     $proxyClass->addInterfaces($introducedInterfaces);
     foreach ($propertyIntroductions as $propertyIntroduction) {
         $proxyClass->addProperty($propertyIntroduction->getPropertyName(), 'NULL', $propertyIntroduction->getPropertyVisibility(), $propertyIntroduction->getPropertyDocComment());
     }
     $proxyClass->getMethod('FLOW3_Aop_Proxy_buildMethodsAndAdvicesArray')->addPreParentCallCode("\t\tif (method_exists(get_parent_class(\$this), 'FLOW3_Aop_Proxy_buildMethodsAndAdvicesArray') && is_callable('parent::FLOW3_Aop_Proxy_buildMethodsAndAdvicesArray')) parent::FLOW3_Aop_Proxy_buildMethodsAndAdvicesArray();\n");
     $proxyClass->getMethod('FLOW3_Aop_Proxy_buildMethodsAndAdvicesArray')->addPreParentCallCode($this->buildMethodsAndAdvicesArrayCode($interceptedMethods));
     $proxyClass->getMethod('FLOW3_Aop_Proxy_buildMethodsAndAdvicesArray')->overrideMethodVisibility('protected');
     $callBuildMethodsAndAdvicesArrayCode = "\n\t\t\$this->FLOW3_Aop_Proxy_buildMethodsAndAdvicesArray();\n";
     $proxyClass->getConstructor()->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode);
     $proxyClass->getMethod('__wakeup')->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode);
     if (!$this->reflectionService->hasMethod($targetClassName, '__wakeup')) {
         $proxyClass->getMethod('__wakeup')->addPostParentCallCode("\t\tif (method_exists(get_parent_class(\$this), '__wakeup') && is_callable('parent::__wakeup')) parent::__wakeup();\n");
     }
     // FIXME this can be removed again once Doctrine is fixed (see fixMethodsAndAdvicesArrayForDoctrineProxiesCode())
     $proxyClass->getMethod('FLOW3_Aop_Proxy_fixMethodsAndAdvicesArrayForDoctrineProxies')->addPreParentCallCode($this->fixMethodsAndAdvicesArrayForDoctrineProxiesCode());
     // FIXME this can be removed again once Doctrine is fixed (see fixInjectedPropertiesForDoctrineProxiesCode())
     $proxyClass->getMethod('FLOW3_Aop_Proxy_fixInjectedPropertiesForDoctrineProxies')->addPreParentCallCode($this->fixInjectedPropertiesForDoctrineProxiesCode());
     $this->buildGetAdviceChainsMethodCode($targetClassName);
     $this->buildInvokeJoinPointMethodCode($targetClassName);
     $this->buildMethodsInterceptorCode($targetClassName, $interceptedMethods);
     $proxyClass->addProperty('FLOW3_Aop_Proxy_targetMethodsAndGroupedAdvices', 'array()');
     $proxyClass->addProperty('FLOW3_Aop_Proxy_groupedAdviceChains', 'array()');
     $proxyClass->addProperty('FLOW3_Aop_Proxy_methodIsInAdviceMode', 'array()');
     return TRUE;
 }
Пример #5
0
 /**
  * Builds a new instance of $objectType with the given $possibleConstructorArgumentValues.
  * If constructor argument values are missing from the given array the method looks for a
  * default value in the constructor signature.
  *
  * Furthermore, the constructor arguments are removed from $possibleConstructorArgumentValues
  *
  * @param array &$possibleConstructorArgumentValues
  * @param string $objectType
  * @return object The created instance
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidTargetException if a required constructor argument is missing
  */
 protected function buildObject(array &$possibleConstructorArgumentValues, $objectType)
 {
     $className = $this->objectManager->getClassNameByObjectName($objectType);
     if ($this->reflectionService->hasMethod($className, '__construct')) {
         $constructorSignature = $this->reflectionService->getMethodParameters($className, '__construct');
         $constructorArguments = array();
         foreach ($constructorSignature as $constructorArgumentName => $constructorArgumentInformation) {
             if (array_key_exists($constructorArgumentName, $possibleConstructorArgumentValues)) {
                 $constructorArguments[] = $possibleConstructorArgumentValues[$constructorArgumentName];
                 unset($possibleConstructorArgumentValues[$constructorArgumentName]);
             } elseif ($constructorArgumentInformation['optional'] === TRUE) {
                 $constructorArguments[] = $constructorArgumentInformation['defaultValue'];
             } else {
                 throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('Missing constructor argument "' . $constructorArgumentName . '" for object of type "' . $objectType . '".', 1268734872);
             }
         }
         $classReflection = new \ReflectionClass($className);
         return $classReflection->newInstanceArgs($constructorArguments);
     } else {
         return new $className();
     }
 }