| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.controller.front">
- <title>El Front Controller</title>
- <sect2 id="zend.controller.front.overview">
- <title>Introducción</title>
- <para>
- <classname>Zend_Controller_Front</classname> implementa un <ulink
- url="http://www.martinfowler.com/eaaCatalog/frontController.html"
- >Front Controller pattern</ulink> usado en aplicaciones <ulink
- url="http://en.wikipedia.org/wiki/Model-view-controller"
- >Model-View-Controller (MVC)</ulink> . Su propósito es
- inicializar el entorno de la solicitud, rutear la solicitud
- entrante, y luego hacer un envío de cualquier de las acciones
- descubiertas; le agrega las respuestas y las regresa cuando se
- completa el proceso. </para>
- <para>
- <classname>Zend_Controller_Front</classname> también implementa el
- <ulink url="http://en.wikipedia.org/wiki/Singleton_pattern"
- >Singleton pattern</ulink> , significando que solo una única
- instancia de él puede estar disponible en cualquier momento dado.
- Esto le permite actuar también como un registro en el que los demás
- objetos pueden extraer del proceso dispatch. </para>
- <para>
- <classname>Zend_Controller_Front</classname> registra un <link
- linkend="zend.controller.plugins">plugin broker</link> consigo
- mismo, permitiendo que diversos eventos que dispara sean observados
- por plugins. En muchos casos, esto da el desarrollador la
- oportunidad de adaptar el proceso de dispatch al sitio sin la
- necesidad de ampliar el Front Controller para añadir funcionalidad. </para>
- <para> Como mínimo, el front controller necesita una o más paths a
- directorios que contengan <link linkend="zend.controller.action">
- action controllers</link> a fin de hacer su trabajo. Una
- variedad de métodos también pueden ser invocados para seguir
- adaptando el medio ambiente del front controller y ese a sus helper
- classes. </para>
- <note>
- <title>Comportamiento por Defecto</title>
- <para> Por defecto, el front controller carga el <link
- linkend="zend.controller.plugins.standard.errorhandler"
- >ErrorHandler</link> plugin, así como al <link
- linkend="zend.controller.actionhelpers.viewrenderer"
- >ViewRenderer</link> action helper plugin. Estos son para
- simplificar el manejo de errores y el view renderering en sus
- controladores, respectivamente. </para>
- <para> Para deshabilitar el <emphasis>ErrorHandler</emphasis> ,
- ejecutar lo siguiente en cualquier momento antes de llamar a
- <methodname>dispatch()</methodname> : </para>
- <programlisting language="php"><![CDATA[
- // Deshabilitar el ErrorHandler plugin:
- $front->setParam('noErrorHandler', true);
- ]]></programlisting>
- <para> Para deshabilitar el <emphasis>ViewRenderer</emphasis> , haga
- lo siguiente antes de llamar a
- <methodname>dispatch()</methodname> : </para>
- <programlisting language="php"><![CDATA[
- // Deshabilitar el ViewRenderer helper:
- $front->setParam('noViewRenderer', true);
- ]]></programlisting>
- </note>
- </sect2>
- <sect2 id="zend.controller.front.methods.primary">
- <title>Métodos Básicos</title>
- <para>El front controller tiene varios accessors para establecer su
- medio ambiente. Sin embargo, hay tres métodos básicos clave para la
- funcionalidad del front controller:</para>
- <sect3 id="zend.controller.front.methods.primary.getinstance">
- <title>getInstance()</title>
- <para>
- <methodname>getInstance()</methodname> se utiliza para recuperar
- una instancia del front controller. Como el front controller
- implementa un patrón Singleton, este también es el único medio
- posible para instanciar un objeto front controller. </para>
- <programlisting language="php"><![CDATA[
- $front = Zend_Controller_Front::getInstance();
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.setcontrollerdirectory">
- <title>setControllerDirectory() y addControllerDirectory</title>
- <para>
- <methodname>setControllerDirectory()</methodname> se usa para
- decirle a <link linkend="zend.controller.dispatcher">el
- dispatcher</link> dónde buscar para los archivos de clase
- <link linkend="zend.controller.action">action
- controller</link> . Acepta bien un único path o un array
- asociativo de pares módulo/path. </para>
- <para>Como algunos ejemplos:</para>
- <programlisting language="php"><![CDATA[
- // Establer el directorio de controladores por defecto:
- $front->setControllerDirectory('../application/controllers');
- // Establecer varios directorios módulos a la vez:
- $front->setControllerDirectory(array(
- 'default' => '../application/controllers',
- 'blog' => '../modules/blog/controllers',
- 'news' => '../modules/news/controllers',
- ));
- // Agregar un directorio de módulos 'foo':
- $front->addControllerDirectory('../modules/foo/controllers', 'foo');
- ]]></programlisting>
- <note>
- <para> Si usa <methodname>addControllerDirectory()</methodname>
- sin un nombre de módulo, este establecerá el directorio
- <emphasis>default</emphasis> para el módulo --
- sobreescribiéndolo si ya existe. </para>
- </note>
- <para> Puede conseguir la configuración actual para el directorio
- del controlador utilizando
- <methodname>getControllerDirectory()</methodname> ; este
- devolverá un array de pares módulo y directorio. </para>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.addmoduledirectory">
- <title>addModuleDirectory() y getModuleDirectory()</title>
- <para> Uno de los aspectos del front controller es que puede <link
- linkend="zend.controller.modular"> definir una estructura
- modular de directorio</link> para crear componentes
- standalone; estos son llamados "módulos". </para>
- <para> Cada módulo debe estar en su propio directorio y ser un
- espejo de la estructura del directorio del módulo por defecto --
- es decir, que debería tener como mínimo un subdirectorio de
- <filename>/controllers/</filename> , y típicamente un
- subdirectorio de <filename>/views/</filename> y otros
- subdirectorios de aplicaciones. </para>
- <para>
- <methodname>addModuleDirectory()</methodname> permite pasar el
- nombre de un directorio que contiene uno o más directorios de
- módulos. A continuación lo analiza y los añade como directorios
- de controladores al front controller. </para>
- <para> Después, si quiere determinar el path a un determinado módulo
- o al módulo actual, puede llamar a
- <methodname>getModuleDirectory()</methodname> ,
- opcionalmente puede pasar un nombre de módulo para conseguir el
- directorio de ese módulo específico. </para>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.dispatch">
- <title>dispatch()</title>
- <para>
- <methodname>dispatch(Zend_Controller_Request_Abstract $request =
- null, Zend_Controller_Response_Abstract $response =
- null)</methodname> hace el trabajo pesado del front
- controller. Puede opcionalmente tomar un <link
- linkend="zend.controller.request">request object</link> y/o
- un <link linkend="zend.controller.response">response
- object</link> , permitiendo al desarrollador pasar objetos
- peronalizados para cada uno. </para>
- <para> Si no se pasa ningun objeto solicitud o respuesta,
- <methodname>dispatch()</methodname> comprobará por objetos
- previamente registrados y utilizará esos o instanciará versiones
- por defecto a utilizar en su proceso (en ambos casos, el sabor
- de <acronym>HTTP</acronym> será utilizado por defecto). </para>
- <para> Similarmente, <methodname>dispatch()</methodname> comprueba
- los objetos registrados <link linkend="zend.controller.router"
- >router</link> y <link linkend="zend.controller.dispatcher"
- >dispatcher</link> , instanciando las versiones por defecto
- de cada uno si ninguno de ellos se encuentra. </para>
- <para>El proceso de dispatch tiene tres eventos distintos:</para>
- <itemizedlist>
- <listitem>
- <para>Routing</para>
- </listitem>
- <listitem>
- <para>Dispatching</para>
- </listitem>
- <listitem>
- <para>Response</para>
- </listitem>
- </itemizedlist>
- <para> El routing se lleva a cabo exactamente una vez, utilizando
- los valores del objeto solicitud cuando se llama a
- <methodname>dispatch()</methodname> . El dispatching se
- lleva a cabo en un bucle; una solicitud puede indicar, bien
- múltiples acciones de dispatch, o el controlador o un plugin
- pueden restablecer el objeto solicitud para forzar medidas
- adicionales para dispatch. Cuando todo está hecho, el front
- controller devuelve una respuesta. </para>
- </sect3>
- <sect3 id="zend.controller.front.methods.primary.run">
- <title>run()</title>
- <para>
- <methodname>Zend_Controller_Front::run($path)</methodname> es un
- método estático que toma simplemente un path a un directorio que
- contiene controladores. Obtiene una instancia del front
- controller (via <link
- linkend="zend.controller.front.methods.primary.getinstance"
- >getInstance()</link> , registra el path provisto via <link
- linkend="zend.controller.front.methods.primary.setcontrollerdirectory"
- >setControllerDirectory()</link> , y finalmente <link
- linkend="zend.controller.front.methods.primary.dispatch"
- >dispatches</link> . </para>
- <para> Básicamente, <methodname>run()</methodname> es un método
- conveniente que pueden utilizarse para setups de sitios que no
- requieran la personalización del medio ambiente del front
- controller. </para>
- <programlisting language="php"><![CDATA[
- // Instanciar el front controller, establecer el directorio de controladores,
- // y hacer el dispatch fácilmente en en un solo paso:
- Zend_Controller_Front::run('../application/controllers');
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.controller.front.methods.environment">
- <title>Métodos Accessor Ambientales</title>
- <para>Además de los métodos enumerados anteriormente, hay una serie de
- métodos accessor que pueden utilizarse para afectar el entorno del
- front controller -- y por lo tanto el ambiente de las clases a las
- cuales delega el front controller.</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>resetInstance()</methodname> puede ser utilizada
- para borrar todos los settings actuales. Su objetivo
- principal es para testing, pero también puede ser utilizada
- para instancias donde desee encadenar múltiples front
- controllers. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>(set|get)DefaultControllerName()</methodname>
- permite especificar un nombre diferente para usar en el
- controlador por defecto (en caso coontrario, se usa 'index')
- y recuperar el valor actual. Delegan a <link
- linkend="zend.controller.dispatcher">el
- dispatcher</link> . </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setDefaultAction()</methodname> y
- <methodname>getDefaultAction()</methodname> le deja
- especificar un nombre diferente a utilizar para la acción
- predeterminada (en caso coontrario, se usa 'index') y
- recuperar el valor actual. Delegan a <link
- linkend="zend.controller.dispatcher">el
- dispatcher</link> . </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setRequest()</methodname> y
- <methodname>getRequest()</methodname> le permite
- especificar la clase u objeto <link
- linkend="zend.controller.request">el request</link> a
- usar durante el proceso de dispatch y recuperar el objeto
- actual. Al setear el objeto solicitud, puede pasarlo en un
- nombre de clase de solicitud, en cuyo caso el método va a
- cargar el archivo clase y lo instanciará. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setRouter()</methodname>
- <methodname>getRouter()</methodname> le permite especificar
- la clase u objeto <link linkend="zend.controller.router">el
- router</link> a usar durante el proceso de dispatch y
- recuperar el objeto actual. Al setear el objeto router,
- puede pasarlo en un nombre de clase de router, en cuyo caso
- el método va a cargar el archivo clase y lo instanciará. </para>
- <para>Al recuperar el objeto router, en primer lugar comprueba
- para ver si hay alguno presente, y si no, instancia al
- router por defecto(reescribe el router). </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setBaseUrl()</methodname> y
- <methodname>getBaseUrl()</methodname> le permite
- especificar <link
- linkend="zend.controller.request.http.baseurl">la URL
- base</link> de la cual tirar cuando se rutean peticiones
- y recuperar el valor actual. El valor se provee al objeto
- solicitud justo antes de rutear. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setDispatcher()</methodname> y
- <methodname>getDispatcher()</methodname> le permite
- especificar la clase u objeto <link
- linkend="zend.controller.dispatcher">el
- dispatcher</link> a usar durante el proceso de dispatch
- y recuperar el objeto actual. Al setear el objeto dispatch,
- puede pasarlo en un nombre de clase de dispatcher, en cuyo
- caso el método va a cargar el archivo clase y lo
- instanciará. </para>
- <para>Al recuperar el objeto dispatch, en primer lugar comprueba
- para ver si hay alguno presente, y si no, instancia al
- dispatcher por defecto.</para>
- </listitem>
- <listitem>
- <para>
- <methodname>setResponse()</methodname> y
- <methodname>getResponse()</methodname> le permite
- especificar la clase u objeto <link
- linkend="zend.controller.response">response</link> a
- usar durante el proceso de dispatch y recuperar el objeto
- actual. Al setear el objeto response, puede pasarlo en un
- nombre de clase de response, en cuyo caso el método va a
- cargar el archivo clase y lo instanciará. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>registerPlugin(Zend_Controller_Plugin_Abstract
- $plugin, $stackIndex = null)</methodname> le permite
- registrar <link linkend="zend.controller.plugins">plugin
- objects</link> . Opcionalmente, setting
- <varname>$stackIndex</varname> , puede controlar el
- orden en que se ejecutarán los plugins. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>unregisterPlugin($plugin)</methodname> le
- permite desregistrar <link linkend="zend.controller.plugins"
- >plugin objects</link> . <varname>$plugin</varname>
- puede ser tanto un objeto plugin o un string que denota la
- clase de plugin a desregistrar. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>throwExceptions($flag)</methodname> se utiliza
- para activar o desactivar la capacidad de arrojar
- excepciones durante el proceso de dispatch. Por defecto, las
- excepciones son capturadas y colocadas en el <link
- linkend="zend.controller.response">objeto response
- </link> ; activando
- <methodname>throwExceptions()</methodname> se anulará
- este comportamiento. </para>
- <para> Para más información, lea <xref
- linkend="zend.controller.exceptions"/> MVC
- Exceptions </para>
- </listitem>
- <listitem>
- <para>
- <methodname>returnResponse($flag)</methodname> se usa para
- decirle al front controller cuando regresar la respuesta (
- <constant>TRUE</constant> ) desde
- <methodname>dispatch()</methodname> , o si la respuesta
- debe ser emitida automáticamente (
- <constant>FALSE</constant> ). Por defecto, la respuesta
- es automáticamente emitida (llamando a
- <methodname>Zend_Controller_Response_Abstract::sendResponse()</methodname>
- ); activando <methodname>returnResponse()</methodname> ) se
- anulará este comportamiento. </para>
- <para>Las razones para regresar la respuesta incluyen un deseo
- de comprobar las excepciones antes de emitir la respuesta,
- necesidad de hacer un log de diversos aspectos de la
- respuesta (tales como cabeceras), etc.</para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.controller.front.methods.params">
- <title>Parámetros de Front Controller</title>
- <para>En la introducción, se indicó que el front controller también
- actúa como un registro de los distintos componentes del controlador.
- Lo hace mediante una familia de métodos "param". Estos métodos le
- permiten registrar datos arbitrarios -- objetos y variables -- con
- el front controller, a ser devueltos en cualquier momento en la
- cadena de dispatch. Estos valores se transmiten al router, al
- dispatcher, y a los action controllers. Los métodos incluyen:</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>setParam($name, $value)</methodname> permite
- establecer un único parámetro de <varname>$name</varname>
- con el valor <varname>$value</varname> . </para>
- </listitem>
- <listitem>
- <para>
- <methodname>setParams(array $params)</methodname> permite
- configurar varios parámetros a la vez usando un array
- asociativo. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getParam($name)</methodname> permite recuperar
- un único parámetro a la vez, utilizando como identificador a
- <varname>$name</varname> . </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getParams()</methodname> permite recuperar toda
- la lista de parámetros a la vez. </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clearParams()</methodname> permite borrar un
- único parámetro (pasando un string identificador),
- parámetros con múltiples nombres (pasando un array de
- strings identificadores), o el stack de parámetros completo
- (pasando nada). </para>
- </listitem>
- </itemizedlist>
- <para>Hay varios parámetros pre-definidos que puede ser seteados para
- tener usos específicos en la cadena de dispatch:</para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>useDefaultControllerAlways</emphasis> se usa para
- indicar a <link linkend="zend.controller.dispatcher">el
- dispatcher</link> que utilice el controlador por defecto
- en el módulo por defecto de cualquier solicitud que no sea
- dispatchable (es decir, el módulo, el controlador y/o la
- acción no existen). Por defecto, está en off. </para>
- <para> Ver <link linkend="zend.controller.exceptions.internal"
- >MVC Exceptions You May Encounter</link> para
- información más detallada sobre el uso de este setting.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>disableOutputBuffering</emphasis> se usa para
- indicarle a <link linkend="zend.controller.dispatcher">el
- dispatcher</link> que no debe utilizar output buffering
- para capturar la salida generada por los controladores de
- acción. Por defecto, el dispatcher captura cualquier salida
- y la añade al contenido del cuerpo del objeto respuesta.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>noViewRenderer</emphasis> se usa para deshabilitar
- el <link
- linkend="zend.controller.actionhelpers.viewrenderer"
- >ViewRenderer</link> . Poniendo este parámetro a true,
- lo deshabilita. </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>noErrorHandler</emphasis> se usa para deshabilitar
- el <link
- linkend="zend.controller.plugins.standard.errorhandler"
- >Error Handler plugin</link> . Poniendo este parámetro a
- true, lo deshabilita. </para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.controller.front.subclassing">
- <title>Extendiendo el Front Controller</title>
- <para> Para extender el Front Controller, como mínimo que necesitará
- anular el método <methodname>getInstance()</methodname> : </para>
- <programlisting language="php"><![CDATA[
- class My_Controller_Front extends Zend_Controller_Front
- {
- public static function getInstance()
- {
- if (null === self::$_instance) {
- self::$_instance = new self();
- }
- return self::$_instance;
- }
- }
- ]]></programlisting>
- <para> Anulando el método <methodname>getInstance()</methodname> asegura
- que las subsiguientes llamadas a
- <methodname>Zend_Controller_Front::getInstance()</methodname>
- devolverá una instancia de su nueva subclase en lugar de una
- instancia <classname>Zend_Controller_Front</classname> -- esto es
- particularmente útil para algunos de los routers alternativos y view
- helpers. </para>
- <para>Típicamente, no necesitará una subclase del front controller a
- menos que necesite añadir nuevas funcionalidades (por ejemplo, un
- plugin autoloader, o una forma de especificar los paths de los
- action helpers). Algunos de los puntos donde puede querer modificar
- el comportamiento puede incluir modificar cómo son almacenados los
- directorios de controladores , o qué router predeterminado o
- dispatcher se utiliza.</para>
- </sect2>
- </sect1>
|