TigerZF
🌐Español

5.2. Uso de plugins

Los componentes que hacen uso de plugins normalmente usan Zend_Loader_PluginLoader para realizar su trabajo. Esta clase le permite registrar plugins especificando una o más "rutas de prefijo". El componente entonces llamará al método load() del PluginLoader, pasándole el nombre corto del plugin. El PluginLoader consultará entonces cada ruta de prefijo para ver si existe una clase que coincida con ese nombre corto. Las rutas de prefijo se buscan en orden LIFO (último en entrar, primero en salir), de modo que coincidirá primero con las rutas de prefijo registradas en último lugar -- lo que le permite sobrescribir plugins existentes.

Algunos ejemplos aclararán todo esto.

Ejemplo 5.1. Ejemplo básico de plugin: añadir una única ruta de prefijo

En este ejemplo, asumiremos que se han escrito algunos validadores y se han colocado en el directorio foo/plugins/validators/, y que todas estas clases comparten el prefijo de clase "Foo_Validate_"; estos dos datos forman nuestra "ruta de prefijo". Además, supongamos que tenemos dos validadores, uno llamado "Even" (que asegura que un número a validar sea par), y otro llamado "Dozens" (que asegura que el número sea un múltiplo de 12). El árbol podría verse así:

foo/
|-- plugins/
|   |-- validators/
|   |   |-- Even.php
|   |   |-- Dozens.php

Ahora, informaremos a una instancia de Zend_Form_Element de esta ruta de prefijo. El método addPrefixPath() de Zend_Form_Element espera un tercer argumento que indica el tipo de plugin para el cual se está registrando la ruta; en este caso, es un plugin "validate".

$element->addPrefixPath('Foo_Validate', 'foo/plugins/validators/', 'validate');

Ahora podemos simplemente indicarle al elemento el nombre corto de los validadores que queremos usar. En el siguiente ejemplo, usamos una combinación de validadores estándar ("NotEmpty", "Int") y validadores personalizados ("Even", "Dozens"):

$element->addValidator('NotEmpty')
        ->addValidator('Int')
        ->addValidator('Even')
        ->addValidator('Dozens');

Cuando el elemento necesite validar, solicitará entonces la clase del plugin al PluginLoader. Los dos primeros validadores se resolverán en Zend_Validate_NotEmpty y Zend_Validate_Int, respectivamente; los siguientes dos se resolverán en Foo_Validate_Even y Foo_Validate_Dozens, respectivamente.


[Note] ¿Qué sucede si no se encuentra un plugin?

¿Qué sucede si se solicita un plugin, pero el PluginLoader no puede encontrar una clase que coincida con él? Por ejemplo, en el ejemplo anterior, si registráramos el plugin "Bar" con el elemento, ¿qué sucedería?

El cargador de plugins recorrerá cada ruta de prefijo, comprobando si se encuentra un archivo que coincida con el nombre del plugin en esa ruta. Si no se encuentra el archivo, pasa entonces a la siguiente ruta de prefijo.

Una vez que se ha agotado la pila de rutas de prefijo, si no se ha encontrado ningún archivo coincidente, lanzará una Zend_Loader_PluginLoader_Exception.

Ejemplo 5.2. Uso intermedio de plugins: sobrescribir plugins existentes

Una fortaleza del PluginLoader es que su uso de una pila LIFO le permite sobrescribir plugins existentes creando sus propias versiones localmente con una ruta de prefijo diferente, y registrando esa ruta de prefijo más adelante en la pila.

Por ejemplo, consideremos Zend_View_Helper_FormButton (los helpers de vista son una forma de plugin). Este helper de vista acepta tres argumentos, un nombre de elemento (también usado como identificador DOM del elemento), un valor (usado como etiqueta del botón), y un array opcional de atributos. El helper entonces genera marcado HTML para un elemento de entrada de formulario.

Supongamos que quiere que el helper genere en su lugar un verdadero elemento button de HTML; no quiere que el helper genere un identificador DOM, sino que use el valor para un selector de clase CSS; y que no tiene interés en manejar atributos arbitrarios. Podría lograr esto de un par de maneras. En ambos casos, crearía su propia clase de helper de vista que implemente el comportamiento que desea; la diferencia está en cómo la nombraría e invocaría.

Nuestro primer ejemplo será nombrar el elemento con un nombre único: Foo_View_Helper_CssButton, lo que implica el nombre de plugin "CssButton". Si bien este es ciertamente un enfoque viable, plantea varios problemas: si ya ha usado el helper de vista Button en su código, ahora tendría que refactorizar; alternativamente, si otro desarrollador comienza a escribir código para su aplicación, podría usar inadvertidamente el helper de vista Button en lugar de su nuevo helper de vista.

Así que el mejor ejemplo es usar el nombre de plugin "Button", lo que nos da el nombre de clase Foo_View_Helper_Button. Entonces registramos la ruta de prefijo con la vista:

// Zend_View::addHelperPath() utilizes the PluginLoader; however, it inverts
// the arguments, as it provides a default value of "Zend_View_Helper" for the
// plugin prefix.
//
// The below assumes your class is in the directory 'foo/view/helpers/'.
$view->addHelperPath('foo/view/helpers', 'Foo_View_Helper');

Una vez hecho esto, ¡en cualquier lugar donde ahora use el helper "Button" se delegará a su clase personalizada Foo_View_Helper_Button!