[ZF-10089] Zend_Log
[zend.git] / documentation / manual / de / module_specs / Zend_Tool-Extending.xml
blob4cf93620c832994d07acad3114d990cbccfc46fc
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 21829 -->
3 <!-- Reviewed: no -->
4 <sect1 id="zend.tool.extending">
5     <title>Zend_Tool erweitern</title>
7     <sect2 id="zend.tool.extending.overview">
8         <title>Übersicht über Zend_Tool</title>
10         <para>
11             <classname>Zend_Tool_Framework</classname> ist ein Framework für die Bereitstellung
12             gemeinsamer Funktionalitäten wie die Erstellung von Projekthüllen, Code Erzeugung,
13             Erstellung von Suchindezes, und noch mehr. Funktionalitäten können geschrieben und über
14             <acronym>PHP</acronym> Klassen in den <acronym>PHP</acronym>
15             <property>include_path</property> geworfen werden, was eine immense Flexibilität der
16             Implementation liefert. Die Funktionalität kann dann verwendet werden indem eine
17             Implementation geschrieben wird oder durch protokoll-spezifische Clients -- wie Konsolen
18             Clients, <acronym>XML-RPC</acronym>, <acronym>SOAP</acronym>, und andere.
19         </para>
21         <para>
22             <classname>Zend_Tool_Project</classname> baut auf die Möglichkeiten von
23             <classname>Zend_Tool_Framework</classname> auf und erweitert diese um ein "Projekt" zu
24             managen. Generell ist ein "Projekt" ein geplantes Ereignis oder eine Initiative. In der
25             Computerwelt sind Projekte generell Sammlungen von Ressourcen. Diese Ressourcen können
26             Dateien, Verzeichnisse, Datenbanken, Schematas, Bilder, Stile und anderes sein.
27         </para>
28     </sect2>
30     <sect2 id="zend.tool.extending.zend-tool-framework">
31         <title>Erweiterungen von Zend_Tool_Framework</title>
33         <sect3 id="zend.tool.extending.zend-tool-framework.architecture">
34             <title>Überblick der Architektur</title>
36             <para>
37                 <classname>Zend_Tool_Framework</classname> bietet das folgende:
38             </para>
40             <itemizedlist>
41                 <listitem>
42                     <para>
43                         <emphasis>Gemeinsame Interfaces und Abstraktes</emphasis> welche es
44                         Entwicklern erlauben Funktionalitäten und Möglichkeiten zu erstellen welche
45                         durch Tooling Clients verwendbar sind.
46                     </para>
47                 </listitem>
49                 <listitem>
50                     <para>
51                         <emphasis>Grundsätzliche Client Funktionalität</emphasis> und eine konkrete
52                         Konsolenimplementation welche externe Tools und Interfaces mit
53                         <classname>Zend_Tool_Framework</classname> verbindet. Der Konsolenclient
54                         kann in <acronym>CLI</acronym> Umgebungen verwendet werden, wie Unix Shells
55                         und der Windows Konsole.
56                     </para>
57                 </listitem>
59                 <listitem>
60                     <para>
61                         <emphasis>"Provider" und "Manifest" Interfaces</emphasis> welche vom
62                         Toolingsystem verwendet werden können. "Provider" repräsentieren den
63                         funktionalen Aspekt des Frameworks, und definieren die Aktionen welche
64                         Tooling Clients aufrufen können. "Manifests" agieren als Metadaten
65                         Registrierungen welche zusätzlichen Kontext für die verschiedenen
66                         definierten Provider bieten.
67                     </para>
68                 </listitem>
70                 <listitem>
71                     <para>
72                         <emphasis>Ein introspektives Ladesystem</emphasis> welches die Umgebung auf
73                         Provider scannt und erkennt was benötigt wird um Sie auszuführen.
74                     </para>
75                 </listitem>
77                 <listitem>
78                     <para>
79                         <emphasis>Ein Standardset von System Provider</emphasis> welche dem System
80                         erlauben zu melden was die kompletten Möglichkeiten des Systems sind, und
81                         ein nützliches Feedback bieten. Das beinhaltet auch ein ausführliches
82                         "Hilfe System".
83                     </para>
84                 </listitem>
85             </itemizedlist>
87             <para>
88                 Definitionen welche man in diesem Handbuch in Bezug auf
89                 <classname>Zend_Tool_Framework</classname> beachten sollte sind:
90             </para>
92             <itemizedlist>
94                 <listitem>
95                     <para>
96                         <classname>Zend_Tool_Framework</classname> - Der Framework welche die
97                         Tooling Möglichkeiten bereitstellt.
98                     </para>
99                 </listitem>
101                 <listitem>
102                     <para>
103                         <emphasis>Tooling Client</emphasis> - Ein Entwickler-Tool welches sich zum
104                         <classname>Zend_Tool_Framework</classname> verbindet und Ihn verwendet.
105                     </para>
106                 </listitem>
108                 <listitem>
109                     <para>
110                         <emphasis>Client</emphasis> - Das Subsystem von
111                         <classname>Zend_Tool_Framework</classname> welches ein Interface
112                         bereitstellt so das sich Tooling-Clienten verbinden, und Kommandos abfragen
113                         und ausführen können.
114                     </para>
115                 </listitem>
117                 <listitem>
118                     <para>
119                         <emphasis>Konsolen Client / Kommandozeilen Interface /
120                         <filename>zf.php</filename></emphasis> - Der Tooling Client für die
121                         Kommandozeile.
122                     </para>
123                 </listitem>
125                 <listitem>
126                     <para>
127                         <emphasis>Provider</emphasis> - Ein Subsystem und eine Sammlung von
128                         eingebauten Funktionalitäten welche der Framework exportiert.
129                     </para>
130                 </listitem>
132                 <listitem>
133                     <para>
134                         <emphasis>Manifest</emphasis> - Ein Subsystem für die Definition,
135                         Organisation, und Verbreitung von Daten welche Provider benötigen.
136                     </para>
137                 </listitem>
139                 <listitem>
140                     <para>
141                         <classname>Zend_Tool_Project</classname> Provider - Ein Set von Providern
142                         speziell für die Erstellung und die Wartung von Zend Framework basierenden
143                         Projekten.
144                     </para>
145                 </listitem>
146             </itemizedlist>
147         </sect3>
149         <sect3 id="zend.tool.extending.zend-tool-framework.cli-client">
150             <title>Verstehen des CLI Clients</title>
152             <para>
153                 Das <acronym>CLI</acronym>, oder Kommandozeilen-Tool (intern als das Konsolen-Tool
154                 bekannt) ist aktuell das primäre Interface für die Bearbeitung von
155                 <classname>Zend_Tool</classname> Anfragen. Mit dem <acronym>CLI</acronym> Tool
156                 können Entwickler Tooling-Anfragen im "Kommandozeilen-Fenster" behandeln,
157                 üblicherweise auch als "Terminal" Fenster bekannt. Diese Umgebung ist in einer *nix
158                 Umgebung vorherrschend, hat aber auch eine übliche Implementation in Windows mit
159                 <filename>cmd.exe</filename>, Console2 und mit dem Cygwin Projekt.
160             </para>
162             <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-general">
163                 <title>Das CLI Tool vorbereiten</title>
165                 <para>
166                     Um Tooling-Anfragen über den Kommandozeilen-Client auszuführen, muss man zuerst
167                     den Client vorbereiten so dass das System den "zf" Befehl ausführen kann. Der
168                     Kommandozeilen-Client ist, für alle Wünsche und Zwecke, die Datei
169                     <filename>.sh</filename> oder <filename>.bat</filename> welche mit der Zend
170                     Framework Distribution bereitgestellt wird. Im Trunk kann er hier gefunden
171                     werden: <ulink
172                         url="http://framework.zend.com/svn/framework/standard/trunk/bin/">http://framework.zend.com/svn/framework/standard/trunk/bin/</ulink>.
173                 </para>
175                 <para>
176                     Wie man sehen kann, gibt es 3 Dateien im <filename>/bin/</filename> Verzeichnis:
177                     <filename>zf.php</filename>, <filename>zf.sh</filename>, und
178                     <filename>zf.bat</filename>. <filename>zf.sh</filename> und
179                     <filename>zf.bat</filename> sind Betriebssystem-spezifische Client-Wrapper:
180                     <filename>zf.sh</filename> für die *nix Umgebung, und
181                     <filename>zf.bat</filename> für die Win32 Umgebung. Diese Client-Wrapper sind
182                     für das Finden der richtigen <filename>php.exe</filename>, das finden der
183                     <filename>zf.php</filename>, und die Übergabe an die Anfrage des Clients
184                     zuständig. Die <filename>zf.php</filename> ist verantwortlich für die
185                     Behandlung der Umgebung, die Erstellung des richtigen include_path, und der
186                     Übergabe von dem was auf der Kommandozeile angegeben wurde an die richtige
187                     Bibliothekskomponente für die Bearbeitung.
188                 </para>
190                 <para>
191                     Ultimativ, muss man zwei Dinge sicherstellen damit alles funktioniert,
192                     unabhängig vom Betriebssystem auf dem man arbeitet:
193                 </para>
195                 <orderedlist>
196                     <listitem>
197                         <para>
198                             <filename>zf.sh/zf.bat</filename> ist vom Systempfad aus erreichbar.
199                             Das ist die Fähigkeit <command>zf</command> von überall aus aufzurufen,
200                             unabhängig von aktuellen Arbeitsverzeichnisses.
201                         </para>
202                     </listitem>
204                     <listitem>
205                         <para>
206                             <filename>ZendFramework/library</filename> ist im
207                             <property>include_path</property>.
208                         </para>
209                     </listitem>
210                 </orderedlist>
212                 <note>
213                     <para>
214                         Zu beachten: Wärend das oben stehende sind die idealsten Notwendigkeiten
215                         sind, kann man einfach Zend Framework herunterladen und erwarten das es
216                         mit <filename>./path/to/zf.php</filename> und einem Kommando funktioniert.
217                     </para>
218                 </note>
219             </sect4>
221             <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-starnix">
222                 <title>Das CLI Tool auf Unix-artigen Systemen einrichten</title>
224                 <para>
225                     Das üblichste Setup in einer *nix Umgebung ist es, <filename>zf.sh</filename>
226                     und <filename>zf.sh</filename> in das selbe Verzeichnis wie die
227                     <acronym>PHP</acronym> Installation zu kopieren. Diese kann normalerweise in
228                     einem der folgenden Plätze gefunden werden:
229                 </para>
231                 <programlisting language="text"><![CDATA[
232 /usr/bin
233 /usr/local/bin
234 /usr/local/ZendServer/bin/
235 /Applications/ZendServer/bin/
236 ]]></programlisting>
238                 <para>
239                     Um den Ort der eigenen <acronym>PHP</acronym> Installation zu finden kann man
240                     'which php' auf der Kommandozeile ausführen. Das gibt den Ort der
241                     <acronym>PHP</acronym> Installation zurück welche verwendet wird um in dieser
242                     Umgebung <acronym>PHP</acronym> Skripte auszuführen.
243                 </para>
245                 <para>
246                     Der nächste Schritt ist es sicherzustellen das die Zend Framework Bibliothek
247                     korrekt im <acronym>PHP</acronym> <property>include_path</property> eingestellt
248                     wurde. Um herauszufinden wo der <property>include_path</property> ist, kann man
249                     <command>php -i</command> ausführen und nach der
250                     <property>include_path</property> Variable sehen, oder kompakter
251                     <command>php -i | grep include_path</command> ausführen. Sobald man
252                     herausgefunden hat wo der <property>include_path</property> ist (er ist
253                     normalerweise etwas wie <filename>/usr/lib/php</filename>,
254                     <filename>/usr/share/php</filename>, <filename>/usr/local/lib/php</filename>,
255                     oder so ähnlich), sollte man sicherstellen das der Inhalt des Verzeichnisses
256                     <filename>/library/</filename> in einem der in <property>include_path</property>
257                     spezifizierten Verzeichnisse ist.
258                 </para>
260                 <para>
261                     Sobald man diese zwei Dinge getan hat, sollte man in der Lage sein ein Kommando
262                     auszuführen und die richtige Antwort zurück zu erhalten, wie zum Beispiel:
263                 </para>
265                 <para>
266                     <inlinegraphic scale="100" align="center" valign="middle"
267                         fileref="figures/zend.tool.framework.cliversionunix.png" format="PNG" />
268                 </para>
270                 <para>
271                     Wenn man diese Art der Ausgabe nicht sieht, sollte man zurückgeben und die
272                     eigenen Einstellungen prüfen um sicherzustellen das man alle notwendigen Teile
273                     am richtigen Ort vorhanden sind.
274                 </para>
276                 <para>
277                     Es gibt eine Anzahl an alternativen Einstellungen die man erstellen kann,
278                     abhängig von der Konfiguration des Servers, dem Zugriffslevel, oder aus anderen
279                     Gründen.
280                 </para>
282                 <para>
283                     Das <emphasis>alternative Setup</emphasis> enthält das man den Download vom Zend
284                     Framework zusammenbehält wie er ist, und einen Link von einem
285                     <constant>PATH</constant> Ort zur <filename>zf.sh</filename> erstellt. Was dies
286                     bedeutet ist, dass man den Inhalt des Zend Framework Downloads in einem Ort wie
287                     <filename>/usr/local/share/ZendFramework</filename> platzieren kann, oder
288                     lokaler unter <filename>/home/username/lib/ZendFramework</filename> und einen
289                     symbolischen Link zu <filename>zf.sh</filename> erstellt.
290                 </para>
292                 <para>
293                     Angenommen man will den Link in <filename>/usr/local/bin</filename> platzieren
294                     (dies könnte zum Beispiel auch für die Platzierung des Links unter
295                     <filename>/home/username/bin/</filename> funktionieren), dan würde man ein
296                     Kommando wie das folgende platzieren:
297                 </para>
299                 <programlisting language="sh"><![CDATA[
300 ln -s /usr/local/share/ZendFramework/bin/zf.sh /usr/local/bin/zf
302 # ODER (zum Beispiel)
303 ln -s /home/username/lib/ZendFramework/bin/zf.sh /home/username/bin/zf
304 ]]></programlisting>
306                 <para>
307                     Das erstellt einen Link auf den man global von der Kommandozeile aus zugreifen
308                     kann.
309                 </para>
310             </sect4>
312             <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-windows">
313                 <title>Das CLI Tool unter Windows einrichten</title>
315                 <para>
316                     Das üblichste Setup in einer Windows Win32 Umgebung ist es
317                     <filename>zf.bat</filename> und <filename>zf.php</filename> in das selbe
318                     Verzeichnis wie die <acronym>PHP</acronym> Bibliothek zu kopieren. Diese kann
319                     generell an einem der folgenden Plätze gefunden werden:
320                 </para>
322                 <programlisting language="text"><![CDATA[
323 C:\PHP
324 C:\Program Files\ZendServer\bin\
325 C:\WAMP\PHP\bin
326 ]]></programlisting>
328                 <para>
329                     Man sollte in der Lage sein <filename>php.exe</filename> von der Kommandozeile
330                     aus auszuführen. Wenn man dazu nicht in der Lage ist, sollte man zuerst die
331                     Dokumentation prüfen welche mit der <acronym>PHP</acronym> Bibliothek
332                     mitgeliefert wird, um sicherzustellen dass der Pfad zu
333                     <filename>php.exe</filename> in der Windows Umgebungsvariable
334                     <constant>PATH</constant> zu finden ist.
335                 </para>
337                 <para>
338                     Der nächste Schritt besteht darin sicherzustellen das die Zend Framework
339                     Bibliothek richtig auf dem <acronym>PHP</acronym>
340                     <property>include_path</property> des Systems eingerichtet ist. Um
341                     herauszufinden wo der <property>include_path</property> ist, kann man
342                     <command>php -i</command> eingeben und nach der Variable
343                     <property>include_path</property> sehen, oder kompakter
344                     <command>php -i | grep include_path</command> ausführen wenn man ein Cygwin
345                     Setup mit vorhandenem grep hat. Sobald man herausgefunden hat wo der
346                     <property>include_path</property> liegt (das ist normalerweise etwas wie
347                     <filename>C:\PHP\pear</filename>, <filename>C:\PHP\share</filename>,
348                     <filename>C:\Program%20Files\ZendServer\share</filename>, oder ähnlich), sollte
349                     man sicherstellen das der Inhalt des Verzeichnisses library/ in einem vom
350                     <property>include_path</property> spezifizierten Verzeichnis ist.
351                 </para>
353                 <para>
354                     Sobald man diese zwei Dinge getan hat, sollte man in der Lage sein ein Kommando
355                     auszuführen und die richtige Antwort, so ähnlich wie die folgende, zu erhalten:
356                 </para>
358                 <para>
359                     <inlinegraphic scale="100" align="center" valign="middle"
360                         fileref="figures/zend.tool.framework.cliversionwin32.png" format="PNG" />
361                 </para>
363                 <para>
364                     Wenn man diese Art der Ausgabe nicht sieht, sollte man zurückgehen und die
365                     Einstellungen prüfen um sicherzustellen das man alle notwendigen Teile an den
366                     richtigen Orten hat.
367                 </para>
369                 <para>
370                     Es gibt eine Anzahl an alternativen Einstellungen die man erstellen kann,
371                     abhängig von der Konfiguration des Servers, dem Zugriffslevel, oder aus anderen
372                     Gründen.
373                 </para>
375                 <para>
376                     Das <emphasis>alternative Setup</emphasis> enthält das man den Download vom Zend
377                     Framework zusammenbehält wie er ist, und sowohl den System
378                     <constant>PATH</constant>, als auch die <filename>php.ini</filename> Datei
379                     verändert. In der Umgebung des Benutzers muss man
380                     <filename>C:\Path\To\ZendFramework\bin</filename> hinzufügen damit die Datei
381                     <filename>zf.bat</filename> ausführbar ist. Auch die Datei
382                     <filename>php.ini</filename> ist zu verändern um sicherzustellen das
383                     <filename>C:\Path\To\ZendFramework\library</filename> im
384                     <property>include_path</property> liegt.
385                 </para>
386             </sect4>
388             <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-othernotes">
389                 <title>Andere Einstellungs-Möglichkeiten</title>
391                 <para>
392                     Wenn man aus bestimmten Gründen die Zend Framework Bibliothek nicht im
393                     <property>include_path</property> haben will, gibt es andere Optionen. Es gibt
394                     zwei spezielle Umgebungsvariablen welche <filename>zf.php</filename> verwendet
395                     um den Ort der Zend Framework Installation zu erkennen.
396                 </para>
398                 <para>
399                     Die erste ist <constant>ZEND_TOOL_INCLUDE_PATH_PREPEND</constant>, welche den
400                     Wert der Umgebungsvariable dem <property>include_path</property> des Systems
401                     (<filename>php.ini</filename>) voranstellt bevor der Client geladen wird.
402                 </para>
404                 <para>
405                     Alternativ kann man <constant>ZEND_TOOL_INCLUDE_PATH</constant> verwenden um den
406                     <property>include_path</property> des System komplett zu
407                     <emphasis>ersetzen</emphasis> für jene bei denen es Sinn macht, speziell für das
408                     <command>zf</command> Kommandozeilen-Tool.
409                 </para>
410             </sect4>
411         </sect3>
413         <sect3 id="zend.tool.extending.zend-tool-framework.providers-and-manifests">
414             <title>Erstellen von Providern</title>
416             <para>
417                 Generell, ist ein Provider für sich selbst gesehen, nichts weiter als eine Shell für
418                 einen Entwickler um einige Möglichkeiten zu bündeln welche er mit den Kommandozeilen
419                 (oder anderen) Clients ausführen will. Das ist eine Analogie für das was der
420                 "Controller" in der <acronym>MVC</acronym> Anwendung ist.
421             </para>
423             <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading">
424                 <title>Wie Zend_Tool eigene Provider findet</title>
426                 <para>
427                     Standardmäßig verwendet <classname>Zend_Tool</classname> den BasicLoader um alle
428                     Provider zu finden die es ausführen kann. Er durchsucht alle Verzeichnisse des
429                     Include Pfades rekursiv und öffnet alle Dateien welche mit "Manifest.php" oder
430                     "Provider.php" enden. Alle Klassen in diesen Dateien werden darauf durchsucht ob
431                     Sie entweder <classname>Zend_Tool_Framework_Provider_Interface</classname> oder
432                     <classname>Zend_Tool_Framework_Manifest_ProviderManifestable</classname>
433                     implementieren. Instanzen des Provider Interfaces sind für die echte
434                     Funktionalität zuständig und alle Ihre öffentlichen Methoden kann als Provider
435                     Aktionen zugegriffen werden. Das ProviderManifestable Interface benötigt
436                     trotzdem die Implementation einer <methodname>getProviders()</methodname>
437                     Methode welche ein Array an instanzierten Provider Interface Instanzen
438                     zurückgibt.
439                 </para>
441                 <para>
442                     Die folgenden Namensregeln sind darauf anzuwenden, wie man auf die Provider
443                     zugreifen kann welche vom IncludePathLoader gefunden werden:
444                 </para>
446                 <itemizedlist>
447                     <listitem>
448                         <para>
449                             Der letzte Teil des eigenen Klassennamens welcher von einem Unterstrich
450                             getrennt ist, wird für den Providernamen verwendet, zum Beispiel führt
451                             "My_Provider_Hello" zum Provider auf welchen mit dem Namen "hello"
452                             zugegriffen werden kann.
453                         </para>
454                     </listitem>
456                     <listitem>
457                         <para>
458                             Wenn der Provider eine Methode <methodname>getName()</methodname> hat,
459                             dann wird diese verwendet statt der vorherigen Methode um den Namen zu
460                             erkennen.
461                         </para>
462                     </listitem>
464                     <listitem>
465                         <para>
466                             Wenn der Provider den Präfix "Provider" hat, zum Beispiel wenn er
467                             <classname>My_HelloProvider</classname> heißt, dann wird er vom Namen
468                             entfernt so dass der Provider "hello" heißt.
469                         </para>
470                     </listitem>
471                 </itemizedlist>
473                 <note>
474                     <para>
475                         Der IncludePathLoader folgt Symlinks nicht, was bedeutet das man Provider
476                         Funktionalitäten nicht in den Include Pfaden verlinken kann, sondern dass
477                         Sie physikalisch in den Include Pfaden vorhanden sein müssen.
478                     </para>
479                 </note>
481                 <example
482                     id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading.example">
483                     <title>Provider mit einem Manifest bekanntmachen</title>
485                     <para>
486                         Man kann eigene Provider bei <classname>Zend_Tool</classname> bekannt machen
487                         indem man ein Manifest anbietet, mit einer speziellen Endung des Dateinamens
488                         von "Manifest.php". Ein Provider-Manifest ist eine Implementation von
489                         <interface>Zend_Tool_Framework_Manifest_ProviderManifestable</interface> und
490                         benötigt die <methodname>getProviders()</methodname> Methode um ein Array
491                         von instanziierten Providern zurückzugeben. Anders als unser erster eigener
492                         Provider <classname>My_Component_HelloProvider</classname> erstellen wir das
493                         folgende Manifest:
494                     </para>
496                     <programlisting language="php"><![CDATA[
497 class My_Component_Manifest
498     implements Zend_Tool_Framework_Manifest_ProviderManifestable
500     public function getProviders()
501     {
502         return array(
503             new My_Component_HelloProvider()
504         );
505     }
507 ]]></programlisting>
508                 </example>
509             </sect4>
511             <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.basic">
512                 <title>Grundsätzliche Instruktionen für die Erstellung von Providern</title>
514                 <para>
515                     Wenn, als Beispiel, ein Entwickler die Fähigkeit, eine Version einer Datendatei
516                     anzuzeigen, hinzufügen will mit der seine 3rd Party Komponente arbeitet, gibt es
517                     nur eine Klasse welche der Entwickler implementieren muss. Angenommen die
518                     Komponente wird <classname>My_Component</classname> genannt, dann würde er eine
519                     Klasse erstellen welche <classname>My_Component_HelloProvider</classname> heißt
520                     in einer Datei wleche <filename>HelloProvider.php</filename> genannt ist und
521                     irgendwo in seinem <property>include_path</property> liegt. Diese Klasse würde
522                     <classname>Zend_Tool_Framework_Provider_Interface</classname> implementieren und
523                     diese Datei würde etwa wie folgt auszusehen haben:
524                 </para>
526                 <programlisting language="php"><![CDATA[
527 class My_Component_HelloProvider
528     implements Zend_Tool_Framework_Provider_Interface
530     public function say()
531     {
532         echo 'Hallo von meinem Provider!';
533     }
535 ]]></programlisting>
537                 <para>
538                     Bei dem obigen Code und der Annahme das der Entwickler Zugriff auf diese
539                     Funktionalität über den Konsolen-Client haben will, würde der Aufruf wie folgt
540                     aussehen:
541                 </para>
543                 <programlisting language="sh"><![CDATA[
544 % zf say hello
545 Hallo von meinem Provider!
546 ]]></programlisting>
547             </sect4>
549             <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.response">
550                 <title>Das Antwort-Objekt</title>
552                 <para>
553                     Wie im Architektur-Abschnitt diskutiert erlaubt es
554                     <classname>Zend_Tool</classname> andere Clients für die Verwendung eigener
555                     <classname>Zend_Tool</classname> Provider zu verknüpfen. Um den
556                     unterschiedlichen Clients zu entsprechen sollte man das Antwort-Objekt verwenden
557                     um Rückgabe-Meldungen von Providern zurückzugeben anstatt
558                     <methodname>echo()</methodname> oder ähnliche Ausgabe-Mechanismen zu verwenden.
559                     Nach dem Umschreiben des Hello-Providers mit diesen Erkenntnissen sieht er wie
560                     folgt aus:
561                 </para>
563                 <programlisting language="php"><![CDATA[
564 class My_Component_HelloProvider
565     extends Zend_Tool_Framework_Provider_Abstract
567     public function say()
568     {
569         $this->_registry->getResponse
570                         ->appendContent("Hallo von meinem Provider!");
571     }
573 ]]></programlisting>
575                 <para>
576                     Wie man sieht muss <classname>Zend_Tool_Framework_Provider_Abstract</classname>
577                     erweitert werden um Zugriff auf die Registry zu erhalten welche die
578                     <classname>Zend_Tool_Framework_Client_Response</classname> Instanz enthält.
579                 </para>
580             </sect4>
582             <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced">
583                 <title>Fortgeschrittene Informationen für die Entwicklung</title>
585                 <sect5
586                     id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.variables">
587                     <title>Variablen an einen Provider übergeben</title>
589                     <para>
590                         Das obige "Hello World" Beispiel ist großartig für einfache Befehle, aber
591                         was ist mit etwas komplizierterem? Wenn die eigenen Skripting- und
592                         Tooling-Bedürfnisse wachsen kann man die Notwendigkeit sehen dass man
593                         Variablen akzeptiert. So wie Funktions-Signaturen Parameter haben, so können
594                         eigene Tooling-Anfragen auch Parmeter akzeptieren.
595                     </para>
597                     <para>
598                         So wie jede Tooling-Anfrage isoliert von einer Methode in einer Klasse sein
599                         kann, können auch die Parameter einer Tooling-Anfrage in einem sehr
600                         bekanntem Platz isoliert sein. Parameter einer Aktions-Methode eines
601                         Providers können die selben Parameter enthalten welche der eigene Client
602                         verwenden soll wenn diese Provider und Aktions-Methode aufgerufen wird.
603                         Wenn man zum Beispiel einen Namen im oben stehenden Beispiel akzeptieren
604                         will, würde man möglicherweise folgendes in OO Code machen:
605                     </para>
607                     <programlisting language="php"><![CDATA[
608 class My_Component_HelloProvider
609     implements Zend_Tool_Framework_Provider_Interface
611     public function say($name = 'Ralph')
612     {
613         echo 'Hallo' . $name . ', von meinem Provider!';
614     }
616 ]]></programlisting>
618                     <para>
619                         Das obige Beispiel kann dann über die Kommandozeile
620                         <command>zf say hello Joe</command> aufgerufen werden. "Joe" wird dem
621                         Provider bereitgestellt so wie ein Parameter eines Methodenaufrufs. Es ist
622                         auch zu beachten das der Parameter optional ist, was bedeutet das er auch
623                         in der Kommandozeile optional ist, so dass
624                         <command>zf say hello</command> trotzdem noch funktioniert, und auf den
625                         Standardwert "Ralph" zeigt.
626                     </para>
627                 </sect5>
629                 <sect5
630                     id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.prompt">
631                     <title>Den Benutzer nach einer Eingabe fragen</title>
633                     <para>
634                         Es gibt Fälle in denen der Workflow des eigenen Providers es notwendig macht
635                         den Benutzer nach einer Eingabe zu fragen. Dies kann getan werden indem der
636                         Client nach einer zusätzlich benötigten Eingabe gefragt wird indem folgendes
637                         aufgerufen wird:
638                     </para>
640                     <programlisting language="php"><![CDATA[
641 class My_Component_HelloProvider
642     extends Zend_Tool_Framework_Provider_Abstract
644     public function say($name = 'Ralph')
645     {
646         $nameResponse = $this->_registry
647                              ->getClient()
648                              ->promptInteractiveInput("Wie ist dein Name?");
649         $name = $name->getContent();
651         echo 'Hallo' . $name . ', von meinem Provider!';
652     }
654 ]]></programlisting>
656                     <para>
657                         Dieses Kommando wirft eine Ausnahme wenn der aktuelle Client nicht in der
658                         Lage ist interaktive Anfragen zu behandeln. Im Falle des standardmäßigen
659                         Konsolen-Clients wird man aber danach gefragt den Namen einzugeben.
660                     </para>
661                 </sect5>
663                 <sect5
664                     id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.pretendable">
665                     <title>Die Ausführung einer Provider-Aktion vorbereiten</title>
667                     <para>
668                         Ein anderes interessantes Feature das man möglicherweise implementieren will
669                         ist die <emphasis>Vorbereitung</emphasis>. Vorbereitung ist die Fähigkeit
670                         des eigenen Providers sich "vorzubereiten", wie wenn er die angefragte
671                         Kombination von Aktion und Provider  durchführt und dem Benutzer so viele
672                         Informationen wie möglich darüber zu geben was er tun
673                         <emphasis>würde</emphasis> ohne es wirklich zu tun. Das kann ein wichtiger
674                         Hinweis sein wenn große Änderungen in der Datenbank oder auf dem Dateisystem
675                         durchgeführt werden welche der Benutzer andernfalls nicht durchführen wollen
676                         würde.
677                     </para>
679                     <para>
680                         Voranstellbarkeit ist einfach zu implementieren. Es gibt zwei Teile zu
681                         diesem Feature: 1) Den Provider markieren, das er die Fähigkeit hat
682                         "vorzubereiten", und 2) die Anfrage prüfen und sicherstellen das die
683                         aktuelle Anfrage wirklich als "vorzubereiten" angefragt wurde. Dieses
684                         Feature wird im folgenden Code-Beispiel demonstriert.
685                     </para>
687                     <programlisting language="php"><![CDATA[
688 class My_Component_HelloProvider
689     extends    Zend_Tool_Framework_Provider_Abstract
690     implements Zend_Tool_Framework_Provider_Pretendable
692     public function say($name = 'Ralph')
693     {
694         if ($this->_registry->getRequest()->isPretend()) {
695             echo 'Ich würde Hallo zu ' . $name . ' sagen.';
696         } else {
697             echo 'Hallo' . $name . ', von meinem Provider!';
698         }
699     }
701 ]]></programlisting>
703                     <para>
704                         Um den Provider im vorbereiteten Modus auszuführen muss nur folgendes
705                         aufgerufen werden:
706                     </para>
708                     <programlisting language="sh"><![CDATA[
709 % zf --pretend say hello Ralph
710 Ich würde Hallo zu Ralph sagen.
711 ]]></programlisting>
712                 </sect5>
714                 <sect5
715                     id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.verbosedebug">
716                     <title>Verbose und Debug Modi</title>
718                     <para>
719                         Man kann Provider Aktionen auch in den Modi "verbose" oder "debug" laufen
720                         lassen. Die Semantik bezüglich dieser Aktionen muss man im Kontext des
721                         Providers implementieren. Man kann auf die Modi Debug oder Verbose wie
722                         folgt zugreifen:
723                     </para>
725                     <programlisting language="php"><![CDATA[
726 class My_Component_HelloProvider
727     implements Zend_Tool_Framework_Provider_Interface
729     public function say($name = 'Ralph')
730     {
731         if($this->_registry->getRequest()->isVerbose()) {
732             echo "Hello::say wurde aufgerufen\n";
733         }
734         if($this->_registry->getRequest()->isDebug()) {
735             syslog(LOG_INFO, "Hello::say wurde aufgerufen\n");
736         }
737     }
739 ]]></programlisting>
740                 </sect5>
742                 <sect5
743                     id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.configstorage">
744                     <title>Auf die Benutzerkonfiguration und den Speicher zugreifen</title>
746                     <para>
747                         Bei Verwendung der Umgebungsvariable <property>ZF_CONFIG_FILE</property>
748                         oder von .zf.ini im Heimverzeichnis können Konfigurationsparameter in jeden
749                         <classname>Zend_Tool</classname> Provider eingefügt werden. Der Zugriff auf
750                         diese Konfiguration ist über die Registry möglich welche dem Provider
751                         übergeben wird wenn man
752                         <classname>Zend_Tool_Framework_Provider_Abstract</classname> erweitert.
753                     </para>
755                     <programlisting language="php"><![CDATA[
756 class My_Component_HelloProvider
757     extends Zend_Tool_Framework_Provider_Abstract
759     public function say()
760     {
761         $username = $this->_registry->getConfig()->username;
762         if(!empty($username)) {
763             echo "Hallo $username!";
764         } else {
765             echo "Hallo!";
766         }
767     }
769 ]]></programlisting>
771                     <para>
772                         Die zurückgegebene Konfiguration ist vom Typ
773                         <classname>Zend_Tool_Framework_Client_Config</classname> allerdings
774                         verweisen die magischen Methoden <methodname>__get()</methodname> und
775                         <methodname>__set()</methodname> intern auf eine
776                         <classname>Zend_Config</classname> oder den angegebenen Konfigurationstyp.
777                     </para>
779                     <para>
780                         Der Speicher erlaubt es notwendige Daten für eine spätere Referenz zu
781                         speichern. Das kann für Aufgaben bei der Ausführung von Batches nützlich
782                         sein oder für das wiederausführen von Aufgaben. Man kann auf den Speicher
783                         auf dem gleichen Weg zugreifen wie auf die Konfiguration:
784                     </para>
786                     <programlisting language="php"><![CDATA[
787 class My_Component_HelloProvider
788     extends Zend_Tool_Framework_Provider_Abstract
790     public function say()
791     {
792         $aValue = $this->_registry->getStorage()->get("myUsername");
793         echo "Hallo $aValue!";
794     }
796 ]]></programlisting>
798                     <para>
799                         Die <acronym>API</acronym> des Speichers ist sehr einfach:
800                     </para>
802                     <programlisting language="php"><![CDATA[
803 class Zend_Tool_Framework_Client_Storage
805     public function setAdapter($adapter);
806     public function isEnabled();
807     public function put($name, $value);
808     public function get($name, $defaultValue=null);
809     public function has($name);
810     public function remove($name);
811     public function getStreamUri($name);
813 ]]></programlisting>
815                     <important>
816                         <para>
817                             Wenn man Provider erstellt welche Konfigurations-fähig oder
818                             Speicher-fähig sind muss man daran denken dass man prüfen muss ob die
819                             notwendigen Benutzerkonfigurations- oder Speicher-Schlüssel wirklich
820                             für diesen Benutzer existieren. Man wird keine fatalen Fehler erhalten
821                             wenn keiner von Ihnen angegeben wurde, da leere Schlüssel bei der
822                             Anfrage erstellt werden.
823                         </para>
824                     </important>
825                 </sect5>
826             </sect4>
827         </sect3>
828     </sect2>
830     <sect2 id="zend.tool.extending.zend-tool-project">
831         <title>Zend_Tool_Project Erweiterungen</title>
833         <para>
834             <classname>Zend_Tool_Project</classname> bietet ein reiches Set an Funktionalitäten
835             und Möglichkeiten welche die Aufgabe der Erstellung neuer Provider, speziell jener
836             welche auf ein Projekt abzielen, einfacher und besser managebar.
837         </para>
839         <sect3 id="zend.tool.extending.zend-tool-project.architecture">
840             <title>Architektur-Übersicht</title>
842             <para>
843                 Das selbe Konzept gilt auch für Zend Framework Projekte. In Zend Framework Projekten
844                 hat man Controller, Aktionen, Views, Modelle, Datenbanken und so weiter. Im Sinn
845                 von <classname>Zend_Tool</classname> benötigen wir einen Weg um diese Arten von
846                 Ressourcen zu verfolgen -- deshalb <classname>Zend_Tool_Project</classname>.
847             </para>
849             <para>
850                 <classname>Zend_Tool_Project</classname> ist in der Lage Projektressourcen wärend
851                 der Entwicklung eines Projekts zu verfolgen. Wenn man, zum Beispiel, in einem
852                 Kommando einen Controller erstellt, und im nächsten Kommando eine Aktion in diesem
853                 Controller erstellen will, muss <classname>Zend_Tool_Project</classname> über die
854                 Controllerdatei bescheid <emphasis>wissen</emphasis> die man erstellt hat, damit
855                 man (in der nächsten Aktion) in der Lage ist diese Aktion daran anzuhängen. Das ist
856                 was das Projekt aktuell hält und <emphasis>zustandsbehaftet</emphasis>.
857             </para>
859             <para>
860                 Ein andere wichtiger Punkt den man über Projekte verstehen sollte ist, dass
861                 Ressourcen typischerweise in einer hierarchischen Art orgainisiert sind. Dies zu
862                 wissen bedeutet das <classname>Zend_Tool_Project</classname> in der Lage ist das
863                 aktuelle Projekt in eine interne Repräsentation zu serialisieren welche es erlaubt
864                 nicht nur jederzeit festzustellen <emphasis>welche</emphasis> Ressourcen Teil eines
865                 Projekts sind, sondern auch <emphasis>wo</emphasis> Sie in Relation zu anderen
866                 stehen.
867             </para>
868         </sect3>
870         <sect3 id="zend.tool.extending.zend-tool-project.providers">
871             <title>Provider erstellen</title>
873             <para>
874                 Projektspezifische Provider werden auf dem selben Weg erstellt wie reine Framework
875                 Provider, mit einer Ausnahme: Projektprovider müssen
876                 <code>Zend_Tool_Project_Provider_Abstract</code> erweitern. Diese Klasse kommt mit
877                 einigen signifikanten Funktionalitäten welche Entwicklern helfen existierende
878                 Projekte zu laden, das Profilobjekt zu erhalten, und in der Lage zu sein das Profil
879                 zu suchen, und später dann alle Änderungen im aktuellen Projektprofil zu speichern.
880             </para>
882             <programlisting language="php"><![CDATA[
883 class My_Component_HelloProvider
884     extends Zend_Tool_Project_Provider_Abstract
886     public function say()
887     {
888         $profile = $this->_loadExistingProfile();
890         /* ... Projektarbeiten hier durchführen */
892         $this->_storeProfile();
893     }
895 ]]></programlisting>
896         </sect3>
898         <!--
899         <sect3 id="zend.tool.extending.zend-tool-project.resources-and-contexts">
900             <title>Creating Resources &amp; Contexts</title>
902         </sect3>
903         -->
904     </sect2>
905 </sect1>