# 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 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.

## 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!