‪TYPO3CMS  9.5
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 
17 use Psr\Log\LoggerInterface;
21 
28 {
32  protected ‪$isInitialized = false;
33 
37  protected ‪$objectManager;
38 
46  protected ‪$slots = [];
47 
51  protected ‪$logger;
52 
61  public function ‪initializeObject()
62  {
63  if (!$this->isInitialized) {
64  $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
65  $logManager = GeneralUtility::makeInstance(LogManager::class);
66  $this->logger = $logManager->getLogger(self::class);
67  $this->isInitialized = true;
68  }
69  }
70 
82  public function ‪connect($signalClassName, $signalName, $slotClassNameOrObject, $slotMethodName = '', $passSignalInformation = true)
83  {
84  $class = null;
85  $object = null;
86  if (is_object($slotClassNameOrObject)) {
87  $object = $slotClassNameOrObject;
88  $method = $slotClassNameOrObject instanceof \Closure ? '__invoke' : $slotMethodName;
89  } else {
90  if ($slotMethodName === '') {
91  throw new \InvalidArgumentException('The slot method name must not be empty (except for closures).', 1229531659);
92  }
93  $class = $slotClassNameOrObject;
94  $method = $slotMethodName;
95  }
96  $slot = [
97  'class' => $class,
98  'method' => $method,
99  'object' => $object,
100  'passSignalInformation' => $passSignalInformation === true,
101  ];
102  // The in_array() comparision needs to be strict to avoid potential issues
103  // with complex objects being registered as slot.
104  if (!is_array($this->slots[$signalClassName][$signalName] ?? false) || !in_array($slot, $this->slots[$signalClassName][$signalName], true)) {
105  $this->slots[$signalClassName][$signalName][] = $slot;
106  }
107  }
108 
119  public function ‪dispatch($signalClassName, $signalName, array $signalArguments = [])
120  {
121  $this->‪initializeObject();
122  $this->logger->debug(
123  'Triggered signal ' . $signalClassName . ' ' . $signalName,
124  [
125  'signalClassName' => $signalClassName,
126  'signalName' => $signalName,
127  'signalArguments' => $signalArguments,
128  ]
129  );
130  if (!isset($this->slots[$signalClassName][$signalName])) {
131  return $signalArguments;
132  }
133  foreach ($this->slots[$signalClassName][$signalName] as $slotInformation) {
134  if (isset($slotInformation['object'])) {
135  $object = $slotInformation['object'];
136  } else {
137  if (!isset($this->objectManager)) {
138  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);
139  }
140  if (!$this->objectManager->isRegistered($slotInformation['class'])) {
141  throw new Exception\InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367);
142  }
143  $object = $this->objectManager->get($slotInformation['class']);
144  }
145 
146  if (!method_exists($object, $slotInformation['method'])) {
147  throw new Exception\InvalidSlotException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() does not exist.', 1245673368);
148  }
149 
150  $preparedSlotArguments = $signalArguments;
151  if ($slotInformation['passSignalInformation'] === true) {
152  $preparedSlotArguments[] = $signalClassName . '::' . $signalName;
153  }
154 
155  $slotReturn = call_user_func_array([$object, $slotInformation['method']], $preparedSlotArguments);
156 
157  if ($slotReturn) {
158  if (!is_array($slotReturn)) {
159  throw new Exception\InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '()\'s return value is of an not allowed type ('
160  . gettype($slotReturn) . ').', 1376683067);
161  }
162  if (count($slotReturn) !== count($signalArguments)) {
163  throw new Exception\InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() returned a different number ('
164  . count($slotReturn) . ') of arguments, than it received (' . count($signalArguments) . ').', 1376683066);
165  }
166  $signalArguments = $slotReturn;
167  }
168  }
169 
170  return $signalArguments;
171  }
172 
180  public function ‪getSlots($signalClassName, $signalName)
181  {
182  return $this->slots[$signalClassName][$signalName] ?? [];
183  }
184 }
‪TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException
Definition: InvalidSlotReturnException.php:21
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\initializeObject
‪initializeObject()
Definition: Dispatcher.php:57
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\$slots
‪array $slots
Definition: Dispatcher.php:43
‪TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException
Definition: InvalidSlotException.php:21
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\connect
‪connect($signalClassName, $signalName, $slotClassNameOrObject, $slotMethodName='', $passSignalInformation=true)
Definition: Dispatcher.php:78
‪TYPO3\CMS\Extbase\SignalSlot
Definition: Dispatcher.php:2
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\$logger
‪LoggerInterface $logger
Definition: Dispatcher.php:47
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\dispatch
‪mixed dispatch($signalClassName, $signalName, array $signalArguments=[])
Definition: Dispatcher.php:115
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\getSlots
‪array getSlots($signalClassName, $signalName)
Definition: Dispatcher.php:176
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\$isInitialized
‪bool $isInitialized
Definition: Dispatcher.php:31
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Core\Log\LogManager
Definition: LogManager.php:25
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\$objectManager
‪TYPO3 CMS Extbase Object ObjectManagerInterface $objectManager
Definition: Dispatcher.php:35
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Extbase\Object\ObjectManager
Definition: ObjectManager.php:25
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher
Definition: Dispatcher.php:28