<?xml version="1.0" encoding="UTF-8"?>
    <!-- EN-Revision: 24249 -->
    <!-- Reviewed: no -->
<sect1 id="zend.controller.dispatcher">
    <title>El Despachador</title>

    <sect2 id="zend.controller.dispatcher.overview">
        <title>Introducción</title>

        <para>
            Despachar es el proceso de tomar el objeto solicitud,
            <classname>Zend_Controller_Request_Abstract</classname>
            ,
            extraer el nombre del módulo, el nombre del controlador, el nombre
            de la acción, y los
            parámetros opcionales contenido en él, y luego
            instanciar un controlador y llamar una
            acción de ese controlador.
            Si no se encuentra algún módulo, controlador o acción, se
            usarán
            los valores por defecto para ellos.
            <classname>Zend_Controller_Dispatcher_Standard</classname>
            especifica
            <emphasis>index</emphasis>
            para cada uno de los controladores y
            acciones por defecto y
            <emphasis>default</emphasis>
            para el valor por
            defecto del módulo, pero permite al desarrollador cambiar los
            valores
            por defecto para cada uno usando los métodos
            <methodname>setDefaultController()</methodname>
            ,
            <methodname>setDefaultAction()</methodname>
            , y
            <methodname>setDefaultModule()</methodname>
            respectivamente.
        </para>

        <note>
            <title>Módulo por Defecto</title>

            <para>
                Cuando se crean aplicaciones modulares, puede encontrarse
                queriendo también el
                namespace por defecto del módulo (la
                configuración por defecto es que el módulo por
                defecto es
                <emphasis>no</emphasis>
                namespaced).
                Como de 1.5.0, ahora puede hacerlo especificando el
                <emphasis>prefixDefaultModule</emphasis>
                como
                <constant>TRUE</constant>
                tanto en el
                front controller como es su despachador:
            </para>

            <programlisting language="php"><![CDATA[
// En su front controller:
$front->setParam('prefixDefaultModule', true);

// En su despachador:
$dispatcher->setParam('prefixDefaultModule', true);
]]></programlisting>

            <para>
                Esto le permite re-determinar un módulo existente para ser el
                módulo por defecto
                para una solicitud.
           </para>
        </note>

        <para>
            El proceso de despachar tiene lugar en un bucle en el front controller.
            Antes de
            llevarse a cabo el despacho, el front controller rutea la
            solicitud para encontrar
            valores especificados por el usuario para
            el módulo, controlador, acción, y los
            parámetros opcionales.
            A continuación entra en un loop de despacho, despachando la
            solicitud.
       </para>

        <para>
            Al comienzo de cada iteración, establece un flag en el objeto
            solicitud indicando que
            la acción se ha despachado.
            Si una acción o un plugin pre o postDispatch resetea ese
            flag,
            el loop de despacho continuará e intentará despachar la nueva
            solicitud. Cambiando
            el controlador y/o la acción en la solicitud y
            reseteando el flag despachado, el
            desarrollador puede definir
            una cadena de peticiones a realizar.
       </para>

        <para>
            El método del controlador de acción que controla ese despacho es
            <methodname>_forward()</methodname>
            ; llamar a este método para cualquiera de los
            pre/postDispatch() o métodos de acción,
            proporcionando un
            controlador de acciónes, módulo y, opcionalmente cualquier parámetro
            adicional que desee enviar a la nueva acción:
        </para>

        <programlisting language="php"><![CDATA[
public function fooAction()
{
    // adelantar a otra acción en el controlador y módulo actuales:
    $this->_forward('bar', null, null, array('baz' => 'bogus'));
}

public function barAction()
{
    // adelantar a una acción en otro controlador:
    // FooController::bazAction(),
    // en el módulo actual:
    $this->_forward('baz', 'foo', null, array('baz' => 'bogus'));
}

public function bazAction()
{
    // adelantar a una acción en otro controlador en otro módulo,
    // Foo_BarController::bazAction():
    $this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus'));
}
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.dispatcher.subclassing">
        <title>Subclaseando el Despachador</title>

        <para>
            <classname>Zend_Controller_Front</classname>
            llamará en primer lugar
            al router para determinar la primera acción en la solicitud.
            A
            continuación se entra en un loop de despacho, el cual llama al
            despachador para despachar
            la acción.
        </para>

        <para>
            El despachador necesita de una variedad de datos a fin de hacer su
            trabajo - necesita
            saber cómo formatear los nombres del controlador
            y de la acción, dónde mirar para los
            archivos de clase del
            controlador, cuándo el nombre de un controlador provisto es válido
            o no, y una
            <acronym>API</acronym>
            para determinar si una determinada solicitud es
            incluso despachable basado en la otra
            información disponible.
        </para>

        <para>
            <classname>Zend_Controller_Dispatcher_Interface</classname>
            define los siguientes métodos como necesarios para cualquier
            implementación de un
            despachador:
        </para>

        <programlisting language="php"><![CDATA[
interface Zend_Controller_Dispatcher_Interface
{
    /**
     * Formatea un string dentro del nombre de clase del controlador.
     *
     * @param string $unformatted
     * @return string
     */
    public function formatControllerName($unformatted);

    /**
     * Formatea un string dentro de un nombre de método de acción.
     *
     * @param string $unformatted
     * @return string
     */
    public function formatActionName($unformatted);

    /**
     * Determina si la solicitud es despachable
     *
     * @param  Zend_Controller_Request_Abstract $request
     * @return boolean
     */
    public function isDispatchable(
        Zend_Controller_Request_Abstract $request
    );

    /**
     * Establece un parámetro de usuario (via front controller, o para uso local)
     *
     * @param string $name
     * @param mixed $value
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function setParam($name, $value);

    /**
     * Establece un array de parámetros de usuario
     *
     * @param array $params
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function setParams(array $params);

    /**
     * Recupera un único parámetro de usuario
     *
     * @param string $name
     * @return mixed
     */
    public function getParam($name);

    /**
     * Recupera todos los parámetros de usuario
     *
     * @return array
     */
    public function getParams();

    /**
     * Limpia el stack de parámetros de usuario, o un único parámetro de usuario
     *
     * @param null|string|array single key or array of keys for
     *        params to clear
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function clearParams($name = null);

    /**
     * Establece el objeto respuesta a usar, si hubiera alguno
     *
     * @param Zend_Controller_Response_Abstract|null $response
     * @return void
     */
    public function setResponse(
        Zend_Controller_Response_Abstract $response = null
    );

    /**
     * Recupera el objeto respuesta, si hubiera alguno
     *
     * @return Zend_Controller_Response_Abstract|null
     */
    public function getResponse();

    /**
     * Agrega un directorio de controladoes al stack de directorios de controladores
     *
     * @param string $path
     * @param string $args
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function addControllerDirectory($path, $args = null);

    /**
     * Establece el directorio (o directorios) donde se almacenan los archivos
     * de controladoes
     *
     * @param string|array $dir
     * @return Zend_Controller_Dispatcher_Interface
     */
    public function setControllerDirectory($path);

    /**
     * Regresa el directorio(s) actualmente establecido para el lookup de los
     * archivos de controladores
     *
     * @return array
     */
    public function getControllerDirectory();

    /**
     * Despacha una solicitud a una acción de (módulo/)controlador.
     *
     * @param  Zend_Controller_Request_Abstract $request
     * @param  Zend_Controller_Response_Abstract $response
     * @return Zend_Controller_Request_Abstract|boolean
     */
    public function dispatch(
        Zend_Controller_Request_Abstract $request,
        Zend_Controller_Response_Abstract $response
    );

    /**
     * Si un módulo dado es válido o no
     *
     * @param string $module
     * @return boolean
     */
    public function isValidModule($module);

    /**
     * Recuperar el nombre por defecto del módulo
     *
     * @return string
     */
    public function getDefaultModule();

    /**
     * Recuperar el nombre por defecto del controlador
     *
     * @return string
     */
    public function getDefaultControllerName();

    /**
     * Recuperar la acción por defecto
     *
     * @return string
     */
    public function getDefaultAction();
}
]]></programlisting>

        <para>
            En muchos casos, sin embargo, simplemente debe extender la clase
            abstracta
            <classname>Zend_Controller_Dispatcher_Abstract</classname>
            ,
            en el que cada uno de estas ya han sido definidas, o
            <classname>Zend_Controller_Dispatcher_Standard</classname>
            para modificar la funcionalidad del despachador estándar.
        </para>

        <para>
            Las posibles razones para subclasear al despachador incluye un
            deseo de utilizar un
            esquema diferente para nombrar las clases o
            métodos en sus controladores de acción, o el
            deseo de utilizar otro
            paradigma de despacho como ser despachar los archivos de acción
            bajo directorios de controladores (en lugar de despacharlos a los
            métodos de clase).
       </para>
    </sect2>
</sect1>
    <!--
vim:se ts=4 sw=4 et:
-->
