TYPO3 CMS  TYPO3_8-7
Dispatcher.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
25 {
29  protected $isInitialized = false;
30 
34  protected $objectManager;
35 
43  protected $slots = [];
44 
53  public function initializeObject()
54  {
55  if (!$this->isInitialized) {
56  $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
57  $this->isInitialized = true;
58  }
59  }
60 
73  public function connect($signalClassName, $signalName, $slotClassNameOrObject, $slotMethodName = '', $passSignalInformation = true)
74  {
75  $class = null;
76  $object = null;
77  if (is_object($slotClassNameOrObject)) {
78  $object = $slotClassNameOrObject;
79  $method = $slotClassNameOrObject instanceof \Closure ? '__invoke' : $slotMethodName;
80  } else {
81  if ($slotMethodName === '') {
82  throw new \InvalidArgumentException('The slot method name must not be empty (except for closures).', 1229531659);
83  }
84  $class = $slotClassNameOrObject;
85  $method = $slotMethodName;
86  }
87  $slot = [
88  'class' => $class,
89  'method' => $method,
90  'object' => $object,
91  'passSignalInformation' => $passSignalInformation === true
92  ];
93  // The in_array() comparision needs to be strict to avoid potential issues
94  // with complex objects being registered as slot.
95  if (!is_array($this->slots[$signalClassName][$signalName]) || !in_array($slot, $this->slots[$signalClassName][$signalName], true)) {
96  $this->slots[$signalClassName][$signalName][] = $slot;
97  }
98  }
99 
111  public function dispatch($signalClassName, $signalName, array $signalArguments = [])
112  {
113  $this->initializeObject();
114  if (!isset($this->slots[$signalClassName][$signalName])) {
115  return $signalArguments;
116  }
117  foreach ($this->slots[$signalClassName][$signalName] as $slotInformation) {
118  if (isset($slotInformation['object'])) {
119  $object = $slotInformation['object'];
120  } else {
121  if (!isset($this->objectManager)) {
122  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);
123  }
124  if (!$this->objectManager->isRegistered($slotInformation['class'])) {
125  throw new Exception\InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367);
126  }
127  $object = $this->objectManager->get($slotInformation['class']);
128  }
129 
130  if (!method_exists($object, $slotInformation['method'])) {
131  throw new Exception\InvalidSlotException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() does not exist.', 1245673368);
132  }
133 
134  $preparedSlotArguments = $signalArguments;
135  if ($slotInformation['passSignalInformation'] === true) {
136  $preparedSlotArguments[] = $signalClassName . '::' . $signalName;
137  }
138 
139  $slotReturn = call_user_func_array([$object, $slotInformation['method']], $preparedSlotArguments);
140 
141  if ($slotReturn) {
142  if (!is_array($slotReturn)) {
143  throw new Exception\InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '()\'s return value is of an not allowed type ('
144  . gettype($slotReturn) . ').', 1376683067);
145  }
146  if (count($slotReturn) !== count($signalArguments)) {
147  throw new Exception\InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() returned a different number ('
148  . count($slotReturn) . ') of arguments, than it received (' . count($signalArguments) . ').', 1376683066);
149  }
150  $signalArguments = $slotReturn;
151  }
152  }
153 
154  return $signalArguments;
155  }
156 
165  public function getSlots($signalClassName, $signalName)
166  {
167  return isset($this->slots[$signalClassName][$signalName]) ? $this->slots[$signalClassName][$signalName] : [];
168  }
169 }
connect($signalClassName, $signalName, $slotClassNameOrObject, $slotMethodName='', $passSignalInformation=true)
Definition: Dispatcher.php:73
static makeInstance($className,... $constructorArguments)
getSlots($signalClassName, $signalName)
Definition: Dispatcher.php:165
dispatch($signalClassName, $signalName, array $signalArguments=[])
Definition: Dispatcher.php:111