Zend_Tool-Extending.xml 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  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 Setup 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> Installation zu kopieren. Diese kann normalerweise in
  197. einem 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. Um den Ort der eigenen <acronym>PHP</acronym> Installation zu finden kann man
  207. 'which php' auf der Kommandozeile ausführen. Das gibt den Ort der
  208. <acronym>PHP</acronym> Installation zurück welche verwendet wird um in dieser
  209. Umgebung <acronym>PHP</acronym> Skripte auszuführen.
  210. </para>
  211. <para>
  212. Der nächste Schritt ist es sicherzustellen das die Zend Framework Bibliothek
  213. korrekt im <acronym>PHP</acronym> <property>include_path</property> eingestellt
  214. wurde. Um herauszufinden wo der <property>include_path</property> ist, kann man
  215. <command>php -i</command> ausführen und nach der
  216. <property>include_path</property> Variable sehen, oder kompakter
  217. <command>php -i | grep include_path</command> ausführen. Sobald man
  218. herausgefunden hat wo der <property>include_path</property> ist (er ist
  219. normalerweise etwas wie <filename>/usr/lib/php</filename>,
  220. <filename>/usr/share/php</filename>, <filename>/usr/local/lib/php</filename>,
  221. oder so ähnlich), sollte man sicherstellen das der Inhalt des Verzeichnisses
  222. <filename>/library/</filename> in einem der in <property>include_path</property>
  223. spezifizierten Verzeichnisse ist.
  224. </para>
  225. <para>
  226. Sobald man diese zwei Dinge getan hat, sollte man in der Lage sein ein Kommando
  227. auszuführen und die richtige Antwort zurück zu erhalten, wie zum Beispiel:
  228. </para>
  229. <para>
  230. <inlinegraphic scale="100" align="center" valign="middle"
  231. fileref="figures/zend.tool.framework.cliversionunix.png" format="PNG" />
  232. </para>
  233. <para>
  234. Wenn man diese Art der Ausgabe nicht sieht, sollte man zurückgeben und die
  235. eigenen Einstellungen prüfen um sicherzustellen das man alle notwendigen Teile
  236. am richtigen Ort vorhanden sind.
  237. </para>
  238. <para>
  239. Es gibt eine Anzahl an alternativen Einstellungen die man erstellen kann,
  240. abhängig von der Konfiguration des Servers, dem Zugriffslevel, oder aus anderen
  241. Gründen.
  242. </para>
  243. <para>
  244. Das <emphasis>alternative Setup</emphasis> enthält das man den Download vom Zend
  245. Framework zusammenbehält wie er ist, und einen Link von einem
  246. <constant>PATH</constant> Ort zur <filename>zf.sh</filename> erstellt. Was dies
  247. bedeutet ist, dass man den Inhalt des Zend Framework Downloads in einem Ort wie
  248. <filename>/usr/local/share/ZendFramework</filename> platzieren kann, oder
  249. lokaler unter <filename>/home/username/lib/ZendFramework</filename> und einen
  250. symbolischen Link zu <filename>zf.sh</filename> erstellt.
  251. </para>
  252. <para>
  253. Angenommen man will den Link in <filename>/usr/local/bin</filename> platzieren
  254. (dies könnte zum Beispiel auch für die Platzierung des Links unter
  255. <filename>/home/username/bin/</filename> funktionieren), dan würde man ein
  256. Kommando wie das folgende platzieren:
  257. </para>
  258. <programlisting language="sh"><![CDATA[
  259. ln -s /usr/local/share/ZendFramework/bin/zf.sh /usr/local/bin/zf
  260. # ODER (zum Beispiel)
  261. ln -s /home/username/lib/ZendFramework/bin/zf.sh /home/username/bin/zf
  262. ]]></programlisting>
  263. <para>
  264. Das erstellt einen Link auf den man global von der Kommandozeile aus zugreifen
  265. kann.
  266. </para>
  267. </sect4>
  268. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-windows">
  269. <title>Das CLI Tool unter Windows einrichten</title>
  270. <para>
  271. Das üblichste Setup in einer Windows Win32 Umgebung ist es
  272. <filename>zf.bat</filename> und <filename>zf.php</filename> in das selbe
  273. Verzeichnis wie die <acronym>PHP</acronym> Bibliothek zu kopieren. Diese kann
  274. generell an einem der folgenden Plätze gefunden werden:
  275. </para>
  276. <programlisting language="text"><![CDATA[
  277. C:\PHP
  278. C:\Program Files\ZendServer\bin\
  279. C:\WAMP\PHP\bin
  280. ]]></programlisting>
  281. <para>
  282. Man sollte in der Lage sein <filename>php.exe</filename> von der Kommandozeile
  283. aus auszuführen. Wenn man dazu nicht in der Lage ist, sollte man zuerst die
  284. Dokumentation prüfen welche mit der <acronym>PHP</acronym> Bibliothek
  285. mitgeliefert wird, um sicherzustellen dass der Pfad zu
  286. <filename>php.exe</filename> in der Windows Umgebungsvariable
  287. <constant>PATH</constant> zu finden ist.
  288. </para>
  289. <para>
  290. Der nächste Schritt besteht darin sicherzustellen das die Zend Framework
  291. Bibliothek richtig auf dem <acronym>PHP</acronym>
  292. <property>include_path</property> des Systems eingerichtet ist. Um
  293. herauszufinden wo der <property>include_path</property> ist, kann man
  294. <command>php -i</command> eingeben und nach der Variable
  295. <property>include_path</property> sehen, oder kompakter
  296. <command>php -i | grep include_path</command> ausführen wenn man ein Cygwin
  297. Setup mit vorhandenem grep hat. Sobald man herausgefunden hat wo der
  298. <property>include_path</property> liegt (das ist normalerweise etwas wie
  299. <filename>C:\PHP\pear</filename>, <filename>C:\PHP\share</filename>,
  300. <filename>C:\Program%20Files\ZendServer\share</filename>, oder ähnlich), sollte
  301. man sicherstellen das der Inhalt des Verzeichnisses library/ in einem vom
  302. <property>include_path</property> spezifizierten Verzeichnis ist.
  303. </para>
  304. <para>
  305. Sobald man diese zwei Dinge getan hat, sollte man in der Lage sein ein Kommando
  306. auszuführen und die richtige Antwort, so ähnlich wie die folgende, zu erhalten:
  307. </para>
  308. <para>
  309. <inlinegraphic scale="100" align="center" valign="middle"
  310. fileref="figures/zend.tool.framework.cliversionwin32.png" format="PNG" />
  311. </para>
  312. <para>
  313. Wenn man diese Art der Ausgabe nicht sieht, sollte man zurückgehen und die
  314. Einstellungen prüfen um sicherzustellen das man alle notwendigen Teile an den
  315. richtigen Orten hat.
  316. </para>
  317. <para>
  318. Es gibt eine Anzahl an alternativen Einstellungen die man erstellen kann,
  319. abhängig von der Konfiguration des Servers, dem Zugriffslevel, oder aus anderen
  320. Gründen.
  321. </para>
  322. <para>
  323. Das <emphasis>alternative Setup</emphasis> enthält das man den Download vom Zend
  324. Framework zusammenbehält wie er ist, und sowohl den System
  325. <constant>PATH</constant>, als auch die <filename>php.ini</filename> Datei
  326. verändert. In der Umgebung des Benutzers muss man
  327. <filename>C:\Path\To\ZendFramework\bin</filename> hinzufügen damit die Datei
  328. <filename>zf.bat</filename> ausführbar ist. Auch die Datei
  329. <filename>php.ini</filename> ist zu verändern um sicherzustellen das
  330. <filename>C:\Path\To\ZendFramework\library</filename> im
  331. <property>include_path</property> liegt.
  332. </para>
  333. </sect4>
  334. <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-othernotes">
  335. <title>Andere Einstellungs-Möglichkeiten</title>
  336. <para>
  337. Wenn man aus bestimmten Gründen die Zend Framework Bibliothek nicht im
  338. <property>include_path</property> haben will, gibt es andere Optionen. Es gibt
  339. zwei spezielle Umgebungsvariablen welche <filename>zf.php</filename> verwendet
  340. um den Ort der Zend Framework Installation zu erkennen.
  341. </para>
  342. <para>
  343. Die erste ist <constant>ZEND_TOOL_INCLUDE_PATH_PREPEND</constant>, welche den
  344. Wert der Umgebungsvariable dem <property>include_path</property> des Systems
  345. (<filename>php.ini</filename>) voranstellt bevor der Client geladen wird.
  346. </para>
  347. <para>
  348. Alternativ kann man <constant>ZEND_TOOL_INCLUDE_PATH</constant> verwenden um den
  349. <property>include_path</property> des System komplett zu
  350. <emphasis>ersetzen</emphasis> für jene bei denen es Sinn macht, speziell für das
  351. <command>zf</command> Kommandozeilen-Tool.
  352. </para>
  353. </sect4>
  354. </sect3>
  355. <sect3 id="zend.tool.extending.zend-tool-framework.providers-and-manifests">
  356. <title>Erstellen von Providern</title>
  357. <para>
  358. Generell, ist ein Provider für sich selbst gesehen, nichts weiter als eine Shell für
  359. einen Entwickler um einige Möglichkeiten zu bündeln welche er mit den Kommandozeilen
  360. (oder anderen) Clients ausführen will. Das ist eine Analogie für das was der
  361. "Controller" in der <acronym>MVC</acronym> Anwendung ist.
  362. </para>
  363. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading">
  364. <title>Wie Zend Tool eigene Provider findet</title>
  365. <para>
  366. Standardmäßig verwendet Zend Tool den BasicLoader um alle Provider zu finden die
  367. es ausführen kann. Er durchsucht alle Verzeichnisse des Include Pfades rekursiv
  368. und öffnet alle Dateien welche mit "Manifest.php" oder "Provider.php" enden.
  369. Alle Klassen in diesen Dateien werden darauf durchsucht ob Sie entweder
  370. <classname>Zend_Tool_Framework_Provider_Interface</classname> oder
  371. <classname>Zend_Tool_Framework_Manifest_ProviderManifestable</classname>
  372. implementieren. Instanzen des Provider Interfaces sind für die echte
  373. Funktionalität zuständig und alle Ihre öffentlichen Methoden kann als Provider
  374. Aktionen zugegriffen werden. Das ProviderManifestable Interface benötigt
  375. trotzdem die Implementation einer <methodname>getProviders()</methodname>
  376. Methode welche ein Array an instanzierten Provider Interface Instanzen
  377. zurückgibt.
  378. </para>
  379. <para>
  380. Die folgenden Namensregeln sind darauf anzuwenden, wie man auf die Provider
  381. zugreifen kann welche vom IncludePathLoader gefunden werden:
  382. </para>
  383. <itemizedlist>
  384. <listitem>
  385. <para>
  386. Der letzte Teil des eigenen Klassennamens welcher von einem Unterstrich
  387. getrennt ist, wird für den Providernamen verwendet, zum Beispiel führt
  388. "My_Provider_Hello" zum Provider auf welchen mit dem Namen "hello"
  389. zugegriffen werden kann.
  390. </para>
  391. </listitem>
  392. <listitem>
  393. <para>
  394. Wenn der Provider eine Methode <methodname>getName()</methodname> hat,
  395. dann wird diese verwendet statt der vorherigen Methode um den Namen zu
  396. erkennen.
  397. </para>
  398. </listitem>
  399. <listitem>
  400. <para>
  401. Wenn der Provider den Präfix "Provider" hat, zum Beispiel wenn er
  402. <classname>My_HelloProvider</classname> heißt, dann wird er vom Namen
  403. entfernt so dass der Provider "hello" heißt.
  404. </para>
  405. </listitem>
  406. </itemizedlist>
  407. <note>
  408. <para>
  409. Der IncludePathLoader folgt Symlinks nicht, was bedeutet das man Provider
  410. Funktionalitäten nicht in den Include Pfaden verlinken kann, sondern dass
  411. Sie physikalisch in den Include Pfaden vorhanden sein müssen.
  412. </para>
  413. </note>
  414. <example id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading.example">
  415. <title>Provider mit einem Manifest bekanntmachen</title>
  416. <para>
  417. You can expose your providers to Zend Tool by offering a manifest
  418. with a special filename ending with "Manifest.php".
  419. A Provider Manifest is an implementation of the
  420. <interface>Zend_Tool_Framework_Manifest_ProviderManifestable</interface>
  421. and requires the <methodname>getProviders()</methodname> method to return
  422. an array of instantiated providers. In anticipation of our first
  423. own provider <classname>My_Component_HelloProvider</classname>
  424. we will create the following manifest:
  425. </para>
  426. <programlisting language="php"><![CDATA[
  427. class My_Component_Manifest
  428. implements Zend_Tool_Framework_Manifest_ProviderManifestable
  429. {
  430. public function getProviders()
  431. {
  432. return array(
  433. new My_Component_HelloProvider()
  434. );
  435. }
  436. }
  437. ]]></programlisting>
  438. </example>
  439. </sect4>
  440. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.basic">
  441. <title>Basic Instructions for Creating Providers</title>
  442. <para>
  443. As an example, if a developer wants to add the capability of showing
  444. the version of a datafile that his 3rd party component is working
  445. from, there is only one class the developer would need to implement.
  446. Assuming the component is called <classname>My_Component</classname>, he would
  447. create a class named <classname>My_Component_HelloProvider</classname> in a
  448. file named <filename>HelloProvider.php</filename> somewhere on the
  449. <property>include_path</property>. This class would implement
  450. <classname>Zend_Tool_Framework_Provider_Interface</classname>, and the body of
  451. this file would only have to look like the following:
  452. </para>
  453. <programlisting language="php"><![CDATA[
  454. class My_Component_HelloProvider
  455. implements Zend_Tool_Framework_Provider_Interface
  456. {
  457. public function say()
  458. {
  459. echo 'Hello from my provider!';
  460. }
  461. }
  462. ]]></programlisting>
  463. <para>
  464. Given that code above, and assuming the developer wishes to access
  465. this functionality through the console client, the call would look
  466. like this:
  467. </para>
  468. <programlisting language="sh"><![CDATA[
  469. % zf say hello
  470. Hello from my provider!
  471. ]]></programlisting>
  472. </sect4>
  473. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.response">
  474. <title>The response object</title>
  475. <para>
  476. As discussed in the architecture section Zend Tool allows to hook different clients for
  477. using your Zend Tool providers. To keep compliant with different clients you should
  478. use the response object to return messages from your providers instead of using
  479. <methodname>echo()</methodname> or a similiar output mechanism. Rewritting our hello
  480. provider with this knowledge it looks like:
  481. </para>
  482. <programlisting language="php"><![CDATA[
  483. class My_Component_HelloProvider
  484. extends Zend_Tool_Framework_Provider_Abstract
  485. {
  486. public function say()
  487. {
  488. $this->_registry->getResponse
  489. ->appendContent("Hello from my provider!");
  490. }
  491. }
  492. ]]></programlisting>
  493. <para>
  494. As you can see one has to extend the <classname>Zend_Tool_Framework_Provider_Abstract</classname>
  495. to gain access to the Registry which holds the <classname>Zend_Tool_Framework_Client_Response</classname>
  496. instance.
  497. </para>
  498. </sect4>
  499. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced">
  500. <title>Advanced Development Information</title>
  501. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.variables">
  502. <title>Passing Variables to a Provider</title>
  503. <para>
  504. The above "Hello World" example is great for simple commands, but
  505. what about something more advanced? As your scripting and tooling
  506. needs grow, you might find that you need the ability to accept
  507. variables. Much like function signatures have parameters, your
  508. tooling requests can also accept parameters.
  509. </para>
  510. <para>
  511. Just as each tooling request can be isolated to a method within a
  512. class, the parameters of a tooling request can also be isolated in a
  513. very well known place. Parameters of the action methods of a
  514. provider can include the same parameters you want your client to
  515. utilize when calling that provider and action combination. For
  516. example, if you wanted to accept a name in the above example, you
  517. would probably do this in OO code:
  518. </para>
  519. <programlisting language="php"><![CDATA[
  520. class My_Component_HelloProvider
  521. implements Zend_Tool_Framework_Provider_Interface
  522. {
  523. public function say($name = 'Ralph')
  524. {
  525. echo 'Hello' . $name . ', from my provider!';
  526. }
  527. }
  528. ]]></programlisting>
  529. <para>
  530. The above example can then be called via the command line
  531. <command>zf say hello Joe</command>. "Joe" will be supplied to the provider as
  532. a parameter of the method call. Also note, as you see that the
  533. parameter is optional, that means it is also optional on the command
  534. line, so that <command>zf say hello</command> will still work, and default
  535. to the name "Ralph".
  536. </para>
  537. </sect5>
  538. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.prompt">
  539. <title>Prompt the User for Input</title>
  540. <para>
  541. There are cases when the workflow of your provider requires
  542. to prompt the user for input. This can be done by requesting
  543. the client to ask for more the required input by calling:
  544. </para>
  545. <programlisting language="php"><![CDATA[
  546. class My_Component_HelloProvider
  547. extends Zend_Tool_Framework_Provider_Abstract
  548. {
  549. public function say($name = 'Ralph')
  550. {
  551. $nameResponse = $this->_registry
  552. ->getClient()
  553. ->promptInteractiveInput("Whats your name?");
  554. $name = $name->getContent();
  555. echo 'Hello' . $name . ', from my provider!';
  556. }
  557. }
  558. ]]></programlisting>
  559. <para>
  560. This command throws an exception if the current client is not
  561. able to handle interactive requests. In case of the default Console Client
  562. however you will be asked to enter the name.
  563. </para>
  564. </sect5>
  565. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.pretendable">
  566. <title>Pretending to execute a Provider Action</title>
  567. <para>
  568. Another interesting feature you might wish to implement is
  569. <emphasis>pretendability</emphasis>. Pretendabilty is the ability
  570. for your provider to "pretend" as if it is doing the requested
  571. action and provider combination and give the user as much
  572. information about what it <emphasis>would</emphasis> do without
  573. actually doing it. This might be an important notion when doing
  574. heavy database or filesystem modifications that the user might not
  575. otherwise want to do.
  576. </para>
  577. <para>
  578. Pretendability is easy to implement. There are two parts to this
  579. feature: 1) marking the provider as having the ability to "pretend",
  580. and 2) checking the request to ensure the current request was indeed
  581. asked to be "pretended". This feature is demonstrated in the code
  582. sample below.
  583. </para>
  584. <programlisting language="php"><![CDATA[
  585. class My_Component_HelloProvider
  586. extends Zend_Tool_Framework_Provider_Abstract
  587. implements Zend_Tool_Framework_Provider_Pretendable
  588. {
  589. public function say($name = 'Ralph')
  590. {
  591. if ($this->_registry->getRequest()->isPretend()) {
  592. echo 'I would say hello to ' . $name . '.';
  593. } else {
  594. echo 'Hello' . $name . ', from my provider!';
  595. }
  596. }
  597. }
  598. ]]></programlisting>
  599. <para>
  600. To run the provider in pretend mode just call:
  601. </para>
  602. <programlisting language="sh"><![CDATA[
  603. % zf --pretend say hello Ralph
  604. I would say hello Ralph.
  605. ]]></programlisting>
  606. </sect5>
  607. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.verbosedebug">
  608. <title>Verbose and Debug modes</title>
  609. <para>
  610. You can also run your provider actions in "verbose" or "debug" modes.
  611. The semantics in regard to this actions have to be implemented by you
  612. in the context of your provider. You can access debug or verbose modes
  613. with:
  614. </para>
  615. <programlisting language="php"><![CDATA[
  616. class My_Component_HelloProvider
  617. implements Zend_Tool_Framework_Provider_Interface
  618. {
  619. public function say($name = 'Ralph')
  620. {
  621. if($this->_registry->getRequest()->isVerbose()) {
  622. echo "Hello::say has been called\n";
  623. }
  624. if($this->_registry->getRequest()->isDebug()) {
  625. syslog(LOG_INFO, "Hello::say has been called\n");
  626. }
  627. }
  628. }
  629. ]]></programlisting>
  630. </sect5>
  631. <sect5 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.configstorage">
  632. <title>Accessing User Config and Storage</title>
  633. <para>
  634. Using the Enviroment variable <property>ZF_CONFIG_FILE</property> or the
  635. .zf.ini in your home directory you can inject configuration parameters into
  636. any Zend Tool provider. Access to this configuration is available via the
  637. registry that is passed to your provider if you extend
  638. <classname>Zend_Tool_Framework_Provider_Abstract</classname>.
  639. </para>
  640. <programlisting language="php"><![CDATA[
  641. class My_Component_HelloProvider
  642. extends Zend_Tool_Framework_Provider_Abstract
  643. {
  644. public function say()
  645. {
  646. $username = $this->_registry->getConfig()->username;
  647. if(!empty($username)) {
  648. echo "Hello $username!";
  649. } else {
  650. echo "Hello!";
  651. }
  652. }
  653. }
  654. ]]></programlisting>
  655. <para>
  656. The returned configuration is of the type
  657. <classname>Zend_Tool_Framework_Client_Config</classname> but internally the
  658. <methodname>__get()</methodname> and <methodname>__set()</methodname> magic methods
  659. proxy to a <classname>Zend_Config</classname> of the given configuration type.
  660. </para>
  661. <para>
  662. The storage allows to save arbitrary data for later reference. This can be useful for batch
  663. processing tasks or for re-runs of your tasks. You can access the storage in a similar way
  664. like the configuration:
  665. </para>
  666. <programlisting language="php"><![CDATA[
  667. class My_Component_HelloProvider
  668. extends Zend_Tool_Framework_Provider_Abstract
  669. {
  670. public function say()
  671. {
  672. $aValue = $this->_registry->getStorage()->get("myUsername");
  673. echo "Hello $aValue!";
  674. }
  675. }
  676. ]]></programlisting>
  677. <para>
  678. The API of the storage is very simple:
  679. </para>
  680. <programlisting language="php"><![CDATA[
  681. class Zend_Tool_Framework_Client_Storage
  682. {
  683. public function setAdapter($adapter);
  684. public function isEnabled();
  685. public function put($name, $value);
  686. public function get($name, $defaultValue=null);
  687. public function has($name);
  688. public function remove($name);
  689. public function getStreamUri($name);
  690. }
  691. ]]></programlisting>
  692. <important>
  693. <para>
  694. When designing your providers that are config or storage aware remember to
  695. check if the required user-config or storage keys really exist for a user.
  696. You won't run into fatal errors when none of these are provided though,
  697. since empty ones are created upon request.
  698. </para>
  699. </important>
  700. </sect5>
  701. </sect4>
  702. </sect3>
  703. </sect2>
  704. <sect2 id="zend.tool.extending.zend-tool-project">
  705. <title>Zend_Tool_Project Extensions</title>
  706. <para>
  707. Zend_Tool_Project exposes a rich set of functionality and capabilities that make the task
  708. of creating new providers, specficially those targetting project easier and more manageable.
  709. </para>
  710. <sect3 id="zend.tool.extending.zend-tool-project.architecture">
  711. <title>Overall Architecture</title>
  712. <para>
  713. This same concept applies to Zend Framework projects. In Zend Framework projects, you have
  714. controllers, actions, views, models, databases and so on and so forth. In terms of
  715. <classname>Zend_Tool</classname>, we need a way to track these types of resources - thus
  716. <classname>Zend_Tool_Project</classname>.
  717. </para>
  718. <para>
  719. <classname>Zend_Tool_Project</classname> is capable of tracking project resources throughout
  720. the development of a project. So, for example, if in one command you created a controller,
  721. and in the next command you wish to create an action within that controller,
  722. <classname>Zend_Tool_Project</classname> is gonna have to <emphasis>know</emphasis> about
  723. the controller file you created so that you can (in the next action), be able to append that
  724. action to it. This is what keeps our projects up to date and <emphasis>stateful</emphasis>.
  725. </para>
  726. <para>
  727. Another important point to understand about projects is that typically, resources are
  728. organized in a hierarchical fashion. With that in mind,
  729. <classname>Zend_Tool_Project</classname> is capable of serializing the current project into
  730. a internal representation that allows it to keep track of not only <emphasis>what</emphasis>
  731. resources are part of a project at any given time, but also <emphasis>where</emphasis> they
  732. are in relation to one another.
  733. </para>
  734. </sect3>
  735. <sect3 id="zend.tool.extending.zend-tool-project.providers">
  736. <title>Creating Providers</title>
  737. <para>
  738. Project specific providers are created in the same fashion as plain framework providers, with
  739. one exception: project providers must extend the <code>Zend_Tool_Project_Provider_Abstract</code>.
  740. This class comes with some significant functionality that helps developers load existing project,
  741. obtian the profile object, and be able to search the profile, then later store any changes to the
  742. current project profile.
  743. </para>
  744. <programlisting language="php"><![CDATA[
  745. class My_Component_HelloProvider
  746. extends Zend_Tool_Project_Provider_Abstract
  747. {
  748. public function say()
  749. {
  750. $profile = $this->_loadExistingProfile();
  751. /* ... do project stuff here */
  752. $this->_storeProfile();
  753. }
  754. }
  755. ]]></programlisting>
  756. </sect3>
  757. <!--
  758. <sect3 id="zend.tool.extending.zend-tool-project.resources-and-contexts">
  759. <title>Creating Resources &amp; Contexts</title>
  760. </sect3>
  761. -->
  762. </sect2>
  763. </sect1>