# O Front Controller

## Resumo

`Zend_Controller_Front` implementa um padrão Front Controller usado nas aplicações Model-View-Controller (MVC). Seu objetivo é inicializar o ambiente de requisição, roterizar as requisições que chegam, e despachalas para quaquel ações descobertas; ele agrega alguma resposta e devolve-os quando o processo é completo.

`Zend_Controller_Front` também implementa o padrão Singleton , signicando que somente uma instancia dele pode estar disponivel em qualquer tempo. Isto permite que ele atue também como um registro em que outros objetos no processo de despacho possam usar.

`Zend_Controller_Front` registra uma plugin de entrada que por si só, permite que vários eventos sejam disparados para outros plugins observadores. Em muitos casos, isto permite ao desenvolvedor a oportunidade para mudar o processo de despacho do site sem a necessidade de extender o controlador de frente para adicionar funcionalidade.

O mínimo necessário, que o controlador de frente necessita é um ou mais caminho para os diretórios contendo os controles de ação para poder fazer seu trabalho. Vários metódos também podem ser invocados para mudar o ambiente do controlador de frente e suas classe auxiliares.

### Comportamento padrão

Por padrão, o controlador de frente carrega o ErrorHandler plugin, bem como o ViewRenderer plugin de ação auxiliar. Faz isto para simplificar o controle de erro e a apresentação de visulizadores em seus controles, repectivamente.

Para desabilitar o `ErrorHandler`, execute a seguinte chamada em qualquer ponto antes de chamar `dispatch()`:

    <?php
    // Disable the ErrorHandler plugin:
    $front->setParam('noErrorHandler', true);

Para desabilitar o `ViewRenderer`, faça o seguinte antes de chamar `dispatch()`:

    <?php
    // Disable the ViewRenderer helper:
    $front->setParam('noViewRenderer', true);

## Metódos Primários

O controlador de frente possuí vários acessores para configurar seu ambiente. Entretanto existem três metódos chaves primários da funcionalidades do controlador de frente:

### getInstance()

`getInstance()` é usado para retirar a instancia do controlador de frente. Como o controlador de frente implementa o padrão Singleton, isto também é a unica maneira possível de instanciar um objeto controlador de frente.

    <?php
    $front = Zend_Controller_Front::getInstance();

### setControllerDirectory() and addControllerDirectory

`setControllerDirectory()` é usado para dizer ao despachador onde procurar os arquivos da classes dos controladores de ação. Ele aceita tanto um caminho único ou um array associativo com pares módulo/caminho.

Alguns exemplos:

    // Set the default controller directory:
    $front->setControllerDirectory('../application/controllers');

    // Set several module directories at once:
    $front->setControllerDirectory(array(
        'default' => '../application/controllers',
        'blog'    => '../modules/blog/controllers',
        'news'    => '../modules/news/controllers',
    ));

    // Add a 'foo' module directory:
    $front->addControllerDirectory('../modules/foo/controllers', 'foo');

Se você usar `addControllerDirectory()` sem um nome de módulo, ele irá configurar o diretório para o módulo `padrão` -- sobrescrevendo-o se ele já existir.

Você pode pegar a configuração corrente do diretório do controlador usando `getControllerDirectory()`; isto irá retornar um array de pares módulo/diretório.

### dispatch()

`dispatch(Zend_Controller_Request_Abstract $request = null, Zend_Controller_Response_Abstract $response = null)` faz o trabalho pesado do controlador de frente. Ele pode opcionalmente pegar um objeto de requisição e/ou um objeto de resposta, permitindo ao desenvolvedor passar a ele objetos personalizados de cada.

Se nenhum objeto de requisição ou resposta for passado, `dispatch()` irá procurar por objetos previamente registrados e usa-los ou instanciar versões padrão para usar em seus processos (em ambos os casos, o HTTP será usado como padrão).

Similarmente, `dispatch()` checa por uma router registrada e um objetos de dispacho, instanceando a versão padrão de cada um deles se não encontrar nenhum.

O processo de dispacho possui três eventos distintos:

- Roterização

- Despacho

- Resposta

A Roterização realiza-se exatamente uma vez, usando os valores no objeto de requisicão quando `dispatch()` é chamado. O Despacho ocorre em um laço; uma requisição pode tanto indicar multiplas ações para dispachar, ou o controlador ou um plugin pode reiniciar o objeto de requisição para forçar ações adicionais para o despacho. Quando tudo está pronto, o controlador de frente retorna uma resposta.

### run()

`Zend_Controller_Front::run($path)` é um método estático que toma simplesmente um caminho para um diretório contendo os controladores. Ele

`Zend_Controller_Front::run($path)` is a static method taking simply a path to a directory containing controllers. Ele traz um exemplo de controlador de frente (via getInstance(), registra o caminho fornecido via setControllerDirectory(), e finalmente dispacha.

Basicamente, `run()` é um método de conveniência que pode ser usado para configurações de sítios que não necessitam de customizações no ambiente de controle de frente.

    <?php
    // Instantiate front controller, set controller directory, and dispatch in one
    // easy step:
    Zend_Controller_Front::run('../application/controllers');

## Métodos Acessores Ambientais

Além dos métodos enumerados em cima, há um número de os métodos acessores que podem ser usados para afetar o ambiente do controlador de frente - e assim o ambiente das classes em que o controlador de frente delega.

- `resetInstance()` pode ser usado para limpar todas as configurações atualmente definidas. Seu propósito inicial é para teste, mas ele também pode ser usado para intâncias onde você deseja encadear um conjunto de múltiplos controladores de frente.

- `(set|get)DefaultControllerName()` permite a você específicar um nome difetente para usar no controlador padrão ('index' é usado de outra maneira) e recuperar o valor atual. Eles apontaram para o o despachante.

- `(set|get)DefaultActionName()` permite a você epecíficar um nome diferente para ser usado na ação padrão ('index' é usado por padrão) e recuperar o valor atual. Eles apontãm para o despachante.

- `(set|get)Request()` permite a você específicar a classe de pedido ou objeto para usar durente o processo de despacho e para recuperar o objeto atual. Ao configurar o objeto de requisição, você pode passar uma nome de classe de requisição, neste caso o metódo irá carregar o arquivo da classe e instancia-la.

- `(set|get)Router()` permite a você especificar o objeto ou classe roteador(a) para usar durante o processo de dispacho e para recuperar o objeto atual. Quando estiver definindo o objeto roteador, você pode passar o nome de uma classe roteadora e neste caso o metódo roteado irá carregar o arquivo da classe e instancia-la.

  Quando recuperá o objeto roteador, ele primeiro verifica se já existe um, se não, instanceia o reteador padrão (roteador re-escrito).

- `(set|get)BaseUrl()` let you specify the base URL to strip when routing requests and to retrieve the current value. The value is provided to the request object just prior to routing.

- `(set|get)Dispatcher()` let you specify the dispatcher class or object to use during the dispatch process and retrieve the current object. When setting the dispatcher object, you may pass in a dispatcher class name, in which case the method will load the class file and instantiate it.

  When retrieving the dispatcher object, it first checks to see if one is present, and if not, instantiates the default dispatcher.

- `(set|get)Response()` let you specify the response class or object to use during the dispatch process and to retrieve the current object. When setting the response object, you may pass in a response class name, in which case the method will load the class file and instantiate it.

- `registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null)` allows you to register a plugin objects. By setting the optional `$stackIndex`, you can control the order in which plugins will execute.

- `unregisterPlugin($plugin)` let you unregister plugin objects. `$plugin` may be either a plugin object or a string denoting the class of plugin to unregister.

- `throwExceptions($flag)` is used to turn on/off the ability to throw exceptions during the dispatch process. By default, exceptions are caught and placed in the response object; turning on `throwExceptions()` will override this behaviour.

  For more information, read .

- `returnResponse($flag)` is used to tell the front controller whether to return the response (`true`) from `dispatch()`, or if the response should be automatically emitted (`false`). By default, the response is automatically emitted (by calling `Zend_Controller_Response_Abstract::sendResponse()`); turning on `returnResponse()` will override this behaviour.

  Reasons to return the response include a desire to check for exceptions prior to emitting the response, needing to log various aspects of the response (such as headers), etc.

## Front Controller Parameters

In the introduction, we indicated that the front controller also acts as a registry for the various controller components. It does so through a family of "param" methods. These methods allow you to register arbitrary data -- objects and variables -- with the front controller to be retrieved at any time in the dispatch chain. These values are passed on to the router, dispatcher, and action controllers. The methods include:

- `setParam($name, $value)` allows you to set a single parameter of `$name` with value `$value`.

- `setParams(array $params)` allows you to set multiple parameters at once using an associative array.

- `getParam($name)` allows you to retrieve a single parameter at a time, using `$name` as the identifier.

- `getParams()` allows you to retrieve the entire list of parameters at once.

- `clearParams()` allows you to clear a single parameter (by passing a string identifier), multiple named parameters (by passing an array of string identifiers), or the entire parameter stack (by passing nothing).

There are several pre-defined parameters that may be set that have specific uses in the dispatch chain:

- `useDefaultControllerAlways` is used to hint to the dispatcher to use the default controller in the default module for any request that is not dispatchable (i.e., the module, controller, and/or action do not exist). By default, this is off.

  See for more detailed information on using this setting.

- `disableOutputBuffering` is used to hint to the dispatcher that it should not use output buffering to capture output generated by action controllers. By default, the dispatcher captures any output and appends it to the response object body content.

- `noViewRenderer` is used to disable the ViewRenderer. Set this parameter to true to disable it.

- `noErrorHandler` is used to disable the Error Handler plugin. Set this parameter to true to disable it.

## Subclassing the Front Controller

To subclass the Front Controller, at the very minimum you will need to override the `getInstance()` method:

    class My_Controller_Front extends Zend_Controller_Front
    {
        public static function getInstance()
        {
            if (null === self::$_instance) {
                self::$_instance = new self();
            }

            return self::$_instance;
        }
    }

Overriding the `getInstance()` method ensures that subsequent calls to `Zend_Controller_Front::getInstance()` will return an instance of your new subclass instead of a `Zend_Controller_Front` instance -- this is particularly useful for some of the alternate routers and view helpers.

Typically, you will not need to subclass the front controller unless you need to add new functionality (for instance, a plugin autoloader, or a way to specify action helper paths). Some points where you may want to alter behaviour may include modifying how controller directories are stored, or what default router or dispatcher are used.