Utilizando Plugins

Componentes que fazem uso de plugins normalmente utilizam Zend_Loader_PluginLoader. Essa classe permite que você registre plugins especificando um ou mais "caminhos prefixados". O componente irá chamar ao método de PluginLoader load(), passando o nome abreviado do plugin. O PluginLoader irá consultar cada caminho prefixado para saber se existe uma classe correspondente. Os caminhos prefixados são procurados na ordem LIFO (last in, first out - último a entrar, primeiro a sair), e com isso, as correspondências ocorrerão primeiramente com os últimos caminhos registrados - o que possibilita a você substituir plugins já existentes.

Os exemplos seguintes deixarão isso mais claro.

Exemplo 1. Exemplo básico de Plugin: Adicionando um caminho prefixado

Neste exemplo, vamos supor que alguns validadores foram escritos e colocados no diretório foo/plugins/validators/, e que todas essas classes possuem o prefixo "Foo_Validate_"; essas duas partes de informação formam o "caminho prefixado". Além disso, vamos supor que temos dois validadores, um chamado "Par" (garantindo que um número seja par), e outro chamado "Dúzias" (garantindo que o número é um múltiplo de 12). A árvore terá esta aparência:

foo/
|-- plugins/
|   |-- validators/
|   |   |-- Par.php
|   |   |-- Duzias.php

Agora, vamos informar uma instância de Zend_Form_Element deste caminho prefixado. O método addPrefixPath() da classe Zend_Form_Element espera um terceiro argumento que indica o tipo de plugin para o qual o caminho está sendo registrado, neste caso, é um plugin "validador".

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

Agora podemos simplesmente informar ao elemento o nome abreviado dos validadores que queremos usar. No exemplo seguinte, usaremos uma mistura de validadores padrão ("NotEmpty", "Int") e validadores customizados ("Par", "Duzias"):

$element->addValidator('NotEmpty')
        ->addValidator('Int')
        ->addValidator('Par')
        ->addValidator('Duzias');

Quando o elemento demanda validação, requisitará a classe de plugin através do PluginLoader. Os dois primeiros validadores serão Zend_Validate_NotEmpty e Zend_Validate_Int, respectivamente; os dois seguintes serão Foo_Validate_Par e Foo_Validate_Duzias, respectivamente.


O que acontece caso um plugin não seja encontrado?

O que acontece se um plugin é solicitado, mas o PluginLoader é incapaz de encontrar uma classe correspondente? Por exemplo, no exemplo acima, se registrássemos o plugin "Bar", com o elemento, o que aconteceria?

O carregador de plugin irá procurar em cada caminho prefixado, verificando se há um arquivo correspondente ao nome do plugin. Se o arquivo não for encontrado, ele passa ao próximo caminho prefixado.

Uma vez que a pilha de caminhos prefixados tenha se esgotado, caso nenhum arquivo tenha sido encontrado, será gerada uma exceção Zend_Loader_PluginLoader_Exception.

Exemplo 2. Uso Intermediário do Plugin: Sobrescrevendo plugins existentes

Uma característica do PluginLoader é que seu uso da pilha LIFO permite sobrescrever plugins existentes, criando sua própria versão localmente com um caminho prefixado diferente e registrá-lo mais tarde na pilha.

Por exemplo, vamos considerar Zend_View_Helper_FormButton (auxiliares de visualização - view helpers - são um tipo de plugin). Esse auxiliar de visualização aceita três argumentos, um nome de elemento (também usado como seu identificador DOM), um valor (usado como o rótulo do botão) e um vetor opcional de atributos. O auxiliar gera marcação HTML para um elemento de inserção em formulário.

Digamos que você deseja que o auxiliar, ao invés de gerar um elemento button em HTML; não quer que o auxiliar gere um identificador DOM, mas sim utilizar o valor para um seletor de classe em CSS; sem interesse em manipular atributos arbitrários. Você pode fazer isso de algumas maneiras. Em todos os casos, você criaria sua própria classe "auxiliar de visualização" que implementa o comportamento desejado; a diferença está em como você iria nomeá-los e chamá-los.

Nosso primeiro exemplo será o de nomear o elemento com um nome único: Foo_View_Helper_CssButton, o que implica no nome do plugin "CssButton". Embora isso seja uma abordagem viável, apresenta várias questões: caso você já tenha utilizado o auxiliar de visualização Button, você terá que refatorar; em outro caso, se outro desenvolvedor começar a escrever código para a sua aplicação, pode inadvertidamente usar o auxiliar de visualização Button em vez de seu novo auxiliar.

Então, o melhor exemplo é usar o plugin de nome "Button", ficando o nome da classe como Foo_View_Helper_Button. Em seguida, registrar o caminho prefixado com a visualização (view):

// Zend_View::addHelperPath() utiliza o PluginLoader; entretanto, inverte
// os argumentos e fornece o valor padrão de "Zend_View_Helper" para o
// prefixo de plugin.
//
// O código abaixo assume que sua classe está no diretório 'foo/view/helpers/'.
$view->addHelperPath('foo/view/helpers', 'Foo_View_Helper');

Uma vez feito, em qualquer lugar que utilizar o auxiliar "Button" irá direcionar para a sua classe Foo_View_Helper_Button customizada!