2
0

Zend_Tool-Extending.xml 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 22745 -->
  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 <classname>Zend_Tool</classname> den BasicLoader um alle
  367. Provider zu finden die es ausführen kann. Er durchsucht alle Verzeichnisse des
  368. Include Pfades rekursiv und öffnet alle Dateien welche mit "Manifest.php" oder
  369. "Provider.php" enden. Alle Klassen in diesen Dateien werden darauf durchsucht ob
  370. Sie entweder <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
  415. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading.example">
  416. <title>Provider mit einem Manifest bekanntmachen</title>
  417. <para>
  418. Man kann eigene Provider bei <classname>Zend_Tool</classname> bekannt machen
  419. indem man ein Manifest anbietet, mit einer speziellen Endung des Dateinamens
  420. von "Manifest.php". Ein Provider-Manifest ist eine Implementation von
  421. <interface>Zend_Tool_Framework_Manifest_ProviderManifestable</interface> und
  422. benötigt die <methodname>getProviders()</methodname> Methode um ein Array
  423. von instanziierten Providern zurückzugeben. Anders als unser erster eigener
  424. Provider <classname>My_Component_HelloProvider</classname> erstellen wir das
  425. folgende Manifest:
  426. </para>
  427. <programlisting language="php"><![CDATA[
  428. class My_Component_Manifest
  429. implements Zend_Tool_Framework_Manifest_ProviderManifestable
  430. {
  431. public function getProviders()
  432. {
  433. return array(
  434. new My_Component_HelloProvider()
  435. );
  436. }
  437. }
  438. ]]></programlisting>
  439. </example>
  440. </sect4>
  441. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.basic">
  442. <title>Grundsätzliche Instruktionen für die Erstellung von Providern</title>
  443. <para>
  444. Wenn, als Beispiel, ein Entwickler die Fähigkeit, eine Version einer Datendatei
  445. anzuzeigen, hinzufügen will mit der seine 3rd Party Komponente arbeitet, gibt es
  446. nur eine Klasse welche der Entwickler implementieren muss. Angenommen die
  447. Komponente wird <classname>My_Component</classname> genannt, dann würde er eine
  448. Klasse erstellen welche <classname>My_Component_HelloProvider</classname> heißt
  449. in einer Datei wleche <filename>HelloProvider.php</filename> genannt ist und
  450. irgendwo in seinem <property>include_path</property> liegt. Diese Klasse würde
  451. <classname>Zend_Tool_Framework_Provider_Interface</classname> implementieren und
  452. diese Datei würde etwa wie folgt auszusehen haben:
  453. </para>
  454. <programlisting language="php"><![CDATA[
  455. class My_Component_HelloProvider
  456. implements Zend_Tool_Framework_Provider_Interface
  457. {
  458. public function say()
  459. {
  460. echo 'Hallo von meinem Provider!';
  461. }
  462. }
  463. ]]></programlisting>
  464. <para>
  465. Bei dem obigen Code und der Annahme das der Entwickler Zugriff auf diese
  466. Funktionalität über den Konsolen-Client haben will, würde der Aufruf wie folgt
  467. aussehen:
  468. </para>
  469. <programlisting language="sh"><![CDATA[
  470. % zf say hello
  471. Hallo von meinem Provider!
  472. ]]></programlisting>
  473. </sect4>
  474. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.response">
  475. <title>Das Antwort-Objekt</title>
  476. <para>
  477. Wie im Architektur-Abschnitt diskutiert erlaubt es
  478. <classname>Zend_Tool</classname> andere Clients für die Verwendung eigener
  479. <classname>Zend_Tool</classname> Provider zu verknüpfen. Um den
  480. unterschiedlichen Clients zu entsprechen sollte man das Antwort-Objekt verwenden
  481. um Rückgabe-Meldungen von Providern zurückzugeben anstatt
  482. <methodname>echo()</methodname> oder ähnliche Ausgabe-Mechanismen zu verwenden.
  483. Nach dem Umschreiben des Hello-Providers mit diesen Erkenntnissen sieht er wie
  484. folgt aus:
  485. </para>
  486. <programlisting language="php"><![CDATA[
  487. class My_Component_HelloProvider
  488. extends Zend_Tool_Framework_Provider_Abstract
  489. {
  490. public function say()
  491. {
  492. $this->_registry->getResponse
  493. ->appendContent("Hallo von meinem Provider!");
  494. }
  495. }
  496. ]]></programlisting>
  497. <para>
  498. Wie man sieht muss <classname>Zend_Tool_Framework_Provider_Abstract</classname>
  499. erweitert werden um Zugriff auf die Registry zu erhalten welche die
  500. <classname>Zend_Tool_Framework_Client_Response</classname> Instanz enthält.
  501. </para>
  502. </sect4>
  503. <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced">
  504. <title>Fortgeschrittene Informationen für die Entwicklung</title>
  505. <sect5
  506. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.variables">
  507. <title>Variablen an einen Provider übergeben</title>
  508. <para>
  509. Das obige "Hello World" Beispiel ist großartig für einfache Befehle, aber
  510. was ist mit etwas komplizierterem? Wenn die eigenen Skripting- und
  511. Tooling-Bedürfnisse wachsen kann man die Notwendigkeit sehen dass man
  512. Variablen akzeptiert. So wie Funktions-Signaturen Parameter haben, so können
  513. eigene Tooling-Anfragen auch Parmeter akzeptieren.
  514. </para>
  515. <para>
  516. So wie jede Tooling-Anfrage isoliert von einer Methode in einer Klasse sein
  517. kann, können auch die Parameter einer Tooling-Anfrage in einem sehr
  518. bekanntem Platz isoliert sein. Parameter einer Aktions-Methode eines
  519. Providers können die selben Parameter enthalten welche der eigene Client
  520. verwenden soll wenn diese Provider und Aktions-Methode aufgerufen wird.
  521. Wenn man zum Beispiel einen Namen im oben stehenden Beispiel akzeptieren
  522. will, würde man möglicherweise folgendes in OO Code machen:
  523. </para>
  524. <programlisting language="php"><![CDATA[
  525. class My_Component_HelloProvider
  526. implements Zend_Tool_Framework_Provider_Interface
  527. {
  528. public function say($name = 'Ralph')
  529. {
  530. echo 'Hallo' . $name . ', von meinem Provider!';
  531. }
  532. }
  533. ]]></programlisting>
  534. <para>
  535. Das obige Beispiel kann dann über die Kommandozeile
  536. <command>zf say hello Joe</command> aufgerufen werden. "Joe" wird dem
  537. Provider bereitgestellt so wie ein Parameter eines Methodenaufrufs. Es ist
  538. auch zu beachten das der Parameter optional ist, was bedeutet das er auch
  539. in der Kommandozeile optional ist, so dass
  540. <command>zf say hello</command> trotzdem noch funktioniert, und auf den
  541. Standardwert "Ralph" zeigt.
  542. </para>
  543. </sect5>
  544. <sect5
  545. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.prompt">
  546. <title>Den Benutzer nach einer Eingabe fragen</title>
  547. <para>
  548. Es gibt Fälle in denen der Workflow des eigenen Providers es notwendig macht
  549. den Benutzer nach einer Eingabe zu fragen. Dies kann getan werden indem der
  550. Client nach einer zusätzlich benötigten Eingabe gefragt wird indem folgendes
  551. aufgerufen wird:
  552. </para>
  553. <programlisting language="php"><![CDATA[
  554. class My_Component_HelloProvider
  555. extends Zend_Tool_Framework_Provider_Abstract
  556. {
  557. public function say($name = 'Ralph')
  558. {
  559. $nameResponse = $this->_registry
  560. ->getClient()
  561. ->promptInteractiveInput("Wie ist dein Name?");
  562. $name = $name->getContent();
  563. echo 'Hallo' . $name . ', von meinem Provider!';
  564. }
  565. }
  566. ]]></programlisting>
  567. <para>
  568. Dieses Kommando wirft eine Ausnahme wenn der aktuelle Client nicht in der
  569. Lage ist interaktive Anfragen zu behandeln. Im Falle des standardmäßigen
  570. Konsolen-Clients wird man aber danach gefragt den Namen einzugeben.
  571. </para>
  572. </sect5>
  573. <sect5
  574. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.pretendable">
  575. <title>Die Ausführung einer Provider-Aktion vorbereiten</title>
  576. <para>
  577. Ein anderes interessantes Feature das man möglicherweise implementieren will
  578. ist die <emphasis>Vorbereitung</emphasis>. Vorbereitung ist die Fähigkeit
  579. des eigenen Providers sich "vorzubereiten", wie wenn er die angefragte
  580. Kombination von Aktion und Provider durchführt und dem Benutzer so viele
  581. Informationen wie möglich darüber zu geben was er tun
  582. <emphasis>würde</emphasis> ohne es wirklich zu tun. Das kann ein wichtiger
  583. Hinweis sein wenn große Änderungen in der Datenbank oder auf dem Dateisystem
  584. durchgeführt werden welche der Benutzer andernfalls nicht durchführen wollen
  585. würde.
  586. </para>
  587. <para>
  588. Voranstellbarkeit ist einfach zu implementieren. Es gibt zwei Teile zu
  589. diesem Feature: 1) Den Provider markieren, das er die Fähigkeit hat
  590. "vorzubereiten", und 2) die Anfrage prüfen und sicherstellen das die
  591. aktuelle Anfrage wirklich als "vorzubereiten" angefragt wurde. Dieses
  592. Feature wird im folgenden Code-Beispiel demonstriert.
  593. </para>
  594. <programlisting language="php"><![CDATA[
  595. class My_Component_HelloProvider
  596. extends Zend_Tool_Framework_Provider_Abstract
  597. implements Zend_Tool_Framework_Provider_Pretendable
  598. {
  599. public function say($name = 'Ralph')
  600. {
  601. if ($this->_registry->getRequest()->isPretend()) {
  602. echo 'Ich würde Hallo zu ' . $name . ' sagen.';
  603. } else {
  604. echo 'Hallo' . $name . ', von meinem Provider!';
  605. }
  606. }
  607. }
  608. ]]></programlisting>
  609. <para>
  610. Um den Provider im vorbereiteten Modus auszuführen muss nur folgendes
  611. aufgerufen werden:
  612. </para>
  613. <programlisting language="sh"><![CDATA[
  614. % zf --pretend say hello Ralph
  615. Ich würde Hallo zu Ralph sagen.
  616. ]]></programlisting>
  617. </sect5>
  618. <sect5
  619. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.verbosedebug">
  620. <title>Verbose und Debug Modi</title>
  621. <para>
  622. Man kann Provider Aktionen auch in den Modi "verbose" oder "debug" laufen
  623. lassen. Die Semantik bezüglich dieser Aktionen muss man im Kontext des
  624. Providers implementieren. Man kann auf die Modi Debug oder Verbose wie
  625. folgt zugreifen:
  626. </para>
  627. <programlisting language="php"><![CDATA[
  628. class My_Component_HelloProvider
  629. implements Zend_Tool_Framework_Provider_Interface
  630. {
  631. public function say($name = 'Ralph')
  632. {
  633. if($this->_registry->getRequest()->isVerbose()) {
  634. echo "Hello::say wurde aufgerufen\n";
  635. }
  636. if($this->_registry->getRequest()->isDebug()) {
  637. syslog(LOG_INFO, "Hello::say wurde aufgerufen\n");
  638. }
  639. }
  640. }
  641. ]]></programlisting>
  642. </sect5>
  643. <sect5
  644. id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.configstorage">
  645. <title>Auf die Benutzerkonfiguration und den Speicher zugreifen</title>
  646. <para>
  647. Bei Verwendung der Umgebungsvariable <property>ZF_CONFIG_FILE</property>
  648. oder von .zf.ini im Heimverzeichnis können Konfigurationsparameter in jeden
  649. <classname>Zend_Tool</classname> Provider eingefügt werden. Der Zugriff auf
  650. diese Konfiguration ist über die Registry möglich welche dem Provider
  651. übergeben wird wenn man
  652. <classname>Zend_Tool_Framework_Provider_Abstract</classname> erweitert.
  653. </para>
  654. <programlisting language="php"><![CDATA[
  655. class My_Component_HelloProvider
  656. extends Zend_Tool_Framework_Provider_Abstract
  657. {
  658. public function say()
  659. {
  660. $username = $this->_registry->getConfig()->username;
  661. if(!empty($username)) {
  662. echo "Hallo $username!";
  663. } else {
  664. echo "Hallo!";
  665. }
  666. }
  667. }
  668. ]]></programlisting>
  669. <para>
  670. Die zurückgegebene Konfiguration ist vom Typ
  671. <classname>Zend_Tool_Framework_Client_Config</classname> allerdings
  672. verweisen die magischen Methoden <methodname>__get()</methodname> und
  673. <methodname>__set()</methodname> intern auf eine
  674. <classname>Zend_Config</classname> oder den angegebenen Konfigurationstyp.
  675. </para>
  676. <para>
  677. Der Speicher erlaubt es notwendige Daten für eine spätere Referenz zu
  678. speichern. Das kann für Aufgaben bei der Ausführung von Batches nützlich
  679. sein oder für das wiederausführen von Aufgaben. Man kann auf den Speicher
  680. auf dem gleichen Weg zugreifen wie auf die Konfiguration:
  681. </para>
  682. <programlisting language="php"><![CDATA[
  683. class My_Component_HelloProvider
  684. extends Zend_Tool_Framework_Provider_Abstract
  685. {
  686. public function say()
  687. {
  688. $aValue = $this->_registry->getStorage()->get("myUsername");
  689. echo "Hallo $aValue!";
  690. }
  691. }
  692. ]]></programlisting>
  693. <para>
  694. Die <acronym>API</acronym> des Speichers ist sehr einfach:
  695. </para>
  696. <programlisting language="php"><![CDATA[
  697. class Zend_Tool_Framework_Client_Storage
  698. {
  699. public function setAdapter($adapter);
  700. public function isEnabled();
  701. public function put($name, $value);
  702. public function get($name, $defaultValue=null);
  703. public function has($name);
  704. public function remove($name);
  705. public function getStreamUri($name);
  706. }
  707. ]]></programlisting>
  708. <important>
  709. <para>
  710. Wenn man Provider erstellt welche Konfigurations-fähig oder
  711. Speicher-fähig sind muss man daran denken dass man prüfen muss ob die
  712. notwendigen Benutzerkonfigurations- oder Speicher-Schlüssel wirklich
  713. für diesen Benutzer existieren. Man wird keine fatalen Fehler erhalten
  714. wenn keiner von Ihnen angegeben wurde, da leere Schlüssel bei der
  715. Anfrage erstellt werden.
  716. </para>
  717. </important>
  718. </sect5>
  719. </sect4>
  720. </sect3>
  721. </sect2>
  722. <sect2 id="zend.tool.extending.zend-tool-project">
  723. <title>Zend_Tool_Project Erweiterungen</title>
  724. <para>
  725. <classname>Zend_Tool_Project</classname> bietet ein reiches Set an Funktionalitäten
  726. und Möglichkeiten welche die Aufgabe der Erstellung neuer Provider, speziell jener
  727. welche auf ein Projekt abzielen, einfacher und besser managebar.
  728. </para>
  729. <sect3 id="zend.tool.extending.zend-tool-project.architecture">
  730. <title>Architektur-Übersicht</title>
  731. <para>
  732. Das selbe Konzept gilt auch für Zend Framework Projekte. In Zend Framework Projekten
  733. hat man Controller, Aktionen, Views, Modelle, Datenbanken und so weiter. Im Sinn
  734. von <classname>Zend_Tool</classname> benötigen wir einen Weg um diese Arten von
  735. Ressourcen zu verfolgen -- deshalb <classname>Zend_Tool_Project</classname>.
  736. </para>
  737. <para>
  738. <classname>Zend_Tool_Project</classname> ist in der Lage Projektressourcen während
  739. der Entwicklung eines Projekts zu verfolgen. Wenn man, zum Beispiel, in einem
  740. Kommando einen Controller erstellt, und im nächsten Kommando eine Aktion in diesem
  741. Controller erstellen will, muss <classname>Zend_Tool_Project</classname> über die
  742. Controllerdatei bescheid <emphasis>wissen</emphasis> die man erstellt hat, damit
  743. man (in der nächsten Aktion) in der Lage ist diese Aktion daran anzuhängen. Das ist
  744. was das Projekt aktuell hält und <emphasis>zustandsbehaftet</emphasis>.
  745. </para>
  746. <para>
  747. Ein andere wichtiger Punkt den man über Projekte verstehen sollte ist, dass
  748. Ressourcen typischerweise in einer hierarchischen Art orgainisiert sind. Dies zu
  749. wissen bedeutet das <classname>Zend_Tool_Project</classname> in der Lage ist das
  750. aktuelle Projekt in eine interne Repräsentation zu serialisieren welche es erlaubt
  751. nicht nur jederzeit festzustellen <emphasis>welche</emphasis> Ressourcen Teil eines
  752. Projekts sind, sondern auch <emphasis>wo</emphasis> Sie in Relation zu anderen
  753. stehen.
  754. </para>
  755. </sect3>
  756. <sect3 id="zend.tool.extending.zend-tool-project.providers">
  757. <title>Provider erstellen</title>
  758. <para>
  759. Projektspezifische Provider werden auf dem selben Weg erstellt wie reine Framework
  760. Provider, mit einer Ausnahme: Projektprovider müssen
  761. <classname>Zend_Tool_Project_Provider_Abstract</classname> erweitern. Diese Klasse
  762. kommt mit einigen signifikanten Funktionalitäten welche Entwicklern helfen
  763. existierende Projekte zu laden, das Profilobjekt zu erhalten, und in der Lage zu
  764. sein das Profil zu suchen, und später dann alle Änderungen im aktuellen
  765. Projektprofil zu speichern.
  766. </para>
  767. <programlisting language="php"><![CDATA[
  768. class My_Component_HelloProvider
  769. extends Zend_Tool_Project_Provider_Abstract
  770. {
  771. public function say()
  772. {
  773. $profile = $this->_loadExistingProfile();
  774. /* ... Projektarbeiten hier durchführen */
  775. $this->_storeProfile();
  776. }
  777. }
  778. ]]></programlisting>
  779. </sect3>
  780. <!--
  781. <sect3 id="zend.tool.extending.zend-tool-project.resources-and-contexts">
  782. <title>Creating Resources &amp; Contexts</title>
  783. </sect3>
  784. -->
  785. </sect2>
  786. </sect1>