Programmer's Reference Guide

Contrôleurs d'action

Aides d'action (Helper)

Introduction

Les aides d'action permettent aux développeurs d'injecter, en cours d'exécution et/ou à la demande, des fonctionnalités dans tout contrôleurs d'action qui étendent Zend_Controller_Action. Le but des aides d'action est de minimiser la nécessité d'étendre le contrôleur d'action abstrait en y injectant des fonctionnalités communes de contrôleur d'action.

Il y a de nombreuses manières d'utiliser les aides d'action. Les aides d'action utilisent le système de gestionnaire ("Broker"), similaire aux types de gestionnaire vu pour les Zend_View_Helper, et les Zend_Controller_Plugin. Les aides d'action (comme les aides de vue Zend_View_Helper) peuvent être chargées et appelées à la demande, ou elles peuvent être instanciées au début de la requête ("bootstrap") ou au moment de la création des contrôleurs d'action (init()). Pour mieux comprendre ceci, reportez vous à la section d'utilisation ci-dessous.

Initialisation des aides

Une aide peut être initialisée de plusieurs manières différentes, basées sur vos besoins aussi bien que la fonctionnalité de l'aide.

Le gestionnaire d'aide est stocké en tant que membre $_helper du Zend_Controller_Action ; utilisez le gestionnaire pour récupérer ou appeler les aides. Les méthodes pour faire ceci inclent :

  • L'utilisation explicite de getHelper(). Passez lui simplement un nom, et l'objet d'aide est retourné :

    <?php
    $flashMessenger = $this->_helper->getHelper('FlashMessenger');
    $flashMessenger->addMessage('Nous avons fait quelquechose lors de la dernière requête');
                    
  • L'utilisation de la fonctionnalité __get() du gestionnaire d'aide et récupérez l'aide comme si elle était une propriété membre du gestionnaire :

    <?php
    $flashMessenger = $this->_helper->FlashMessenger;
    $flashMessenger->addMessage('Nous avons fait quelquechose lors de la dernière requête');
                    
  • Enfin, la plupart des aides d'action implémente la méthode direct() qui va appeler une méthode spécifique par défaut dans l'aide. Dans l'exemple de FlashMessenger, ceci appelle addMessage() :

    <?php
    $this->_helper->FlashMessenger('Nous avons fait quelquechose lors de la dernière requête');
                    

Note: Tous les exemples ci-dessus sont équivalents.

Vous pouvez vouloir aussi instancier les aides explicitemet. Vous pourriez avoir besoin de ceci si vous utilisez l'aide hors du contexte du contrôleur d'action, ou si vous souhaitez fournir une aide au gestionnaire d'aide à utiliser pour une action quelconque. L'instanciation se fait comme tout autre classe PHP.

Le gestionaire d'aide (Broker)

Zend_Controller_Action_HelperBroker gére les détails de l'enregistrement des objets d'aide et les chemins de ces aides, ainsi que la récupération des aides à la demande.

Pour enregistrer une aide dans le gestionnaire, utilisez addHelper :

<?php
Zend_Controller_Action_HelperBroker::addHelper($helper);
        

Bien sûr, instancier et fournir des aides au gestionnaire est coûteux en temps et en ressource donc deux méthodes existent pour automatiser les choses légèrement : addPrefix() et addPath().

  • addPrefix() prend un préfixe de classe et l'utilise pour déterminer le chemin des dossiers dans lesquels les classes d'aides ont été définies. Ceci suppose que le préfixe de la classe respecte la convention de nommage du Zend Framework.

    <?php
    // Ajoute les aides préfixées Mes_Action_Helpers dans Mes/Action/Helpers/
    Zend_Controller_Action_HelperBroker::addPrefix('Mes_Action_Helpers');
                    
  • addPath() prend un répertoire en premier argument et un préfixe de classe en second (par défaut réglé à "Zend_Controller_Action_Helper"). Ceci vous permet de faire correspondre vos propres préfixes de classe à vos dossiers spécifiques.

    <?php
    // Ajoute les aides préfixées avec Aide dans Plugins/Aides/
    Zend_Controller_Action_HelperBroker::addPath('./Plugins/Aides', 'Aide');
                    

Puisque ces méthodes sont statiques, elles peuvent être appelées en tout point du déroulement du contrôleur pour ajouter dynamiquement les aides nécessaires.

Pour déterminer si une aide existe dans le gestionnaire d'aide, utilisez hasHelper($name), où $name est le nom raccourci de l'aide (sans le préfixe) :

<?php
// Vérifie si l'aide 'redirector' est enregistrée dans le gestionnaire :
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    echo 'L\'aide Redirector est enregistrée';
}
        

Il existe aussi deux méthodes statiques pour récupérer les aides issues du gestionnaire d'aide : getExistingHelper() et getStaticHelper(). getExistingHelper() récupérera une aide seulement si elle a précédemment été invoquée par ou explicitement enregistrée dans le gestionnaire d'aide ; la méthode lèvera une exception si non. getStaticHelper() réalise la même chose que getExistingHelper(), mais tentera d'instancier l'aide si elle n'a pas déjà été enregistrée dans la pile des aides. getStaticHelper() est un bon choix pour récupérer les aides que vous voulez configurer.

Les deux méthodes prennent un unique paramètre, $name, qui est le nom court de l'aide (c'est-à-dire sans le préfixe).

<?php
// Vérifie si l'aide 'redirector' est enregistrée dans le gestionnaire, et l'extrait :
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    $redirector = Zend_Controller_Action_HelperBroker::getExistingHelper('redirector');
}

// Ou, simplement le récupère, sans se soucier s'il a ou non été
// enregistré précédemment :
$redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
}
        

Enfin, pour effacer une aide enregistrée du gestionnaire, utilisez removeHelper($name), où $name est le nom raccourci de l'aide (sans le préfixe) :

<?php
// Effacement conditionnel de l'aide 'redirector' du gestionnaire :
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
    Zend_Controller_Action_HelperBroker::removeHelper('redirector')
}
        

Aides d'action intégrées

Le Zend Framework inclue plusieurs aides d'action par défaut : AutoComplete pour des réponses automatiques à des auto-complétions AJAX ; ContextSwitch et AjaxContext pour distribuer des formats de réponse alternatifs pour vos actions ; FlashMessenger pour gérer des messages entre les sessions ; Redirector, qui fournit différentes implémentations pour rediriger vers des pages internes ou externes à votre application ; et ViewRenderer pour automatiser le processus de paramétrage de vos objets de vues dans votre contrôleur et du rendu de ces vues.

ActionStack

L'aide ActionStack vous permet d'empiler les requêtes dans le plugin de contrôleur frontal ActionStack, en vous aidant effectivement à créer une liste d'actions à exécuter durant la requête. Cet aide vous permet d'ajouter des actions soit en spécifiant de nouveaux objets de requêtes, soit en paramètrant action/controller/module.

Note: Invoquer l'aide ActionStack initialise le plugin ActionStack
L'appel de l'aide ActionStack enregistre implicitement le plugin ActionStack - ce qui veut dire que vous n'avez pas besoin d'enregistrer explicitement le plugin ActionStack pour utiliser cette fonctionnalité.

Exemple #1 Ajouter une tâche en utilisant une action, un contrôleur et un module

Souvent, il est plus simple de spécifier l'action, le contrôleur et le module (et optionnellement des paramètres de requêtes), comme vous le feriez en appelant Zend_Controller_Action::_forward() :

<?php
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Ajoute deux actions à la pile

        // Ajoute un appel à /foo/baz/bar/baz
        // (FooController::bazAction() avec une variable de requête bar == baz)
        $this->_helper->actionStack('baz', 'foo', 'default', array('bar' => 'baz'));

        // Ajoute un appel à /bar/bat
        // (BarController::batAction())
        $this->_helper->actionStack('bat', 'bar');
    }
}
?>

Exemple #2 Ajouter une tâche en utilisant un objet de requête

Parfois la nature OO d'un objet de requête a plus de sens ; vous pouvez alors fournir l'objet à l'aide ActionStack.

<?php
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Ajoute deux actions à la pile

        // Ajoute un appel à /foo/baz/bar/baz
        // (FooController::bazAction() avec une variable de requête bar == baz)
        $request = clone $this->getRequest();
        $request->setActionName('baz')              // sans régler le contrôleur ou le module
                ->setParams(array('bar' => 'baz')); // utilise les valeurs courantes
        $this->_helper->actionStack($request);

        // Ajoute un appel à /bar/bat
        // (BarController::batAction())
        $request = clone $this->getRequest();
        $request->setActionName('bat')      // sans régler le module
                ->setControllerName('bar'); // utilise la valeur courante
        $this->_helper->actionStack($request);
    }
}
?>

AutoComplete

Many AJAX javascript libraries offer functionality for providing autocompletion whereby a selectlist of potentially matching results is displayed as the user types. The AutoComplete helper aims to simplify returning acceptable responses to such methods.

Since not all JS libraries implement autocompletion in the same way, the AutoComplete helper provides some abstract base functionality necessary to many libraries, and concrete implementations for individual libraries. Return types are generally either JSON arrays of strings, JSON arrays of arrays (with each member array being an associative array of metadata used to create the selectlist), or HTML.

Basic usage for each implementation is the same:

<?php
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Perform some logic...

        // Encode and send response;
        $this->_helper->autoCompleteDojo($data);

        // Or explicitly:
        $response = $this->_helper->autoCompleteDojo->sendAutoCompletion($data);

        // Or simply prepare autocompletion response:
        $response = $this->_helper->autoCompleteDojo->prepareAutoCompletion($data);
    }
}
?>

By default, autocompletion does the following:

  • Disables layouts and ViewRenderer.

  • Sets appropriate response headers.

  • Sets response body with encoded/formatted autocompletion data.

  • Sends response.

Available methods of the helper include:

  • disableLayouts() can be used to disable layouts and the ViewRenderer. Typically, this is called within prepareAutoCompletion().

  • encodeJson($data, $keepLayouts = false) will encode data to JSON, optionally enabling or disabling layouts. Typically, this is called within prepareAutoCompletion().

  • prepareAutoCompletion($data, $keepLayouts = false) is used to prepare data in the response format necessary for the concrete implementation, optionally enabling or disabling layouts. The return value will vary based on the implementation.

  • sendAutoCompletion($data, $keepLayouts = false) is used to send data in the response format necessary for the concrete implementation. It calls prepareAutoCompletion(), and then sends the response.

  • direct($data, $sendNow = true, $keepLayouts = false) is used when calling the helper as a method of the helper broker. The $sendNow flag is used to determine whether to call sendAutoCompletion() or prepareAutoCompletion(), respectively.

Currently, AutoComplete supports the Dojo and Scriptaculous AJAX libraries.

AutoCompletion with Dojo

Dojo does not have an AutoCompletion widget per se, but has two widgets that can perform AutoCompletion: ComboBox and FilteringSelect. In both cases, they require a data store that implements the QueryReadStore; for more information on these topics, see the » dojo.data documentation.

In Zend Framework, you can pass a simple indexed array to the AutoCompleteDojo helper, and it will return a JSON response suitable for use with such a store:

<?php
// within a controller action:
$this->_helper->autoCompleteDojo($data);

Exemple #3 AutoCompletion with Dojo Using Zend MVC

AutoCompletion with Dojo via the Zend MVC requires several things: generating a form object for the ComboBox on which you want AutoCompletion, a controller action for serving the AutoCompletion results, creating a custom QueryReadStore to connect to the AutoCompletion action, and generation of the javascript to use to initialize AutoCompletion on the server side.

First, let's look at the javascript necessary. Dojo offers a complete framework for creating OOP javascript, much as Zend Framework does for PHP. Part of that is the ability to create pseudo-namespaces using the directory hierarchy. We'll create a 'custom' directory at the same level as the Dojo directory that's part of the Dojo distribution. Inside that directory, we'll create a javascript file, TestNameReadStore.js, with the following contents:

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

This class is simply an extenstion of Dojo's own QueryReadStore, which is itself an abstract class. We simply define a method by which to request, and assigning it to the 'test' element.

Next, let's create the form element for which we want AutoCompletion:

<?php
class TestController extends Zend_Controller_Action
{
    protected $_form;

    public function getForm()
    {   
        if (null === $this->_form) {
            require_once 'Zend/Form.php';
            $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;
    }
}

Here, we simply create a form with 'test' and 'go' methods. The 'test' method adds several special, Dojo-specific attributes: dojoType, store, autoComplete, and hasDownArrow. The dojoType is used to indicate that we are creating a ComboBox, and we will link it to a data store (key 'store') of 'testStore' -- more on that later. Specifying 'autoComplete' as false tells Dojo not to automatically select the first match, but instead show a list of matches. Finally, 'hasDownArrow' creates a down arrow similar to a select box so we can show and hide the matches.

Let's add a method to display the form, as well as an end point for processing AutoCompletion:

<?php
class TestController extends Zend_Controller_Action
{
    // ...

    /**
     * Landing page
     */
    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 our autocompleteAction() we do a number of things. First, we look to make sure we have a post request, and that there is a 'format' parameter set to the value 'ajax'; these are simply to help reduce spurious queries to the action. Next, we check for a 'test' parameter, and compare it against our data. (I purposely leave out the implementation of getData() here -- it could be any sort of data source.) Finally, we send our matches to our AutoCompletion helper.

Now that we have all the pieces on the backend, let's look at what we need to deliver in our view script for the landing page. First, we need to setup our data store, then render our form, and finally ensure that the appropriate Dojo libraries -- including our custom data store -- get loaded. Let's look at the view script, which comments the steps:

<? // setup our data store: ?>
<div dojoType="custom.TestNameReadStore" jsId="testStore"
    url="<?= $this->baseUrl() ?>/unit-test/autocomplete/format/ajax" requestMethod="get"></div>

<? // render our form: ?>
<?= $this->form ?>

<? // setup Dojo-related CSS to load in HTML head: ?>
<? $this->headStyle()->captureStart() ?>
@import "<?= $this->baseUrl() ?>/javascript/dijit/themes/tundra/tundra.css";
@import "<?= $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
<? $this->headStyle()->captureEnd() ?>

<? // setup javascript to load in HTML head, including all required Dojo
   // libraries: ?>
<? $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");
<? $this->headScript()->captureEnd() ?>

Note the calls to view helpers such as headStyle and headScript; these are placeholders, which we can then render in the HTML head section of our layout view script.

We now have all the pieces to get Dojo AutoCompletion working.

AutoCompletion with Scriptaculous

» Scriptaculous expects an HTML response in a specific format.

The helper to use with this library is 'AutoCompleteScriptaculous'. Simply provide it an array of data, and the helper will create an HTML response compatible with Ajax.Autocompleter.

ContextSwitch and AjaxContext

The ContextSwitch action helper is intended for facilitating returning different response formats on request. The AjaxContext helper is a specialized version of ContextSwitch that facilitates returning responses to XmlHttpRequests.

To enable either one, you must provide hinting in your controller as to what actions can respond to which contexts. If an incoming request indicates a valid context for the given action, the helper will then:

  • Disable layouts, if enabled.

  • Set an alternate view suffix, effectively requiring a separate view script for the context.

  • Send approprite response headers for the context desired.

  • Optionally, call specified callbacks to setup the context and/or perform post-processing.

As an example, let's consider the following controller:

<?php
class NewsController extends Zend_Controller_Action
{
    /**
     * Landing page; forwards to listAction()
     */
    public function indexAction()
    {
        $this->_forward('list');
    }

    /**
     * List news items
     */
    public function listAction()
    {
    }

    /**
     * View a news item
     */
    public function viewAction()
    {
    }
}
?>

Let's say that we want the listAction() to also be available in an XML format. Instead of creating a different action, we can hint that it can return an XML response:

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

    // ...
}
?>

What this will do is:

  • Set the 'Content-Type' response header to 'text/xml'.

  • Change the view suffix to 'xml.phtml' (or, if you use an alternate view suffix, 'xml.[your suffix]').

Now, you'll need to create a new view script, 'news/list.xml.phtml', which will create and render the XML.

To determine if a request should initiate a context switch, the helper checks for a token in the request object. By default, it looks for the 'format' parameter, though this may be configured. This means that, in most cases, to trigger a context switch, you can add a 'format' parameter to your request:

  • Via URL parameter: /news/list/format/xml (recall, the default routing schema allows for arbitrary key/value pairs following the action)

  • Via GET parameter: /news/list?format=xml

ContextSwitch allows you to specify arbitrary contexts, including what suffix change will occur (if any), any response headers that should be sent, and arbitrary callbacks for initialization and post processing.

Default Contexts Available

By default, two contexts are available to the ContextSwitch helper: json and xml.

  • JSON. The JSON context sets the 'Content-Type' response header to 'application/json', and the view script suffix to 'json.phtml'.

    By default, however, no view script is required. It will simply serialize all view variables, and emit the JSON response immediately.

    This behaviour can be disabled by turning off auto-JSON serialization:

    <?php
    $this->_helper->contextSwitch()->setAutoJsonSerialization(false);
    ?>
  • XML. The XML context sets the 'Content-Type' response header to 'text/xml', and the view script suffix to 'xml.phtml'. You will need to create a new view script for the context.

Creating Custom Contexts

Sometimes, the default contexts are not enough. For instance, you may wish to return YAML, or serialized PHP, an RSS or ATOM feed, etc. ContextSwitch allows you to do so.

The easiest way to add a new context is via the addContext() method. This method takes two arguments, the name of the context, and an array specification. The specification should include one or more of the following:

  • suffix: the suffix to prepend to the default view suffix as registered in the ViewRenderer.

  • headers: an array of header/value pairs you wish sent as part of the response.

  • callbacks: an array containing one or more of the keys 'init' or 'post', pointing to valid PHP callbacks that can be used for context initialization and post processing.

    Initialization callbacks occur when the context is detected by ContextSwitch. You can use it to perform arbitrary logic that should occur. As an example, the JSON context uses a callback to disable the ViewRenderer when auto-JSON serialization is on.

    Post processing occurs during the action's postDispatch() routine, and can be used to perform arbitrary logic. As an example, the JSON context uses a callback to determine if auto-JSON serialization is on; if so, it serializes the view variables to JSON and sends the response, but if not, it re-enables the ViewRenderer.

There are a variety of methods for interacting with contexts:

  • addContext($context, array $spec): add a new context. Throws an exception if the context already exists.

  • setContext($context, array $spec): add a new context or overwrite an existing context. Uses the same specification as addContext().

  • addContexts(array $contexts): add many contexts at once. The $contexts array should be an array of context/specification pairs. If any of the contexts already exists, it will throw an exception.

  • setContexts(array $contexts): add new contexts and overwrite existing ones. Uses the same specification as addContexts().

  • hasContext($context): returns true if the context exists, false otherwise.

  • getContext($context): retrieve a single context by name. Returns an array following the specification used in addContext().

  • getContexts(): retrieve all contexts. Returns an array of context/specification pairs.

  • removeContext($context): remove a single context by name. Returns true if successful, false if the context was not found.

  • clearContexts(): remove all contexts.

Setting Contexts Per Action

There are two mechanisms for setting available contexts. You can either manually create arrays in your controller, or use several methods in ContextSwitch to assemble them.

The principle method for adding action/context relations is addActionContext(). It expects two arguments, the action to which the context is being added, and either the name of a context or an array of contexts. As an example, consider the following controller class:

<?php
class FooController extends Zend_Controller_Action
{
    public function listAction()
    {
    }

    public function viewAction()
    {
    }

    public function commentsAction()
    {
    }

    public function updateAction()
    {
    }
}
?>

Let's say we wanted to add an XML context to the 'list' action, and XML and JSON contexts to the 'comments' action. We could do so in the init() method:

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

Alternately, you could simply define the array property $contexts:

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

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

The above is less overhead, but also prone to potential errors.

The following methods can be used to build the context mappings:

  • addActionContext($action, $context): marks one or more contexts as available to an action. If mappings already exists, simply appends to those mappings. $context may be a single context, or an array of contexts.

    A value of true for the context will mark all available contexts as available for the action.

    An empty value for $context will disable all contexts for the given action.

  • setActionContext($action, $context): marks one or more contexts as available to an action. If mappings already exists, it replaces them with those specified. $context may be a single context, or an array of contexts.

  • addActionContexts(array $contexts): add several action/context pairings at once. $contexts should be an associative array of action/context pairs. It proxies to addActionContext(), meaning that if pairings already exist, it appends to them.

  • setActionContexts(array $contexts): acts like addActionContexts(), but overwrites existing action/context pairs.

  • hasActionContext($action, $context): determine if a particular action has a give context.

  • getActionContexts($action = null): returns either all contexts for a given action, or all action/context pairs.

  • removeActionContext($action, $context): remove one or more contexts from a given action. $context may be a single context or an array of contexts.

  • clearActionContexts($action = null): remove all contexts from a given action, or from all actions with contexts.

Initializizing Context Switching

To initialize context switching, you need to call initContext() in your action controller:

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

In some cases, you may want to force the context used; for instance, you may only want to allow the XML context if context switching is activated. You can do so by passing the context to initContext():

<?php
$contextSwitch->initContext('xml');
?>

Additional Functionality

A variety of methods can be used to alter the behaviour of the ContextSwitch helper. These include:

  • setAutoJsonSerialization($flag): By default, JSON contexts will serialize any view variables to JSON notation and return this as a response. If you wish to create your own response, you should turn this off; this needs to be done prior to the call to initContext().

    <?php
    $contextSwitch->setAutoJsonSerialization(false);
    $contextSwitch->initContext();
    ?>

    You can retrieve the value of the flag with getAutoJsonSerialization().

  • setSuffix($context, $suffix, $prependViewRendererSuffix): With this method, you can specify a different suffix to use for a given context. The third argument is used to indicate whether or not to prepend the current ViewRenderer suffix with the new suffix; this flag is enabled by default.

    Passing an empty value to the suffix will cause only the ViewRenderer suffix to be used.

  • addHeader($context, $header, $content): Add a response header for a given context. $header is the header name, and $content is the value to pass for that header.

    Each context can have multiple headers; addHeader() adds additional headers to the context's header stack.

    If the $header specified already exists for the context, an exception will be thrown.

  • setHeader($context, $header, $content): setHeader() acts just like addHeader(), except it allows you to overwrite existing context headers.

  • addHeaders($context, array $headers): Add multiple headers at once to a given context. Proxies to addHeader(), so if the header already exists, an exception will be thrown. $headers is an array of header/context pairs.

  • setHeaders($context, array $headers.): like addHeaders(), except it proxies to setHeader(), allowing you to overwrite existing headers.

  • getHeader($context, $header): retrieve the value of a header for a given context. Returns null if not found.

  • removeHeader($context, $header): remove a single header for a given context.

  • clearHeaders($context, $header): remove all headers for a given context.

  • setCallback($context, $trigger, $callback): set a callback at a given trigger for a given context. Triggers may be either 'init' or 'post' (indicating callback will be called at either context initialization or postDispatch). $callback should be a valid PHP callback.

  • setCallbacks($context, array $callbacks): set multiple callbacks for a given context. $callbacks should be trigger/callback pairs. In actuality, the most callbacks that can be registered are two, one for initialization and one for post processing.

  • getCallback($context, $trigger): retrieve a callback for a given trigger in a given context.

  • getCallbacks($context): retrieve all callbacks for a given context. Returns an array of trigger/callback pairs.

  • removeCallback($context, $trigger): remove a callback for a given trigger and context.

  • clearCallbacks($context): remove all callbacks for a given context.

  • setContextParam($name): set the request parameter to check when determining if a context switch has been requested. The value defaults to 'format', but this accessor can be used to set an alternate value.

    getContextParam() can be used to retrieve the current value.

  • setAutoDisableLayout($flag): By default, layouts are disabled when a context switch occurs; this is because typically layouts will only be used for returning normal responses, and have no meaning in alternate contexts. However, if you wish to use layouts (perhaps you may have a layout for the new context), you can change this behaviour by passing a true value to setAutoDisableLayout(). You should do this before calling initContext().

    To get the value of this flag, use the accessor getAutoDisableLayout().

  • getCurrentContext() can be used to determine what context was detected, if any. This returns null if no context switch occurred, or if called before initContext() has been invoked.

AjaxContext Functionality

The AjaxContext helper extends ContextSwitch, so all of the functionality listed for ContextSwitch is available to it. There are a few key differences, however.

First, it uses a different action controller property for determining contexts, $ajaxable. This is so you can have different contexts used for AJAX versus normal HTTP requests. The various *ActionContext*() methods of AjaxContext will write to this property.

Second, it will only trigger if an XmlHttpRequest has occurred, as determined by the request object's isXmlHttpRequest() method. Thus, if the context parameter ('format') is passed in the request, but the request was not made as an XmlHttpRequest, no context switch will trigger.

Third, AjaxContext adds an additional context, HTML. In this context, it sets the suffix to 'ajax.phtml' in order to differentiate the context from a normal request. No additional headers are returned.

Exemple #4 Allowing Actions to Respond To Ajax Requests

In this following example, we're allowing requests to the actions 'view', 'form', and 'process' to respond to AJAX requests. In the first two cases, 'view' and 'form', we'll return HTML snippets with which to update the page; in the latter, we'll return JSON.

<?php
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()
    {
        // Pull a single comment to view.
        // When AjaxContext detected, uses the comment/view.ajax.phtml 
        // view script.
    }

    public function formAction()
    {
        // Render the "add new comment" form.
        // When AjaxContext detected, uses the comment/form.ajax.phtml 
        // view script.
    }

    public function processAction()
    {
        // Process a new comment
        // Return the results as JSON; simply assign the results as view
        // variables, and JSON will be returned.
    }
}
?>

On the client end, your AJAX library will simply request the endpoints '/comment/view', '/comment/form', and '/comment/process', and pass the 'format' parameter: '/comment/view/format/html', '/comment/form/format/html', '/comment/process/format/json'. (Or you can pass the parameter via query string: e.g., "?format=json".)

Assuming your library passes the 'X-Requested-With: XmlHttpRequest' header, these actions will then return the appropriate response format.

FlashMessenger

Introduction

L'aide FlashMessenger vous permet de fournir les messages dont l'utilisateur pourrait avoir besoin dans la requête suivante. Pour accomplir ceci, FlashMessenger utilise Zend_Session_Namespace pour stocker les messages à retrouver dans la prochaine requête. C'est généralement une bonne idée si vous planifiez d'utiliser Zend_Session ou Zend_Session_Namespace, que vous initialisez avec Zend_Session::start() dans votre fichier d'amorçage. (Reportez vous à la documentation de Zend_Session pour plus de détails sur son utilisation.)

Exemple d'utilisation basique

L'exemple ci-dessous vous montre l'utilisation du flash messenger dans sa forme la plus basique. Quand l'action /some/my est appelée, il ajoute le message "Record Saved!". Une requête suivante vers l'action /some/my-next-request le retouvera (ainsi que le détruira).

<?php
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()
    {
        /**
         * Méthode par défaut por obtenir l'instance de
         * Zend_Controller_Action_Helper_FlashMessenger à la demande
         */
        $this->_flashMessenger->addMessage('Record Saved!');
    }

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

JSON

Les réponses JSON sont les réponses de choix dans une architecure de type AJAX qui attend des données structurées. JSON peut être immédiatement interprété du coté du client, ce qui rend la tâche plus simple et plus rapide.

L'aide d'action JSON effectue plusieurs traitements :

  • Désactive les layouts si elles sont activées.

  • Désactive le ViewRenderer s'il est activé.

  • Envoie à la réponse un en-tête 'Content-Type' à 'application/json'.

  • Par défaut, retourne immédiatement la réponse, sans attendre la fin de l'exécution de l'action.

Son utilisation est toute simple, appelez le depuis le le conteneur d'aides (Broker), ou appelez une de ses méthodes encodeJson() ou sendJson():

<?php
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Effectue des traitements ici ...
        // Envoie la réponse JSON :
        $this->_helper->json($data);

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

        // ou retourne la chaine json:
        $json = $this->_helper->json->encodeJson($data);
    }
}
?>

Note: Conserver les Layouts
Si vous avez besoin des Layouts, pour par exemple générer vos réponses JSON dans un contexte particulier, chaque méthode de l'aide JSON accepte un second paramètre booléen. A true, les layouts resteront activées (défaut false) :

<?php
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Récupère la chaine JSON, en laissant les layouts activées :
        $json = $this->_helper->json->encodeJson($data, true);
    }
}
?>

Redirector

Introduction

L'aide Redirector vous permet d'utiliser un objet de redirection qui remplit tous les besoins de votre application nécessaire à une redirection vers une nouvelle URL. Il fournit de nombreux avantages par rapport à la méthode _redirect(), comme la capacité de préconfigurer le comportement du site dans l'objet redirector ou d'utiliser l'interface intégrée goto($action, $controller, $module, $params) similaire à Zend_Controller_Action::_forward().

Redirector possède une certain nombre de méthodes qui peuvent être utilisées pour affecter le comportement de la redirection :

  • setCode() peut être utilisée pour paramètrer le code HTTP de la réponse à utiliser pendant la redirection.

  • setExit() peut être utilisée pour forcer un exit() juste après la redirection. Par défaut ceci vaut true.

  • setGoto() peut être utilisée pour paramètrer l'URL par défaut à utiliser si aucune n'est fournie à goto(). Elle utilise les API de Zend_Controller_Action::_forward() : setgoto($action, $controller = null, $module = null, array $params = array());

  • setGotoRoute() peut être utilisée pour paramètrer une URL basée sur une route enregistrée. Fournissez un tableau de paires clé/valeur et une route nommée, et elle assemblera une URL suivant le type de la route et sa définition.

  • setGotoUrl() peut être utilisée pour paramètrer l'URL par défaut à utiliser si aucune n'est fournie à gotoUrl(). Accepte une chaîne unique correspondant à une URL.

  • setPrependBase() peut être utilisée pour ajouter une chaîne au début de l'URL de base de l'objet requête pour les URLs spécifiées avec setGotoUrl(), gotoUrl(), ou gotoUrlAndExit().

  • setUseAbsoluteUri() peut être utilisée pour forcer le Redirector à utiliser des URI absolus pour la redirection. Quand cette option est choisie, elle utilise les valeurs de $_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], et $_SERVER['HTTPS'] pour former un URI complet à partir de l'URL spécifiée par une des méthodes de redirection. Cette option est inactive par défaut, mais pourra être activée par défaut dans les prochaines releases.

De plus, il y a une variété de méthodes dans le redirector pour réaliser les redirections actuelles :

  • goto() utilise setGoto() (API de type _forward()) pour construire une URL et réaliser une redirection.

  • gotoRoute() utilise setGotoRoute() (assemblage de route) pour construire une URL et réaliser une redirection.

  • gotoUrl() utilise setGotoUrl() (URL sous forme de chaîne) pour construire une URL et réaliser une redirection.

Enfin, vous pouvez déterminer l'URL de la redirection courante à tout moment en utilisant getRedirectUrl().

Exemples d'utilisation basique

Exemple #5 Options de réglage

Cet exemple surcharge de multiples options, incluant le réglage du code de statut HTTP à utiliser dans la redirection ("303"), le retrait du exit par défaut après la redirection, et la définition d'une URL par défaut à utiliser lors d'une redirection.

<?php
class SomeController extends Zend_Controller_Action
{
    /**
     * Redirector - défini pour l'auto-complétion
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

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

        // Régle les options par défaut pour le redirector
        // Puisque l'objet est enregistré dans le gestionnaire d'aide, ceci sera effectif
        // pour toutes les actions réalisées après ce point
        $this->_redirector->setCode('303')
                          ->setExit(false)
                          ->setGoto("this-action", "some-controller");
    }

    public function myAction()
    {
        /* Faire quelquechose */

        // Redirige vers une URL enregistré précédemment, et force une sortie pour finir
        $this->_redirector->redirectAndExit();
        return; // jamais atteint
    }
}
            

Exemple #6 Utiliser les valeurs par défaut

Cet exemple suppose que vous utilisez les paramètres par défaut, ce qui inclut que toute redirection sera suivie d'un exit() immédiat.

<?php
// EXEMPLE ALTERNATIF
class AlternativeController extends Zend_Controller_Action
{
    /**
     * Redirector - défini pour l'auto-complétion
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

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

    public function myAction()
    {
        /* Faire quelquechose */

        $this->_redirector->gotoUrl('/my-controller/my-action/param1/test/param2/test2');
        return; // jamais atteint puisque les paramètres par défaut sont à goto et exit
    }
}
            

Exemple #7 Utilisation de l'API _forward() de goto()

L'API de goto() imite celle de Zend_Controller_Action::_forward(). La différence principale est qu'elle construit un URL à partir des paramètres fournis, et du format de route par défaut :module/:controller/:action/* du routeur. Il réalise alors une redirection au lieu d'enchaîner l'action.

<?php
class ForwardController extends Zend_Controller_Action
{
    /**
     * Redirector - défini pour l'auto-complétion
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

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

    public function myAction()
    {
        /* Faire quelquechose */

        // Redirige vers 'my-action' de 'my-controller' dans le module courant
        // en utilisant les paramètres param1 => test et param2 => test2
        $this->_redirector->goto('my-action', 'my-controller', null, array('param1' => 'test', 'param2' => 'test2'));
    }
}
            

Exemple #8 Utilisation de l'assemblage de la route avec gotoRoute()

L'exemple suivant utilise la méthode assemble() du router pour créer une URL basée sur un tableau associatif de paramètres fournis. Il suppose que la route suivante a été enregistrée :

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

En donnant un tableau avec l'année règlée à 2006, le mois à 4, le jour à 24 et l'id à 42, il construira l'URL /blog/2006/4/24/42.

<?php
class BlogAdminController extends Zend_Controller_Action
{
    /**
     * Redirector - défini pour l'auto-complétion
     *
     * @var Zend_Controller_Action_Helper_Redirector
     */
    protected $_redirector = null;

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

    public function returnAction()
    {
        /* Faire quelquechose */

        // Redirige vers les archives de blog. Construit l'URL suivant
        // /blog/2006/4/24/42
        $this->_redirector->gotoRoute(
            array('year' => 2006, 'month' => 4, 'day' => 24, 'id' => 42),
            'blogArchive'
        );
    }
}
            

ViewRenderer

Introduction

L'aide ViewRenderer apporte les comportements suivants :

  • Elimine le besoin d'instancier un objet de vue dans ses contrôleurs. Ceci devient automatique.

  • Configure automatiquement les chemins vers les scripts de vue, les aides, et les filtres, en se basant sur le module actuel et associe le nom du module comme préfixe de classe pour les aides et les filtres.

  • Créer un objet de vue général accessible pour tous les contrôleurs et donc pour toutes les actions disptachées.

  • Autorise le développeur à personnaliser les options de rendu de la vue.

  • Donne la possibilité de rendre automatiquement un script de vue.

  • Donne accès aux paramètres configurant le chemin de base (base path) et le chemin des scripts (script path), de la vue.

Note: Su vous utilsez _forward(), redirect, ou render manuellement, le rendu automatique sera annulé car ViewRenderer saura que vous prennez la main.

Note: Le ViewRenderer est activé par défaut dans le contrôleur frontal. Pour le désactiver, utilisez le paramètre noViewRenderer ($front->setParam('noViewRenderer', true)) ou retirez l'objet du gestionnaire d'aides (helper broker) (Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')).
Si vous voulez modifier un paramètre du ViewRenderer avant le dispatching du contrôleur frontal, il existe deux moyens :

  • Instanciez et enregistrez votre propre objet ViewRenderer et passez le au gestionnaire d'aides :

    <?php
    $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
    $viewRenderer->setView($view)
                 ->setViewSuffix('php');
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);?>
                        
  • Initialisez et/ou récupérez l'objet ViewRenderer via le gestionnaire d'aides :

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

API

L'usage le plus banal consiste à instancier et passer l'objet ViewRenderer au gestionnaire d'aides. La manière la plus simple est d'utiliser la méthode statique getStaticHelper() du gestionnaire, qui s'occupe de tout ceci en une passe :

<?php
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');?>
        

La première action demandée instancie ou récupère l'objet de vue. A chaque instatiation de contrôleur, la méthode init() de l'objet ViewRenderer est appelée. Elle va configurer la vue et appeller addScriptPath() avec un chemin relatif au dossier courant. Ceci a pour effet de "namespacer" toutes les aides et les filtres de vue pour le module en cours.

A chaque postDispatch() d'action, render() est appelée.

Voici un exemple :

<?php
// Bar controller , module foo :
class Foo_BarController extends Zend_Controller_Action
{
    // Rend bar/index.phtml par défaut; rien à faire c'est automatique
    public function indexAction()
    {
    }

    // Rend bar/populate.phtml avec une variable 'foo' à la valeur 'bar'.
    // l'objet de vue est définit dans le preDispatch(), il est donc accessible.
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }
}

...

// Dans un des scripts de vue :
$this->foo(); // appelle Foo_View_Helper_Foo::foo()?>

        

Le ViewRenderer définit de même des accesseurs pour configurer la vue qu'il encapsule :

  • setView($view) Passage de l'objet de vue. Il devient accessible comme une propriété publique de l'objet : $view.

  • setNeverRender($flag = true) peut être utilisée pour désactiver le rendu automatique de la vue dans tous les contrôleurs. postDispatch() est alors court-circuitée. getNeverRender() retourne ce paramètre.

  • setNoRender($flag = true) peut être utilisée pour désactiver le rendu automatique de la vue dans le contrôleur actuel. postDispatch() est alors court-circuitée, mais preDispatch() réactive le paramètre pour l'action suivante. getNoRender() retourne cette option.

  • setNoController($flag = true) est utilisée pour spécifier à render() de ne pas chercher le script de vue dans le sous repertoire après le contrôleur (correspondant à l'action). Par défaut, cette recherche est effectuée. getNoController() retourne ce paramètre.

  • setNeverController($flag = true) fonctionne de manière similaire à setNoController(), mais pour tous les contrôleurs.getNeverController() est l'autre accesseur.

  • setScriptAction($name) peut être utiliséee pour spécifier le script de vue d'une action à rendre. $name doit être le nom de l'action sans le suffixe (et sans le nom du contrôleur sauf si noController a été activé). Si vous n'utilisez pas cette méthode elle cherchera le script de vue correspondant au nom de l'action en cours (issue de l'objet de requête). getScriptAction() retourne la valeur actuelle de ce paramètre.

  • setResponseSegment($name) dit dans quel segment de la réponse rendre le script. Par défaut, la vue est rendue dans le segment par défaut. getResponseSegment() retourne cete valeur.

  • initView($path, $prefix, $options) doit être appelée pour configurer la vue : son 'base path', le préfixe de classe pour les filtres et aides, et des options matérialisées par : neverRender, noRender, noController, scriptAction, et responseSegment.

  • setRender($action = null, $name = null, $noController = false) vous permet de spécifier les paramètres scriptAction, responseSegment, et noController en une fois. direct() est un alias qui permet un appel rapide depuis le contrôleur :

    // Rend 'foo' au lieu du script correspondant à l'action courante
    $this->_helper->viewRenderer('foo');
    
    // rend form.phtml dans le segment 'html' de la réponse sans utiliser le 
    // sous repertoire contrôleur pour chercher le script de vue :
    $this->_helper->viewRenderer('form', 'html', true);
    
                    

    Note: setRender() et direct() ne rendent pas un script de vue à proprement parler, mais elles notifient au postDispatch() de le faire.

Le constructeur de ViewRenderer accepte aussi un objet de vue et un tableau d'options, de la même manière que initView() :

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

        

Il est aussi possible de personnaliser les chemins utilisés pour determiner le base path (chemin de base) de la vue ainsi que le script path (chemin vers les scripts de vue). Des méthodes le permettent, utilisez les options suivantes avec :

  • :moduleDir représente le module courant (par convention le dossier parent au dossier contrôleur).

  • :module pointe vers le module actuel.

  • :controller pointe vers le contrôleur actuel.

  • :action représente l'action actuellement traitée.

  • :suffix est utilisée pour le suffixe du script de vue. setViewSuffix() permet aussi de le modifier.

Toutes ces options s'utilisent avec les méthodes ci-après :

  • setViewBasePathSpec($spec) vous permet de changer le dossier donnant accès aux dossiers de la vue : le base path. Par défaut il s'agit de :moduleDir/views. L'accesseur de récupération est getViewBasePathSpec().

  • setViewScriptPathSpec($spec) Une fois dans le base path, le rendu cherche le script de vue dans le script path, que cette méthode permet de définir. La valeur par défaut est :controller/:action.:suffix et l'autre accesseur est getViewScriptPathSpec().

  • setViewScriptPathNoControllerSpec($spec) Une fois dans le base path, si noController est activé, le rendu cherche le script de vue dans le chemin que cette méthode permet de définir. La valeur par défaut est :action.:suffix et l'autre accesseur est getViewScriptPathNoControllerSpec().

ViewRenderer utilise un inflecteur : Zend_Filter_Inflector, pour résoudre les options de chemin, en chemins réels. Pour une personnalisation maximale, vous pouvez intérragir avec cet inflécteur à l'aide des méthodes suivantes :

  • getInflector() retourne l'inflecteur. Si aucun n'existe, ViewRenderer en crée un avec des options par défaut.

    Par défaut, les règles de l'inflecteurs sont statiques autant pour le suffixe et le repertoire module, que pour la cible. Ceci permet au ViewRenderer de modifier ces valeurs dynamiquement.

  • setInflector($inflector, $reference) peut être utilisée pour passer son propre inflecteur à ViewRenderer. Si $reference est à true, alors le suffixe, le repertoire du module et la cible seront affectés en fonction des propriétés de ViewRenderer.

Note: Règles de résolution par défaut
Le ViewRenderer utilise certaines règles par défaut pour chercher ses scripts de vue, voyez plutôt :

  • :module : casseMélangée et motsCamelCase qui deviennent des mots séparés par des tirets, et en minuscule. "FooBarBaz" devient "foo-bar-baz".

    En interne, l'inflecteur utilise les filtres Zend_Filter_Word_CamelCaseToDash et Zend_Filter_StringToLower.

  • :controller : casseMélangée et motsCamelCase qui deviennent des mots séparés par des tiret; les underscores eux, se transforment en séparateur de dossier et tout est passé en minuscules. "FooBar" devient "foo-bar"; "FooBar_Admin" devient "foo-bar/admin".

    En interne, l'inflecteur utilise les filtres Zend_Filter_Word_CamelCaseToDash, Zend_Filter_Word_UnderscoreToSeparator, et Zend_Filter_StringToLower.

  • :action : casseMélangée et motsCamelCase qui se transforment en mots séparés par des tirets, minuscules. Les caractères non alphanumeriques deviennent des tirets. "fooBar" devient "foo-bar"; "foo-barBaz" devient "foo-bar-baz".

    Pour ceci, l'inflecteur interne utilise les filtres Zend_Filter_Word_CamelCaseToDash, Zend_Filter_PregReplace, et Zend_Filter_StringToLower.

Enfin, l'API ViewRenderer vous propose aussi des méthodes pour determiner les scripts de vue, et rendre la vue. Celles-ci se décomposent en :

  • renderScript($script, $name) va vous permettre de spécifier pleinement le script de vue à rendre, et éventuellement un nom de segment de réponse dans lequel rendre. ViewRenderer s'attend à un paramètre $script représentant un chemin complet vers un script de vue, tel que la méthode de la vue render() l'attend.

    Note: Une fois rendue, la vue utilise noRender pour éviter un double rendu automatisé.

    Note: Par défaut, Zend_Controller_Action::renderScript() est un proxy vers la méthode renderScript() de ViewRenderer.

  • getViewScript($action, $vars) récupère le chemin du script de vue en se basant sur les paramètres $action et $vars. $vars peut contenir 'moduleDir', 'module', 'controller', 'action', et 'suffix'), sinon les valeurs de la requête actuelle seront utilisées.

    getViewScript() utilisera viewScriptPathSpec ou viewScriptPathNoControllerSpec selon le paramètre noController.

    L'inflecteur sera utilisé, par défaut un contrôleur 'foo.bar' et une action 'baz:bat' amèneront à un script de vue 'foo-bar/baz-bat.phtml'.

    Note: Par défaut Zend_Controller_Action::getViewScript() est un proxy vers la méthode getViewScript() de ViewRenderer.

  • render($action, $name, $noController) a beaucoup de responsabilités : d'abord, elle vérifie si $name ou $noController lui ont été passés, si c'est le cas, elle configure correctement les paramètres responseSegment et noController dans le ViewRenderer. Elle passe ensuite $action, si spécifié, à getViewScript(). Enfin, elle passe le script de vue calculé à renderScript().

    Note: Attention aux effets secondaires avec render() : les valeurs segment de réponse, et noController vont persister dans l'objet ViewRenderer. De plus, noRender() va être appelée.

    Note: Par défaut, Zend_Controller_Action::render() est un proxy vers render() de ViewRenderer.

  • renderBySpec($action, $vars, $name) vous fournit le moyen de passer des paramètres de spécification pour le dossier de script de vue. Cette méthode passe $action et $vars à getScriptPath(), pour en déduire un chemin qu'elle envoie alors avec $name à renderScript().

Exemples

Exemple #9 Usage de base

L'utilisation la plus basique consiste à initialiser ou et enregistrer un objet ViewRenderer dans le gestionnaire d'aides (helper broker), et ensuite lui passer des variables dans vos contrôleurs.

<?php
// Dans le fichier de démarrage :
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');

...


// 'foo' module, contrôleur 'bar' :
class Foo_BarController extends Zend_Controller_Action
{
    // Rend bar/index.phtml par défaut, rien à faire
    public function indexAction()
    {
    }

    // Rend bar/populate.phtml avec la variable 'foo' à la valeur 'bar'.
    // L'objet de vue est rendu disponible en preDispatch().
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }

    // Ne rend rien, car on demande un nouveau jeton de dispatching
    public function bazAction()
    {
        $this->_forward('index');
    }

    // Ne rend rien, une redirection est demandée
    public function batAction()
    {
        $this->_redirect('/index');
    }
}?>
            

Note: Conventions de noms : délimiteurs de mots dans les noms de contrôleur et d'action
Si les noms de votre contrôleur ou de votre action sont composés de plusieurs mots, le dispatcheur s'attend à ce qu'ils soient séparés par des caractères bien définis, dans l'URL. Le ViewRenderer les transforme alors en '/' pour les chemins, ou tirets '-' pour les mots. Ainsi, un appel à /foo.bar/baz.bat dispatchera FooBarController::bazBatAction() dans FooBarController.php, et ceci rendra foo-bar/baz-bat.phtml. Un appel à /bar_baz/baz-bat dispatchera vers Bar_BazController::bazBatAction() dans Bar/BazController.php (notez la séparation du chemin), et rend bar/baz/baz-bat.phtml.
Notez dans le second exemple, le module est celui par défaut, mais comme un séparateur de chemin (underscore '_') est donné, alors le contrôleur dispatché devient Bar_BazController, dans Bar/BazController.php.

Exemple #10 Désactivation du rendu automatique

Il peut être nécéssaire dans certains cas de désactiver manuellement le rendu automatique de vue effectué par ViewRenderer. Par exemple, si le contrôleur doit retourner une sortie spéciale, comme XML ou JSON. Deux options s'offrent à vous : setNeverRender()) et setNoRender().

<?php
// Baz controller class, bar module :
class Bar_BazController extends Zend_Controller_Action
{
    public function fooAction()
    {
        // Ne rend pas automatiquement cette action
        $this->_helper->viewRenderer->setNoRender();
    }
}

// Bat controller class, bar module :
class Bar_BatController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // Ne rend plus aucune action de ce contrôleur
        $this->_helper->viewRenderer->setNoRender();
    }
}?>
            

Note: Utiliser setNeverRender()), pour désactiver totalement le rendu automatique de vue vous fera perdre un des avantages majeur de ViewRenderer.

Exemple #11 Choix d'un script de vue différent

Il peut arriver que vous éprouviez le besoin de rendre un script de vue différent de celui correspondant à l'action en cours de dispatching. Par exemple, un contrôleur qui possède deux actions ajout et édition, qui sont susceptibles toutes les deux de rendre le même script de vue. Utilisez alors setScriptAction(), setRender(), ou appelez l'aide ViewRenderer directement :

<?php
// Bar controller class, foo module :
class Foo_BarController extends Zend_Controller_Action
{
    public function addAction()
    {
        // Rend 'bar/form.phtml' plutôt que 'bar/add.phtml'
        $this->_helper->viewRenderer('form');
    }

    public function editAction()
    {
        // Rend 'bar/form.phtml' au lieu de 'bar/edit.phtml'
        $this->_helper->viewRenderer->setScriptAction('form');
    }

    public function processAction()
    {
        // un peu de validation...
        if (!$valid) {
            // Rend 'bar/form.phtml' à la place de 'bar/process.phtml'
            $this->_helper->viewRenderer->setRender('form');
            return;
        }

        // continue le processus...
    }

}?>
            

Exemple #12 Modification de l'objet de vue

Si vous désirez modifier l'objet de vue absorbé par ViewRenderer, pour par exemple ajouter un chemin vers des aides spécifique, ou spécifier l'encodage, vous pourriez par exemple récupérer l'objet de vue depuis le ViewRenderer, ou dans un contrôleur.

<?php
// Bar controller class, foo module :
class Foo_BarController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // change l'encodage de la vue
        $this->view->setEncoding('UTF-8');
    }

    public function bazAction()
    {
        // Récupère l'objet de vue, et lui passe la fonction d'echappement 'htmlspecialchars'
        $view = $this->_helper->viewRenderer->view;
        $view->setEscape('htmlspecialchars');
    }
}?>
            

Utilisation avancée

Exemple #13 Changement des specifications de dossier

Dans certains cas, il peut être nécéssaire d'utiliser un chemin absolu, fixe. Par exemple si vous ne donnez accès à vos graphistes qu'à un seul dossier, en utilisant un moteur de template tel que » Smarty.

Pour ceci, imaginons que le base path soit fixé à '/opt/vendor/templates', et que vous voulez que vos scripts de vues soit référencés par ':moduleDir/:controller/:action.:suffix'; si le paramètre noController est activé, vous désirez utiliser le dossier plus haut ':action.:suffix'. Enfin, vous désirez un suffixe en 'tpl' :

<?php
/**
 * Dans le fichier de démarrage :
 */

// Une implémentation personnalisée de la vue
$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);?>
            

Exemple #14 Rendu de plusieurs scripts de vue dans une même action

Afin de rendre plusieurs scripts de vue dans une même action, appelez tout simplement plusieurs fois render() :

<?php
class SearchController extends Zend_Controller_Action
{
    public function resultsAction()
    {
        // Considérons $this->model comme étant un modèle valide
        $this->view->results = $this->model->find($this->_getParam('query', '');

        // render() est proxiée vers ViewRenderer
        // Rend d'abord un formaulaire, puis un résultat
        $this->render('form');
        $this->render('results');
    }

    public function formAction()
    {
        // Rien : ViewRenderer rend automatiquement un script de vue
    }
}?>
            

Ecrire vos propres aides

Les aides d'action étendent Zend_Controller_Action_Helper_Abstract, une classe abstraite qui fournit l'interface basique et les fonctionnalités requises par le gestionnaire d'aide. Ceci inclue les méthodes suivantes :

  • setActionController() est utilisée pour paramétrer le contrôleur d'action courant.

  • init(), déclenchée par le gestionnaire d'aide à l'instanciation, peut être utilisée pour déclencher l'initialisation dans l'aide ; ceci peut être pratique pour remettre dans l'état initial quand de multiples contrôleurs utilisent la même aide dans des actions enchaînées.

  • preDispatch(), est déclenchée avant le dispatchage d'une action.

  • postDispatch() est déclenchée quand une action a été dispatchée - même si un plugin preDispatch() a évité l'action. Principalement utile pour le nettoyage.

  • getRequest() récupère l'objet de requête courant.

  • getResponse() récupère l'objet de réponse courant.

  • getName() récupère le nom de l'aide. Elle récupère la portion du nom de la classe qui suit le dernier tiret bas ("_"), ou le nom de la classe entier sinon. Pour exemple, si la classe est nommée Zend_Controller_Action_Helper_Redirector, elle retourne Redirector ; une classe nommée FooMessage retournera FooMessage.

Vous pouvez optionnellement inclure une méthode direct() dans votre classe d'aide. Si défini, ceci vous permet de traiter l'aide comme une méthode du gestionnaire, dans le but de faciliter un usage unique de l'aide. Pour exemple, l'aide redirector définit direct() comme un alias de goto(), vous permettant d'utiliser l'aide comme ceci :

<?php
// Redirige vers /blog/view/item/id/42
$this->_helper->redirector('item', 'view', 'blog', array('id' => 42));
        

En interne, la méthode __call() du gestionnaire d'aide cherche une aide nommée redirector, puis vérifie si cette aide possède une méthode direct, et enfin appelle cette méthode avec les arguments fournis.

Une fois que vous avez créé vos propres classes d'aide, vous pouvez en fournir l'accès comme décrit dans les sections ci-dessus.


Contrôleurs d'action
blog comments powered by Disqus

Select a Version

Languages Available

Components

Search the Manual