[FEATURE] Allow signalSlots to modify arguments
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / SignalSlot / Dispatcher.php
index d6d79dc..933ced6 100644 (file)
@@ -115,35 +115,54 @@ class Dispatcher implements \TYPO3\CMS\Core\SingletonInterface {
         * @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
+        * @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;
+                       return NULL;
                }
                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);
+                                       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 \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367);
+                                       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) {
-                               $signalArguments[] = $signalClassName . '::' . $signalName;
+                               $preparedSlotArguments[] = $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);
+
+                       $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 recieved (' . count($signalArguments) . ').', 1376683066);
+                               } else {
+                                       $signalArguments = $slotReturn;
+                               }
                        }
-                       call_user_func_array(array($object, $slotInformation['method']), $signalArguments);
                }
+
+               return $signalArguments;
        }
 
        /**