Techniquement, un plugin est une classe qui implémente l'interface des plugins (Zend_Controller_Plugin_Interface). Dans la pratique, une classe abstraite est fournie pour simplifier la tache (Zend_Controller_Plugin_Abstract). Notre premier plugin s'appellera AutoView (My_Controller_Plugin_AutoView, stocké dans My/Controller/Plugin/AutoView.php).

Un plugin est donc une classe dont les méthodes seront appelées a différents moments de la dispatch loop du controlleur frontal, comme on peut le voir dans Zend_Controller_Front::dispatch():

  • routeStartup(), à la mise en route du routeur
  • routeShutdown($action), à l'arrêt du routeur
  • dispatchLoopStartup($action), avant la dispatch loop
  • preDispatch($action), avant d'executer une action
  • postDispatch($action), après avoir executé une action
  • dispatchLoopShutdown(), pour finir.

A chaud, on pourrait se dire que postDispatch est exactement ce dont on n'a besoin, et on se tromperait. Ce qu'il faut savoir, c'est que l'argument $action passé à postDispatch contient l'action qui suit celle qui vient d'être executé. Dans la majorité des cas, n'ayant qu'une seule action à executer, $action sera vide, et on se retrouve l'air un peu con.

Bon donc, on va user d'un stratagème: notre plugin va stocker les actions qui passent dans preDispatch, pour s'occuper de la dernière à être passée dans dispatchLoopShutdown. Dernier détail, notre plugin s'occupera lui même de gérer son instance de Zend_View. Et sans plus attendre, le code, qui n'a finalement rien de compliqué:

<?php

require_once 'Zend/Controller/Plugin/Abstract.php';

class My_Controller_Plugin_AutoView extends Zend_Controller_Plugin_Abstract {

	private $_lastAction;

	public function __construct() {
		$view = new Zend_View;
		$view->setScriptPath(APP_ROOT.'/views/');
		Zend::register('view', $view);
	}

	public function preDispatch($action) {
		$this->_lastAction = clone($action);
		return $action;
	}

	public function dispatchLoopShutdown() {
		if (!is_null($this->_lastAction)) {
			$viewPath = sprintf('%s/%s.php', $this->_lastAction->getControllerName(), $this->_lastAction->getActionName());
			echo Zend::registry('view')->render($viewPath);
		}
	}
}

?>

Bien, notre plugin vaillament codé, il nous faut désormais expliquer au controlleur frontal qu'on aimerai bien qu'il en tienne compte. Cela se passe fort logiquement dans le bootstrap, via la méthode registerPlugin du sus-cité controlleur frontal, qui prend en argument une instance d'un objet implémentant Zend_Controller_Plugin_Interface:

$controller = Zend_Controller_Front::getInstance();
$controller->registerPlugin(new My_Controller_Plugin_AutoView);

And viola !