‪TYPO3CMS  11.5
Dispatcher.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Log\LoggerInterface;
25 
34 {
38  protected ‪$objectManager;
39 
47  protected ‪$slots = [];
48 
52  protected ‪$logger;
53 
59  {
60  $this->objectManager = ‪$objectManager;
61  $this->logger = ‪$logger;
62  }
63 
75  public function ‪connect(string $signalClassName, string $signalName, $slotClassNameOrObject, string $slotMethodName = '', bool $passSignalInformation = true): void
76  {
77  $class = null;
78  $object = null;
79  if (is_object($slotClassNameOrObject)) {
80  $object = $slotClassNameOrObject;
81  $method = $slotClassNameOrObject instanceof \Closure ? '__invoke' : $slotMethodName;
82  } else {
83  if ($slotMethodName === '') {
84  throw new \InvalidArgumentException('The slot method name must not be empty (except for closures).', 1229531659);
85  }
86  $class = $slotClassNameOrObject;
87  $method = $slotMethodName;
88  }
89  $slot = [
90  'class' => $class,
91  'method' => $method,
92  'object' => $object,
93  'passSignalInformation' => $passSignalInformation === true,
94  ];
95  // The in_array() comparision needs to be strict to avoid potential issues
96  // with complex objects being registered as slot.
97  if (!is_array($this->slots[$signalClassName][$signalName] ?? false) || !in_array($slot, $this->slots[$signalClassName][$signalName], true)) {
98  $this->slots[$signalClassName][$signalName][] = $slot;
99  }
100  }
101 
112  public function ‪dispatch(string $signalClassName, string $signalName, array $signalArguments = [])
113  {
114  $this->logger->debug('Triggered signal {signal_class} {signal_name} ', [
115  'signal_class' => $signalClassName,
116  'signal_name' => $signalName,
117  'signalArguments' => $signalArguments,
118  ]);
119  if (!isset($this->slots[$signalClassName][$signalName])) {
120  return $signalArguments;
121  }
122  foreach ($this->slots[$signalClassName][$signalName] as $slotInformation) {
123  if (isset($slotInformation['object'])) {
124  $object = $slotInformation['object'];
125  } else {
126  if (!class_exists($slotInformation['class'])) {
127  throw new ‪InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367);
128  }
129  $object = $this->objectManager->get($slotInformation['class']);
130  }
131 
132  $method = (string)($slotInformation['method'] ?? '');
133  $callable = [$object, $method];
134 
135  if (!is_object($object) || !is_callable($callable)) {
136  throw new ‪InvalidSlotException('The slot method ' . get_class($object) . '->' . $method . '() does not exist.', 1245673368);
137  }
138 
139  $preparedSlotArguments = $signalArguments;
140  if ($slotInformation['passSignalInformation'] === true) {
141  $preparedSlotArguments[] = $signalClassName . '::' . $signalName;
142  }
143 
144  $slotReturn = $callable(...$preparedSlotArguments);
145 
146  if ($slotReturn) {
147  if (!is_array($slotReturn)) {
148  throw new ‪InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $method . '()\'s return value is of an not allowed type ('
149  . gettype($slotReturn) . ').', 1376683067);
150  }
151  if (count($slotReturn) !== count($signalArguments)) {
152  throw new ‪InvalidSlotReturnException('The slot method ' . get_class($object) . '->' . $method . '() returned a different number ('
153  . count($slotReturn) . ') of arguments, than it received (' . count($signalArguments) . ').', 1376683066);
154  }
155  $signalArguments = $slotReturn;
156  }
157  }
158 
159  return $signalArguments;
160  }
161 
169  public function ‪getSlots(string $signalClassName, string $signalName): array
170  {
171  return $this->slots[$signalClassName][$signalName] ?? [];
172  }
173 }
‪TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException
Definition: InvalidSlotReturnException.php:27
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\getSlots
‪array getSlots(string $signalClassName, string $signalName)
Definition: Dispatcher.php:166
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\$slots
‪array $slots
Definition: Dispatcher.php:45
‪TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException
Definition: InvalidSlotException.php:27
‪TYPO3\CMS\Extbase\Object\ObjectManagerInterface
Definition: ObjectManagerInterface.php:29
‪TYPO3\CMS\Extbase\SignalSlot
Definition: Dispatcher.php:18
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\dispatch
‪mixed dispatch(string $signalClassName, string $signalName, array $signalArguments=[])
Definition: Dispatcher.php:109
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\$logger
‪LoggerInterface $logger
Definition: Dispatcher.php:49
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\__construct
‪__construct(ObjectManagerInterface $objectManager, LoggerInterface $logger)
Definition: Dispatcher.php:55
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\$objectManager
‪ObjectManagerInterface $objectManager
Definition: Dispatcher.php:37
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher\connect
‪connect(string $signalClassName, string $signalName, $slotClassNameOrObject, string $slotMethodName='', bool $passSignalInformation=true)
Definition: Dispatcher.php:72
‪TYPO3\CMS\Extbase\SignalSlot\Dispatcher
Definition: Dispatcher.php:34