Exemplo n.º 1
0
 /**
  * Dispatches a signal by calling the registered Slot methods
  *
  * @param string $signalClassName Name of the class containing the signal
  * @param string $signalName Name of the signal
  * @param array $signalArguments arguments passed to the signal method
  * @return void
  * @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException if the slot is not valid
  * @api
  */
 public function dispatch($signalClassName, $signalName, array $signalArguments = array())
 {
     if (!isset($this->slots[$signalClassName][$signalName])) {
         return;
     }
     foreach ($this->slots[$signalClassName][$signalName] as $slotInformation) {
         if (isset($slotInformation['object'])) {
             $object = $slotInformation['object'];
         } else {
             if (!isset($this->objectManager)) {
                 throw new \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException(sprintf('Cannot dispatch %s::%s to class %s. The object manager is not yet available in the Signal Slot Dispatcher and therefore it cannot dispatch classes.', $signalClassName, $signalName, $slotInformation['class']), 1298113624);
             }
             if (!$this->objectManager->isRegistered($slotInformation['class'])) {
                 throw new \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367);
             }
             $object = $this->objectManager->get($slotInformation['class']);
         }
         $slotArguments = $signalArguments;
         if ($slotInformation['omitSignalInformation'] !== true) {
             $slotArguments[] = $signalClassName . '::' . $signalName;
         }
         if (!method_exists($object, $slotInformation['method'])) {
             throw new \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() does not exist.', 1245673368);
         }
         call_user_func_array(array($object, $slotInformation['method']), $slotArguments);
     }
 }
Exemplo n.º 2
0
 /**
  * Builds a base validator conjunction for the given data type.
  *
  * The base validation rules are those which were declared directly in a class (typically
  * a model) through some validate annotations on properties.
  *
  * If a property holds a class for which a base validator exists, that property will be
  * checked as well, regardless of a validate annotation
  *
  * Additionally, if a custom validator was defined for the class in question, it will be added
  * to the end of the conjunction. A custom validator is found if it follows the naming convention
  * "Replace '\Model\' by '\Validator\' and append 'Validator'".
  *
  * Example: $targetClassName is TYPO3\Foo\Domain\Model\Quux, then the validator will be found if it has the
  * name TYPO3\Foo\Domain\Validator\QuuxValidator
  *
  * @param string $indexKey The key to use as index in $this->baseValidatorConjunctions; calculated from target class name and validation groups
  * @param string $targetClassName The data type to build the validation conjunction for. Needs to be the fully qualified class name.
  * @param array $validationGroups The validation groups to build the validator for
  * @return void
  * @throws \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException
  * @throws \InvalidArgumentException
  */
 protected function buildBaseValidatorConjunction($indexKey, $targetClassName, array $validationGroups = array())
 {
     $conjunctionValidator = new ConjunctionValidator();
     $this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator;
     // note: the simpleType check reduces lookups to the class loader
     if (!TypeHandlingUtility::isSimpleType($targetClassName) && class_exists($targetClassName)) {
         // Model based validator
         /** @var \TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator $objectValidator */
         $objectValidator = $this->objectManager->get(\TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator::class, array());
         foreach ($this->reflectionService->getClassPropertyNames($targetClassName) as $classPropertyName) {
             $classPropertyTagsValues = $this->reflectionService->getPropertyTagsValues($targetClassName, $classPropertyName);
             if (!isset($classPropertyTagsValues['var'])) {
                 throw new \InvalidArgumentException(sprintf('There is no @var annotation for property "%s" in class "%s".', $classPropertyName, $targetClassName), 1363778104);
             }
             try {
                 $parsedType = TypeHandlingUtility::parseType(trim(implode('', $classPropertyTagsValues['var']), ' \\'));
             } catch (\TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException $exception) {
                 throw new \InvalidArgumentException(sprintf(' @var annotation of ' . $exception->getMessage(), 'class "' . $targetClassName . '", property "' . $classPropertyName . '"'), 1315564744, $exception);
             }
             $propertyTargetClassName = $parsedType['type'];
             // note: the outer simpleType check reduces lookups to the class loader
             if (!TypeHandlingUtility::isSimpleType($propertyTargetClassName)) {
                 if (TypeHandlingUtility::isCollectionType($propertyTargetClassName)) {
                     $collectionValidator = $this->createValidator(\TYPO3\CMS\Extbase\Validation\Validator\CollectionValidator::class, array('elementType' => $parsedType['elementType'], 'validationGroups' => $validationGroups));
                     $objectValidator->addPropertyValidator($classPropertyName, $collectionValidator);
                 } elseif (class_exists($propertyTargetClassName) && !TypeHandlingUtility::isCoreType($propertyTargetClassName) && $this->objectManager->isRegistered($propertyTargetClassName) && $this->objectManager->getScope($propertyTargetClassName) === \TYPO3\CMS\Extbase\Object\Container\Container::SCOPE_PROTOTYPE) {
                     $validatorForProperty = $this->getBaseValidatorConjunction($propertyTargetClassName, $validationGroups);
                     if (!empty($validatorForProperty)) {
                         $objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty);
                     }
                 }
             }
             $validateAnnotations = array();
             // @todo: Resolve annotations via reflectionService once its available
             if (isset($classPropertyTagsValues['validate']) && is_array($classPropertyTagsValues['validate'])) {
                 foreach ($classPropertyTagsValues['validate'] as $validateValue) {
                     $parsedAnnotations = $this->parseValidatorAnnotation($validateValue);
                     foreach ($parsedAnnotations['validators'] as $validator) {
                         array_push($validateAnnotations, array('argumentName' => $parsedAnnotations['argumentName'], 'validatorName' => $validator['validatorName'], 'validatorOptions' => $validator['validatorOptions']));
                     }
                 }
             }
             foreach ($validateAnnotations as $validateAnnotation) {
                 // @todo: Respect validationGroups
                 $newValidator = $this->createValidator($validateAnnotation['validatorName'], $validateAnnotation['validatorOptions']);
                 if ($newValidator === NULL) {
                     throw new Exception\NoSuchValidatorException('Invalid validate annotation in ' . $targetClassName . '::' . $classPropertyName . ': Could not resolve class name for  validator "' . $validateAnnotation->type . '".', 1241098027);
                 }
                 $objectValidator->addPropertyValidator($classPropertyName, $newValidator);
             }
         }
         if (!empty($objectValidator->getPropertyValidators())) {
             $conjunctionValidator->addValidator($objectValidator);
         }
     }
     $this->addCustomValidators($targetClassName, $conjunctionValidator);
 }
Exemplo n.º 3
0
 /**
  * Dispatches a signal by calling the registered Slot methods
  *
  * @param string $signalClassName Name of the class containing the signal
  * @param string $signalName Name of the signal
  * @param array $signalArguments arguments passed to the signal method
  * @return mixed
  * @throws Exception\InvalidSlotException if the slot is not valid
  * @throws Exception\InvalidSlotReturnException if a slot returns invalid arguments (too few or return value is not an array)
  * @api
  */
 public function dispatch($signalClassName, $signalName, array $signalArguments = array())
 {
     $this->initializeObject();
     if (!isset($this->slots[$signalClassName][$signalName])) {
         return $signalArguments;
     }
     foreach ($this->slots[$signalClassName][$signalName] as $slotInformation) {
         if (isset($slotInformation['object'])) {
             $object = $slotInformation['object'];
         } else {
             if (!isset($this->objectManager)) {
                 throw new Exception\InvalidSlotException(sprintf('Cannot dispatch %s::%s to class %s. The object manager is not yet available in the Signal Slot Dispatcher and therefore it cannot dispatch classes.', $signalClassName, $signalName, $slotInformation['class']), 1298113624);
             }
             if (!$this->objectManager->isRegistered($slotInformation['class'])) {
                 throw new Exception\InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367);
             }
             $object = $this->objectManager->get($slotInformation['class']);
         }
         if (!method_exists($object, $slotInformation['method'])) {
             throw new Exception\InvalidSlotException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() does not exist.', 1245673368);
         }
         $preparedSlotArguments = $signalArguments;
         if ($slotInformation['passSignalInformation'] === true) {
             $preparedSlotArguments[] = $signalClassName . '::' . $signalName;
         }
         $slotReturn = call_user_func_array(array($object, $slotInformation['method']), $preparedSlotArguments);
         if ($slotReturn) {
             if (!is_array($slotReturn)) {
                 throw new Exception\InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '()\'s return value is of an not allowed type (' . gettype($slotReturn) . ').', 1376683067);
             } elseif (count($slotReturn) !== count($signalArguments)) {
                 throw new Exception\InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() returned a different number (' . count($slotReturn) . ') of arguments, than it received (' . count($signalArguments) . ').', 1376683066);
             } else {
                 $signalArguments = $slotReturn;
             }
         }
     }
     return $signalArguments;
 }