:::: MENU ::::

Front Controller y Routers en Magento

4.00 avg. rating (75% score) - 2 votes

Cuando una petición (Request) llega a Magento, éste busca un Router que pueda procesar dicha petición. El encargado de conocer los Routers disponibles en el sistema y buscar el Router adecuado para el procesamiento de la petición, es el Front Controller (Mage_Core_Front_Controller), que corresponde a la implementación del patrón de diseño del mismo nombre. Ver más en Front Controller Pattern.

En una instalación limpia de Magento existen cuatro Routers diferentes que pueden reclamar el procesamiento de una petición:

  • Standard Router. Procesa las peticiones del frontend de Magento.
  • Admin Router. Procesa las peticiones del backend de Magento
  • CMS Router. Procesa las peticiones del CMS.
  • Default Router. Cuando todos los anteriores routers fallan, es el encargado de establecer la acción noRoute, que en una instalación por defecto hace que se muestre la página de error 404.

La lista de cuatro Routers se inicializa en el Front Controler, encargado del procesamiento de las peticiones al sistema.

En Mage_Core_Controller_Varien_Front::init, podemos ver el siguiente fragmento:

Mage::dispatchEvent('controller_front_init_before', array('front'=>$this));

$routersInfo = Mage::app()->getStore()->getConfig(self::XML_STORE_ROUTERS_PATH);

Varien_Profiler::start('mage::app::init_front_controller::collect_routers');
foreach ($routersInfo as $routerCode => $routerInfo) {
    if (isset($routerInfo['disabled']) && $routerInfo['disabled']) {
	continue;
    }
    if (isset($routerInfo['class'])) {
	$router = new $routerInfo['class'];
	if (isset($routerInfo['area'])) {
	    $router->collectRoutes($routerInfo['area'], $routerCode);
	}
	$this->addRouter($routerCode, $router);
    }
}
Varien_Profiler::stop('mage::app::init_front_controller::collect_routers');

Mage::dispatchEvent('controller_front_init_routers', array('front'=>$this));

// Add default router at the last
$default = new Mage_Core_Controller_Varien_Router_Default();
$this->addRouter('default', $default);

return $this;

En la parte central del fragmento, vemos como se obtiene de la configuración:

$routersInfo = Mage::app()->getStore()->getConfig(self::XML_STORE_ROUTERS_PATH);

Y se itera a través de la lista de Routers obtenidos llamando a:

$this->addRouter($routerCode, $router);

La lista de routers obtenida de configuración en una instalación nueva de Magento, contiene dos elementos: Standard y Admin.

Al final del fragmento, vemos también la siguiente línea, que añade al final de la lista el Router Default:

$this->addRouter('default', $default);

Pero no vemos ninguna referencia al Router CMS. ¿Cómo se añade ese Router a la lista?.

Ese es precisamente el objetivo de los dos eventos lanzados en el fragmento de código:

Mage::dispatchEvent('controller_front_init_before', array('front'=>$this));
Mage::dispatchEvent('controller_front_init_routers', array('front'=>$this));

Escuchando estos dos eventos, podemos añadir Routers a la lista antes de que Magento se ejecute. En concreto, el Router CMS se añade a la lista de esta forma. Si vemos el fichero config.xml del módulo CMS de Magento, vemos el siguiente bloque, que añade un listener para el primero de los eventos anteriores.

<events>
    <controller_front_init_routers>
	<observers>
	    <cms>
		<class>Mage_Cms_Controller_Router</class>
		<method>initControllerRouters</method>
	    </cms>
	</observers>
    </controller_front_init_routers>
</events>

Si vemos dentro del método Mage_Cms_Controller_Router::initControllerRouters, vemos el siguiente código:

$front = $observer->getEvent()->getFront();
$front->addRouter('cms', $this);

Que obtiene la instancia del Front Controller y añade a la lista un nuevo Router (el propio Mage_Cms_Controller_Router).




Hey! Qué opinas sobre el artículo?