Zend_Tool-Extending.xml 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 20807 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.tool.extending">
  5. <title>Zend_Tool erweitern</title>
  6. <sect2 id="zend.tool.extending.overview">
  7. <title>Übersicht über Zend_Tool</title>
  8. <para>
  9. <classname>Zend_Tool_Framework</classname> ist ein Framework für die Bereitstellung
  10. gemeinsamer Funktionalitäten wie die Erstellung von Projekthüllen, Code Erzeugung,
  11. Erstellung von Suchindezes, und noch mehr. Funktionalitäten können geschrieben und über
  12. <acronym>PHP</acronym> Klassen in den <acronym>PHP</acronym>
  13. <property>include_path</property> geworfen werden, was eine immense Flexibilität der
  14. Implementation liefert. Die Funktionalität kann dann verwendet werden indem eine
  15. Implementation geschrieben wird oder durch protokoll-spezifische Clients -- wie Konsolen
  16. Clients, <acronym>XML-RPC</acronym>, <acronym>SOAP</acronym>, und andere.
  17. </para>
  18. <para>
  19. <classname>Zend_Tool_Project</classname> baut auf die Möglichkeiten von
  20. <classname>Zend_Tool_Framework</classname> auf und erweitert diese um ein "Projekt" zu
  21. managen. Generell ist ein "Projekt" ein geplantes Ereignis oder eine Initiative. In der
  22. Computerwelt sind Projekte generell Sammlungen von Ressourcen. Diese Ressourcen können
  23. Dateien, Verzeichnisse, Datenbanken, Schematas, Bilder, Stile und anderes sein.
  24. </para>
  25. </sect2>
  26. <sect2 id="zend.tool.extending.zend-tool-framework">
  27. <title>Erweiterungen von Zend_Tool_Framework</title>
  28. <sect3 id="zend.tool.extending.zend-tool-framework.architecture">
  29. <title>Überblick der Architektur</title>
  30. <para>
  31. <classname>Zend_Tool_Framework</classname> bietet das folgende:
  32. </para>
  33. <itemizedlist>
  34. <listitem>
  35. <para>
  36. <emphasis>Gemeinsame Interfaces und Abstraktes</emphasis> welche es
  37. Entwicklern erlauben Funktionalitäten und Möglichkeiten zu erstellen welche
  38. durch Tooling Clients verwendbar sind.
  39. </para>
  40. </listitem>
  41. <listitem>
  42. <para>
  43. <emphasis>Grundsätzliche Client Funktionalität</emphasis> und eine konkrete
  44. Konsolenimplementation welche externe Tools und Interfaces mit
  45. <classname>Zend_Tool_Framework</classname> verbindet. Der Konsolenclient
  46. kann in <acronym>CLI</acronym> Umgebungen verwendet werden, wie Unix Shells
  47. und der Windows Konsole.
  48. </para>
  49. </listitem>
  50. <listitem>
  51. <para>
  52. <emphasis>"Provider" und "Manifest" Interfaces</emphasis> welche vom
  53. Toolingsystem verwendet werden können. "Provider" repräsentieren den
  54. funktionalen Aspekt des Frameworks, und definieren die Aktionen welche
  55. Tooling Clients aufrufen können. "Manifests" agieren als Metadaten
  56. Registrierungen welche zusätzlichen Kontext für die verschiedenen
  57. definierten Provider bieten.
  58. </para>
  59. </listitem>
  60. <listitem>
  61. <para>
  62. <emphasis>Ein introspektives Ladesystem</emphasis> welches die Umgebung auf
  63. Provider scannt und erkennt was benötigt wird um Sie auszuführen.
  64. </para>
  65. </listitem>
  66. <listitem>
  67. <para>
  68. <emphasis>Ein Standardset von System Provider</emphasis> welche dem System
  69. erlauben zu melden was die kompletten Möglichkeiten des Systems sind, und
  70. ein nützliches Feedback bieten. Das beinhaltet auch ein ausführliches
  71. "Hilfe System".
  72. </para>
  73. </listitem>
  74. </itemizedlist>
  75. <para>
  76. Definitionen welche man in diesem Handbuch in Bezug auf
  77. <classname>Zend_Tool_Framework</classname> beachten sollte sind:
  78. </para>
  79. <itemizedlist>
  80. <listitem>
  81. <para>
  82. <classname>Zend_Tool_Framework</classname> - Der Framework welche die
  83. Tooling Möglichkeiten bereitstellt.
  84. </para>
  85. </listitem>
  86. <listitem>
  87. <para>
  88. <emphasis>Tooling Client</emphasis> - Ein Entwickler-Tool welches sich zum
  89. <classname>Zend_Tool_Framework</classname> verbindet und Ihn verwendet.
  90. </para>
  91. </listitem>
  92. <listitem>
  93. <para>
  94. <emphasis>Client</emphasis> - Das Subsystem von
  95. <classname>Zend_Tool_Framework</classname> welches ein Interface
  96. bereitstellt so das sich Tooling-Clienten verbinden, und Kommandos abfragen
  97. und ausführen können.
  98. </para>
  99. </listitem>
  100. <listitem>
  101. <para>
  102. <emphasis>Konsolen Client / Kommandozeilen Interface /
  103. <filename>zf.php</filename></emphasis> - Der Tooling Client für die
  104. Kommandozeile.
  105. </para>
  106. </listitem>
  107. <listitem>
  108. <para>
  109. <emphasis>Provider</emphasis> - Ein Subsystem und eine Sammlung von
  110. eingebauten Funktionalitäten welche der Framework exportiert.
  111. </para>
  112. </listitem>
  113. <listitem>
  114. <para>
  115. <emphasis>Manifest</emphasis> - Ein Subsystem für die Definition,
  116. Organisation, und Verbreitung von Daten welche Provider benötigen.
  117. </para>
  118. </listitem>
  119. <listitem>
  120. <para>
  121. <classname>Zend_Tool_Project</classname> Provider - Ein Set von Providern
  122. speziell für die Erstellung und die Wartung von Zend Framework basierenden
  123. Projekten.
  124. </para>
  125. </listitem>
  126. </itemizedlist>
  127. </sect3>
  128. <sect3 id="zend.tool.extending.zend-tool-framework.cli-client">
  129. <title>Verstehen des CLI Clients</title>
  130. <para>
  131. Das <acronym>CLI</acronym>, oder Kommandozeilen-Tool (intern als das Konsolen-Tool
  132. bekannt) ist aktuell das primäre Interface für die Bearbeitung von
  133. <classname>Zend_Tool</classname> Anfragen. Mit dem <acronym>CLI</acronym> Tool
  134. können Entwickler Tooling-Anfragen im "Kommandozeilen-Fenster" behandeln,
  135. üblicherweise auch als "Terminal" Fenster bekannt. Diese Umgebung ist in einer *nix
  136. Umgebung vorherrschend, hat aber auch eine übliche Implementation in Windows mit
  137. <filename>cmd.exe</filename>, Console2 und mit dem Cygwin Projekt.
  138. </para>
  139. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-general">
  140. <title>Das CLI Tool vorbereiten</title>
  141. <para>
  142. Um Tooling-Anfragen über den Kommandozeilen-Client auszuführen, muss man zuerst
  143. den Client vorbereiten so dass das System den "zf" Befehl ausführen kann. Der
  144. Kommandozeilen-Client ist, für alle Wünsche und Zwecke, die Datei
  145. <filename>.sh</filename> oder <filename>.bat</filename> welche mit der Zend
  146. Framework Distribution bereitgestellt wird. Im Trunk kann er hier gefunden
  147. werden: <ulink
  148. url="http://framework.zend.com/svn/framework/standard/trunk/bin/">http://framework.zend.com/svn/framework/standard/trunk/bin/</ulink>.
  149. </para>
  150. <para>
  151. Wie man sehen kann, gibt es 3 Dateien im <filename>/bin/</filename> Verzeichnis:
  152. <filename>zf.php</filename>, <filename>zf.sh</filename>, und
  153. <filename>zf.bat</filename>. <filename>zf.sh</filename> und
  154. <filename>zf.bat</filename> sind Betriebssystem-spezifische Client-Wrapper:
  155. <filename>zf.sh</filename> für die *nix Umgebung, und
  156. <filename>zf.bat</filename> für die Win32 Umgebung. Diese Client-Wrapper sind
  157. für das Finden der richtigen <filename>php.exe</filename>, das finden der
  158. <filename>zf.php</filename>, und die Übergabe an die Anfrage des Clients
  159. zuständig. Die <filename>zf.php</filename> ist verantwortlich für die
  160. Behandlung der Umgebung, die Erstellung des richtigen include_path, und der
  161. Übergabe von dem was auf der Kommandozeile angegeben wurde an die richtige
  162. Bibliothekskomponente für die Bearbeitung.
  163. </para>
  164. <para>
  165. Ultimativ, muss man zwei Dinge sicherstellen damit alles funktioniert,
  166. unabhängig vom Betriebssystem auf dem man arbeitet:
  167. </para>
  168. <orderedlist>
  169. <listitem>
  170. <para>
  171. <filename>zf.sh/zf.bat</filename> ist vom Systempfad aus erreichbar.
  172. Das ist die Fähigkeit <command>zf</command> von überall aus aufzurufen,
  173. unabhängig von aktuellen Arbeitsverzeichnisses.
  174. </para>
  175. </listitem>
  176. <listitem>
  177. <para>
  178. <filename>ZendFramework/library</filename> ist im
  179. <property>include_path</property>.
  180. </para>
  181. </listitem>
  182. </orderedlist>
  183. <note>
  184. <para>
  185. Zu beachten: Wärend das oben stehende sind die idealsten Notwendigkeiten
  186. sind, kann man einfach Zend Framework herunterladen und erwarten das es
  187. mit <filename>./path/to/zf.php</filename> und einem Kommando funktioniert.
  188. </para>
  189. </note>
  190. </sect4>
  191. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-starnix">
  192. <title>Das CLI Tool auf Unix-artigen Systemen einrichten</title>
  193. <para>
  194. Das üblichste Setzup in einer *nix Umgebung ist es, <filename>zf.sh</filename>
  195. und <filename>zf.sh</filename> in das selbe Verzeichnis wie die
  196. <acronym>PHP</acronym> Bibliothek zu kopieren. Diese kann normalerweise in einem
  197. der folgenden Plätze gefunden werden:
  198. </para>
  199. <programlisting language="text"><![CDATA[
  200. /usr/bin
  201. /usr/local/bin
  202. /usr/local/ZendServer/bin/
  203. /Applications/ZendServer/bin/
  204. ]]></programlisting>
  205. <para>
  206. To find out the location of your <acronym>PHP</acronym> binary, you can execute
  207. 'which php' on the command line. This will return the location of the
  208. <acronym>PHP</acronym> binary you will be using to run <acronym>PHP</acronym>
  209. scripts in this environment.
  210. </para>
  211. <para>
  212. The next order of business is to ensure that Zend Framework
  213. library is set up correctly inside of the system <acronym>PHP</acronym>
  214. <property>include_path</property>. To find out where your
  215. <property>include_path</property> is located, you can execute
  216. <command>php -i</command> and look for the <property>include_path</property>
  217. variable, or more succinctly, execute
  218. <command>php -i | grep include_path</command>. Once you have found where
  219. your <property>include_path</property> is located (this will generally be
  220. something like <filename>/usr/lib/php</filename>,
  221. <filename>/usr/share/php</filename>, <filename>/usr/local/lib/php</filename>, or
  222. similar), ensure that the contents of the <filename>/library/</filename>
  223. directory are put inside your <property>include_path</property> specified
  224. directory.
  225. </para>
  226. <para>
  227. Once you have done those two things, you should be able to issue a
  228. command and get back the proper response like this:
  229. </para>
  230. <para>
  231. <inlinegraphic scale="100" align="center" valign="middle"
  232. fileref="figures/zend.tool.framework.cliversionunix.png" format="PNG" />
  233. </para>
  234. <para>
  235. If you do not see this type of output, go back and check your setup
  236. to ensure you have all of the necessary pieces in the proper place.
  237. </para>
  238. <para>
  239. There are a couple of alternative setups you might want to employ
  240. depending on your servers configuration, your level of access, or
  241. for other reasons.
  242. </para>
  243. <para>
  244. <emphasis>Alternative Setup</emphasis> involves keeping the Zend Framework
  245. download together as is, and creating a link from a <constant>PATH</constant>
  246. location to the <filename>zf.sh</filename>. What this means is you can
  247. place the contents of the ZendFramework download into a location
  248. such as <filename>/usr/local/share/ZendFramework</filename>, or more locally
  249. like <filename>/home/username/lib/ZendFramework</filename>, and creating a
  250. symbolic link to the <filename>zf.sh</filename>.
  251. </para>
  252. <para>
  253. Assuming you want to put the link inside <filename>/usr/local/bin</filename>
  254. (this could also work for placing the link inside
  255. <filename>/home/username/bin/</filename> for example) you would issue a
  256. command similar to this: </para>
  257. <programlisting language="sh"><![CDATA[
  258. ln -s /usr/local/share/ZendFramework/bin/zf.sh /usr/local/bin/zf
  259. # OR (for example)
  260. ln -s /home/username/lib/ZendFramework/bin/zf.sh /home/username/bin/zf
  261. ]]></programlisting>
  262. <para>
  263. This will create a link which you should be able to access globally
  264. on the command line.
  265. </para>
  266. </sect4>
  267. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-windows">
  268. <title>Setting up the CLI tool on Windows</title>
  269. <para>
  270. The most common setup in the Windows Win32 environment, is to copy
  271. the <filename>zf.bat</filename> and <filename>zf.php</filename> into the same
  272. directory as your <acronym>PHP</acronym> binary. This can generally be found in
  273. one of the following places:
  274. </para>
  275. <programlisting language="text"><![CDATA[
  276. C:\PHP
  277. C:\Program Files\ZendServer\bin\
  278. C:\WAMP\PHP\bin
  279. ]]></programlisting>
  280. <para>
  281. You should be able to run <filename>php.exe</filename> on the command line.
  282. If you are not able to, first check the documentation that came with
  283. your <acronym>PHP</acronym> distribution, or ensure that the path to
  284. <filename>php.exe</filename> is in your
  285. Windows <constant>PATH</constant> environment variable.
  286. </para>
  287. <para>
  288. The next order of business is to ensure that Zend Framework
  289. library is set up correctly inside of the system <acronym>PHP</acronym>
  290. <property>include_path</property>. To find out where your
  291. <property>include_path</property> is located, you can type <command>php -i</command> and
  292. look for the <property>include_path</property> variable, or more succinctly
  293. execute <command>php -i | grep include_path</command> if you have Cygwin setup with
  294. grep available. Once you have found where your
  295. <property>include_path</property> is located (this will generally be
  296. something like <filename>C:\PHP\pear</filename>, <filename>C:\PHP\share</filename>,
  297. <filename>C:\Program%20Files\ZendServer\share</filename> or similar), ensure
  298. that the contents of the library/ directory are put inside your
  299. <property>include_path</property> specified directory.
  300. </para>
  301. <para>
  302. Once you have done those two things, you should be able to issue a
  303. command and get back the proper response like this:
  304. </para>
  305. <para>
  306. <inlinegraphic scale="100" align="center" valign="middle"
  307. fileref="figures/zend.tool.framework.cliversionwin32.png" format="PNG" />
  308. </para>
  309. <para>
  310. If you do not see this type of output, go back and check your setup
  311. to ensure you have all of the necessary pieces in the proper place.
  312. </para>
  313. <para>
  314. There are a couple of alternative setups you might want to employ
  315. depending on your server's configuration, your level of access, or
  316. for other reasons.
  317. </para>
  318. <para>
  319. <emphasis>Alternative Setup</emphasis> involves keeping the Zend
  320. Framework download together as is, and altering both your system
  321. <constant>PATH</constant> as well as the <filename>php.ini</filename> file.
  322. In your user's environment, make sure to add
  323. <filename>C:\Path\To\ZendFramework\bin</filename>, so that your
  324. <filename>zf.bat</filename> file is executable. Also, alter the
  325. <filename>php.ini</filename> file to ensure that
  326. <filename>C:\Path\To\ZendFramework\library</filename> is in your
  327. <property>include_path</property>.
  328. </para>
  329. </sect4>
  330. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-othernotes">
  331. <title>Other Setup Considerations</title>
  332. <para>
  333. If for some reason you do not want Zend Framework library inside
  334. your <property>include_path</property>, there is another option. There are
  335. two special environment variables that <filename>zf.php</filename> will
  336. utilize to determine the location of your Zend Framework
  337. installation.
  338. </para>
  339. <para>
  340. The first is <constant>ZEND_TOOL_INCLUDE_PATH_PREPEND</constant>, which will
  341. prepend the value of this environment variable to the system
  342. (<filename>php.ini</filename>) <property>include_path</property> before loading the
  343. client.
  344. </para>
  345. <para>
  346. Alternatively, you might want to use
  347. <constant>ZEND_TOOL_INCLUDE_PATH</constant> to completely
  348. <emphasis>replace</emphasis> the system <property>include_path</property>
  349. for one that makes sense specifically for the <command>zf</command>
  350. command line tool.
  351. </para>
  352. </sect4>
  353. </sect3>
  354. <sect3 id="zend.tool.extending.zend-tool-framework.providers-and-manifests">
  355. <title>Creating Providers</title>
  356. <para>
  357. In general, a provider, on its own, is nothing more than the shell for a
  358. developer to bundle up some capabilities they wish to dispatch with the
  359. command line (or other) clients. It is an analogue to what a
  360. "controller" is inside of your <acronym>MVC</acronym> application.
  361. </para>
  362. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading">
  363. <title>How Zend Tool finds your Providers</title>
  364. <para>
  365. By default Zend Tool uses the BasicLoader to find all
  366. the providers that you can run. It recursivly iterates all
  367. include path directories and opens all files that end
  368. with "Manifest.php" or "Provider.php". All classes in these
  369. files are inspected if they implement either
  370. <classname>Zend_Tool_Framework_Provider_Interface</classname>
  371. or <classname>Zend_Tool_Framework_Manifest_ProviderManifestable</classname>.
  372. Instances of the provider interface make up for the real functionality
  373. and all their public methods are accessible as provider actions.
  374. The ProviderManifestable interface however requires the implementation of a method
  375. <methodname>getProviders()</methodname> which returns an array of
  376. instantiated provider interface instances.
  377. </para>
  378. <para>
  379. The following naming rules apply on how you can access the providers
  380. that were found by the IncludePathLoader:
  381. </para>
  382. <itemizedlist>
  383. <listitem>
  384. <para>
  385. The last part of your classname split by underscore is used
  386. for the provider name, e.g. "My_Provider_Hello" leads to your
  387. provider being accessible by the name "hello".
  388. </para>
  389. </listitem>
  390. <listitem>
  391. <para>
  392. If your provider has a method <methodname>getName()</methodname>
  393. it will be used instead of the previous method to determine
  394. the name.
  395. </para>
  396. </listitem>
  397. <listitem>
  398. <para>
  399. If your provider has "Provider" as prefix, e.g. it is called
  400. <classname>My_HelloProvider</classname> it will be stripped
  401. from the name so that the provider will be called "hello".
  402. </para>
  403. </listitem>
  404. </itemizedlist>
  405. <note>
  406. <para>The IncludePathLoader does not follow symlinks, that means
  407. you cannot link provider functionality into your include paths,
  408. they have to be physically present in the include paths.</para>
  409. </note>
  410. <example id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading.example">
  411. <title>Exposing Your Providers with a Manifest</title>
  412. <para>
  413. You can expose your providers to Zend Tool by offering a manifest
  414. with a special filename ending with "Manifest.php".
  415. A Provider Manifest is an implementation of the
  416. <interface>Zend_Tool_Framework_Manifest_ProviderManifestable</interface>
  417. and requires the <methodname>getProviders()</methodname> method to return
  418. an array of instantiated providers. In anticipation of our first
  419. own provider <classname>My_Component_HelloProvider</classname>
  420. we will create the following manifest:
  421. </para>
  422. <programlisting language="php"><![CDATA[
  423. class My_Component_Manifest
  424. implements Zend_Tool_Framework_Manifest_ProviderManifestable
  425. {
  426. public function getProviders()
  427. {
  428. return array(
  429. new My_Component_HelloProvider()
  430. );
  431. }
  432. }
  433. ]]></programlisting>
  434. </example>
  435. </sect4>
  436. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.basic">
  437. <title>Basic Instructions for Creating Providers</title>
  438. <para>
  439. As an example, if a developer wants to add the capability of showing
  440. the version of a datafile that his 3rd party component is working
  441. from, there is only one class the developer would need to implement.
  442. Assuming the component is called <classname>My_Component</classname>, he would
  443. create a class named <classname>My_Component_HelloProvider</classname> in a
  444. file named <filename>HelloProvider.php</filename> somewhere on the
  445. <property>include_path</property>. This class would implement
  446. <classname>Zend_Tool_Framework_Provider_Interface</classname>, and the body of
  447. this file would only have to look like the following:
  448. </para>
  449. <programlisting language="php"><![CDATA[
  450. class My_Component_HelloProvider
  451. implements Zend_Tool_Framework_Provider_Interface
  452. {
  453. public function say()
  454. {
  455. echo 'Hello from my provider!';
  456. }
  457. }
  458. ]]></programlisting>
  459. <para>
  460. Given that code above, and assuming the developer wishes to access
  461. this functionality through the console client, the call would look
  462. like this:
  463. </para>
  464. <programlisting language="sh"><![CDATA[
  465. % zf say hello
  466. Hello from my provider!
  467. ]]></programlisting>
  468. </sect4>
  469. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.response">
  470. <title>The response object</title>
  471. <para>
  472. As discussed in the architecture section Zend Tool allows to hook different clients for
  473. using your Zend Tool providers. To keep compliant with different clients you should
  474. use the response object to return messages from your providers instead of using
  475. <methodname>echo()</methodname> or a similiar output mechanism. Rewritting our hello
  476. provider with this knowledge it looks like:
  477. </para>
  478. <programlisting language="php"><![CDATA[
  479. class My_Component_HelloProvider
  480. extends Zend_Tool_Framework_Provider_Abstract
  481. {
  482. public function say()
  483. {
  484. $this->_registry->getResponse
  485. ->appendContent("Hello from my provider!");
  486. }
  487. }
  488. ]]></programlisting>
  489. <para>
  490. As you can see one has to extend the <classname>Zend_Tool_Framework_Provider_Abstract</classname>
  491. to gain access to the Registry which holds the <classname>Zend_Tool_Framework_Client_Response</classname>
  492. instance.
  493. </para>
  494. </sect4>
  495. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced">
  496. <title>Advanced Development Information</title>
  497. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.variables">
  498. <title>Passing Variables to a Provider</title>
  499. <para>
  500. The above "Hello World" example is great for simple commands, but
  501. what about something more advanced? As your scripting and tooling
  502. needs grow, you might find that you need the ability to accept
  503. variables. Much like function signatures have parameters, your
  504. tooling requests can also accept parameters.
  505. </para>
  506. <para>
  507. Just as each tooling request can be isolated to a method within a
  508. class, the parameters of a tooling request can also be isolated in a
  509. very well known place. Parameters of the action methods of a
  510. provider can include the same parameters you want your client to
  511. utilize when calling that provider and action combination. For
  512. example, if you wanted to accept a name in the above example, you
  513. would probably do this in OO code:
  514. </para>
  515. <programlisting language="php"><![CDATA[
  516. class My_Component_HelloProvider
  517. implements Zend_Tool_Framework_Provider_Interface
  518. {
  519. public function say($name = 'Ralph')
  520. {
  521. echo 'Hello' . $name . ', from my provider!';
  522. }
  523. }
  524. ]]></programlisting>
  525. <para>
  526. The above example can then be called via the command line
  527. <command>zf say hello Joe</command>. "Joe" will be supplied to the provider as
  528. a parameter of the method call. Also note, as you see that the
  529. parameter is optional, that means it is also optional on the command
  530. line, so that <command>zf say hello</command> will still work, and default
  531. to the name "Ralph".
  532. </para>
  533. </sect5>
  534. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.prompt">
  535. <title>Prompt the User for Input</title>
  536. <para>
  537. There are cases when the workflow of your provider requires
  538. to prompt the user for input. This can be done by requesting
  539. the client to ask for more the required input by calling:
  540. </para>
  541. <programlisting language="php"><![CDATA[
  542. class My_Component_HelloProvider
  543. extends Zend_Tool_Framework_Provider_Abstract
  544. {
  545. public function say($name = 'Ralph')
  546. {
  547. $nameResponse = $this->_registry
  548. ->getClient()
  549. ->promptInteractiveInput("Whats your name?");
  550. $name = $name->getContent();
  551. echo 'Hello' . $name . ', from my provider!';
  552. }
  553. }
  554. ]]></programlisting>
  555. <para>
  556. This command throws an exception if the current client is not
  557. able to handle interactive requests. In case of the default Console Client
  558. however you will be asked to enter the name.
  559. </para>
  560. </sect5>
  561. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.pretendable">
  562. <title>Pretending to execute a Provider Action</title>
  563. <para>
  564. Another interesting feature you might wish to implement is
  565. <emphasis>pretendability</emphasis>. Pretendabilty is the ability
  566. for your provider to "pretend" as if it is doing the requested
  567. action and provider combination and give the user as much
  568. information about what it <emphasis>would</emphasis> do without
  569. actually doing it. This might be an important notion when doing
  570. heavy database or filesystem modifications that the user might not
  571. otherwise want to do.
  572. </para>
  573. <para>
  574. Pretendability is easy to implement. There are two parts to this
  575. feature: 1) marking the provider as having the ability to "pretend",
  576. and 2) checking the request to ensure the current request was indeed
  577. asked to be "pretended". This feature is demonstrated in the code
  578. sample below.
  579. </para>
  580. <programlisting language="php"><![CDATA[
  581. class My_Component_HelloProvider
  582. extends Zend_Tool_Framework_Provider_Abstract
  583. implements Zend_Tool_Framework_Provider_Pretendable
  584. {
  585. public function say($name = 'Ralph')
  586. {
  587. if ($this->_registry->getRequest()->isPretend()) {
  588. echo 'I would say hello to ' . $name . '.';
  589. } else {
  590. echo 'Hello' . $name . ', from my provider!';
  591. }
  592. }
  593. }
  594. ]]></programlisting>
  595. <para>
  596. To run the provider in pretend mode just call:
  597. </para>
  598. <programlisting language="sh"><![CDATA[
  599. % zf --pretend say hello Ralph
  600. I would say hello Ralph.
  601. ]]></programlisting>
  602. </sect5>
  603. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.verbosedebug">
  604. <title>Verbose and Debug modes</title>
  605. <para>
  606. You can also run your provider actions in "verbose" or "debug" modes.
  607. The semantics in regard to this actions have to be implemented by you
  608. in the context of your provider. You can access debug or verbose modes
  609. with:
  610. </para>
  611. <programlisting language="php"><![CDATA[
  612. class My_Component_HelloProvider
  613. implements Zend_Tool_Framework_Provider_Interface
  614. {
  615. public function say($name = 'Ralph')
  616. {
  617. if($this->_registry->getRequest()->isVerbose()) {
  618. echo "Hello::say has been called\n";
  619. }
  620. if($this->_registry->getRequest()->isDebug()) {
  621. syslog(LOG_INFO, "Hello::say has been called\n");
  622. }
  623. }
  624. }
  625. ]]></programlisting>
  626. </sect5>
  627. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.configstorage">
  628. <title>Accessing User Config and Storage</title>
  629. <para>
  630. Using the Enviroment variable <property>ZF_CONFIG_FILE</property> or the
  631. .zf.ini in your home directory you can inject configuration parameters into
  632. any Zend Tool provider. Access to this configuration is available via the
  633. registry that is passed to your provider if you extend
  634. <classname>Zend_Tool_Framework_Provider_Abstract</classname>.
  635. </para>
  636. <programlisting language="php"><![CDATA[
  637. class My_Component_HelloProvider
  638. extends Zend_Tool_Framework_Provider_Abstract
  639. {
  640. public function say()
  641. {
  642. $username = $this->_registry->getConfig()->username;
  643. if(!empty($username)) {
  644. echo "Hello $username!";
  645. } else {
  646. echo "Hello!";
  647. }
  648. }
  649. }
  650. ]]></programlisting>
  651. <para>
  652. The returned configuration is of the type
  653. <classname>Zend_Tool_Framework_Client_Config</classname> but internally the
  654. <methodname>__get()</methodname> and <methodname>__set()</methodname> magic methods
  655. proxy to a <classname>Zend_Config</classname> of the given configuration type.
  656. </para>
  657. <para>
  658. The storage allows to save arbitrary data for later reference. This can be useful for batch
  659. processing tasks or for re-runs of your tasks. You can access the storage in a similar way
  660. like the configuration:
  661. </para>
  662. <programlisting language="php"><![CDATA[
  663. class My_Component_HelloProvider
  664. extends Zend_Tool_Framework_Provider_Abstract
  665. {
  666. public function say()
  667. {
  668. $aValue = $this->_registry->getStorage()->get("myUsername");
  669. echo "Hello $aValue!";
  670. }
  671. }
  672. ]]></programlisting>
  673. <para>
  674. The API of the storage is very simple:
  675. </para>
  676. <programlisting language="php"><![CDATA[
  677. class Zend_Tool_Framework_Client_Storage
  678. {
  679. public function setAdapter($adapter);
  680. public function isEnabled();
  681. public function put($name, $value);
  682. public function get($name, $defaultValue=null);
  683. public function has($name);
  684. public function remove($name);
  685. public function getStreamUri($name);
  686. }
  687. ]]></programlisting>
  688. <important>
  689. <para>
  690. When designing your providers that are config or storage aware remember to
  691. check if the required user-config or storage keys really exist for a user.
  692. You won't run into fatal errors when none of these are provided though,
  693. since empty ones are created upon request.
  694. </para>
  695. </important>
  696. </sect5>
  697. </sect4>
  698. </sect3>
  699. </sect2>
  700. <sect2 id="zend.tool.extending.zend-tool-project">
  701. <title>Zend_Tool_Project Extensions</title>
  702. <para>
  703. Zend_Tool_Project exposes a rich set of functionality and capabilities that make the task
  704. of creating new providers, specficially those targetting project easier and more manageable.
  705. </para>
  706. <sect3 id="zend.tool.extending.zend-tool-project.architecture">
  707. <title>Overall Architecture</title>
  708. <para>
  709. This same concept applies to Zend Framework projects. In Zend Framework projects, you have
  710. controllers, actions, views, models, databases and so on and so forth. In terms of
  711. <classname>Zend_Tool</classname>, we need a way to track these types of resources - thus
  712. <classname>Zend_Tool_Project</classname>.
  713. </para>
  714. <para>
  715. <classname>Zend_Tool_Project</classname> is capable of tracking project resources throughout
  716. the development of a project. So, for example, if in one command you created a controller,
  717. and in the next command you wish to create an action within that controller,
  718. <classname>Zend_Tool_Project</classname> is gonna have to <emphasis>know</emphasis> about
  719. the controller file you created so that you can (in the next action), be able to append that
  720. action to it. This is what keeps our projects up to date and <emphasis>stateful</emphasis>.
  721. </para>
  722. <para>
  723. Another important point to understand about projects is that typically, resources are
  724. organized in a hierarchical fashion. With that in mind,
  725. <classname>Zend_Tool_Project</classname> is capable of serializing the current project into
  726. a internal representation that allows it to keep track of not only <emphasis>what</emphasis>
  727. resources are part of a project at any given time, but also <emphasis>where</emphasis> they
  728. are in relation to one another.
  729. </para>
  730. </sect3>
  731. <sect3 id="zend.tool.extending.zend-tool-project.providers">
  732. <title>Creating Providers</title>
  733. <para>
  734. Project specific providers are created in the same fashion as plain framework providers, with
  735. one exception: project providers must extend the <code>Zend_Tool_Project_Provider_Abstract</code>.
  736. This class comes with some significant functionality that helps developers load existing project,
  737. obtian the profile object, and be able to search the profile, then later store any changes to the
  738. current project profile.
  739. </para>
  740. <programlisting language="php"><![CDATA[
  741. class My_Component_HelloProvider
  742. extends Zend_Tool_Project_Provider_Abstract
  743. {
  744. public function say()
  745. {
  746. $profile = $this->_loadExistingProfile();
  747. /* ... do project stuff here */
  748. $this->_storeProfile();
  749. }
  750. }
  751. ]]></programlisting>
  752. </sect3>
  753. <!--
  754. <sect3 id="zend.tool.extending.zend-tool-project.resources-and-contexts">
  755. <title>Creating Resources &amp; Contexts</title>
  756. </sect3>
  757. -->
  758. </sect2>
  759. </sect1>