ZF2 – ein Cookbook

In 3 Schritten einen URL-Shortener mit dem neuen Zend Framework 2 bauen [Schritt 3]
Kommentare

Diese Route ist jetzt nur eine Child-Route, d. h. sie ist abhängig von der Route mit dem zhorty-trim. Statt des Typs Literal wird jetzt auch hier Segment gewählt. Das bedeutet im Klartext, dass wir ein

Diese Route ist jetzt nur eine Child-Route, d. h. sie ist abhängig von der Route mit dem zhorty-trim. Statt des Typs Literal wird jetzt auch hier Segment gewählt. Das bedeutet im Klartext, dass wir ein Route-Match haben, wenn der Pfad /trim/list aufgerufen wird. Die Ausgabe sollte ähnlich der in Abbildung 3 sein. Die Option may_terminate beeinflusst das Verhalten der Parent-Route. Nur wenn dieser auf „true“ gesetzt wird, stoppt das Route-Matching, wenn es einen Treffer für /trim hat.

Im TrimController können wir nun noch die Redirect-Route ändern, sodass nach erfolgreichem Speichern direkt auf die Liste umgeleitet wird:

return $this->redirect()->toRoute('zhorty-trim/zhorty-trim-list');

Bitte beachten: Hier werden nicht der eigentliche URL-Pfad, sondern die Bezeichner der Routen eingetragen.

Abb. 3: Listenausgabe von Tabelleninhalten
Delete

Nach der Liste könnten wir auch noch ein „Delete“ gut gebrauchen. Wir widmen uns zuerst dem Routing mit dem Ziel, die ID des zu löschenden Eintrags in den URL mit einzubauen. Der folgende Code ist eine weitere Child-Route. Diese wird in der module.config.php als weiterer Untereintrag der zhorty-trim-Route eingefügt (Listing 20).

Listing 20

'zhorty-trim-delete' => array(
    'type'    => 'Segment',
    'options' => array(
        'route'    => '/delete/[:id]',
        'defaults' => array(
            'action' => 'delete',
         ),
         'constraints' => array(
             'id' => '[0-9]+',
         ),
     ),
 ),

Die ID wird als Platzhalter in der Route definiert, und ein Constraint bestimmt über einen regulären Ausdruck, dass nur ganze Zahlen akzeptiert werden. Wird etwas anderes als eine Ziffernfolge an der entsprechenden Stelle im URL gesetzt, gibt es auch keinen RouteMatch und damit automatisch einen 404-Fehler.

Aber wie kommen wir an die ID des zu löschenden Eintrags in unserem Controller? Als Platzhaltername wurde im Routing der Name id definiert. Die ID steckt somit nicht im Request-Objekt als einzelner Wert, da sie ja im URL kodiert war und nicht als GET-Parameter übermittelt wurde. Die ID bekommen wir aus einem RouteMatch-Objekt. Die folgende Methode findet in unserem TrimController Platz (Listing 21).

Listing 21

public function deleteAction()
{
    $routeMatch = $this->getEvent()->getRouteMatch();
    $id = $routeMatch->getParam('id');
        
    $sm = $this->getServiceLocator();
    $model = $sm->get('ZhortyModelTrim');
        
    $model->delete(array("id = $id"));
        
    return $this->redirect()->toRoute('zhorty-trim/zhorty-trim-list');
} 

Wir sehen, dass wir über das Event an das besagte RouteMatch-Objekt herankommen. Event? ZF2 baut auf einem Event-getriebenen Model auf. Es gibt für die MVC-Implementierung einen Fluss von Events, die an unterschiedlichen Zeitpunkten gefeuert werden. An jedes dieser Events kann ein so genannter Listener zugefügt werden. Dieser wird umgehend nach der Triggerung eines Events ausgeführt. Auch der Controller ist ein solcher Event Listener. Genauer gesagt wurde dieser an das Dispatch-Event gehängt. Und dieses Event ist wiederum mit dem RouteMatch-Objekt verknüpft. Dieses Objekt stellt eine getParam()-Methode zu Verfügung, die uns auch die ID zurückliefert. Wir könnten die ID jetzt tatsächlich gefahrlos ohne Filterung für das Löschen benutzen – wir wissen ja anhand der Routing-Definition, dass keine Nicht-Integer übertragen werden. Allerdings gehen wir auf Nummer sicher und casten den Wert.

Zu guter Letzt passen wir noch das View-Template list.phtml an, damit wir auch Links zum Löschen einzelner Einträge bekommen. Dazu wird die Tabelle um eine weitere Spalte erweitert:

<a href="/trim/delete/getId();?>">Delete
Redirect

Jetzt haben wir eine Liste von Pfaden und dazugehöriger URLs. Wie machen wir daraus Redirects? Dazu müssen wir uns in den Workflow des ZF2 einhängen. Am besten nach dem Matching der Route, dann wissen wir, ob wir einen Match auf einen von uns definierten Controller haben, oder ob wir in der Zhorty-DB nach einem passenden Eintrag schauen müssen. Doch wann ist das Routing vorbei? Und wie hängen wir uns da ein? In ZF1 waren Controller-Plug-ins die Implementierung der Wahl. Die gibt es im ZF2 nicht mehr. Wie oben bereits beschrieben, beherrschen Events den Fluss des Frameworks. Der erste Platz zum Einhaken ist in der Module.php. Die onBootstrap()-Methode wird automatisch und vor allem sehr früh im Ablauf aufgerufen – und kann als Ausgangspunkt für weitere Modifizierungen genutzt werden:

public function onBootstrap(MvcEvent $e) {
    $eventManager = $e->getApplication()->getEventManager();
    $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onRouteCheckForRedirect'), 999);
}
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -