Ver Mensaje Individual
  #9 (permalink)  
Antiguo 06/06/2011, 05:08
nerthalas
 
Fecha de Ingreso: noviembre-2010
Mensajes: 21
Antigüedad: 13 años, 5 meses
Puntos: 1
Respuesta: Don´t repeat yourself (DRY). Dudas con la reutilización de controladores y

Finalmente he encontrado una solución que me permite reutilizar el mismo controlador y personalizar su salida según el parámetro "Marca" que reciba. De esta manera no tengo que repetir el mismo código para cada marca de coche que gestione en mi web. Masterpuppet me puso sobre la pista, todo hay que decirlo.

Expongo el resultado para compartirlo con el foro:

Comencemos por los enlaces a las distintas marcas que aparecen en el menú del index principal de la web. Cuando alguien pincha en alguno de los enlaces el plug-in ControllerCheck intercepta el $request y lo gestiona según lo expuesto más adelante.

Código PHP:
<li><a href="<?php echo $this->url(array('controller'=>'opel''action'=>'index'))?>">Opel</a></li> 

<li><a href="<?php echo $this->url(array('controller'=>'seat''action'=>'index'))?>">Seat</a></li> 

<li><a href="<?php echo $this->url(array('controller'=>'ford''action'=>'index'))?>">Ford</a></li> 

<li><a href="<?php echo $this->url(array('controller'=>'bmw''action'=>'index'))?>">BMW</a></li>

ControllerCheck incercepta el $request, comprueba si el nombre del controlador está en un array de nombres, y tras ello lo redirige a un controlador genérico "marca" inyectándole en el frontController un parámetro con el nombre de la marca.

Código PHP:
class My_Controller_Plugin_ControllerCheck extends Zend_Controller_Plugin_Abstract
{
    public function 
preDispatch(Zend_Controller_Request_Abstract $request
    {
        
//Guarda el nombre del controlador original en una variable
        
$controllerName $this->getRequest()->getControllerName();
        
        
//Array donde se guardan los nombres a "interceptar"
        
$controladores = array('seat','opel','bmw','ford');
        
        
//Si el nombre del controlador original está en el array....
        
if(in_array($controllerName$controladores))
        {
            
//Redirijo la $request al controlador genérico
            //inyectándole como parámetro al front Controller 
            //el nombre del controlador inicial
            
$request->setControllerName('marca');
            
$nombre Zend_Controller_Front::getInstance();
            
$nombre->setParam('nombre'$controllerName);
        }
        
    }



Controlador genérico "marca" que recibe el parámetro del frontController dentro de sus acciones:

Código PHP:
class MarcaController extends Zend_Controller_Action
{
            
    public function 
init()
    {
        
    }

    public function 
indexAction()
    {
      
//Recoge el nombre del controlador original inyectado en el frontController
        
$nombre $this->getFrontController()->getParam('nombre');
        
//Envía el nombre de la marca a la vista
        
$this->view->nombre $nombre;      
    }
    
    public function 
informacionAction()
    {
        
$nombre $this->getFrontController()->getParam('nombre');
        
//Envía el nombre de la marca a la vista
        
$this->view->nombre $nombre
    }
    
    public function 
galeriaAction()
    {
        
$nombre =$this->getFrontController()->getParam('nombre');
        
//Envía el nombre de la marca a la vista
        
$this->view->nombre $nombre
    }



En la vista Index del controlador genérico Marca muestro los enlaces personalizados de las distintas acciones según el parámetro recibido:

Código PHP:
<a href="<?php echo $this->url(array('controller'=>"$this->nombre"'action'=>'informacion'))?>">Informacion</a>
<br />
<a href="<?php echo $this->url(array('controller'=>"$this->nombre"'action'=>'galeria'))?>">Galeria</a>
Finalmente, en las vistas concretas de las acciones también puedo enviar el nombre de la marca si hiciera falta

Por ejemplo, información.phtml
Código PHP:
echo $this->nombre

¿Qué desventaja veo así a bote pronto? Almacenar los nombres de los controladores a interceptar dentro de un array. Si son varias decenas no hay problema, pero, ¿qué pasaría si fueran 500? Pues probablemente la mejor solución fuese almacenarlos en una BBDD y hacer una consulta. Sin embargo, conviene tener en cuenta la sobrecarga de peticiones que puede producir en el servidor.

No he mirado la sugerencia que me propusiste, GatorV, aunque me gustaría saber qué opináis aquellos que tenéis más experiencia con Zend sobre la solución que he creado para el problema. Sobre todo si le véis algún inconveniente grave.

Un saludo.