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!