Extbase - Signal Slots: Unterschied zwischen den Versionen

Aus Wikizone
Wechseln zu: Navigation, Suche
Zeile 75: Zeile 75:
 
=== Beispiel Manipulation beim Update eines Datensatzes ===
 
=== Beispiel Manipulation beim Update eines Datensatzes ===
 
localconf.php
 
localconf.php
 +
 
<syntaxhighlight lang="php">
 
<syntaxhighlight lang="php">
 
// enable SignalSlot via Dependency Injection
 
// enable SignalSlot via Dependency Injection
Zeile 89: Zeile 90:
 
typo3conf/ext/gbmaps/Classes/Slots/MyObjectSlot.php
 
typo3conf/ext/gbmaps/Classes/Slots/MyObjectSlot.php
 
<syntaxhighlight lang="php">
 
<syntaxhighlight lang="php">
</syntaxhighlight lang="php">
+
</syntaxhighlight>
 +
 
 
=== Beispiel Signal Slot beim löschen eines Datensatzes ausführen ===
 
=== Beispiel Signal Slot beim löschen eines Datensatzes ausführen ===
 
localconf.php
 
localconf.php

Version vom 19. Juni 2015, 08:12 Uhr

Links

http://blog.foertel.com/2011/10/using-signalslots-in-extbase/

Typo3 Backend Signals

in typo3/sysext/extbase/Classes/Persistance/Generic/Backend.php

afterRemoveObject
afterUpdateObject
beforeGettingObjectData
afterGettingObjectData
afterInsertObject

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):

/** 
 * @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

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

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
    }
}