1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="learning.plugins.usage">
<title>Utilizando Plugins</title>
<para>
Componentes que fazem uso de plugins normalmente utilizam
<classname>Zend_Loader_PluginLoader</classname>. Essa classe permite que você registre
plugins especificando um ou mais "caminhos prefixados". O componente irá chamar ao método
de PluginLoader <methodname>load()</methodname>, 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.
</para>
<para>
Os exemplos seguintes deixarão isso mais claro.
</para>
<example id="learning.plugins.usage.basic">
<title>Exemplo básico de Plugin: Adicionando um caminho prefixado</title>
<para>
Neste exemplo, vamos supor que alguns validadores foram escritos e colocados no
diretório <filename>foo/plugins/validators/</filename>, 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:
</para>
<programlisting language="text"><![CDATA[
foo/
|-- plugins/
| |-- validators/
| | |-- Par.php
| | |-- Duzias.php
]]></programlisting>
<para>
Agora, vamos informar uma instância de <classname>Zend_Form_Element</classname>
deste caminho prefixado. O método <methodname>addPrefixPath()</methodname> da classe
<classname>Zend_Form_Element</classname> espera um terceiro argumento que indica
o tipo de plugin para o qual o caminho está sendo registrado, neste caso, é um
plugin "validador".
</para>
<programlisting language="php"><![CDATA[
$element->addPrefixPath('Foo_Validate', 'foo/plugins/validators/', 'validate');
]]></programlisting>
<para>
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"):
</para>
<programlisting language="php"><![CDATA[
$element->addValidator('NotEmpty')
->addValidator('Int')
->addValidator('Par')
->addValidator('Duzias');
]]></programlisting>
<para>
Quando o elemento demanda validação, requisitará a classe de plugin através do
PluginLoader. Os dois primeiros validadores serão
<classname>Zend_Validate_NotEmpty</classname> e
<classname>Zend_Validate_Int</classname>, respectivamente; os dois seguintes serão
<classname>Foo_Validate_Par</classname> e <classname>Foo_Validate_Duzias</classname>,
respectivamente.
</para>
</example>
<note>
<title>O que acontece caso um plugin não seja encontrado?</title>
<para>
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?
</para>
<para>
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.
</para>
<para>
Uma vez que a pilha de caminhos prefixados tenha se esgotado, caso nenhum arquivo
tenha sido encontrado, será gerada uma exceção
<exceptionname>Zend_Loader_PluginLoader_Exception</exceptionname>.
</para>
</note>
<example id="learning.plugins.usage.override">
<title>Uso Intermediário do Plugin: Sobrescrevendo plugins existentes</title>
<para>
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.
</para>
<para>
Por exemplo, vamos considerar <classname>Zend_View_Helper_FormButton</classname>
(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 <acronym>HTML</acronym> para um elemento de
inserção em formulário.
</para>
<para>
Digamos que você deseja que o auxiliar, ao invés de gerar um elemento
<constant>button</constant> em <acronym>HTML</acronym>; 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.
</para>
<para>
Nosso primeiro exemplo será o de nomear o elemento com um nome único:
<classname>Foo_View_Helper_CssButton</classname>, 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.
</para>
<para>
Então, o melhor exemplo é usar o plugin de nome "Button", ficando o nome da classe
como <classname>Foo_View_Helper_Button</classname>. Em seguida, registrar o caminho
prefixado com a visualização (view):
</para>
<programlisting language="php"><![CDATA[
// 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');
]]></programlisting>
<para>
Uma vez feito, em qualquer lugar que utilizar o auxiliar "Button" irá direcionar para
a sua classe <classname>Foo_View_Helper_Button</classname> customizada!
</para>
</example>
</sect1>
|