Action Helfer

Einführung

Aktion Helfer erlauben Entwicklern Runtime und/oder On-Demand Funktionalität in jeden Aktion Controller zu inizieren der Zend_Controller_Action erweitert. Aktion Controller versuchen den Notwendigkeit zu minimieren, den abstrakten Aktion Controller zu erweitern um damit normale Aktion Controller Funktionen inizieren.

Es gibt eine Menge an Wegen um Aktion Helfer zu verwenden. Aktion Helfer verwenden ein Broker System, ähnlich den Typen von Brokern in Zend_View_Helper, und denen von Zend_Controller_Plugin. Aktion Helfer Zend_View_Helper) können bei Bedarf geladen und aufgerufen werden, oder Sie können wärend der Anfragezeit (Bootstrap) instanziert werden oder wären der Erstellungszeit des Aktion Controllers (init()). Um Sie näher zu verstehen, betrachten wir Ihre Verwendung in der folgenden Sektion.

Helfer Initialisierung

Ein Helfer kann auf vielen verschiedenen Wegen initialisiert werden, basierend auf den eigenen Bedürfnissen und den Funktionalitäten dieses Helfers.

Ein Helfer Broker wir das der $_helper Teilnehmer von Zend_Controller_Action gespeichert; der Broker kann verwendet werden um Helfer zu empfangen oder aufzurufen. Einige Methoden das zu tun sind:

  • Explizit getHelper() verwenden. Ihm einfach einen Namen übergeben und ein Helfer Objekt wird zurückgegeben:

    $flashMessenger = $this->_helper->getHelper('FlashMessenger');
    $flashMessenger->addMessage('Wir haben in der letzten Anfrage etwas getan');
    
  • Verwenden der __get() Funktionalität des Helfer Brokers und Empfangen des Helfers wie wenn er eine Teilnehmer Eigenschaft des Brokers wäre:

    $flashMessenger = $this->_helper->FlashMessenger;
    $flashMessenger->addMessage('Wir haben in der letzten Anfrage etwas getan');
    
  • Letztendlich implmentieren die meisten Aktion Helfer die direct() Methode welche eine spezielle, Standardmethode im Helfer aufruft. In Beispiel des FlashMessenger's, wird addMessage() aufgerufen:

    $this->_helper->FlashMessenger('Wir haben in der letzten Anfrage etwas getan');
    

Anmerkung

Alle oben angeführten Beispiel sind funktionell gleichwertig.

Man kann Helfer auch explizit instanzieren. Das kann gewollt sein wenn der Helfer ausserhalb eines Aktion Controllers verwendet werden soll, oder wenn ein Helfer an einen Helfer Broker übergeben wird um Ihn durch irgendeine Aktion zu verwenden. Instanziert wird er wie jede andere PHP Klasse.

Der Helfer Broker

Zend_Controller_Action_HelperBroker behandelt die Details der Registrierung von Helfer Objekten und Helfer Pfaden, sowie dem Empfangen von Helfern bei Befarf.

Um einen Helfer im Browser zu registrieren, kann addHelper() verwendet werden:

Zend_Controller_Action_HelperBroker::addHelper($helper);

Natürlich ist das Instanzieren und übergeben von Helfern an den Broker etwas Zeit- und Ressourcen intensiv, weswegen twei Methoden existieren um die Dinge etwas zu automatisieren: addPrefix() und addPath().

  • addPrefix() nimmt einen Klassenpräfix und verwendet Ihn um einen Pfad zu ermitteln wo Helferklassen definiert wurden. Er nimmt an das der Präfix den Konventionen der Benamung von Klassen im Zend Framework folgt.

    // Helfer mit vorangestelltem My_Action_Helpers in My/Action/Helpers/ hinzufügen
    Zend_Controller_Action_HelperBroker::addPrefix('My_Action_Helpers');
    
  • addPath() nimmt ein Verzeichnis als erstes Argument und einen Klassenprefix als zweites Argument (Standardwert ist 'Zend_Controller_Action_Helper'). Das erlaubt es die eigenen Klassenpräfixes mit speziellen Verzeichnissen zu verbinden.

    // Helfer mit vorangestelltem Helper in Plugins/Helpers/ hinzufügen
    Zend_Controller_Action_HelperBroker::addPath('./Plugins/Helpers',
                                                 'Helper');
    

Da diese Methoden statisch sind, können Sie zu jeder Zeit in der Controllerkette aufgerufen werden um Helfer dynamisch hinzuzufügen wenn es notwendig wird.

Intern verwendet der Helfer Broker eine Instanz des PluginLoader's um die Pfade zu verwalten. Man erhlt den PluginLoader indem die statische Methode getPluginLoader() verwendet, oder alternativ, eine eigene PluginLoader Instanz einfügt durch Verwenden von setPluginLoader().

Um zu ermitteln ob ein Helfer im Helfer Broker existiert, kann hasHelper($name) verwendet werden, wobei $name der Kurzname des Helfers ist (ohne das Präfix):

// Prüft ob der 'redirector' Helfer im Broker registriert ist:
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    echo 'Der Redirector Helfer ist registriert';
}

Es gibt auch zwei statische Methoden für das bekommen von Helfern vom Helferbroker: getExistingHelper() und getStaticHelper(). getExistingHelper() empfängt einen Helfer nur dann wenn er davor durch den Helferbroker ausgerufen wirde oder explizit in Ihm registriert wurde; wenn nicht wird eine Ausnahme geworfen. getStaticHelper() macht das selbe wie getExistingHelper(), wird aber versuchen den Helfer zu initiieren wenn dieser davor noch nicht im Helferstack registriert wurde. getStaticHelper() ist eine gute Wahl für das empfangen von Helfern welche man konfigurieren will.

Beide Methoden nehmen ein einzelnes Argument, $name, welches der Kurzname des Helfers (ohne den Präfix) ist.

// Prüfe ob der 'redirector' Helfer im Broker registriert ist und holt Ihn:
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    $redirector =
        Zend_Controller_Action_HelperBroker::getExistingHelper('redirector');
}

// Oder, Ihn einfach empfangen, ohne darüber nachzudenken ob er bereits
// registriert wurde oder nicht:
$redirector =
    Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
}

Schlußendlich, um einen registrierten Helfer vom Broker zu entfernen, kann removeHelper($name) verwendet werden, wobei $name der Kurzname des Helfers ist (ohne den Prefix):

// Wenn vorhanden, entferne den 'redirector' Helfer vom Broker:
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    Zend_Controller_Action_HelperBroker::removeHelper('redirector')
}

Eingebaute Aktions Helfer

Zend Framework enthält standardmäßig verschiedene Action Helfer: AutoComplete für automatisierte Antworten für AJAX Autovervollständigung; ContextSwitch und AjaxContext für alternative Antwort Formate eigener Aktionen; einen FlashMessenger für die Behandlung von Kurznachrichten; Json für das verschlüsseln und senden von JSON Antworten; einen Redirector, um verschiedene Implementationen, für das Umleiten zu internen und externen Seiten, für die Anwendung bereitzustellen und einen ViewRenderer um den Prozess des Setzens eines View Objekts im Controller und dem Rendern von Views zu automatisieren.

ActionStack

Der ActionStack Helfer erlaubt das Verschieben von Anfragen zum ActionStack Front Controller Plugin, welches effektiv hilft um eine Queue von Aktionen zu erstellen die wärend der Anfrage ausgeführt wird. Der Helfer erlaubt das hinzufügen von Aktionen entweder durch Spezifikation von neuen Anfrage Objekten oder Aktion - Controller - Modul Sets.

Der Aufruf des ActionStack Helpers inizialisiert das ActionStack Plugin

Der Aufruf des ActionStack Helpers registriert das ActionStack Plugin implizit -- was bedeutet dass das ActionStack Plugin nicht explizit registriert werden muß um dessen Funktionalität zu verwenden.

Beispiel 133. Eine Aufgabe hinzufügen indem Aktion, Controller und Modulnamen verwendet werden

Oft ist es am einfachsten, einfach die Aktion, den Controller und das Modul (und optionale Anfrage Parameter) zu spezifizieren, wie wenn Zend_Controller_Action::_forward() aufgerufen werden würde:

class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Dem Stack zwei Aktionen hinzufügen
        // Und /foo/baz/bar/baz aufrufen
        // (FooController::bazAction() mit der Anfrage var bar == baz)
        $this->_helper->actionStack('baz',
                                    'foo',
                                    'default',
                                    array('bar' => 'baz'));

        // Aufruf für /bar/bat hinzufügen
        // (BarController::batAction())
        $this->_helper->actionStack('bat', 'bar');
    }
}

Beispiel 134. Eine Aufgabe hinzufügen durch Verwendung eines Anfrage Objektes

Machmal macht die OOP Natur eines Anfrage Objektes mehr Sinn; solch ein Objekt kann dem ActionStack Helfer genauso übergeben werden.

class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Dem Stack zwei Aktionen hinzufügen
        // Aufruf zu /foo/baz/bar/baz hinzufügen
        // (FooController::bazAction() mit der Anfrage var bar == baz)
        $request = clone $this->getRequest();
        // Controller oder Modul nicht setzen, verwende aktuelle Werte
        $request->setActionName('baz')
                ->setParams(array('bar' => 'baz'));
        $this->_helper->actionStack($request);

        // Aufruf zu /bar/bat hinzufügen
        // (BarController::batAction())
        $request = clone $this->getRequest();
        // Modul nicht setzen, verwende aktuelle Werte
        $request->setActionName('bat')
                ->setControllerName('bar');
        $this->_helper->actionStack($request);
    }
}

AutoComplete

Viele AJAX Javascript Bibliotheken bieten Funktionalitäten an für eine automatische Vervollständigung wobei eine Auswahlliste von potentiell passenden Ergebnissen angezeigt wird während der Benutzer tippt. Der AutoComplete Helfer zielt darauf ab einfach akzeptierbare Ergebnisse zu solchen Methoden zurückzugeben.

Da nicht alle JS Bibliotheken automatische Vervollständigung auf die gleiche Art implementieren bietet der AutoComplete Helfer einige grundsätzliche abstrakte Funktionalitäten zu vielen Bibliotheken und konkrete Implementierungen für individuelle Bibliotheken. Zurückgegebene Typen sind generell entweder JSON Arrays von Strings, JSON Arrays von Arrays (mit jedem Mitgliedsarray das ein assoziatives Array von Metadaten ist, das verwendet wird um die Auswahlliste zu erstellen), oder HTML.

Die grundsätzliche Verwendung ist für jede Implementierung die selbe:

class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // etwas Logik durchführen...

        // Verschlüsseln und Antwort senden;
        $this->_helper->autoCompleteDojo($data);

        // oder explizit:
        $response = $this->_helper->autoCompleteDojo
                                  ->sendAutoCompletion($data);

        // oder einfach die Antwort der automatischen
        // Vervollständigung vorbereiten;
        $response = $this->_helper->autoCompleteDojo
                                  ->prepareAutoCompletion($data);
    }
}

Standardmäßig mach die automatische Vervollständigung folgendes:

  • Layouts und ViewRenderer ausschalten.

  • Die richtigen Antwort Header zu setzen.

  • Antwort Body mit verschlüsselten oder formatierten automatisch vervollständigten Daten setzen.

  • Antwort senden.

Mögliche Methoden des Helfers beinhalten:

  • disableLayouts() kann verwendet werden um Layouts und den ViewRenderer auszuschalten. Typischerweise wird das innerhalb von prepareAutoCompletion() aufgerufen.

  • encodeJson($data, $keepLayouts = false) verschlüsselt Daten zu JSON, und aktiviert oder deaktiviert Layouts optional. Typischerweise wird das innerhalb von prepareAutoCompletion() aufgerufen.

  • prepareAutoCompletion($data, $keepLayouts = false) wird verwendet um Daten im Antwortformat vorzubereiten wenn das für die konkrete Implementation notwendig ist, wobei Layouts optional aktiviert oder deaktiviert werden können. Der Rückgabewert variiert basierend auf der Implementierung.

  • sendAutoCompletion($data, $keepLayouts = false) wird verwendet um Daten im Antwortformat zu senden was für die konkrete Implementierung notendig ist. Sie ruft prepareAutoCompletion() und sendet dann die Antwort.

  • direct($data, $sendNow = true, $keepLayouts = false) wird verwendet wenn der Helfer als Methode des Helfer Brokers aufgerufen wird. Das $sendNow Flag wird verwendet um festzustellen ob sendAutoCompletion() oder prepareAutoCompletion() aufgerufen werden muß.

Aktuell unterstützt AutoComplete die folgenden Dojo und Scriptaculous AJAX Bibliotheken.

AutoCompletion mit Dojo

Dojo hat per se keinen AutoCompletion Wizard, hat aber zwei Wizards die AutoCompletion ausführen können: ComboBox und FilteringSelect. In beiden Fällen benötigen Sie einen Datenspeicher der QueryReadStore implementiert; für mehr Informationen über dieses Thema siehe die dojo.data Dokumentation.

Im Zend Framework kann ein einfaches indiziertes Array an den AutoCompletionDojo Helfer übergeben werden, und er wird eine JSON Antwort zurückgeben die passend für die Verwendung in so einem Speicher ist:

// In der Controller Aktion:
$this->_helper->autoCompleteDojo($data);

Beispiel 135. AutoCompletion mit Dojo und der Verwendung von Zend MVC

AutoCompletion mit Dojo, über Zend MVC, benötigt verschiedene Dinge: Erstellung eines Form Objekts für die Kombobox bei der man AutoCompletion will, eine Controller Action für das anbieten der AutoCompletion Ergebnisse, Erstellung eines eigenen QueryReadSote um die AutoCompletion Aktion damit zu verbinden, und Erstellung des Javascripts das zur Initialisierung der AutoCompletion auf der Serverseite zu verwenden ist.

Schauen wir uns zuerst das benötigte Javascript an. Dojo bietet ein komplettes Framework für die Erstellung von OOP Javascript, so wie Zend Framework für PHP. Teile davon sind die Möglichkeit Pseudo-Namespaces zu erstellen indem die Verzeichnis Hirarchie verwendet wird. Wir erstellen ein 'custom' Verzeichnis auf dem gleichen Level wie das Dojo Verzeichnis das Teil der Distribution von Dojo ist. In diesem Verzeichnis, erstellen wir eine Javascript Datei, TestNameReadStore.js, mit den folgenden Inhalten:

dojo.provide("custom.TestNameReadStore");
dojo.declare("custom.TestNameReadStore", dojox.data.QueryReadStore, {
    fetch:function (request) {
        request.serverQuery = { test:request.query.name };
        return this.inherited("fetch", arguments);
    }
});

Diese Klasse ist einfach eine Erweiterung von Dojo's eigenem QueryReadStore, welche selbst eine Abstrakte Klasse ist. Wir definieren einfach eine Methode mit der angefragt werden soll, und verknüpfen Sie mit dem 'test' Element.

Als nächstes, erstellen wir das Form Element für das wir AutoCompletion wollen:

class TestController extends Zend_Controller_Action
{
    protected $_form;

    public function getForm()
    {
        if (null === $this->_form) {
            $this->_form = new Zend_Form();
            $this->_form->setMethod('get')
                ->setAction(
                    $this->getRequest()->getBaseUrl() . '/test/process'
                )
                ->addElements(array(
                    'test' => array('type' => 'text', 'options' => array(
                        'filters'        => array('StringTrim'),
                        'dojoType'       => array('dijit.form.ComboBox'),
                        'store'          => 'testStore',
                        'autoComplete'   => 'false',
                        'hasDownArrow'   => 'true',
                        'label' => 'Your input:',
                    )),
                    'go' => array('type' => 'submit',
                                  'options' => array('label' => 'Go!'))
                ));
        }
        return $this->_form;
    }
}

Hier erstellen wir einfach eine Form mit den 'test' und 'go' Methoden. Die 'test' Methode fügt verschiedene spezielle, Dojo-spezifische Attribute hinzu: dojoType, store, autoComplete, und hasDownArrow. Der dojoType wird verwendet um anzuzeigen das wir eine ComboBox erstellen, und wir Sie zum Datenspeicher von 'testStore' verbinden wollen (Schlüssel 'store') -- mehr dazu später. Die Spezifizierung von 'autoComplete' mit FALSE sagt Dojo das der erste passende Eintrag nicht automatisch ausgewählt wird, aber stattdessen eine Liste von Entsprechnungen angezeigt wird. Letztendlich, erstellt 'hasDownArrow' einen Abwärtspfeil ähnlich einer Selectbox sodas Wir die Entsprechnungen zeigen und verstecken können.

Fügen wir eine Methode hinzu um die Form anzuzeigen, sowie einen Endpunkt für die Bearbeitung der AutoCompletion:

class TestController extends Zend_Controller_Action
{
    // ...

    /**
     * Startseite
     */
    public function indexAction()
    {
        $this->view->form = $this->getForm();
    }

    public function autocompleteAction()
    {
        if ('ajax' != $this->_getParam('format', false)) {
            return $this->_helper->redirector('index');
        }
        if ($this->getRequest()->isPost()) {
            return $this->_helper->redirector('index');
        }

        $match = trim($this->getRequest()->getQuery('test', ''));

        $matches = array();
        foreach ($this->getData() as $datum) {
            if (0 === strpos($datum, $match)) {
                $matches[] = $datum;
            }
        }
        $this->_helper->autoCompleteDojo($matches);
    }
}

in unserer autocompleteAction() machen wir eine Anzahl von Dingen. Zuerst schauen wir darauf eine Post Anfrage durchzuführen, und das dort ein 'format' Parameter auf den Wert 'ajax' gesetzt ist; das hilft einfach störende Anfragen zur Aktion zu reduzieren. Als nächstes prüfen wir auf den 'test' Parameter, und vergleichen Ihn mit unseren Daten. (wir haben absichtlich die Implementation von getData() hier ausgelassen -- es können einfach jede Art von Datenquelle sein.) Letztendlich senden wir unsere Entsprechungen zum AutoCompletion Helfer.

Jetzt da wir alle Teile des Backends haben, sehen wir uns an was wir benötigen um es in unserem View Skript für die Startseite auszugeben. Zuerst müssen wir unseren Datenspeicher einstellen, dann unsere Form darstellen, und letztendlich sicherstellen das die richtigen Dojo Bibliotheken -- inklusive unserer eigenen Datenspeicher -- geladen werden. Schauen wir uns das View Skript an, das die Schritte kommentiert:

<?php // Den Datenspeicher einstellen: ?>
<div dojoType="custom.TestNameReadStore" jsId="testStore"
    url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
    requestMethod="get"></div>

<?php // Die Form darstellen: ?>
<?php echo $this->form ?>

<?php // Das Dojo-betreffende CSS einstellen das im
      // HTML Head geladen werden soll: ?>
<?php $this->headStyle()->captureStart() ?>
@import "<?php echo $this->baseUrl()
?>/javascript/dijit/themes/tundra/tundra.css";
@import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
<?php $this->headStyle()->captureEnd() ?>

<?php // Javascript einstellen das im HTML Head geladen werden soll,
      // inklusive aller benötigten Dojo Bibliotheken: ?>
<?php $this->headScript()
        ->setAllowArbitraryAttributes(true)
        ->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
            'text/javascript',
            array('djConfig' => 'parseOnLoad: true'))
        ->captureStart() ?>
djConfig.usePlainJson=true;
dojo.registerModulePath("custom","../custom");
dojo.require("dojo.parser");
dojo.require("dojox.data.QueryReadStore");
dojo.require("dijit.form.ComboBox");
dojo.require("custom.TestNameReadStore");
<?php $this->headScript()->captureEnd() ?>

Beachte die Aufrufe zu den View Helfern wie headStyle und headScript; das sind Platzhalter, welche dann in der HTML Head Sektion des Layout View Skripts dargestellt werden können.

Wir haben jetzt alle Teil um mit Dojo AutoCompletion zu arbeiten.


AutoCompletion mit Scriptaculous

Scriptaculous erwartet eine HTML Antwort in einem speziellen Format.

Der Helfer der mit dieser Bibliothek zu verwenden ist 'AutoCompleteScriptaculous'. Es muß einfach ein Array von Daten angegeben werden, und der Helfer wird eine HTML Antwort erstellen die mit Ajax.Autocompleter kompatibel ist.

ContextSwitch und AjaxContext

Der ContextSwitch Action Helfer ist vorgesehen für die Erleicherung bei der Rückgabe von unserschiedlichen Antwortformaten oder Anfragen. Der AjaxContext Helfer ist eine spezialisierte Version von ContextSwitch welche die Rückgabe von Antworten zu XmlHttpRequests erleichtert.

Um einen von Ihnen zu aktivieren, muß der Controller darauf hingewiesen werden welche Aktion zu welchem Kontext antworten kann. Wenn eine hereinkommende Anfrage einen gültigen Kontext für eine gegebene Aktion indiziert, dann wird der Helfer:

  • das Layout ausschalten wenn es eingeschaltet ist.

  • einen alternativen View suffix setzen, was effektiv ein separates View Skript für den Kontext benötigt.

  • die richtigen Antwort Header für den gewünschten Kontext senden.

  • optional den spezifizierten Callback aufrufen um den Kontext zu definieren und/oder anschließende Berechnungen durchführen.

Als Beispiel wird der folgende Controller angenommen:

class NewsController extends Zend_Controller_Action
{
    /**
     * Landeseite; leitet zu listAction() weiter
     */
    public function indexAction()
    {
        $this->_forward('list');
    }

    /**
     * News Items auflisten
     */
    public function listAction()
    {
    }

    /**
     * Ein News Item anzeigen
     */
    public function viewAction()
    {
    }
}

Angenommen wir wollen das listAction() auch im XML Format vorhanden ist. Statt der Erstellung einer anderen Aktion, kann angezeigt werden das eine XML Antwort zurückgegeben wird:

class NewsController extends Zend_Controller_Action
{
    public function init()
    {
        $contextSwitch = $this->_helper->getHelper('contextSwitch');
        $contextSwitch->addActionContext('list', 'xml')
                      ->initContext();
    }

    // ...
}

Was macht das:

  • Setzt den 'Content-Type' Antwort Header auf 'text/xml'.

  • Ändert den View Suffix auf 'xml.phtml' (oder, wenn ein alternativer View Suffix verwendet wird, 'xml.[dein Suffix]').

Jetzt muß ein neues View Skript erstellt werden, 'news/list.xml.phtml', welches das XML erzeugt und darstellt.

Um zu ermitteln ob eine Anfrage eine Kontextänderung initiiert, prüft der Helfer auf ein token im Anfrage Objekt. Standardäßig schaut er auf den 'format' Parameter, durch den das konfiguriert werden kann. Das bedeutet das, in den meisten Fällen, um eine Kontextänderung zu triggern, ein 'format' Parameter in der Anfrage hinzugefügt werden kann:

  • über URL Parameter: /news/list/format/xml (beachte, das Standard Routing Schema erlaubt übliche Schlüssel/Werte Paare nach der Aktion)

  • über GET Parameter: z.B., /news/list?format=xml

ContextSwitch erlaubt es beliebige Kontexte zu spezifizieren, inklusive welche Kontextänderung stattfinden wird (wenn überhaupt), jegliche Antwort Header die gesendet werden sollen, und beliebige Callbacks für Initialisierung und folgende Bearbeitung.

Vorhandene Standard Kontexte

Standardmäßig sind zwei Kontexte im ContextSwitch Helfer vorhanden: json und XML.

  • JSON. Der JSON Kontext setzt den 'Content-Type' Antwort Header auf 'application/json' und den View Skript Suffix auf 'json.phtml'.

    Trotzdem wird standardmäßig kein View Skript benötigt. Es serialisiert einfach alle View Variablen und sendet die JSON Antwort sofort aus.

    Dieses Verhalten kann deaktiviert werden indem die automatische JSON Serialisierung abgeschaltet wird:

    $this->_helper->contextSwitch()->setAutoJsonSerialization(false);
    
  • XML. Der XML Kontext setzt den 'Content-Type' Antwort Header auf 'text/xml' und den View Skript Suffix auf 'xml.phtml'. Es muß ein neues View Skript für den Kontext erstellt werden.

Eigene Kontexte erstellen

Manchmal sind die Standardkontexte nicht genug. Zum Beispiel wenn man YAML zurückgeben will, oder PHP serialisieren, ein RSS oder ATOM Feed, usw. ContextSwitch erlaubt es das zu tun.

Der einfachste Weg einen neuen Kontext hinzuzufügen ist über die addContext() Methode. Diese Methoe nimmt zwei Argumente, den Namen des Kontextes, und eine Array Spezifikation. Die Spezifikation sollte ein oder mehrere der folgenden Dinge enthalten:

  • suffix: Der Suffix der dem Standard View Suffix angefügt werden soll der im ViewRenderer registriert ist.

  • headers: Ein Array von Header zu Wert Paaren das als Teil der Antwort gesendet werden soll.

  • callbacks: Ein Array das ein oder mehrere der Schlüssel 'init' oder 'post' enthält, die auf gültige PHP Callbacks zeigen und die für die Initialisierung des Contextes und die Nachbearbeitung verwendet werden können.

    Initialisierungs Callbacks treten auf wenn der Kontext durch ContextSwitch erkannt wird. Sie können verwendet werden um spezielle Logik auszuführen die stattfinden soll. Als Beispiel verwendet der JSON Kontext einen Callback um den ViewRenderer auszuschalten wenn die automatische JSON Serialisierung eingeschaltet ist.

    Nachbearbeitung tritt wärend der postDispatch() Routine der Aktion auf, und kann verwendet werden um spezielle Logik auszuführen. Als Beispiel verwendet der JSON Kontext einen Callback um festzustellen ob die automatische JSON Serialisierung eingeschaltet ist; wenn dem so ist, serialisiert es die View Variablen zu JSON und sendet die Antwort, aber wenn dem nicht so ist, schaltet es den ViewRenderer wieder ein.

Es gibt eine Vielzahl an Methoden für die Interaktion mit Kontexten:

  • addContext($context, array $spec): Fügt einen neuen Kontext hinzu. Wirft eine Ausnahme wenn der Kontext bereits existiert.

  • setContext($context, array $spec): Fügt einen neuen Kontext hinzu oder überschreibt einen bestehenden Kontext. Verwendet die gleiche Spezifikation wie addContext().

  • addContexts(array $contexts): Fügt viele Kontexte auf einmal hinzu. Das $contexts Array sollte ein Array von Kontext zu Spezifikation Paaren sein. Wenn einer der Kontexte bereits existiert, wird eine Ausnahme geworfen.

  • setContexts(array $contexts): Fügt neue Kontexte hinzu und überschreibt bestehende. Verwendet die gleiche Spezifikation wie addContexts().

  • hasContext($context): Gibt TRUE zurück wenn der Kontext existiert, andernfalls FALSE.

  • getContext($context): Empfängt einen einzelnen Kontext durch den Namen. Gibt ein Array zurück das der Spezifikation folgt die in addContext() verwendet wird.

  • getContexts(): Empfängt alle Kontexte. Gibt ein Array von Kontext zu Spezifikation Paaren zurück.

  • removeContext($context): Entfernt einen einzelnen Kontext durch seinen Namen. Gibt im Erfolgsfall TRUE zurück, und FALSE wenn der Kontext nicht gefunden wurde.

  • clearContexts(): Entfernt alle Kontexte.

Kontexte per Aktion setzen

Es gibt zwei Mechanismen für das Setzen vorhandener Kontexte. Es kann entweder manuell ein Array im Controller erstellt werden, oder es können verschiedene Methoden in ContextSwitch verwendet werden um Sie zu bauen.

Die prinzipielle Methode für das Hinzufügen von Aktion zu Kontext Relationen ist addActionContext(). Sie erwartet zwei Argumente, die Aktion zu welcher der Kontext hinzugefügt werden soll, und entweder den Namen des Kontextes oder ein Array von Kontexten. Als Beispiel nehmen wir die folgende Controller Klasse an:

class FooController extends Zend_Controller_Action
{
    public function listAction()
    {
    }

    public function viewAction()
    {
    }

    public function commentsAction()
    {
    }

    public function updateAction()
    {
    }
}

Angenommen wir sollen einen XML Kontext zu der 'list' Aktion hinzufügen, und XML und JSON Kontexte zu der 'comments' Aktion. Wir können das in der init() Methode machen:

class FooController extends Zend_Controller_Action
{
    public function init()
    {
        $this->_helper->contextSwitch()
             ->addActionContext('list', 'xml')
             ->addActionContext('comments', array('xml', 'json'))
             ->initContext();
    }
}

Alternativ kann einfach die Array-Eigenschaft $contexts definiert werden:

class FooController extends Zend_Controller_Action
{
    public $contexts = array(
        'list'     => array('xml'),
        'comments' => array('xml', 'json')
    );

    public function init()
    {
        $this->_helper->contextSwitch()->initContext();
    }
}

Das obige ist weniger Overhead, aber enthält auch potentielle Fehler.

Die folgenden Methoden können verwendet werden um die Kontext-Mappings zu erstellen:

  • addActionContext($action, $context): markiert einen oder mehrere Kontexte als in einer Aktion vorhanden. Wenn bereits Mapping existieren wird einfach bei diesen Mappings angehängt. $context kann ein einzelner Kontext sein, oder ein Array von Kontexten.

    Ein Wert von TRUE für den Kontext markiert alle vorhandenen Kontexte als vorhanden für die Aktion.

    Ein leerer Wert für $context deaktiviert alle Kontexte für die gegebene Aktion.

  • setActionContext($action, $context): markiert einen oder mehrere Kontexte als in einer Aktion vorhanden. Wenn bereits Mappings existieren werden Sie mit den spezifizierten ersetzt. $context kann ein einzelner Kontext sein, oder ein Array von Kontexten.

  • addActionContexts(array $contexts): fügt mehrere Aktion zu Kontext Paare auf einmal hinzu. $contexts sollte ein assoziatives Array von Aktion zu Kontext Paaren sein. Es entspricht addActionContext(), was bedeutet das wenn eine Paarung bereits existiert, diese hinzugefügt wird.

  • setActionContexts(array $contexts): fungiert wie addActionContexts(), überschreibt aber bestehende Aktion zu Kontext Paare.

  • hasActionContext($action, $context): ermittelt ob eine spezielle Aktion einen gegebenen Kontext hat.

  • getActionContexts($action = null): gibt entweder alle Kontexte für eine gegebene Aktion zurück, oder alle Aktion zu Kontext Paare.

  • removeActionContext($action, $context): entfernt ein oder mehrere Kontexte von einer gegebenen Aktion. $context kann ein einzelner Kontext sein, oder ein Array von Kontexten.

  • clearActionContexts($action = null): entfernt alle Kontexte von einer gegebenen Aktion, oder von allen Aktionen mit Kontexten.

Kontext Switching initialisieren

Um Kontext Switching zu initialisieren, muß initContext() im Action Controller aufgerufen werden:

class NewsController extends Zend_Controller_Action
{
    public function init()
    {
        $this->_helper->contextSwitch()->initContext();
    }
}

In einigen Fällen, will man einen Kontext erzwingen der verwendet werden soll; zum Beispiel wenn man nur den XML Kontext erlauben will wenn Kontext Switching aktiviert ist. Das kann durch die Übergaben des Kontextes zu initContext() getan werden:

$contextSwitch->initContext('xml');
Zusätzliche Funktionalitäten

Eine Vielzahl an Methoden kann verwendet werden um das Verhalten des ContextSwitch Helfers zu verändern. Diese sind:

  • setAutoJsonSerialization($flag): Standardmäßig serialisieren JSON Kontexte alle View Variablen in die JSON Notierung und geben diese als Antwort zurück. Wenn man seine eigene Antwort erstellen will, sollte das ausgeschaltet werden; das muß vor dem Aufruf von initContext() geschehen.

    $contextSwitch->setAutoJsonSerialization(false);
    $contextSwitch->initContext();
    

    Der Wert des Flags erhält man mit getAutoJsonSerialization().

  • setSuffix($context, $suffix, $prependViewRendererSuffix): Mit dieser Methode kann ein anderer Suffix spezifiziert werden der für einen gegebenen Kontext verwendet werden soll. Das dritte Argument wird verwendet um anzuzeigen ob der aktuelle Suffix des ViewRenderers dem neuen Suffix vorangestellt werden soll oder nicht; dieses Flag ist standardmäßig aktiviert.

    Die Übergabe eines leeren Werte an den Suffix führt dazu das nur der Suffix des ViewRenderers verwendet wird.

  • addHeader($context, $header, $content): Fügt einen Antwort Header für einen gegebenen Kontext hinzu. $header ist der Headername, und $content ist der Wert der an diesen Header übergeben werden soll.

    Jeder Kontxt kann mehrere Header haben; addHeader() fügt zusätzliche Header in den Header Stack des Kontextes ein.

    Wenn der spezifizierte $header bereits für diesen Kontext existiert, wird eine Ausnahme geworfen.

  • setHeader($context, $header, $content): setHeader() funktioniert wie addHeader(), ausser das sie erlaubt das existierende Kontext Header überschrieben werden.

  • addHeaders($context, array $headers): Fügt einen gegebenen Kontext mehrere Header auf einmal hinzu. Entspricht addHeader(), was bedeutet das eine Ausnahme geworfen wird wenn der Header bereits existiert. $headers ist ein Array von Header zu Kontext Paaren.

  • setHeaders($context, array $headers.): Wie addHeaders(), nur das es setHeader() entspricht und damit das Überschreiben existierender Header erlaubt.

  • getHeader($context, $header): Enpfängt den Wert eines Headers für einen gegebenen Kontext. Gibt NULL zurück wenn dieser nicht gefunden wird.

  • removeHeader($context, $header): Entfernt einen einzelnen Header für einen gegebenen Kontext.

  • clearHeaders($context, $header): Entfernt alle Header für einen gegebenen Kontext.

  • setCallback($context, $trigger, $callback): Setzt einen Callback bei einem gegebenen Trigger für einen gegebenen Kontext. Trigger können entweder 'init' oder 'post' sein (was zeigt das der Callback entweder bei der Initialisierung oder der Nachbearbeitung aufgerufen wird). $callback sollte ein gültiger PHP Callback sein.

  • setCallbacks($context, array $callbacks): Setzt mehrere Callbacks für einen gegebenen Kontext. $callbacks sollte ein Trigger zu Callback Paar sein. Aktuell sind die meisten Callbacks die registriert werden können zwei, einer für Initialisierung und einer für die Nachbearbeitung.

  • getCallback($context, $trigger): Empfängt einen Callback für einen gegebenen Trigger in einem gegebenen Kontext.

  • getCallbacks($context): Empfängt alle Callbacks für einen gegebenen Kontext. Gibt ein Array von Trigger zu Callback Paaren zurück.

  • removeCallback($context, $trigger): Entfernt einen Callback für einen gegebenen Trigger und Kontext.

  • clearCallbacks($context): Entfernt alle Callbacks für einen gegebenen Kontext.

  • setContextParam($name): Setzt den Anfrageparameter der geprüft werden muß um zu entscheiden ob eine Kontextumschaltung angefragt wurde oder nicht. Der Wert ist standardmäßig 'format', aber dieser Zugriffspunkt kann verwendet werden um einen alternativen wert zu setzen.

    getContextParam() kann verwendet werden um den aktuellen Wert zu erhalten.

  • setAutoDisableLayout($flag): Standardmäßig sind Layouts ausgeschaltet wenn eine Kontextumschaltung erfolgt; das ist weil Layouts typischerweise dafür verwendet werden um normale Antworten darzustellen, und Sie in alternativen Kontexten keine Bedeutung haben. Wenn man trotzdem Layouts verwenden will (möglicherweise hat man ein Layout für einen neuen Kontext), kann dieses Verhalten mit der Übergabe eines FALSE Wertes an setAutoDisableLayout() geändert werden. Das sollte aber before dem Aufruf von initContext() geschehen.

    Um den Wert dieses Flags zu erhalten, kann der Zugriffspunkt getAutoDisableLayout() verwendet werden.

  • getCurrentContext() kann verwendet werden um festzustellen welcher Kontext erkannt wurde, wenn überhaupt. Er gibt NULL zurück wenn keine Kontextumschaltung stattgefunden hat, oder wenn er aufgerufen wurde bevor initContext() stattgefunden hat.

AjaxContext Funktionalität

Der AjaxContext Helfer erweitert ContextSwitch, sodas alle für ContextSwitch gelisteten Funktionalitäten in Ihm vorhanden sind. Es gibt trotzdem ein paar wichtige Änderungen.

Zuerst, verwendet es eine andere Action Controller Eigenschaft $ajaxable um Kontexte festzustellen. Damit kann man verschiedene Kontexte verwenden für AJAX gegenüber normalen HTTP Anfragen. Die verschiedenen *ActionContext()* Methoden von AjaxContext schreiben in diese Eigenschaft.

Zweitens, wird nur dann getriggert wenn ein XmlHttpRequest stattgefunden hat, was durch die isXmlHttpRequest() Methode den Anfrageobjektes festgestellt wird. Deshalb wird, wenn der Kontextparameter ('format') in der Anfrage übergeben wird, aber die anfrage nicht als XmlHttpRequest gemacht wurde, keine Kontextumschaltung getriggert.

Drittens, fügt der AjaxContext einen zusätzlichen, HTML, Kontext hinzu. In diesem Kontext setzt er den Suffix auf 'ajax.phtml' um diesen Kontext von einer normalen Anfrage zu unterscheiden. Es werden keine zusätzlichen Header zurückgegeben.

Beispiel 136. Aktionen erlauben auf Ajax Anfragen zu antworten

In dem folgenden Beispiel erlauben wir Anfragen auf die Aktionen 'view', 'form' und 'process' auf AJAX Anfragen zu antworten. In den ersten zwei Fällen, 'view' und 'form' wird ein HTML Teilstück zurückgegeben mit dem die Seite aktualisiert werden soll; im letzteren wird JSON zurückgegeben.

class CommentController extends Zend_Controller_Action
{
    public function init()
    {
        $ajaxContext = $this->_helper->getHelper('AjaxContext');
        $ajaxContext->addActionContext('view', 'html')
                    ->addActionContext('form', 'html')
                    ->addActionContext('process', 'json')
                    ->initContext();
    }

    public function viewAction()
    {
        // Ein einzelnes Kommentar holen um es anzuzeigen.
        // Wenn AjaxContext erkannt wurde, verwendet es das
        // comment/view.ajax.phtml View Skript.
    }

    public function formAction()
    {
        // Stellt die "add new comment" Form dar.
        // Wenn AjaxContext erkannt wurde, verwendes es das
        // comment/form.ajax.phtml View Skript.
    }

    public function processAction()
    {
        // Bearbeitet einen neuen Kommentar
        // Gibt das Ergebnis als JSON zurück; fügt die Ergebnisse einfach als
        // View Variablen hinzu, und JSON wird zurückgegeben.
    }
}

Auf der Seite des Clients, wird die AJAX Bibliothek einfach die Endpunkte '/comment/view', '/comment/form', und '/comment/process' anfragen, und den 'format' Parameter übergeben: '/comment/view/format/html', '/comment/form/format/html', '/comment/process/format/json'. (Oder der Parameter kann über den Abfrage String übergeben werden: z.B. , "?format=json".)

Angenommen die Bibliothek übergibt den 'X-Requested-With: XmlHttpRequest' Header, dann werden diese Aktionen das richtige Antwortformat zurückgeben.


FlashMessenger

Einführung

Der FlashMessenger Helfer erlaubt es Nachrichten zu übergeben die ein Benutzer bei der nächsten Anfrage sehen können soll. Um das durchführen zu können, verwendet FlashMessenger den Zend_Session_Namespace um Nachrichten für die Zukunft oder den nächsten Empfang einer Anfrage zu speichern. Es ist generell eine gute Idee, das wenn man plant Zend_Session oder Zend_Session_Namespace zu verwenden, diese mit Zend_Session::start() in der Bootstrap Datei zu initialisieren. (Siehe die Zend_Session Dokumentation für weitere Details über die Verwendung)

Beispiel einer standardmäßigen Verwendung

Das Anwendungsbeispiel von unten zeigt die Verwendung einer Flash Nachricht und Ihre Grundlagen. Wenn die Aktion /some/my aufgerufen wird, fügt Sie die Flash Nachricht "Eintrag gespeichert!" hinzu. Eine weitere Anfrage zu der Aktion /some/my-next-request empfängt Sie (und löscht Sie auch).

class SomeController extends Zend_Controller_Action
{
    /**
     * FlashMessenger
     *
     * @var Zend_Controller_Action_Helper_FlashMessenger
     */
    protected $_flashMessenger = null;

    public function init()
    {
        $this->_flashMessenger =
            $this->_helper->getHelper('FlashMessenger');
        $this->initView();
    }

    public function myAction()
    {
        /**
         * default method of getting
         * Zend_Controller_Action_Helper_FlashMessenger
         * instance on-demand
         */
        $this->_flashMessenger->addMessage('Eintrag gespeichert!');
    }

    public function myNextRequestAction()
    {
        $this->view->messages = $this->_flashMessenger->getMessages();
        $this->render();
    }
}

JSON

JSON Antworten sind die Antworten der Wahl wenn mit AJAX Anfragen gearbeitet wird die Dataset Antworten erwarten; JSON kann sofort auf Seite des Clienten geparst werden, was zu schneller Ausführung führt.

Der JSON Action Helfer macht verschiedene Dinge:

  • Layouts auschalten wenn sie aktuell aktiviert sind.

  • Optional ein Array von Optionen als zweites Argument an Zend_Json::encode() übergeben. Dieses Array von Optionen erlaubt es Layouts und Kodierungen einzuschalten indem Zend_Json_Expr verwendet wird.

    $this->_helper->json($data, array('enableJsonExprFinder' => true));
    
  • Den ViewRenderer ausschalten wenn er aktiviert ist.

  • Den 'Content-Type' Antwort Header auf 'application/json' setzen.

  • Standardmäßig, die Antwort sofort zurückgeben, ohne darauf zu warten das die Aktion die Ausführung beendet.

Die Verwendung ist einfach: Entweder als Methode des Helfer Brokers aufrufen, oder eine der Methoden encodeJson() oder sendJson() aufrufen:

class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // einige Berechnungen durchführen...
        // Die JSON Antwort senden:
        $this->_helper->json($data);

        // oder...
        $this->_helper->json->sendJson($data);

        // oder das JSON empfangen:
        $json = $this->_helper->json->encodeJson($data);
    }
}

Layouts behalten

Wenn man ein separates Layout für JSON Antworten hat -- möglicherweise um die JSON Antworten in einer Art Kontext zu wrappen -- akzeptiert jede Methode im JSON Helfer ein zweites, optionales Argument: Ein Flag um Layouts zu aktivieren oder deaktivieren. Die Übergabe eines boolschen TRUE Wertes hält Layouts aktiviert:

$this->_helper->json($data, true);

Optional kann ein Array als zweiter Parameter übergeben werden. Dieses Array kann eine Vielzahl von Optionen enthalten, inklusive der keepLayouts Option:

$this->_helper->json($data, array('keepLayouts' => true);

Kodierung einschalten durch Verwendung von Zend_Json_Expr

Zend_Json::encode() erlaubt die Kodierung von nativen JSON Ausdrücken indem Zend_Json_Expr Objekte verwendet werden. Diese Option ist standardmäßig ausgeschaltet. Um diese Option einzuschalten muß ein boolscher TRUE Wert an die enableJsonExprFinder Option übergeben werden:

$this->_helper->json($data, array('enableJsonExprFinder' => true);

Wenn man das durchführen will, muss man ein Array als zweite Option übergeben. Das erlaubt es auch andere Optionen, wie zum Beispiel die keepLayouts Option, zu kombinieren. Alle diese Optionen werden dann an Zend_Json::encode() übergeben.

$this->_helper->json($data, array(
    'enableJsonExprFinder' => true,
    'keepLayouts'          => true,
));

Redirector

Einführung

Der Redirector Helfer erlaubt die Verwendung eines Redirector Objektes um die Notwendigkeiten der Anwendung für das Umleiten zu einer neuen URL zu erfüllen. Er bietet vielfache Vorteile gegenüber der _redirect() Methode. Er ist zum Beispiel fähig seitenweises Verhalten im Redirector Objekt vorzudefinieren oder bietet ein eingebautes gotoSimple($action, $controller, $module, $params) Interface ähnlich dem von Zend_Controller_Action::_forward().

Der Redirector hat eine Anzahl von Methoden die verwendet werden können um das Verhalten beim Umleiten zu beeinflussen:

  • setCode() kann verwendet werden um den HTTP Antwort Code zu setzen der während des Umleitens verwendet werden soll.

  • setExit() kann verwendet werden um ein exit() nach einer Umleitung zu erzwingen. Standardmäßig ist dieser TRUE.

  • setGotoSimple() kann verwendet werden um eine Standard URL zu setzen die verwendet wird wenn keine an gotoSimple() übergeben wird. Verwendet die API von Zend_Controller_Action::_forward(): setGotoSimple($action, $controller = null, $module = null, array $params = array())

  • setGotoRoute() kann verwendet werden um eine URL basierend auf einer registrierten Route zu setzen. Übergeben in einem Array von Schlüssel und Werte Paaren und einem Routernamen, wird die URL anhand des Routertyps und der Definition zusammengebaut.

  • setGotoUrl() kann verwendet werden um eine Standard URL zu setzen die verwendet wird wenn keine an gotoUrl() übergeben wird. Akzeptiert einen einzelnen URL String.

  • setPrependBase() kann verwendet werden um die Basis URL des Anfrage Objektes einer mit setGotoUrl(), gotoUrl() oder gotoUrlAndExit() definierten URL, voranzustellen.

  • setUseAbsoluteUri() kann verwendet werden um den Redirector dazu zu zwingen absolute URIs zu verwenden wenn umgeleitet wird. Wenn diese Option gesetzt ist, verwendet Sie den Wert von $_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], und $_SERVER['HTTPS'] um eine komplete URI zur, durch eine der Umleitungsmethoden, spezifizierten URL zu erstellen. Diese Option ist standardmäßig ausgeschaltet, kann aber in späteren Releases standardmäßig eingeschaltet sein.

Zusätzlich gibt es eine Reihe von Methoden im Redirector für die Bearbeitung der aktuellen Umleitungen:

  • gotoSimple() verwendet setGotoSimple() (_forward()-ähnliche API) um eine URL zu erstellen und eine Umleitung durchzuführen.

  • gotoRoute() verwendet setGotoRoute() (route-assembly) um eine URL zu erstellen und eine Umleitung durchzuführen.

  • gotoUrl() verwendet setGotoUrl() (URL string) um eine URL zu erstellen und eine Umleitung durchzuführen.

Letztendlich kann die aktuelle Umleitungs URL jederzeit festgestellt werden durch Verwendung von getRedirectUrl().

Beispiel für die grundsätzliche Verwendung

Beispiel 137. Optionen setzen

Dieses Beispiel überschreibt diverse Optionen, inklusive dem Setzen des HTTP Statuscodes und dessen Verwendung in der Umleitung ('303'), nicht abbrechen der Umleitung und definieren einer Standard URL die beim Umleiten verwendet wird.

class SomeController extends Zend_Controller_Action
{
    /**
     * Redirector - definiert zur Komplettierung des Codes
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

    public function init()
    {
        $this->_redirector = $this->_helper->getHelper('Redirector');

        // Setzt die Standardoptionen für die Umleitung
        // Da das Objekt in der Helferanwendung registriert ist,
        // wird diese für alle Aktionen ab diesem Zeitpunkt relevant
        $this->_redirector->setCode(303)
                          ->setExit(false)
                          ->setGotoSimple("this-action",
                                          "some-controller");
    }

    public function myAction()
    {
        /* Mach was */

        // Umleiten zu einer vorher definierten URL, und einen Ausstieg
        // erzwingen der stattfindet sobald das getan wurde:
        $this->_redirector->redirectAndExit();
        return; // wird nie erreicht
    }
}

Beispiel 138. Standardwerte verwenden

Diese Beispiel nimmt an das die Standardwerte verwendet werden, was bedeutet das jede Umleitung in einem sofortigen exit() resultiert.

// ALTERNATIVES BEISPIEL
class AlternativeController extends Zend_Controller_Action
{
    /**
     * Redirector - definiert zur Komplettierung des Codes
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

    public function init()
    {
        $this->_redirector = $this->_helper->getHelper('Redirector');
    }

    public function myAction()
    {
        /* Mach was */

        $this->_redirector
            ->gotoUrl('/my-controller/my-action/param1/test/param2/test2');
        return; // wird nie erreicht da standardmäßig gegangen und beendet wird
    }
}

Beispiel 139. Verwenden von goto()'s _forward() API

gotoSimple()'s API entspricht der von Zend_Controller_Action::_forward(). Der primäre Unterschied ist das Sie eine URL von den übergebenen Parametern erstellt und das Standardformat :module/:controller/:action/* des Standardrouters verwendet. Dann leitet es um statt die Aktion zu verketten.

class ForwardController extends Zend_Controller_Action
{
    /**
     * Redirector - definiert zur Komplettierung des Codes
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

    public function init()
    {
        $this->_redirector = $this->_helper->getHelper('Redirector');
    }

    public function myAction()
    {
        /* Mach was */

        // Umleiten zu 'my-action' von 'my-controller' im aktuellen Modul,
        // und verwenden der Parameter param1 => test und param2 => test2
        $this->_redirector->gotoSimple('my-action',
                                       'my-controller',
                                       null,
                                       array('param1' => 'test',
                                             'param2' => 'test2'
                                             )
                                       );
    }
}

Beispiel 140. Verwenden von Routen die mit gotoRoute() zusammengebaut wurden

Das folgende Beispiel verwendet die assemble() Methode des Router's um eine URL zu erstellen die auf einem assoziativen Array von Parametern basiert das übergeben wurde. Es nimmt an das die folgende Route registriert wurde:

$route = new Zend_Controller_Router_Route(
    'blog/:year/:month/:day/:id',
    array('controller' => 'archive',
          'module' => 'blog',
          'action' => 'view')
);
$router->addRoute('blogArchive', $route);

Angenommen ein Array hat year auf 206 gesetzt, month auf 4, day auf 24, und id auf 42, dann würde dieses eine URL wie die folgende erstellen: /blog/2006/4/24/42.

class BlogAdminController extends Zend_Controller_Action
{
    /**
     * Redirector - definiert zur Komplettierung des Codes
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

    public function init()
    {
        $this->_redirector = $this->_helper->getHelper('Redirector');
    }

    public function returnAction()
    {
        /* Mach was */

        // Umleiten zum Blog Archiv. Erstellt die folgende URL:
        // /blog/2006/4/24/42
        $this->_redirector->gotoRoute(
            array('year' => 2006,
                  'month' => 4,
                  'day' => 24,
                  'id' => 42),
            'blogArchive'
        );
    }
}

ViewRenderer

Einführung

Der ViewRenderer Helfer wurde designt um die folgenden Ziele erfüllen:

  • Entfernen der Notwendigkeit View Objekte innerhalb der Controller zu instanzieren; View Objekte werden automatisch mit dem Controller registriert.

  • Automatisch View Skript, Helfer und Filter Pfade setzen basierend auf dem aktuellen Modul, und den aktuellen Modulnamen automatisch als Klassenprefix für Helfer und Filterklassen assoziieren.

  • Ein global vorhandenes View Objekt für alle bearbeitenden Controller und Aktionen erstellen.

  • Dem Entwickler erlauben das Standard View Rendering Optionen für alle Controller gesetzt werden.

  • Die Fähigkeit hinzufügen das ein View Skript ohne Intervention automatisch gerendert wird.

  • Dem Entwickler erlauben seine eigenen Spezifikationen, für den View Basisnamen und für View Skriptpfade, zu erstellen.

Anmerkung

Wenn man ein _forward(), redirect() oder render() manuell durchführt, wird kein automatisches rendern erfolgen, da man beim Ausführen von jeder dieser Aktionen dem ViewRenderer mitteilt das man seine eigene Ausgabe durchführen will.

Anmerkung

Der ViewRenderer ist standardmäßig aktiviert. Man kann Ihn über den Parameter noViewRenderer des Frontcontrollers deaktivieren ($front->setParam('noViewRenderer', true);) oder den Helfer vom Helfer Broker Stack entfernen (Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')).

Wenn man Einstellungen vom ViewRenderer vor der Ausführung des Front Controllers ändern will, kann das auf zwei Wegen getan werden:

  • Instanzieren und Registrieren eines eigenen ViewRenderer Objekts und dieses an den Helfer Broker übergeben:

    $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
    $viewRenderer->setView($view)
                 ->setViewSuffix('php');
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
    
  • Initialisieren und/oder empfangen eines ViewRenderer Objekts auf Wunsch über den Helfer Broker:

    $viewRenderer =
        Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
    $viewRenderer->setView($view)
                 ->setViewSuffix('php');
    
API

In seiner einfachsten Verwendung, kann der ViewRenderer ganz einfach instanziert und an den Aktion Helfer Broker übergeben werden. Der einfachste Weg Ihn auf einmal zu Instanzieren und Registrieren ist es, die Methode getStaticHelper() des Helfer Brokers zu verwenden:

Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');

Das erste Mal wenn ein Aktion Controller instanziert wird, triggert er den ViewRenderer ein View Objekt zu instanzieren. Jedes Mal wenn ein Controller Instanziert wird, wird die init() Methode des ViewRenderer's aufgerufen, was dazu führt das er die view Eigenschaft des Aktion Controllers setzt, und addScriptPath(), mit einem Pfad relativ zum aktuellen Modul, aufruft; das wird mit einem Klassenprefix aufgerufen der nach dem aktuellen Modul benannt ist, was effektiv für alle Helfer und Filterklassen die im Modul definiert werden den Namensraum setzt.

Jedes Mal wenn postDispatch() aufgerufen wird, ruft dieses render() für die aktuelle Aktion auf.

Als Beispiel kann die folgende Klasse angenommen werden:

// Eine Controller Klasse, foo Modul:
class Foo_BarController extends Zend_Controller_Action
{
    // Rendert standardmäßig bar/index.phtml; keine Aktion benötigt
    public function indexAction()
    {
    }

    // Rendert bar/populate.phtml mit der Variable 'foo' gesetzt auf 'bar'.
    // Da View Objekte beim preDispatch() definiert werden, sind diese
    // bereits vorhanden.
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }
}

...

// In einem der View Sktipte:
$this->foo(); // Foo_View_Helper_Foo::foo() aufrufen

Der ViewRenderer definiert auch eine Anzahl von Zugriffspunkten um das Setzen und Empfangen von View Optionen zu erlauben:

  • setView($view) erlaubt das Setzen des View Objektes für den ViewRenderer. Er wird als öffentliche Klasseneigenschaft $view gesetzt.

  • setNeverRender($flag = true) kann verwendet werden um das automatische rendern global ein- oder auszuschalten, z.B. für alle Controller. Wenn er auf TRUE gesetzt wird, ruft postDispatch() nicht automatisch render() im aktuellen Controller auf. getNeverRender() empfängt den aktuellen Wert.

  • setNoRender($flag = true) kann verwendet werden um das automatische rendern ein- oder auszuschalten. Wenn er auf TRUE gesetzt wird, wird postDispatch() render() im aktuellen Controller nicht automatisch aufrufen. Diese Einstellung wird jedesmal zurückgesetzt wenn preDispatch() aufgerufen wird (z.B. muß dieses Flag für jeden Controller gesetzt werden für den das automatische rendern nicht automatisch stattfinden soll). getNoRender() empfängt den aktuellen Wert.

  • setNoController($flag = true) kann verwendet werden um render() zu sagen das für Aktion Skripts nicht in einem Unterverzeichnis gesucht werden soll das nach dem Controller benannt ist (was das Standardverhalten ist). getNoController() empfängt den aktuellen Wert.

  • setNeverController($flag = true) ist analog zu setNoController(), arbeitet aber auf einem globalen Level -- z.B. wird es nicht für jede ausgeführte Aktion zurückgesetzt. getNeverController() empfängt den aktuellen Wert.

  • setScriptAction($name) kann verwendet werden um das Aktion Skript zu spezifizieren das gerendert werden soll. $name sollte der Name des Skripts sein, ohne den Datei Suffix (und ohne das Controller Unterverzeichnis, ausser wenn noController eingeschaltet wurde). Wenn nicht spezifiziert, wird nach einem View Skript gesucht das nach der Aktion in Anfrage Objekt benannt ist. getScriptAction() empfängt den aktuellen Wert.

  • setResponseSegment($name) kann verwendet werden um zu spezifizieren in welches Segment das nach einem Antwort Objekt benannt ist, gerendert werden soll. Wenn nicht spezifiziert, wird in das Standard Segment gerendert. getResponseSegment() empfängt den aktuellen Wert.

  • initView($path, $prefix, $options) kann aufgerufen werden um den Basis View Pfad, den Klassenprefix für Helfer, Filter Skripts und ViewRenderer Optionen zu spezifizieren. Es kann eines der folgenden Flags übergeben werden: neverRender, noRender, noController, scriptAction, und responseSegment.

  • setRender($action = null, $name = null, $noController = false) erlaubt es scriptAction, responseSegment, oder noController in einem Schritt zu übergeben. direct() ist ein Alias für diese Methode, und erlaubt es diese Methode einfach vom eigenen Controller aus aufzurufen:

    // Rendert 'foo' statt dem aktuellen Aktion Skript
    $this->_helper->viewRenderer('foo');
    
    // Rendert form.phtml zum 'html' Antwort Segment, ohne einen Controller aus dem
    // Unterverzeichnis des View Skripts zu verwenden:
    $this->_helper->viewRenderer('form', 'html', true);
    

    Anmerkung

    setRender() und direct() stellen das View Sktript nicht dar, sondern setzen Hinweise die postDispatch() und render() dann verwenden wenn die View dargestellt wird.

Der Constructor erlaubt es optional das View Objekt und ViewRenderer Optionen zu übergeben; er akzeptiert die gleichen Flags wie initView():

$view    = new Zend_View(array('encoding' => 'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer =
    new Zend_Controller_Action_Helper_ViewRenderer($view, $options);

Es gibt einige zusätzliche Methoden für das individualisieren von Pfadspezifikationen die für das Herausfinden des Basis View Pfades verwendet werden der dem View Objekt hinzugefügt wird, und den View Skript Pfad der verwendet wird wenn das View Skript zu dem gerendert werden soll automatisch herausgefunden wird. Diese Methoden nehmen alle ein oder mehrere der folgenden Platzhalter:

  • :moduleDir zeigt auf das aktuelle Modul Basisverzeichnis (von der Konvention her das Elternverzeicnis des Controller Verzeichnisses des Moduls).

  • :module zeigt auf den aktuellen Modulnamen.

  • :controller zeigt auf den aktuellen Controllernamen.

  • :action zeigt auf den aktuellen Aktionsnamen.

  • :suffix zeigt auf das aktuelle Suffix des View Skripts (welcher über setViewSuffix() gesetzt werden kann).

Die Methoden für das kontrollieren der Pfad Spezifikationen sind:

  • setViewBasePathSpec($spec) erlaubt die Änderung der Pfad Spezifikation die verwendet wird um den Basispfad herauszufinden zu dem das View Objekt hinzugefügt werden soll. Die Standardspezifikation ist :moduleDir/views. Die aktuelle Spezifikation kann jederzeit durch Verwenden von getViewBasePathSpec() erhalten werden.

  • setViewScriptPathSpec($spec) erlaubt die Änderung der Pfad Spezifikation die verwendet wird um den Pfad zu einem individuellen View Skript herauszufinden (ohne den Basis View Skript Pfad). Die Standard Spezifikation ist :controller/:action.:suffix. Die aktuelle Spezifikation kann jederzeit durch Verwenden von getViewScriptPathSpec() erhalten werden.

  • setViewScriptPathNoControllerSpec($spec) erlaubt die Änderung der Pfad Spezifkiation die verwendet wird um den Pfad zu einem individuellen View Skript herauszufinden wenn noController aktiv ist (ohne den Basis View Skript Pfad). Die Standard Spezifikation ist :action.:suffix. Die aktuelle Spezikifation kann jederzeit durch Verwenden von getViewScriptPathNoControllerSpec() erhalten werden.

Für eine feinkörnige Kontrolle über Pfadspezifikationen kann Zend_Filter_Inflector verwendet werden. Im Hintergrund verwendet der ViewRenderer einen Inflector um bereits Abstimmungen am Pfad durchzuführen. Um auf dem Inflector einzuwirken, damit entweder ein eigener für die Verwendung gesetzt wird, oder um den Standard Inflector zu verändern, können die folgenden Methoden verwendet werden:

  • getInflector() empfängt den Inflector. Wenn bis dahin keiner im ViewRenderer existiert, wird dieser, anhand der Verwendung der Standard Regeln, erstellt.

    Standardmäßig verwendet dieser statische Referenzregeln für das Suffix und Modulverzeichnis, sowie ein statisches Ziel; das erlaubt verschiedenen ViewRenderer Eigenschaften den Inflector dynamisch zu ändern.

  • setInflector($inflector, $reference) erlaubt das Setzen eines eigenen Inflectors für die Verwendung mit dem ViewRenderer. Wenn $reference TRUE ist, setzt dieser das Suffix und Modulverzeichnis als statische Referenz zu ViewRenderer Eigenschaften, genauso wie das Ziel.

Standard Konventionen für das Eruieren

Der ViewRenderer führt einige Pfad Normalisierungen durch um das Eruieren von View Skripten einfacher zu machen. Die Standardregeln sind wie folgt:

  • :module: MixedCase und camelCaseWörter werden durch Bindestriche getrennt, und der komplette String wird auf Kleinschreibung geändert. z.B.: "FooBarBaz" wird "foo-bar-baz".

    Intern verwendet der Inflector die Filter Zend_Filter_Word_CamelCaseToDash und Zend_Filter_StringToLower.

  • :controller: MixedCase und camelCaseWörter werden durch Bindestriche getrennt; Unterstriche werden in Verzeichnistrennzeichen konvertiert, und der komplette String wird auf Kleinschreibung geändert. Beispiele: "FooBar" wird "foo-bar"; "FooBar_Admin" wird "foo-bar/admin".

    Intern verwendet der Inflector die Filter Zend_Filter_Word_CamelCaseToDash, Zend_Filter_Word_UnderscoreToSeparator und Zend_Filter_StringToLower.

  • :action: MixedCase und camelCaseWörter werden durch Bindestriche getrennt; nicht-anphanummerische Zeichen werden zu Bindestrichen übersetzt, und der komplette String wird auf Kleinschreibung geändert. Beispiele: "fooBar" wird "foo-bar"; "foo-barBaz" wird "foo-bar-baz".

    Intern verwendet der Inflector die Filter Zend_Filter_Word_CamelCaseToDash, Zend_Filter_PregReplace und Zend_Filter_StringToLower.

Die letzten Teile in der ViewRenderer API sind die Methoden für das aktuelle herausfinden von View Skript Pfaden und Rendern von Views. Diese enthalten:

  • renderScript($script, $name) erlaubt es ein Skript mit einem selbst spezifizierten Pfad zu rendern, optional zu einem benannten Pfad Segment. Wenn diese Methode verwendet wird, ermittelt der ViewRenderer nicht automatisch den Skriptnamen sondern übergibt das $script Argument direkt der render() Methode des View Objekts.

    Anmerkung

    Sobald die View zum Antwort Objekt gerendert wurde, setzt diese noRender um irrtümliches mehrfaches rendern zum selben View Skript zu verhindern.

    Anmerkung

    Standardmäßig handelt Zend_Controller_Action::renderScript() in Vertretung zur renderScript() Methode des ViewRenderer's.

  • getViewScript($action, $vars) erstellt den Pfad zu einem View Skript das auf einer Aktion basiert die übergeben wird, und/oder allen Variablen die in $vars übergeben werden. Schlüssel für dieses Array können jede der Pfad Spezifikations Schhüssel enthalten ('moduleDir', 'module', 'controller', 'action', und 'suffix'). Jede übergebene Variable wird verwendet; andernfalls werden Werte die auf der aktuellen Anfrage basieren angewendet.

    getViewScript() verwendet entweder viewScriptPathSpec oder viewScriptPathNoControllerSpec basierend auf den Einstellungen des noController Flags.

    Wortbegrenzer die in Modul-, Controller- oder Aktionsnamen vorkommen werden mit Bindestrichen ('-') ersetzt. Deshalb resultiert, wenn der Controllername 'foo.bar' und die Aktion 'baz:bat' ist, die Verwendung der standard Pfad Spezifikation einen View Skript Pfad von 'foo-bar/baz-bat.phtml'.

    Anmerkung

    Standardmäßig handelt Zend_Controller_Action::getViewScript() in Vertretung zur getViewScript() Methode des ViewRenderer's.

  • render($action, $name, $noController) prüft zuerst ob entweder $name oder $noController übergeben wurde, und wenn dem so ist, wird das betreffende Flag (respektive responseSegment und noController) im ViewRenderer gesetzt. Dann übergibt er das $action Argument, wenn vorhanden, an getViewScript(). Am Ende wird der berechnete View Skript Pfad an renderScript() übergeben.

    Anmerkung

    Achtung vor den Nebeneffekten bei der Verwendung von render(): Die Werte die für den Anwort Segment Namen und für das noController Flag übergeben werden sind im Objekt dauerhaft. Zusätzlich wird noRender gesetzt nachdem das rendern fertig ist.

    Anmerkung

    Standardmäßig handelt Zend_Controller_Action::render() in Vertretung zur render() Methode des ViewRenderer's.

  • renderBySpec($action, $vars, $name) erlaubt es Pfad Spezifikations Variablen zu übergeben um den View Skript Pfad zu ermitteln der erstellt werden soll. Es übergibt $action und $vars an getScriptPath() und übergibt anschließend den resultierenden Skript Pfad und $name an renderScript().

Grundsätzliches Beispiel der Verwendung

Beispiel 141. Grundsätzliche Verwendung

Am einfachsten, wird einfach der ViewRenderer Helfer mit dem Helfer Broker in der eigenen Bootstrap Datei, initialisiert und registriert, und anschließend die Variablen in den Aktion Methoden gesetzt.

// In der Bootstrap Datei:
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');

...

// 'foo' Modul, 'bar' Controller:
class Foo_BarController extends Zend_Controller_Action
{
    // Rendert standardmäßig bar/index.phtml; keine Aktion benötigt
    public function indexAction()
    {
    }

    // Rendert bar/populate.phtml wobei die Variable 'foo' auf 'bar'
    // gesetzt wird. Da das View Objekt beim preDispatch() definiert,
    // ist es bereits vorhanden.
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }

    // Rendert nichts da zu einer anderen Aktion weitergeleitet wird;
    // die neue Aktion wird jegliches rendern durchführen
    public function bazAction()
    {
        $this->_forward('index');
    }

    // Rendert nichts da zu einer anderen Lokation weitergeleitet wird
    public function batAction()
    {
        $this->_redirect('/index');
    }
}

Benamungs Konventionen: Wort Begrenzer in Controller- und Aktionnamen

Wenn der Controller- oder Aktionsname aus mehreren Wörtern aufgebaut ist, müssen diese, da der Dispatcher das benötigt, seperiert sein durch die URL nach spezifischem Pfad und Wort Begrenzer Zeichen. Der ViewRenderer ersetzt jeden Pfad Begrenzer den er im Controllernamen findet mit einem aktuellen Pfad Begrenzer ('/'), und jeden Wort Begrenzer der gefunden wird mit einem Bindestrich ('-') wenn Pfade erstellt werden. Deshalb würde ein Aufruf der Aktion /foo.bar/baz.bat zu FooBarController::bazBatAction() in FooBarControll.php weiterleiten was wiederum foo-bar/baz-bat.phtml darstellen würde; ein Aufruf der Aktion /bar_baz/baz-bat für dazu das Bar_BazController::bazBatAction() in Bar/BazController.php dispatched wird (betrachte die Separation des Pfades) und bar/baz/baz-bat.phtml gerendert wird.

Es ist zu beachten das im zweiten Beispiel, das Modul noch immer das Standardmodul ist, aber das der Controller, wegen der Existenz eines Pfad Separators, den Namen Bar_BazController in Bar/BazController.php empfängt. Der ViewRenderer emuliert die Controller Verzeichnis Hierarchie.

Beispiel 142. Automatisches rendern ausschalten

Für einige Aktionen oder Controller, kann es gewünscht sein das automatische Rendern auszuschalten -- zum Beispiel, wenn eine andere Art von Ausgabe (XML, JSON, etc) ausgegeben werden soll, oder wenn man einfach nichts ausgeben will. Es gibt zwei Optionen: Alle Fälle von automatischem Rendern ausschalten (setNeverRender()), oder dieses einfach für die aktuelle Aktion ausschalten (setNoRender()).

// Baz Controller Klasse, bar Modul:
class Bar_BazController extends Zend_Controller_Action
{
    public function fooAction()
    {
        // Diese Sektion nicht automatisch Rendern
        $this->_helper->viewRenderer->setNoRender();
    }
}

// Bat Controller Klasse, Bar Modul:
class Bar_BatController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // Die Aktionen dieses Controller nie automatisch Rendern
        $this->_helper->viewRenderer->setNoRender();
    }
}

Anmerkung

In den meisten Fällen, macht es keinen Sinn das automatische Rendern global auszuschalten (ala setNeverRender()), da das einzige das man dann vom ViewRenderer erhält das automatische Setup des View Objekts ist.

Beispiel 143. Ein anderes View Skript auswählen

Einige Situationen erfordern das ein anderes Skript, als das nach der Aktion benannte, ausgeführt wird. Zum Beispiel, wenn man einen Controller hat der Aktionen sowohl hinzufügen als auch bearbeiten kann, und beide mit der selben 'form' View angezeigt werden, aber mit unterschiedlichen Werten gesetzt werden. Der Skript Name kann ganz einfach geändert werden. Entweder mit setScriptAction(), setRender() oder durch Aufruf des Helfers als Methode, was wiederum setRender() ausruft.

// Bar Controller Klasse, foo Modul:
class Foo_BarController extends Zend_Controller_Action
{
    public function addAction()
    {
        // Rendert 'bar/form.phtml' statt 'bar/add.phtml'
        $this->_helper->viewRenderer('form');
    }

    public function editAction()
    {
        // Rendert 'bar/form.phtml' statt 'bar/edit.phtml'
        $this->_helper->viewRenderer->setScriptAction('form');
    }

    public function processAction()
    {
        // einige Prüfungen durchführen...
        if (!$valid) {
            // Rendert 'bar/form.phtml' statt 'bar/process.phtml'
            $this->_helper->viewRenderer->setRender('form');
            return;
        }

        // andernfalls die Bearbeitung weiter durchführen...
    }

}

Beispiel 144. Die resigstrierte View ändern

Was wenn ein View Objekt modifiziert werden soll -- zum Beispiel, die Helfer Pfade ändern, oder die Kodierung? Das kann durch Modifikation des View Objekts, das im Controller gesetzt ist, gemacht werden, oder durch herausnehmen des View Objekts aus dem ViewRenderer; beide referenzieren auf das gleiche Objekt.

// Bar Controller Klasse, foo Modul:
class Foo_BarController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // Die Kodierung der View ändern
        $this->view->setEncoding('UTF-8');
    }

    public function bazAction()
    {
        // Das View Objekt erhalten, und den Kommentar Callback
        // auf 'htmlspecialchars' setzen
        $view = $this->_helper->viewRenderer->view;
        $view->setEscape('htmlspecialchars');
    }
}

Erweiterte Beispiel der Verwendung

Beispiel 145. Die Pfad Spezifikationen ändern

In einigen Fällen, kann man entscheiden das die standardmäßige Pfad Spezifikation nicht den Notwendigkeiten der Seite entspricht. Zum Beispiel, wenn man einen einzelnen Template Baum haben will zu dem man dann Zugriff für Entwickler geben kann (das ist sehr typisch wenn man zum Beispiel Smarty verwendet). In solchen Fällen, kann es gewünscht sein die Spezifkiation des View Basispfades hardkodiert zu erstellen und eine alternative Spezifikation für die Pfade der Aktions View Skripte selbst zu erstellen.

Für die Zwecke dieses Beispiels, nehmen wir an das der Basispfad zur View '/opt/vendor/templates' sein soll, und das die View Skripte durch ':moduleDir/:controller/:action.:suffix' referenziert werden sollen; wenn das noController Flag gesetzt wurde, soll aus dem Top Level statt aus einem Unterverzeichnis gerendert werden (':action.:suffix'). Zuletzt soll 'tpl' als View Skript Suffix für Dateinamen verwendet werden.

/**
 * In der Bootstrap Datei:
 */

// Unterschiedliche View Implmentation
$view = new ZF_Smarty();

$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
             ->setViewScriptPathSpec(':module/:controller/:action.:suffix')
             ->setViewScriptPathNoControllerSpec(':action.:suffix')
             ->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

Beispiel 146. Mehrfache View Skripte von der gleichen Aktion rendern

Manchmal, ist es notwendig mehrfache View Skripte von einer einzelnen Aktion zu rendern. Das ist sehr geradlinig -- einfach mehrere Aufrufe zu render() machen:

class SearchController extends Zend_Controller_Action
{
    public function resultsAction()
    {
        // Annahme das $this->model das aktuelle Modell ist
        $this->view->results =
            $this->model->find($this->_getParam('query', '');

        // render() handelt standardmäßig in Vertretung zum ViewRenderer
        // Rendert zuerst die Such Form und anschließend die Ergebnisse
        $this->render('form');
        $this->render('results');
    }

    public function formAction()
    {
        // tue nichts; der ViewRenderer bearbeitet das View Skript automatisch
    }
}

Schreiben eigener Helfer

Aktions Helfer erweitern Zend_Controller_Action_Helper_Abstract, eine abstrakte Klasse die das Basisinterface bietet und vom Helfer Broker funktionell benötigt wird. Diese inkludiert die folgenden Methoden:

  • setActionController() wird verwendet um den aktuellen Aktion Controller zu setzen.

  • init(), wird vom Helfer Broker wärend der Instanzierung ausgeführt und kann verwendet werden um den Status zurückzusetzen wenn mehrere Controller den gleichen Helfer in einer verketteten Aktion verwenden.

  • preDispatch(), wird vor der ausführenden Aktion gestartet.

  • postDispatch() wird ausgeführt nachdem eine Aktion fertig ist -- selbst wenn ein preDispatch() Plugin die Aktion abgebrochen hat. Normalerweise nützlich für das Saubermachen.

  • getRequest() empfängt das aktuelle Anfrage Objekt.

  • getResponse() empfängt das aktuelle Antwort Objekt.

  • getName() empfängt den Helfernamen. Sie empfängt die Portion des Klassennamens der dem letzten Unterstrich-Zeichen folgt, oder andererseits den kompletten Klassennamen. Als Beispiel, wenn die Klasse Zend_Controller_Action_Helper_Redirector heißt, wird Redirector zurückgegeben; eine Klasse die FooMessage heißt wird einfach sich selbst zurückgeben.

Optional kann eine direct() Methode in der eigenen Helfer Klasse inkludiert werden. Wenn Sie definiert ist, erlaubt Sie den Helfer als eine Methode des Helfer Brokers zu verwenden, um eine einfache rein-raus Verwendung des Helfers zu ermöglichen. Als Beispiel definiert der Umleiter direct() als einen Alias von goto() und erlaubt damit die Verwendung des Helfers wie folgt:

// Umleiten zu /blog/view/item/id/42
$this->_helper->redirector('item', 'view', 'blog', array('id' => 42));

Intern schaut die __call() Methode des Helfer Brokers nach einem Helfer der redirector heißt, prüft anschließend ob der Helfer eine definierte direct() Methode besitzt und ruft diese mit den angegebenen Argumenten auf.

Wenn eine eigene Helfer Klasse erstellt wurde, kann man zu Ihr wie im obigen Kapitel beschrieben, Zugang erhalten.