Extbase - Signal Slots: Unterschied zwischen den Versionen
(Die Seite wurde neu angelegt: „Beispiel Signal Slot beim löschen eines Datensatzes ausführen localconf.php <syntaxhighlight lang="php"> $signalSlotDispatcher = \TYPO3\CMS\Core\Utility\Gene…“) |
|||
| (6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
| − | Beispiel Signal Slot beim löschen eines Datensatzes ausführen | + | == Links == |
| + | http://blog.foertel.com/2011/10/using-signalslots-in-extbase/ | ||
| + | == Typo3 Backend Signals == | ||
| + | in typo3/sysext/extbase/Classes/Persistance/Generic/Backend.php | ||
| + | <pre> | ||
| + | afterRemoveObject | ||
| + | afterUpdateObject | ||
| + | beforeGettingObjectData | ||
| + | afterGettingObjectData | ||
| + | afterInsertObject | ||
| + | </pre> | ||
| + | |||
| + | == Einführung == | ||
| + | Quelle: (2015-6) | ||
| + | |||
| + | Genauso wie der Hook besteht das Signal/Slot Pattern aus zwei Bausteinen. Auf der einen Seite sind die '''Slots (Connector, Listener)''' und auf der anderen Seite die '''Signale (Dispatcher)'''. Beide Funktionalität sind '''über die Klasse “Tx_Extbase_SignalSlot_Dispatcher” erreichbar''', welche wir uns zuerst erstellen müssen. Dies geht entweder über Dependency Injection (z.B. im Controller): | ||
| + | |||
| + | <syntaxhighlight lang="php"> | ||
| + | /** | ||
| + | * @var Tx_Extbase_SignalSlot_Dispatcher | ||
| + | */ | ||
| + | protected $signalSlotDispatcher; | ||
| + | |||
| + | /** | ||
| + | * @param Tx_Extbase_SignalSlot_Dispatcher $signalSlotDispatcher | ||
| + | */ | ||
| + | public function injectSignalSlotDispatcher(Tx_Extbase_SignalSlot_Dispatcher $signalSlotDispatcher) { | ||
| + | $this->signalSlotDispatcher = $signalSlotDispatcher; | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | oder aber auch über einfaches erstellen der Instanz: | ||
| + | |||
| + | <syntaxhighlight lang="php"> | ||
| + | $this->signalSlotDispatcher = t3lib_div::makeInstance('Tx_Extbase_Object_Manager')->get('Tx_Extbase_SignalSlot_Dispatcher'); | ||
| + | </syntaxhighlight> | ||
| + | Im Anschluss verfügt ihr über ein “Tx_Extbase_SignalSlot_Dispatcher” Objekt mit dem ihr nun Signale senden oder Slots registrieren könnte. Im Folgenden nun die beiden Sichten, welche möglich sind. | ||
| + | Dispatch / Signal | ||
| + | |||
| + | Beispiel: Am Ende eurer Action stellt ihr alle nötigen Variablen der View bereit. Nun befindet ihr euch an einer Stelle, welcher gern erweitert wird, weshalb ihr euch für ein “Signal” entscheidet. Das Signal wird über den Signal/Slot-Dispatcher getriggert und kann von anderen Extensions benutzt werden, um die eigene Action zu ergänzen. Hier der Beispielcode: | ||
| + | <syntaxhighlight lang="php"> | ||
| + | $this->signalSlotDispatcher->dispatch(__CLASS__, 'beforeRenderView', array($data, $this)); | ||
| + | </syntaxhighlight> | ||
| + | Die Funktion hat drei Parameter “Klassenname”, “Signalname” und “Parameter”. '''Der Klassennamen ist ähnlich einem Namespace zu betrachten. “__CLASS__” macht hier meistens Sinn''' – möglich wäre aber auch “get_class($this)”. | ||
| + | |||
| + | Achtung/Tipp: Letzteres hat einen interessanten Vererbungseffekt, sodass eine vererbte Klasse automatisch andere Signale schickt als die Klasse von der geerbt wurde. Evtl. Tricky, deshalb empfehle ich anfangs “__CLASS__”. | ||
| + | |||
| + | Der Signalname ist frei wählbar und sollte die Position und Funktion beschreiben. Bei den Parametern sollten alle nötigen Parameter übergeben werden, sodass diese von einem Externen gut verarbeitet werden können. | ||
| + | Connect / Slot | ||
| + | |||
| + | Beispiel: Wir haben die Action (oben) gesehen und wollen die von außen (aber auch in der selben Extension wäre es möglich!) bearbeiten. Dazu erstellen wir uns ebenfalls den Signal/Slog-Dispatcher und registrieren eine Callback-Function (Slot / Listener) für das Signal. Hierzu gibt es verschiedene Möglichkeiten: | ||
| + | Anonym mit einem Closure, | ||
| + | |||
| + | <syntaxhighlight lang="php"> | ||
| + | $this->signalSlotDispatcher->connect( | ||
| + | 'Tx_Extension_Controller_NameController', 'beforeRenderView', function($data, $obj) { /* ... */ }, NULL, FALSE | ||
| + | ); | ||
| + | </syntaxhighlight> | ||
| + | eine Methode aus dem aktuellen Objekt oder | ||
| + | <syntaxhighlight lang="php"> | ||
| + | $this->signalSlotDispatcher->connect( | ||
| + | 'Tx_Extension_Controller_NameController', 'beforeRenderView', $this, 'addInformation', FALSE | ||
| + | ); | ||
| + | </syntaxhighlight> | ||
| + | eine Methode aus einem anderen Objekt. | ||
| + | <syntaxhighlight lang="php"> | ||
| + | $this->signalSlotDispatcher->connect( | ||
| + | 'Tx_Extension_Controller_NameController', 'beforeRenderView', 'Tx_OtherExtension_Controller_NameController', 'addOtherInformation', FALSE | ||
| + | ); | ||
| + | </syntaxhighlight> | ||
| + | Wie ihr seht sind die ersten beiden Parameter identisch zu dem “Signal-Aufruf”. Diese diesen der Identifikation des Signals. Über die beiden folgenden Parameter wird die '''Callback-Funktion''' gesteuert. Der letzte Parameter (welcher hier auf FALSE steht) kann auf TRUE gesetzt werden, wenn ihr in der Slot-Klasse zusätzliche Informationen über das Signal benötigt. Diese stehen dann als erster Parameter in der Zielfunktion zur Verfügung. | ||
| + | |||
| + | Fazit | ||
| + | |||
| + | Ein wirklich schönes Pattern – sauberer und einheitlicher als die “üblichen” Hooks. Gerade bei den Hooks war störend, das viele mit “User”-Functions benutzt werden mussten, weshalb die Klassen mit “user_” beginnen mussten. Das neue Pattern ist leicht zu bedienen und schlank im Einsatz. Felix, Vielen Dank dafür. Weitere Informationen bekommt ihr in der API. | ||
| + | === Beispiel Manipulation beim Update eines Datensatzes === | ||
| + | Hinweis -> funktioniert nicht aus dem Backend, weil die Klasse Backend.php hierbei nicht genutzt wird. Beim speichern aus dem Frontend geht es wahrscheinlich (nicht getestet) | ||
| + | |||
| + | localconf.php | ||
| + | |||
| + | <syntaxhighlight lang="php"> | ||
| + | // enable SignalSlot via Dependency Injection | ||
| + | /** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */ | ||
| + | $signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher'); | ||
| + | $signalSlotDispatcher->connect( | ||
| + | 'TYPO3\CMS\Extbase\Persistence\Generic\Backend', | ||
| + | 'afterUpdateObject', | ||
| + | 'Geobit\\Gbmaps\\Slots\\MyObjectSlot', | ||
| + | 'myObjectMethod', | ||
| + | TRUE | ||
| + | ); | ||
| + | </syntaxhighlight> | ||
| + | typo3conf/ext/gbmaps/Classes/Slots/MyObjectSlot.php | ||
| + | <syntaxhighlight lang="php"> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Beispiel Signal Slot beim löschen eines Datensatzes ausführen === | ||
localconf.php | localconf.php | ||
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
| Zeile 10: | Zeile 105: | ||
'TYPO3\CMS\Extbase\Persistence\Generic\Backend', | 'TYPO3\CMS\Extbase\Persistence\Generic\Backend', | ||
'afterRemoveObject', | 'afterRemoveObject', | ||
| − | 'Vendor\MxExtension\Slots\MyAfterRemoveObjectSlot', | + | 'Vendor\MxExtension\Classes\Slots\MyAfterRemoveObjectSlot', |
'myAfterRemoveObjectMethod' | 'myAfterRemoveObjectMethod' | ||
); | ); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | + | im Slotpfad (siehe oben .../myext/Classes/Slots/ | |
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
namespace Vendor\MxExtension\Slots; | namespace Vendor\MxExtension\Slots; | ||
Aktuelle Version vom 22. Juni 2015, 10:23 Uhr
Links[Bearbeiten]
http://blog.foertel.com/2011/10/using-signalslots-in-extbase/
Typo3 Backend Signals[Bearbeiten]
in typo3/sysext/extbase/Classes/Persistance/Generic/Backend.php
afterRemoveObject afterUpdateObject beforeGettingObjectData afterGettingObjectData afterInsertObject
Einführung[Bearbeiten]
Quelle: (2015-6)
Genauso wie der Hook besteht das Signal/Slot Pattern aus zwei Bausteinen. Auf der einen Seite sind die Slots (Connector, Listener) und auf der anderen Seite die Signale (Dispatcher). Beide Funktionalität sind über die Klasse “Tx_Extbase_SignalSlot_Dispatcher” erreichbar, welche wir uns zuerst erstellen müssen. Dies geht entweder über Dependency Injection (z.B. im Controller):
/**
* @var Tx_Extbase_SignalSlot_Dispatcher
*/
protected $signalSlotDispatcher;
/**
* @param Tx_Extbase_SignalSlot_Dispatcher $signalSlotDispatcher
*/
public function injectSignalSlotDispatcher(Tx_Extbase_SignalSlot_Dispatcher $signalSlotDispatcher) {
$this->signalSlotDispatcher = $signalSlotDispatcher;
}
oder aber auch über einfaches erstellen der Instanz:
$this->signalSlotDispatcher = t3lib_div::makeInstance('Tx_Extbase_Object_Manager')->get('Tx_Extbase_SignalSlot_Dispatcher');
Im Anschluss verfügt ihr über ein “Tx_Extbase_SignalSlot_Dispatcher” Objekt mit dem ihr nun Signale senden oder Slots registrieren könnte. Im Folgenden nun die beiden Sichten, welche möglich sind. Dispatch / Signal
Beispiel: Am Ende eurer Action stellt ihr alle nötigen Variablen der View bereit. Nun befindet ihr euch an einer Stelle, welcher gern erweitert wird, weshalb ihr euch für ein “Signal” entscheidet. Das Signal wird über den Signal/Slot-Dispatcher getriggert und kann von anderen Extensions benutzt werden, um die eigene Action zu ergänzen. Hier der Beispielcode:
$this->signalSlotDispatcher->dispatch(__CLASS__, 'beforeRenderView', array($data, $this));
Die Funktion hat drei Parameter “Klassenname”, “Signalname” und “Parameter”. Der Klassennamen ist ähnlich einem Namespace zu betrachten. “__CLASS__” macht hier meistens Sinn – möglich wäre aber auch “get_class($this)”.
Achtung/Tipp: Letzteres hat einen interessanten Vererbungseffekt, sodass eine vererbte Klasse automatisch andere Signale schickt als die Klasse von der geerbt wurde. Evtl. Tricky, deshalb empfehle ich anfangs “__CLASS__”.
Der Signalname ist frei wählbar und sollte die Position und Funktion beschreiben. Bei den Parametern sollten alle nötigen Parameter übergeben werden, sodass diese von einem Externen gut verarbeitet werden können. Connect / Slot
Beispiel: Wir haben die Action (oben) gesehen und wollen die von außen (aber auch in der selben Extension wäre es möglich!) bearbeiten. Dazu erstellen wir uns ebenfalls den Signal/Slog-Dispatcher und registrieren eine Callback-Function (Slot / Listener) für das Signal. Hierzu gibt es verschiedene Möglichkeiten: Anonym mit einem Closure,
$this->signalSlotDispatcher->connect(
'Tx_Extension_Controller_NameController', 'beforeRenderView', function($data, $obj) { /* ... */ }, NULL, FALSE
);
eine Methode aus dem aktuellen Objekt oder
$this->signalSlotDispatcher->connect(
'Tx_Extension_Controller_NameController', 'beforeRenderView', $this, 'addInformation', FALSE
);
eine Methode aus einem anderen Objekt.
$this->signalSlotDispatcher->connect(
'Tx_Extension_Controller_NameController', 'beforeRenderView', 'Tx_OtherExtension_Controller_NameController', 'addOtherInformation', FALSE
);
Wie ihr seht sind die ersten beiden Parameter identisch zu dem “Signal-Aufruf”. Diese diesen der Identifikation des Signals. Über die beiden folgenden Parameter wird die Callback-Funktion gesteuert. Der letzte Parameter (welcher hier auf FALSE steht) kann auf TRUE gesetzt werden, wenn ihr in der Slot-Klasse zusätzliche Informationen über das Signal benötigt. Diese stehen dann als erster Parameter in der Zielfunktion zur Verfügung.
Fazit
Ein wirklich schönes Pattern – sauberer und einheitlicher als die “üblichen” Hooks. Gerade bei den Hooks war störend, das viele mit “User”-Functions benutzt werden mussten, weshalb die Klassen mit “user_” beginnen mussten. Das neue Pattern ist leicht zu bedienen und schlank im Einsatz. Felix, Vielen Dank dafür. Weitere Informationen bekommt ihr in der API.
Beispiel Manipulation beim Update eines Datensatzes[Bearbeiten]
Hinweis -> funktioniert nicht aus dem Backend, weil die Klasse Backend.php hierbei nicht genutzt wird. Beim speichern aus dem Frontend geht es wahrscheinlich (nicht getestet)
localconf.php
// enable SignalSlot via Dependency Injection
/** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
$signalSlotDispatcher->connect(
'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
'afterUpdateObject',
'Geobit\\Gbmaps\\Slots\\MyObjectSlot',
'myObjectMethod',
TRUE
);
typo3conf/ext/gbmaps/Classes/Slots/MyObjectSlot.php
Beispiel Signal Slot beim löschen eines Datensatzes ausführen[Bearbeiten]
localconf.php
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
'TYPO3\CMS\Extbase\Object\ObjectManager'
)->get(
'TYPO3\CMS\Extbase\SignalSlot\Dispatcher'
);
$signalSlotDispatcher->connect(
'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
'afterRemoveObject',
'Vendor\MxExtension\Classes\Slots\MyAfterRemoveObjectSlot',
'myAfterRemoveObjectMethod'
);
im Slotpfad (siehe oben .../myext/Classes/Slots/
namespace Vendor\MxExtension\Slots;
class MyAfterRemoveObjectSlot {
public function myAfterRemoveObjectMethod($object) {
// do something
}
}