Zend_Tool-Extending.xml 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24346 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.tool.extending">
  5. <title>Extendendo o Zend_Tool</title>
  6. <sect2 id="zend.tool.extending.overview">
  7. <title>Visão Geral do Zend_Tool</title>
  8. <para>
  9. <classname>Zend_Tool_Framework</classname> é uma framework para expor as funcionalidades
  10. comuns, tais como a criação da estrutura do projeto, geração de código, geração de
  11. índice de pesquisa, e muito mais. Funcionalmente pode ser escrito e exposto por meio de
  12. classes <acronym>PHP</acronym> dentro do <property>include_path</property> do <acronym>PHP</acronym>,
  13. permitindo uma flexibilidade incrível de implementação. A funcionalidade pode ser consumida
  14. escrevendo implementação e/ou clientes de protocolo-específico -- tais como clientes console,
  15. <acronym>XML-RPC</acronym>, <acronym>SOAP</acronym>, e muito mais.
  16. </para>
  17. <para>
  18. <classname>Zend_Tool_Project</classname> desenvolve e amplia os recursos do
  19. <classname>Zend_Tool_Framework</classname> ao de gerenciar um "projeto". Em geral,
  20. um "projeto" é um esforço planejado ou uma iniciativa. No mundo da informática, projetos
  21. em geral são uma coleção de recursos. Esses recursos podem ser arquivos, diretórios,
  22. bases de dados, esquemas, imagens, estilos e muito mais.
  23. </para>
  24. </sect2>
  25. <sect2 id="zend.tool.extending.zend-tool-framework">
  26. <title>Extensões do Zend_Tool_Framework</title>
  27. <sect3 id="zend.tool.extending.zend-tool-framework.architecture">
  28. <title>Arquitetura Geral</title>
  29. <para>
  30. <classname>Zend_Tool_Framework</classname> fornece o seguinte:
  31. </para>
  32. <itemizedlist>
  33. <listitem>
  34. <para>
  35. <emphasis>Interfaces comuns e abstratas</emphasis> que permitem a
  36. desenvolvedores criar funcionalidades e capacidades que são
  37. invocadas por clientes da ferramenta.
  38. </para>
  39. </listitem>
  40. <listitem>
  41. <para>
  42. <emphasis>Funcionalidade base de clientes</emphasis> e uma implementação
  43. concreta do console que conectam ferramentas externas e interfaces para o
  44. Zend_Tool_Framework. O cliente do console pode ser utilizado em ambientes CLI,
  45. como console unix e o console do Windows.
  46. </para>
  47. </listitem>
  48. <listitem>
  49. <para>
  50. <emphasis>Interfaces de "Provider" e "Manifest"</emphasis> que
  51. podem ser usadas pela ferramenta do sistema. "Providers" representam o
  52. aspecto functional do framework, e define as ações que os clientes
  53. da ferramenta podem chamar. "Manifests" age como registros de metadados
  54. que proveem contexto adicional para os vários providers definidos.
  55. </para>
  56. </listitem>
  57. <listitem>
  58. <para>
  59. <emphasis>Um sistema de loading introspectivo</emphasis> que irá
  60. examinar o ambiente a procura de providers e determinar o que é necessário
  61. para chama-los.
  62. </para>
  63. </listitem>
  64. <listitem>
  65. <para>
  66. <emphasis>Uma conjunto padrão de sistemas de providers</emphasis> que
  67. permite o sistema relatar o que todos os recursos do sistemas são, bem como
  68. fornecer um feedback útil. Ele também inclui um compreessível "Systema de Ajuda".
  69. </para>
  70. </listitem>
  71. </itemizedlist>
  72. <para>
  73. Definições que você deve estar ciente de através deste manual com relação
  74. ao <classname>Zend_Tool_Framework</classname> incluem:
  75. </para>
  76. <itemizedlist>
  77. <listitem>
  78. <para>
  79. <classname>Zend_Tool_Framework</classname> - O framework que expõe
  80. recursos da ferramenta.
  81. </para>
  82. </listitem>
  83. <listitem>
  84. <para>
  85. <emphasis>Tooling Client</emphasis> - Uma ferramenta de desenvolvimento que se conecta
  86. ao e consome <classname>Zend_Tool_Framework</classname>.
  87. </para>
  88. </listitem>
  89. <listitem>
  90. <para>
  91. <emphasis>Client</emphasis> - O subsistema do
  92. <classname>Zend_Tool_Framework</classname> que expoe uma interface tal que
  93. tooling clients podem conectar, pesquisar e executar comandos.
  94. </para>
  95. </listitem>
  96. <listitem>
  97. <para>
  98. <emphasis>Console Client / Command Line Interface /
  99. <filename>zf.php</filename></emphasis> - A tooling client para a linha
  100. de comando.</para>
  101. </listitem>
  102. <listitem>
  103. <para>
  104. <emphasis>Provider</emphasis> - Um subsistema e uma coleção de funcionalidades
  105. internas que o framework exporta.
  106. </para>
  107. </listitem>
  108. <listitem>
  109. <para>
  110. <emphasis>Manifest</emphasis> - Um subsistema para definição,
  111. organização, e divulgação de dados exigidos pelo provider.
  112. </para>
  113. </listitem>
  114. <listitem>
  115. <para>
  116. <classname>Zend_Tool_Project</classname> Provider - Um conjunto de providers
  117. especificamente para criação e manutenção de projetos baseados no Zend Framework.
  118. </para>
  119. </listitem>
  120. </itemizedlist>
  121. </sect3>
  122. <sect3 id="zend.tool.extending.zend-tool-framework.cli-client">
  123. <title>Entendendo o Cliente CLI</title>
  124. <para>
  125. A <acronym>CLI</acronym>, ou ferramenta de linha de comando (internamente
  126. conhecida como ferramenta de console), é atualmente a interface primária para enviar
  127. pedidos ao <classname>Zend_Tool</classname> requests. Com a ferramenta <acronym>CLI</acronym>,
  128. desenvolvedores podem enviar pedidos para a ferramenta dentro da "janela de linha de comando", também
  129. comumente conhecida como janela do "terminal". Este ambiente é predominante em
  130. embientes *unix, mas também tem uma implementação comum no Windows como o
  131. <filename>cmd.exe</filename>, console2 e também com o projeto Cygwin.
  132. </para>
  133. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-general">
  134. <title>Configuração da ferramenta CLI</title>
  135. <para>
  136. Para distribuir pedidos via cliente de linha de comando, primeiro você
  137. precisa configurar o cliente para que seu sistema possa manipular os
  138. comandos "zf". O cliente de linha de comando, para todos as intenções e
  139. propósitos, é o arquivo <filename>.sh</filename> ou <filename>.bat</filename>
  140. que é provido com a sua distribuição do Zend Framework. No trunk, ele pode ser
  141. encontrado aqui:
  142. <ulink
  143. url="http://framework.zend.com/svn/framework/standard/trunk/bin/">http://framework.zend.com/svn/framework/standard/trunk/bin/</ulink>.
  144. </para>
  145. <para>
  146. Como você pode ver, existem 3 arquivos no diretório <filename>/bin/</filename>:
  147. <filename>zf.php</filename>, <filename>zf.sh</filename>, e
  148. <filename>zf.bat</filename>. O <filename>zf.sh</filename> e o <filename>zf.bat</filename>
  149. são os pacotes específicos do sistema operacional: <filename>zf.sh</filename> para ambientes
  150. *nix, e <filename>zf.bat</filename> para ambientes Win32. Estes empacotadores clientes são
  151. responsáveis por procurar o php.exe correto, achando o <filename>zf.php</filename>, e
  152. passando o pedido para o cliente. O <filename>zf.php</filename>, é responsável por
  153. manipular a identificação do seu ambiente, construindo um include_path adequado, e passar o
  154. que é fornecido na linha de comando para o componente de biblioteca adequado
  155. para a expedição.
  156. </para>
  157. <para>
  158. Finalmente, você quer garantir duas coisas para fazer tudo funcionar
  159. independentemente do sistema operacional em que você está:
  160. </para>
  161. <orderedlist>
  162. <listitem>
  163. <para>
  164. <filename>zf.sh/zf.bat</filename> acessível a partir do path do sistema.
  165. Esta é a capacidade de chamar <command>zf</command> de qualquer lugar na sua linha de comando,
  166. independentemente de qual é o seu diretório de trabalho atual.
  167. </para>
  168. </listitem>
  169. <listitem>
  170. <para>
  171. <filename>ZendFramework/library</filename> estar no seu
  172. <property>include_path</property>.
  173. </para>
  174. </listitem>
  175. </orderedlist>
  176. <note>
  177. <para>
  178. Nota: enquanto os acima são os requisitos ideais, você pode simplesmente
  179. baixar o Zend Framework e esperar que ele funcione como <filename>./path/to/zf.php</filename>
  180. algum comando..
  181. </para>
  182. </note>
  183. </sect4>
  184. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-starnix">
  185. <title>Configurando a ferramenta CLI em Sistemas Unix-like</title>
  186. <para>
  187. A configuração mais comum no ambiente *nix, é copiar o <filename>zf.sh</filename> e
  188. o <filename>zf.php</filename> no mesmo diretório que o seu binário <acronym>PHP</acronym>.
  189. Isto pode geralmente ser achado nos seguintes lugares:
  190. </para>
  191. <programlisting language="text"><![CDATA[
  192. /usr/bin
  193. /usr/local/bin
  194. /usr/local/ZendServer/bin/
  195. /Applications/ZendServer/bin/
  196. ]]></programlisting>
  197. <para>
  198. Para achar a localização do seu binário <acronym>PHP</acronym>, você pode executar
  199. 'which php' na linha de comando. Isto retornará a localização do binário do <acronym>PHP</acronym>
  200. que você está usando para rodar scripts <acronym>PHP</acronym> no seu ambiente.
  201. </para>
  202. <para>
  203. O próximo passo é certificar que a biblioteca Zend Framework está configurada
  204. corretamente dentro do sistema de <property>include_path</property> do
  205. <acronym>PHP</acronym>. Para achar onde seu <property>include_path</property>
  206. está localizado, você pode executar <command>php -i</command> e olhar para
  207. a variável <property>include_path</property>, o mais sucintamente, executar
  208. <command>php -i | grep include_path</command>. Uma vez que você tenha achado
  209. onde seu <property>include_path</property> está localizado (isto irá geralmente
  210. estar em algum lugar como <filename>/usr/lib/php</filename>,
  211. <filename>/usr/share/php</filename>, <filename>/usr/local/lib/php</filename>, ou
  212. similar), certifique que o conteúdos do diretório <filename>/library/</filename>
  213. estão colocados dentro do seu diretório <property>include_path</property>
  214. especificado.
  215. </para>
  216. <para>
  217. Uma vez que você tenha terminado estas duas coisas, você deve ser capaz de digitar
  218. um comando e obter devolta a resposta adequada como:
  219. </para>
  220. <para>
  221. <inlinegraphic scale="100" align="center" valign="middle"
  222. fileref="figures/zend.tool.framework.cliversionunix.png" format="PNG" />
  223. </para>
  224. <para>
  225. Se vocÊ não ver isto digitado na saída, volte e verifique sua configuração
  226. para ter certeza que tem todas as partes necessárias in devido lugar.
  227. </para>
  228. <para>
  229. Existem uma combinação de configurações alternativas que você pode querer empregar
  230. dependendo das configurações dos servidores, seu nível de acesso, ou
  231. por outras razões.
  232. </para>
  233. <para>
  234. <emphasis>Configuração Alternativa</emphasis> envolve guardar o download do
  235. Zend Framework junto como está, e criar um link de um local <constant>PATH</constant>
  236. para o <filename>zf.sh</filename>. O que isto significa é que você coloca o conteúdo
  237. do download do Zend Framework em uma localização tal como <filename>/usr/local/share/ZendFramework</filename>,
  238. ou mais localmente como <filename>/home/username/lib/ZendFramework</filename>, e cria
  239. um link simbólico para o <filename>zf.sh</filename>.
  240. </para>
  241. <para>
  242. Assumindo que você quer colocar o link dentro de <filename>/usr/local/bin</filename>
  243. (isto pode também funcionar colocando o link dentro de <filename>/home/username/bin/</filename>
  244. por exemplo) você poderia dgitar um comando similar a este:
  245. </para>
  246. <programlisting language="sh"><![CDATA[
  247. ln -s /usr/local/share/ZendFramework/bin/zf.sh /usr/local/bin/zf
  248. # OU (por exemplo)
  249. ln -s /home/username/lib/ZendFramework/bin/zf.sh /home/username/bin/zf
  250. ]]></programlisting>
  251. <para>
  252. Isto irá criar um link que você poderá ser capaz de acessar globalmente
  253. na linha de comando.
  254. </para>
  255. </sect4>
  256. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-windows">
  257. <title>Configurando a ferramenta CLI no Windows</title>
  258. <para>
  259. A confuguração mais comum no ambiente Win32, é copiar o
  260. <filename>zf.bat</filename> e o <filename>zf.php</filename> para dentr do mesmo
  261. diretório do seu binário <acronym>PHP</acronym>. Este pode geralmente ser achado
  262. nos seguintes lugares:
  263. </para>
  264. <programlisting language="text"><![CDATA[
  265. C:\PHP
  266. C:\Program Files\ZendServer\bin\
  267. C:\WAMP\PHP\bin
  268. ]]></programlisting>
  269. <para>
  270. Você deve ser capaz de rodar <filename>php.exe</filename> na linha de comando.
  271. Se você não for capaz, primeiro verifique a documentação que veio com sua
  272. distribuição <acronym>PHP</acronym>, ou tenha certeza que o caminho para o
  273. <filename>php.exe</filename> está na sua variável de ambiente
  274. <constant>PATH</constant> do Windows.
  275. </para>
  276. <para>
  277. O próximo passo é ter certeza que a biblioteca do Zend Framework
  278. está configurada corretamente dentro do sistema de <property>include_path</property>
  279. do <acronym>PHP</acronym>. Para achar onde seu <property>include_path</property>
  280. está localizado, você pode digitar <command>php -i</command> e olhar para a
  281. variável <property>include_path</property>, ou mais sucintamente executar
  282. <command>php -i | grep include_path</command> se você tem um Cygwin configurado
  283. com grep disponível. Uma vez você tenha achado onde seu <property>include_path</property>
  284. está localizado(isto irá geralmente ser algo como <filename>C:\PHP\pear</filename>,
  285. <filename>C:\PHP\share</filename>,<filename>C:\Program%20Files\ZendServer\share</filename>
  286. ou similar), verifique que os conteúdos do diretório library/ estão postos dentro
  287. do seu diretório <property>include_path</property>especificado.
  288. </para>
  289. <para>
  290. Uma vez tenha terminado aquilas duas coisas, você deve ser capaz de enviar um
  291. comando e receber o devida resposta como:
  292. </para>
  293. <para>
  294. <inlinegraphic scale="100" align="center" valign="middle"
  295. fileref="figures/zend.tool.framework.cliversionwin32.png" format="PNG" />
  296. </para>
  297. <para>
  298. Se você não ver isto digitado na saída, volte e verifique sua configuração
  299. para ter certeza que você tem todas as partes necessárias no lugar correto.
  300. </para>
  301. <para>
  302. Existe uma combinação de configurações alternativas que você pode querer empregar
  303. dependendo das configurações do seu servidor, do seu nível de acesso, ou de
  304. outras razões.
  305. </para>
  306. <para>
  307. <emphasis>Configuração Alternativa</emphasis> envolve guardar o download do
  308. Zend Framework junto como está, e alterar ambos seu sistema de <constant>PATH</constant>
  309. bem como o arquivo <filename>php.ini</filename>. No seu ambiente de usuário,
  310. tenha certeza de adcionar <filename>C:\Path\To\ZendFramework\bin</filename>,
  311. então seu arquivo <filename>zf.bat</filename> será executável. Também, altere
  312. o arquivo <filename>php.ini</filename> certificando que
  313. <filename>C:\Path\To\ZendFramework\library</filename> está no seu
  314. <property>include_path</property>.
  315. </para>
  316. </sect4>
  317. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-othernotes">
  318. <title>Outras Considerações de Configuração</title>
  319. <para>
  320. Se por alguma razão você não quiser a biblioteca do Zend Framework dentro
  321. do seu <property>include_path</property>, existe uma outra opção. Existem
  322. duas variáveis de ambiente especiais que o <filename>zf.php</filename> irá
  323. utilizar para determinar a localização da sua instalação do Zend Framework.
  324. </para>
  325. <para>
  326. A primeira é <constant>ZEND_TOOL_INCLUDE_PATH_PREPEND</constant>, que irá
  327. preceder o valor da variável de ambiente para o sistema de (<filename>php.ini</filename>)
  328. <property>include_path</property> <property>include_path</property> antes
  329. da carga do cliente.
  330. </para>
  331. <para>
  332. Alternativamente, você pode querer usar <constant>ZEND_TOOL_INCLUDE_PATH</constant>
  333. para <emphasis>substituir</emphasis> completamente o sistema de
  334. <property>include_path</property> para um que faça sentido especialmente para
  335. a ferramente de linha de comando <command>zf</command>.
  336. </para>
  337. </sect4>
  338. </sect3>
  339. <sect3 id="zend.tool.extending.zend-tool-framework.providers-and-manifests">
  340. <title>Criando Providers</title>
  341. <para>
  342. Em geral, um provider, por si só, é nada mais que o a casca para um
  343. desenvolvedor para agrupar-se algumas das capacidades que eles desejam
  344. enviar com um o cliente de linha de comando (ou outro). Ele é um análogo
  345. para o que um "controller" é dentro da sua aplicação <acronym>MVC</acronym>.
  346. </para>
  347. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading">
  348. <title>Como o Zend_Tool encontra seus Providers</title>
  349. <para>
  350. Por padrão <classname>Zend_Tool</classname> usa o BasicLoader para encontrar
  351. todos os providers que você pode rodar. Ele itera recursivamente todos
  352. os diretórios do include path e abre todos os arquivos que terminam
  353. com "Manifest.php" ou "Provider.php". Todas as classes naqueles arquivos
  354. são inspecionadas se implementam ou <classname>Zend_Tool_Framework_Provider_Interface</classname>
  355. ou <classname>Zend_Tool_Framework_Manifest_ProviderManifestable</classname>.
  356. Instancias da interface do provider implementam a real funcionalidade e
  357. todos os métodos públicos estão acessíveis como actions do provider.
  358. A interface ProviderManifestable de qualquer forma requer a implementação de um
  359. metodo <methodname>getProviders()</methodname> que reforna um array de
  360. instâncias da interface provider.
  361. </para>
  362. <para>
  363. The following naming rules apply on how you can access the providers
  364. that were found by the IncludePathLoader:
  365. </para>
  366. <itemizedlist>
  367. <listitem>
  368. <para>
  369. The last part of your classname split by underscore is used
  370. for the provider name, e.g. "My_Provider_Hello" leads to your
  371. provider being accessible by the name "hello".
  372. </para>
  373. </listitem>
  374. <listitem>
  375. <para>
  376. If your provider has a method <methodname>getName()</methodname>
  377. it will be used instead of the previous method to determine
  378. the name.
  379. </para>
  380. </listitem>
  381. <listitem>
  382. <para>
  383. If your provider has "Provider" as prefix, e.g. it is called
  384. <classname>My_HelloProvider</classname> it will be stripped
  385. from the name so that the provider will be called "hello".
  386. </para>
  387. </listitem>
  388. </itemizedlist>
  389. <note>
  390. <para>The IncludePathLoader does not follow symlinks, that means
  391. you cannot link provider functionality into your include paths,
  392. they have to be physically present in the include paths.</para>
  393. </note>
  394. <example
  395. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading.example">
  396. <title>Exposing Your Providers with a Manifest</title>
  397. <para>
  398. You can expose your providers to <classname>Zend_Tool</classname> by
  399. offering a manifest with a special filename ending with "Manifest.php".
  400. A Provider Manifest is an implementation of the
  401. <interface>Zend_Tool_Framework_Manifest_ProviderManifestable</interface>
  402. and requires the <methodname>getProviders()</methodname> method to return
  403. an array of instantiated providers. In anticipation of our first
  404. own provider <classname>My_Component_HelloProvider</classname>
  405. we will create the following manifest:
  406. </para>
  407. <programlisting language="php"><![CDATA[
  408. class My_Component_Manifest
  409. implements Zend_Tool_Framework_Manifest_ProviderManifestable
  410. {
  411. public function getProviders()
  412. {
  413. return array(
  414. new My_Component_HelloProvider()
  415. );
  416. }
  417. }
  418. ]]></programlisting>
  419. </example>
  420. </sect4>
  421. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.basic">
  422. <title>Basic Instructions for Creating Providers</title>
  423. <para>
  424. As an example, if a developer wants to add the capability of showing
  425. the version of a datafile that his 3rd party component is working
  426. from, there is only one class the developer would need to implement.
  427. Assuming the component is called <classname>My_Component</classname>, he would
  428. create a class named <classname>My_Component_HelloProvider</classname> in a
  429. file named <filename>HelloProvider.php</filename> somewhere on the
  430. <property>include_path</property>. This class would implement
  431. <classname>Zend_Tool_Framework_Provider_Interface</classname>, and the body of
  432. this file would only have to look like the following:
  433. </para>
  434. <programlisting language="php"><![CDATA[
  435. class My_Component_HelloProvider
  436. implements Zend_Tool_Framework_Provider_Interface
  437. {
  438. public function say()
  439. {
  440. echo 'Hello from my provider!';
  441. }
  442. }
  443. ]]></programlisting>
  444. <para>
  445. Given that code above, and assuming the developer wishes to access
  446. this functionality through the console client, the call would look
  447. like this:
  448. </para>
  449. <programlisting language="sh"><![CDATA[
  450. % zf say hello
  451. Hello from my provider!
  452. ]]></programlisting>
  453. </sect4>
  454. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.response">
  455. <title>The response object</title>
  456. <para>
  457. As discussed in the architecture section <classname>Zend_Tool</classname> allows
  458. to hook different clients for using your <classname>Zend_Tool</classname>
  459. providers. To keep compliant with different clients you should use the response
  460. object to return messages from your providers instead of using
  461. <methodname>echo()</methodname> or a similiar output mechanism. Rewritting our
  462. hello provider with this knowledge it looks like:
  463. </para>
  464. <programlisting language="php"><![CDATA[
  465. class My_Component_HelloProvider
  466. extends Zend_Tool_Framework_Provider_Abstract
  467. {
  468. public function say()
  469. {
  470. $this->_registry
  471. ->getResponse()
  472. ->appendContent("Hello from my provider!");
  473. }
  474. }
  475. ]]></programlisting>
  476. <para>
  477. As you can see one has to extend the
  478. <classname>Zend_Tool_Framework_Provider_Abstract</classname> to gain access to
  479. the Registry which holds the
  480. <classname>Zend_Tool_Framework_Client_Response</classname> instance.
  481. </para>
  482. </sect4>
  483. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced">
  484. <title>Advanced Development Information</title>
  485. <sect5
  486. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.variables">
  487. <title>Passing Variables to a Provider</title>
  488. <para>
  489. The above "Hello World" example is great for simple commands, but
  490. what about something more advanced? As your scripting and tooling
  491. needs grow, you might find that you need the ability to accept
  492. variables. Much like function signatures have parameters, your
  493. tooling requests can also accept parameters.
  494. </para>
  495. <para>
  496. Just as each tooling request can be isolated to a method within a
  497. class, the parameters of a tooling request can also be isolated in a
  498. very well known place. Parameters of the action methods of a
  499. provider can include the same parameters you want your client to
  500. utilize when calling that provider and action combination. For
  501. example, if you wanted to accept a name in the above example, you
  502. would probably do this in OO code:
  503. </para>
  504. <programlisting language="php"><![CDATA[
  505. class My_Component_HelloProvider
  506. implements Zend_Tool_Framework_Provider_Interface
  507. {
  508. public function say($name = 'Ralph')
  509. {
  510. echo 'Hello' . $name . ', from my provider!';
  511. }
  512. }
  513. ]]></programlisting>
  514. <para>
  515. The above example can then be called via the command line
  516. <command>zf say hello Joe</command>. "Joe" will be supplied to the provider
  517. as a parameter of the method call. Also note, as you see that the
  518. parameter is optional, that means it is also optional on the command
  519. line, so that <command>zf say hello</command> will still work, and default
  520. to the name "Ralph".
  521. </para>
  522. </sect5>
  523. <sect5
  524. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.prompt">
  525. <title>Prompt the User for Input</title>
  526. <para>
  527. There are cases when the workflow of your provider requires
  528. to prompt the user for input. This can be done by requesting
  529. the client to ask for more the required input by calling:
  530. </para>
  531. <programlisting language="php"><![CDATA[
  532. class My_Component_HelloProvider
  533. extends Zend_Tool_Framework_Provider_Abstract
  534. {
  535. public function say($name = 'Ralph')
  536. {
  537. $nameResponse = $this->_registry
  538. ->getClient()
  539. ->promptInteractiveInput("Whats your name?");
  540. $name = $nameResponse->getContent();
  541. echo 'Hello' . $name . ', from my provider!';
  542. }
  543. }
  544. ]]></programlisting>
  545. <para>
  546. This command throws an exception if the current client is not
  547. able to handle interactive requests. In case of the default Console Client
  548. however you will be asked to enter the name.
  549. </para>
  550. </sect5>
  551. <sect5
  552. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.pretendable">
  553. <title>Pretending to execute a Provider Action</title>
  554. <para>
  555. Another interesting feature you might wish to implement is
  556. <emphasis>pretendability</emphasis>. Pretendabilty is the ability
  557. for your provider to "pretend" as if it is doing the requested
  558. action and provider combination and give the user as much
  559. information about what it <emphasis>would</emphasis> do without
  560. actually doing it. This might be an important notion when doing
  561. heavy database or filesystem modifications that the user might not
  562. otherwise want to do.
  563. </para>
  564. <para>
  565. Pretendability is easy to implement. There are two parts to this
  566. feature: 1) marking the provider as having the ability to "pretend",
  567. and 2) checking the request to ensure the current request was indeed
  568. asked to be "pretended". This feature is demonstrated in the code
  569. sample below.
  570. </para>
  571. <programlisting language="php"><![CDATA[
  572. class My_Component_HelloProvider
  573. extends Zend_Tool_Framework_Provider_Abstract
  574. implements Zend_Tool_Framework_Provider_Pretendable
  575. {
  576. public function say($name = 'Ralph')
  577. {
  578. if ($this->_registry->getRequest()->isPretend()) {
  579. echo 'I would say hello to ' . $name . '.';
  580. } else {
  581. echo 'Hello' . $name . ', from my provider!';
  582. }
  583. }
  584. }
  585. ]]></programlisting>
  586. <para>
  587. To run the provider in pretend mode just call:
  588. </para>
  589. <programlisting language="sh"><![CDATA[
  590. % zf --pretend say hello Ralph
  591. I would say hello Ralph.
  592. ]]></programlisting>
  593. </sect5>
  594. <sect5
  595. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.verbosedebug">
  596. <title>Verbose and Debug modes</title>
  597. <para>
  598. You can also run your provider actions in "verbose" or "debug" modes.
  599. The semantics in regard to this actions have to be implemented by you
  600. in the context of your provider. You can access debug or verbose modes
  601. with:
  602. </para>
  603. <programlisting language="php"><![CDATA[
  604. class My_Component_HelloProvider
  605. implements Zend_Tool_Framework_Provider_Interface
  606. {
  607. public function say($name = 'Ralph')
  608. {
  609. if($this->_registry->getRequest()->isVerbose()) {
  610. echo "Hello::say has been called\n";
  611. }
  612. if($this->_registry->getRequest()->isDebug()) {
  613. syslog(LOG_INFO, "Hello::say has been called\n");
  614. }
  615. }
  616. }
  617. ]]></programlisting>
  618. </sect5>
  619. <sect5
  620. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.configstorage">
  621. <title>Accessing User Config and Storage</title>
  622. <para>
  623. Using the Enviroment variable <property>ZF_CONFIG_FILE</property> or the
  624. .zf.ini in your home directory you can inject configuration parameters into
  625. any <classname>Zend_Tool</classname> provider. Access to this configuration
  626. is available via the registry that is passed to your provider if you extend
  627. <classname>Zend_Tool_Framework_Provider_Abstract</classname>.
  628. </para>
  629. <programlisting language="php"><![CDATA[
  630. class My_Component_HelloProvider
  631. extends Zend_Tool_Framework_Provider_Abstract
  632. {
  633. public function say()
  634. {
  635. $username = $this->_registry->getConfig()->username;
  636. if(!empty($username)) {
  637. echo "Hello $username!";
  638. } else {
  639. echo "Hello!";
  640. }
  641. }
  642. }
  643. ]]></programlisting>
  644. <para>
  645. The returned configuration is of the type
  646. <classname>Zend_Tool_Framework_Client_Config</classname> but internally the
  647. <methodname>__get()</methodname> and <methodname>__set()</methodname> magic
  648. methods proxy to a <classname>Zend_Config</classname> of the given
  649. configuration type.
  650. </para>
  651. <para>
  652. The storage allows to save arbitrary data for later reference. This can be
  653. useful for batch processing tasks or for re-runs of your tasks. You can
  654. access the storage in a similar way like the configuration:
  655. </para>
  656. <programlisting language="php"><![CDATA[
  657. class My_Component_HelloProvider
  658. extends Zend_Tool_Framework_Provider_Abstract
  659. {
  660. public function say()
  661. {
  662. $aValue = $this->_registry->getStorage()->get("myUsername");
  663. echo "Hello $aValue!";
  664. }
  665. }
  666. ]]></programlisting>
  667. <para>
  668. The <acronym>API</acronym> of the storage is very simple:
  669. </para>
  670. <programlisting language="php"><![CDATA[
  671. class Zend_Tool_Framework_Client_Storage
  672. {
  673. public function setAdapter($adapter);
  674. public function isEnabled();
  675. public function put($name, $value);
  676. public function get($name, $defaultValue=null);
  677. public function has($name);
  678. public function remove($name);
  679. public function getStreamUri($name);
  680. }
  681. ]]></programlisting>
  682. <important>
  683. <para>
  684. When designing your providers that are config or storage aware remember
  685. to check if the required user-config or storage keys really exist for a
  686. user. You won't run into fatal errors when none of these are provided
  687. though, since empty ones are created upon request.
  688. </para>
  689. </important>
  690. </sect5>
  691. </sect4>
  692. </sect3>
  693. </sect2>
  694. <sect2 id="zend.tool.extending.zend-tool-project">
  695. <title>Zend_Tool_Project Extensions</title>
  696. <para>
  697. <classname>Zend_Tool_Project</classname> exposes a rich set of functionality and
  698. capabilities that make the task of creating new providers, specficially those targetting
  699. project easier and more manageable.
  700. </para>
  701. <sect3 id="zend.tool.extending.zend-tool-project.architecture">
  702. <title>Overall Architecture</title>
  703. <para>
  704. This same concept applies to Zend Framework projects. In Zend Framework projects,
  705. you have controllers, actions, views, models, databases and so on and so forth. In
  706. terms of <classname>Zend_Tool</classname>, we need a way to track these types of
  707. resources - thus <classname>Zend_Tool_Project</classname>.
  708. </para>
  709. <para>
  710. <classname>Zend_Tool_Project</classname> is capable of tracking project resources
  711. throughout the development of a project. So, for example, if in one command you
  712. created a controller, and in the next command you wish to create an action within
  713. that controller, <classname>Zend_Tool_Project</classname> is gonna have to
  714. <emphasis>know</emphasis> about the controller file you created so that you can (in
  715. the next action), be able to append that action to it. This is what keeps our
  716. projects up to date and <emphasis>stateful</emphasis>.
  717. </para>
  718. <para>
  719. Another important point to understand about projects is that typically, resources
  720. are organized in a hierarchical fashion. With that in mind,
  721. <classname>Zend_Tool_Project</classname> is capable of serializing the current
  722. project into a internal representation that allows it to keep track of not only
  723. <emphasis>what</emphasis> resources are part of a project at any given time, but
  724. also <emphasis>where</emphasis> they are in relation to one another.
  725. </para>
  726. </sect3>
  727. <sect3 id="zend.tool.extending.zend-tool-project.providers">
  728. <title>Creating Providers</title>
  729. <para>
  730. Project specific providers are created in the same fashion as plain framework
  731. providers, with one exception: project providers must extend the
  732. <classname>Zend_Tool_Project_Provider_Abstract</classname>. This class comes with
  733. some significant functionality that helps developers load existing project, obtian
  734. the profile object, and be able to search the profile, then later store any changes
  735. to the current project profile.
  736. </para>
  737. <programlisting language="php"><![CDATA[
  738. class My_Component_HelloProvider
  739. extends Zend_Tool_Project_Provider_Abstract
  740. {
  741. public function say()
  742. {
  743. $profile = $this->_loadExistingProfile();
  744. /* ... do project stuff here */
  745. $this->_storeProfile();
  746. }
  747. }
  748. ]]></programlisting>
  749. </sect3>
  750. <!--
  751. <sect3 id="zend.tool.extending.zend-tool-project.resources-and-contexts">
  752. <title>Creating Resources &amp; Contexts</title>
  753. </sect3>
  754. -->
  755. </sect2>
  756. </sect1>