| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 22745 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.tool.extending">
- <title>Zend_Tool erweitern</title>
- <sect2 id="zend.tool.extending.overview">
- <title>Übersicht über Zend_Tool</title>
- <para>
- <classname>Zend_Tool_Framework</classname> ist ein Framework für die Bereitstellung
- gemeinsamer Funktionalitäten wie die Erstellung von Projekthüllen, Code Erzeugung,
- Erstellung von Suchindezes, und noch mehr. Funktionalitäten können geschrieben und über
- <acronym>PHP</acronym> Klassen in den <acronym>PHP</acronym>
- <property>include_path</property> geworfen werden, was eine immense Flexibilität der
- Implementation liefert. Die Funktionalität kann dann verwendet werden indem eine
- Implementation geschrieben wird oder durch protokoll-spezifische Clients -- wie Konsolen
- Clients, <acronym>XML-RPC</acronym>, <acronym>SOAP</acronym>, und andere.
- </para>
- <para>
- <classname>Zend_Tool_Project</classname> baut auf die Möglichkeiten von
- <classname>Zend_Tool_Framework</classname> auf und erweitert diese um ein "Projekt" zu
- managen. Generell ist ein "Projekt" ein geplantes Ereignis oder eine Initiative. In der
- Computerwelt sind Projekte generell Sammlungen von Ressourcen. Diese Ressourcen können
- Dateien, Verzeichnisse, Datenbanken, Schematas, Bilder, Stile und anderes sein.
- </para>
- </sect2>
- <sect2 id="zend.tool.extending.zend-tool-framework">
- <title>Erweiterungen von Zend_Tool_Framework</title>
- <sect3 id="zend.tool.extending.zend-tool-framework.architecture">
- <title>Überblick der Architektur</title>
- <para>
- <classname>Zend_Tool_Framework</classname> bietet das folgende:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>Gemeinsame Interfaces und Abstraktes</emphasis> welche es
- Entwicklern erlauben Funktionalitäten und Möglichkeiten zu erstellen welche
- durch Tooling Clients verwendbar sind.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Grundsätzliche Client Funktionalität</emphasis> und eine konkrete
- Konsolenimplementation welche externe Tools und Interfaces mit
- <classname>Zend_Tool_Framework</classname> verbindet. Der Konsolenclient
- kann in <acronym>CLI</acronym> Umgebungen verwendet werden, wie Unix Shells
- und der Windows Konsole.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>"Provider" und "Manifest" Interfaces</emphasis> welche vom
- Toolingsystem verwendet werden können. "Provider" repräsentieren den
- funktionalen Aspekt des Frameworks, und definieren die Aktionen welche
- Tooling Clients aufrufen können. "Manifests" agieren als Metadaten
- Registrierungen welche zusätzlichen Kontext für die verschiedenen
- definierten Provider bieten.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Ein introspektives Ladesystem</emphasis> welches die Umgebung auf
- Provider scannt und erkennt was benötigt wird um Sie auszuführen.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Ein Standardset von System Provider</emphasis> welche dem System
- erlauben zu melden was die kompletten Möglichkeiten des Systems sind, und
- ein nützliches Feedback bieten. Das beinhaltet auch ein ausführliches
- "Hilfe System".
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Definitionen welche man in diesem Handbuch in Bezug auf
- <classname>Zend_Tool_Framework</classname> beachten sollte sind:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <classname>Zend_Tool_Framework</classname> - Der Framework welche die
- Tooling Möglichkeiten bereitstellt.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Tooling Client</emphasis> - Ein Entwickler-Tool welches sich zum
- <classname>Zend_Tool_Framework</classname> verbindet und Ihn verwendet.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Client</emphasis> - Das Subsystem von
- <classname>Zend_Tool_Framework</classname> welches ein Interface
- bereitstellt so das sich Tooling-Clienten verbinden, und Kommandos abfragen
- und ausführen können.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Konsolen Client / Kommandozeilen Interface /
- <filename>zf.php</filename></emphasis> - Der Tooling Client für die
- Kommandozeile.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Provider</emphasis> - Ein Subsystem und eine Sammlung von
- eingebauten Funktionalitäten welche der Framework exportiert.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Manifest</emphasis> - Ein Subsystem für die Definition,
- Organisation, und Verbreitung von Daten welche Provider benötigen.
- </para>
- </listitem>
- <listitem>
- <para>
- <classname>Zend_Tool_Project</classname> Provider - Ein Set von Providern
- speziell für die Erstellung und die Wartung von Zend Framework basierenden
- Projekten.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.tool.extending.zend-tool-framework.cli-client">
- <title>Verstehen des CLI Clients</title>
- <para>
- Das <acronym>CLI</acronym>, oder Kommandozeilen-Tool (intern als das Konsolen-Tool
- bekannt) ist aktuell das primäre Interface für die Bearbeitung von
- <classname>Zend_Tool</classname> Anfragen. Mit dem <acronym>CLI</acronym> Tool
- können Entwickler Tooling-Anfragen im "Kommandozeilen-Fenster" behandeln,
- üblicherweise auch als "Terminal" Fenster bekannt. Diese Umgebung ist in einer *nix
- Umgebung vorherrschend, hat aber auch eine übliche Implementation in Windows mit
- <filename>cmd.exe</filename>, Console2 und mit dem Cygwin Projekt.
- </para>
- <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-general">
- <title>Das CLI Tool vorbereiten</title>
- <para>
- Um Tooling-Anfragen über den Kommandozeilen-Client auszuführen, muss man zuerst
- den Client vorbereiten so dass das System den "zf" Befehl ausführen kann. Der
- Kommandozeilen-Client ist, für alle Wünsche und Zwecke, die Datei
- <filename>.sh</filename> oder <filename>.bat</filename> welche mit der Zend
- Framework Distribution bereitgestellt wird. Im Trunk kann er hier gefunden
- werden: <ulink
- url="http://framework.zend.com/svn/framework/standard/trunk/bin/">http://framework.zend.com/svn/framework/standard/trunk/bin/</ulink>.
- </para>
- <para>
- Wie man sehen kann, gibt es 3 Dateien im <filename>/bin/</filename> Verzeichnis:
- <filename>zf.php</filename>, <filename>zf.sh</filename>, und
- <filename>zf.bat</filename>. <filename>zf.sh</filename> und
- <filename>zf.bat</filename> sind Betriebssystem-spezifische Client-Wrapper:
- <filename>zf.sh</filename> für die *nix Umgebung, und
- <filename>zf.bat</filename> für die Win32 Umgebung. Diese Client-Wrapper sind
- für das Finden der richtigen <filename>php.exe</filename>, das finden der
- <filename>zf.php</filename>, und die Übergabe an die Anfrage des Clients
- zuständig. Die <filename>zf.php</filename> ist verantwortlich für die
- Behandlung der Umgebung, die Erstellung des richtigen include_path, und der
- Übergabe von dem was auf der Kommandozeile angegeben wurde an die richtige
- Bibliothekskomponente für die Bearbeitung.
- </para>
- <para>
- Ultimativ, muss man zwei Dinge sicherstellen damit alles funktioniert,
- unabhängig vom Betriebssystem auf dem man arbeitet:
- </para>
- <orderedlist>
- <listitem>
- <para>
- <filename>zf.sh/zf.bat</filename> ist vom Systempfad aus erreichbar.
- Das ist die Fähigkeit <command>zf</command> von überall aus aufzurufen,
- unabhängig von aktuellen Arbeitsverzeichnisses.
- </para>
- </listitem>
- <listitem>
- <para>
- <filename>ZendFramework/library</filename> ist im
- <property>include_path</property>.
- </para>
- </listitem>
- </orderedlist>
- <note>
- <para>
- Zu beachten: Wärend das oben stehende sind die idealsten Notwendigkeiten
- sind, kann man einfach Zend Framework herunterladen und erwarten das es
- mit <filename>./path/to/zf.php</filename> und einem Kommando funktioniert.
- </para>
- </note>
- </sect4>
- <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-starnix">
- <title>Das CLI Tool auf Unix-artigen Systemen einrichten</title>
- <para>
- Das üblichste Setup in einer *nix Umgebung ist es, <filename>zf.sh</filename>
- und <filename>zf.sh</filename> in das selbe Verzeichnis wie die
- <acronym>PHP</acronym> Installation zu kopieren. Diese kann normalerweise in
- einem der folgenden Plätze gefunden werden:
- </para>
- <programlisting language="text"><![CDATA[
- /usr/bin
- /usr/local/bin
- /usr/local/ZendServer/bin/
- /Applications/ZendServer/bin/
- ]]></programlisting>
- <para>
- Um den Ort der eigenen <acronym>PHP</acronym> Installation zu finden kann man
- 'which php' auf der Kommandozeile ausführen. Das gibt den Ort der
- <acronym>PHP</acronym> Installation zurück welche verwendet wird um in dieser
- Umgebung <acronym>PHP</acronym> Skripte auszuführen.
- </para>
- <para>
- Der nächste Schritt ist es sicherzustellen das die Zend Framework Bibliothek
- korrekt im <acronym>PHP</acronym> <property>include_path</property> eingestellt
- wurde. Um herauszufinden wo der <property>include_path</property> ist, kann man
- <command>php -i</command> ausführen und nach der
- <property>include_path</property> Variable sehen, oder kompakter
- <command>php -i | grep include_path</command> ausführen. Sobald man
- herausgefunden hat wo der <property>include_path</property> ist (er ist
- normalerweise etwas wie <filename>/usr/lib/php</filename>,
- <filename>/usr/share/php</filename>, <filename>/usr/local/lib/php</filename>,
- oder so ähnlich), sollte man sicherstellen das der Inhalt des Verzeichnisses
- <filename>/library/</filename> in einem der in <property>include_path</property>
- spezifizierten Verzeichnisse ist.
- </para>
- <para>
- Sobald man diese zwei Dinge getan hat, sollte man in der Lage sein ein Kommando
- auszuführen und die richtige Antwort zurück zu erhalten, wie zum Beispiel:
- </para>
- <para>
- <inlinegraphic scale="100" align="center" valign="middle"
- fileref="figures/zend.tool.framework.cliversionunix.png" format="PNG" />
- </para>
- <para>
- Wenn man diese Art der Ausgabe nicht sieht, sollte man zurückgeben und die
- eigenen Einstellungen prüfen um sicherzustellen das man alle notwendigen Teile
- am richtigen Ort vorhanden sind.
- </para>
- <para>
- Es gibt eine Anzahl an alternativen Einstellungen die man erstellen kann,
- abhängig von der Konfiguration des Servers, dem Zugriffslevel, oder aus anderen
- Gründen.
- </para>
- <para>
- Das <emphasis>alternative Setup</emphasis> enthält das man den Download vom Zend
- Framework zusammenbehält wie er ist, und einen Link von einem
- <constant>PATH</constant> Ort zur <filename>zf.sh</filename> erstellt. Was dies
- bedeutet ist, dass man den Inhalt des Zend Framework Downloads in einem Ort wie
- <filename>/usr/local/share/ZendFramework</filename> platzieren kann, oder
- lokaler unter <filename>/home/username/lib/ZendFramework</filename> und einen
- symbolischen Link zu <filename>zf.sh</filename> erstellt.
- </para>
- <para>
- Angenommen man will den Link in <filename>/usr/local/bin</filename> platzieren
- (dies könnte zum Beispiel auch für die Platzierung des Links unter
- <filename>/home/username/bin/</filename> funktionieren), dan würde man ein
- Kommando wie das folgende platzieren:
- </para>
- <programlisting language="sh"><![CDATA[
- ln -s /usr/local/share/ZendFramework/bin/zf.sh /usr/local/bin/zf
- # ODER (zum Beispiel)
- ln -s /home/username/lib/ZendFramework/bin/zf.sh /home/username/bin/zf
- ]]></programlisting>
- <para>
- Das erstellt einen Link auf den man global von der Kommandozeile aus zugreifen
- kann.
- </para>
- </sect4>
- <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-windows">
- <title>Das CLI Tool unter Windows einrichten</title>
- <para>
- Das üblichste Setup in einer Windows Win32 Umgebung ist es
- <filename>zf.bat</filename> und <filename>zf.php</filename> in das selbe
- Verzeichnis wie die <acronym>PHP</acronym> Bibliothek zu kopieren. Diese kann
- generell an einem der folgenden Plätze gefunden werden:
- </para>
- <programlisting language="text"><![CDATA[
- C:\PHP
- C:\Program Files\ZendServer\bin\
- C:\WAMP\PHP\bin
- ]]></programlisting>
- <para>
- Man sollte in der Lage sein <filename>php.exe</filename> von der Kommandozeile
- aus auszuführen. Wenn man dazu nicht in der Lage ist, sollte man zuerst die
- Dokumentation prüfen welche mit der <acronym>PHP</acronym> Bibliothek
- mitgeliefert wird, um sicherzustellen dass der Pfad zu
- <filename>php.exe</filename> in der Windows Umgebungsvariable
- <constant>PATH</constant> zu finden ist.
- </para>
- <para>
- Der nächste Schritt besteht darin sicherzustellen das die Zend Framework
- Bibliothek richtig auf dem <acronym>PHP</acronym>
- <property>include_path</property> des Systems eingerichtet ist. Um
- herauszufinden wo der <property>include_path</property> ist, kann man
- <command>php -i</command> eingeben und nach der Variable
- <property>include_path</property> sehen, oder kompakter
- <command>php -i | grep include_path</command> ausführen wenn man ein Cygwin
- Setup mit vorhandenem grep hat. Sobald man herausgefunden hat wo der
- <property>include_path</property> liegt (das ist normalerweise etwas wie
- <filename>C:\PHP\pear</filename>, <filename>C:\PHP\share</filename>,
- <filename>C:\Program%20Files\ZendServer\share</filename>, oder ähnlich), sollte
- man sicherstellen das der Inhalt des Verzeichnisses library/ in einem vom
- <property>include_path</property> spezifizierten Verzeichnis ist.
- </para>
- <para>
- Sobald man diese zwei Dinge getan hat, sollte man in der Lage sein ein Kommando
- auszuführen und die richtige Antwort, so ähnlich wie die folgende, zu erhalten:
- </para>
- <para>
- <inlinegraphic scale="100" align="center" valign="middle"
- fileref="figures/zend.tool.framework.cliversionwin32.png" format="PNG" />
- </para>
- <para>
- Wenn man diese Art der Ausgabe nicht sieht, sollte man zurückgehen und die
- Einstellungen prüfen um sicherzustellen das man alle notwendigen Teile an den
- richtigen Orten hat.
- </para>
- <para>
- Es gibt eine Anzahl an alternativen Einstellungen die man erstellen kann,
- abhängig von der Konfiguration des Servers, dem Zugriffslevel, oder aus anderen
- Gründen.
- </para>
- <para>
- Das <emphasis>alternative Setup</emphasis> enthält das man den Download vom Zend
- Framework zusammenbehält wie er ist, und sowohl den System
- <constant>PATH</constant>, als auch die <filename>php.ini</filename> Datei
- verändert. In der Umgebung des Benutzers muss man
- <filename>C:\Path\To\ZendFramework\bin</filename> hinzufügen damit die Datei
- <filename>zf.bat</filename> ausführbar ist. Auch die Datei
- <filename>php.ini</filename> ist zu verändern um sicherzustellen das
- <filename>C:\Path\To\ZendFramework\library</filename> im
- <property>include_path</property> liegt.
- </para>
- </sect4>
- <sect4 id="zend.tool.extending.zend-tool-framework.cli-client.setup-othernotes">
- <title>Andere Einstellungs-Möglichkeiten</title>
- <para>
- Wenn man aus bestimmten Gründen die Zend Framework Bibliothek nicht im
- <property>include_path</property> haben will, gibt es andere Optionen. Es gibt
- zwei spezielle Umgebungsvariablen welche <filename>zf.php</filename> verwendet
- um den Ort der Zend Framework Installation zu erkennen.
- </para>
- <para>
- Die erste ist <constant>ZEND_TOOL_INCLUDE_PATH_PREPEND</constant>, welche den
- Wert der Umgebungsvariable dem <property>include_path</property> des Systems
- (<filename>php.ini</filename>) voranstellt bevor der Client geladen wird.
- </para>
- <para>
- Alternativ kann man <constant>ZEND_TOOL_INCLUDE_PATH</constant> verwenden um den
- <property>include_path</property> des System komplett zu
- <emphasis>ersetzen</emphasis> für jene bei denen es Sinn macht, speziell für das
- <command>zf</command> Kommandozeilen-Tool.
- </para>
- </sect4>
- </sect3>
- <sect3 id="zend.tool.extending.zend-tool-framework.providers-and-manifests">
- <title>Erstellen von Providern</title>
- <para>
- Generell, ist ein Provider für sich selbst gesehen, nichts weiter als eine Shell für
- einen Entwickler um einige Möglichkeiten zu bündeln welche er mit den Kommandozeilen
- (oder anderen) Clients ausführen will. Das ist eine Analogie für das was der
- "Controller" in der <acronym>MVC</acronym> Anwendung ist.
- </para>
- <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading">
- <title>Wie Zend_Tool eigene Provider findet</title>
- <para>
- Standardmäßig verwendet <classname>Zend_Tool</classname> den BasicLoader um alle
- Provider zu finden die es ausführen kann. Er durchsucht alle Verzeichnisse des
- Include Pfades rekursiv und öffnet alle Dateien welche mit "Manifest.php" oder
- "Provider.php" enden. Alle Klassen in diesen Dateien werden darauf durchsucht ob
- Sie entweder <classname>Zend_Tool_Framework_Provider_Interface</classname> oder
- <classname>Zend_Tool_Framework_Manifest_ProviderManifestable</classname>
- implementieren. Instanzen des Provider Interfaces sind für die echte
- Funktionalität zuständig und alle Ihre öffentlichen Methoden kann als Provider
- Aktionen zugegriffen werden. Das ProviderManifestable Interface benötigt
- trotzdem die Implementation einer <methodname>getProviders()</methodname>
- Methode welche ein Array an instanzierten Provider Interface Instanzen
- zurückgibt.
- </para>
- <para>
- Die folgenden Namensregeln sind darauf anzuwenden, wie man auf die Provider
- zugreifen kann welche vom IncludePathLoader gefunden werden:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- Der letzte Teil des eigenen Klassennamens welcher von einem Unterstrich
- getrennt ist, wird für den Providernamen verwendet, zum Beispiel führt
- "My_Provider_Hello" zum Provider auf welchen mit dem Namen "hello"
- zugegriffen werden kann.
- </para>
- </listitem>
- <listitem>
- <para>
- Wenn der Provider eine Methode <methodname>getName()</methodname> hat,
- dann wird diese verwendet statt der vorherigen Methode um den Namen zu
- erkennen.
- </para>
- </listitem>
- <listitem>
- <para>
- Wenn der Provider den Präfix "Provider" hat, zum Beispiel wenn er
- <classname>My_HelloProvider</classname> heißt, dann wird er vom Namen
- entfernt so dass der Provider "hello" heißt.
- </para>
- </listitem>
- </itemizedlist>
- <note>
- <para>
- Der IncludePathLoader folgt Symlinks nicht, was bedeutet das man Provider
- Funktionalitäten nicht in den Include Pfaden verlinken kann, sondern dass
- Sie physikalisch in den Include Pfaden vorhanden sein müssen.
- </para>
- </note>
- <example
- id="zend.tool.extending.zend-tool-framework.providers-and-manifests.loading.example">
- <title>Provider mit einem Manifest bekanntmachen</title>
- <para>
- Man kann eigene Provider bei <classname>Zend_Tool</classname> bekannt machen
- indem man ein Manifest anbietet, mit einer speziellen Endung des Dateinamens
- von "Manifest.php". Ein Provider-Manifest ist eine Implementation von
- <interface>Zend_Tool_Framework_Manifest_ProviderManifestable</interface> und
- benötigt die <methodname>getProviders()</methodname> Methode um ein Array
- von instanziierten Providern zurückzugeben. Anders als unser erster eigener
- Provider <classname>My_Component_HelloProvider</classname> erstellen wir das
- folgende Manifest:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_Manifest
- implements Zend_Tool_Framework_Manifest_ProviderManifestable
- {
- public function getProviders()
- {
- return array(
- new My_Component_HelloProvider()
- );
- }
- }
- ]]></programlisting>
- </example>
- </sect4>
- <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.basic">
- <title>Grundsätzliche Instruktionen für die Erstellung von Providern</title>
- <para>
- Wenn, als Beispiel, ein Entwickler die Fähigkeit, eine Version einer Datendatei
- anzuzeigen, hinzufügen will mit der seine 3rd Party Komponente arbeitet, gibt es
- nur eine Klasse welche der Entwickler implementieren muss. Angenommen die
- Komponente wird <classname>My_Component</classname> genannt, dann würde er eine
- Klasse erstellen welche <classname>My_Component_HelloProvider</classname> heißt
- in einer Datei wleche <filename>HelloProvider.php</filename> genannt ist und
- irgendwo in seinem <property>include_path</property> liegt. Diese Klasse würde
- <classname>Zend_Tool_Framework_Provider_Interface</classname> implementieren und
- diese Datei würde etwa wie folgt auszusehen haben:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- implements Zend_Tool_Framework_Provider_Interface
- {
- public function say()
- {
- echo 'Hallo von meinem Provider!';
- }
- }
- ]]></programlisting>
- <para>
- Bei dem obigen Code und der Annahme das der Entwickler Zugriff auf diese
- Funktionalität über den Konsolen-Client haben will, würde der Aufruf wie folgt
- aussehen:
- </para>
- <programlisting language="sh"><![CDATA[
- % zf say hello
- Hallo von meinem Provider!
- ]]></programlisting>
- </sect4>
- <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.response">
- <title>Das Antwort-Objekt</title>
- <para>
- Wie im Architektur-Abschnitt diskutiert erlaubt es
- <classname>Zend_Tool</classname> andere Clients für die Verwendung eigener
- <classname>Zend_Tool</classname> Provider zu verknüpfen. Um den
- unterschiedlichen Clients zu entsprechen sollte man das Antwort-Objekt verwenden
- um Rückgabe-Meldungen von Providern zurückzugeben anstatt
- <methodname>echo()</methodname> oder ähnliche Ausgabe-Mechanismen zu verwenden.
- Nach dem Umschreiben des Hello-Providers mit diesen Erkenntnissen sieht er wie
- folgt aus:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- extends Zend_Tool_Framework_Provider_Abstract
- {
- public function say()
- {
- $this->_registry->getResponse
- ->appendContent("Hallo von meinem Provider!");
- }
- }
- ]]></programlisting>
- <para>
- Wie man sieht muss <classname>Zend_Tool_Framework_Provider_Abstract</classname>
- erweitert werden um Zugriff auf die Registry zu erhalten welche die
- <classname>Zend_Tool_Framework_Client_Response</classname> Instanz enthält.
- </para>
- </sect4>
- <sect4 id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced">
- <title>Fortgeschrittene Informationen für die Entwicklung</title>
- <sect5
- id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.variables">
- <title>Variablen an einen Provider übergeben</title>
- <para>
- Das obige "Hello World" Beispiel ist großartig für einfache Befehle, aber
- was ist mit etwas komplizierterem? Wenn die eigenen Skripting- und
- Tooling-Bedürfnisse wachsen kann man die Notwendigkeit sehen dass man
- Variablen akzeptiert. So wie Funktions-Signaturen Parameter haben, so können
- eigene Tooling-Anfragen auch Parmeter akzeptieren.
- </para>
- <para>
- So wie jede Tooling-Anfrage isoliert von einer Methode in einer Klasse sein
- kann, können auch die Parameter einer Tooling-Anfrage in einem sehr
- bekanntem Platz isoliert sein. Parameter einer Aktions-Methode eines
- Providers können die selben Parameter enthalten welche der eigene Client
- verwenden soll wenn diese Provider und Aktions-Methode aufgerufen wird.
- Wenn man zum Beispiel einen Namen im oben stehenden Beispiel akzeptieren
- will, würde man möglicherweise folgendes in OO Code machen:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- implements Zend_Tool_Framework_Provider_Interface
- {
- public function say($name = 'Ralph')
- {
- echo 'Hallo' . $name . ', von meinem Provider!';
- }
- }
- ]]></programlisting>
- <para>
- Das obige Beispiel kann dann über die Kommandozeile
- <command>zf say hello Joe</command> aufgerufen werden. "Joe" wird dem
- Provider bereitgestellt so wie ein Parameter eines Methodenaufrufs. Es ist
- auch zu beachten das der Parameter optional ist, was bedeutet das er auch
- in der Kommandozeile optional ist, so dass
- <command>zf say hello</command> trotzdem noch funktioniert, und auf den
- Standardwert "Ralph" zeigt.
- </para>
- </sect5>
- <sect5
- id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.prompt">
- <title>Den Benutzer nach einer Eingabe fragen</title>
- <para>
- Es gibt Fälle in denen der Workflow des eigenen Providers es notwendig macht
- den Benutzer nach einer Eingabe zu fragen. Dies kann getan werden indem der
- Client nach einer zusätzlich benötigten Eingabe gefragt wird indem folgendes
- aufgerufen wird:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- extends Zend_Tool_Framework_Provider_Abstract
- {
- public function say($name = 'Ralph')
- {
- $nameResponse = $this->_registry
- ->getClient()
- ->promptInteractiveInput("Wie ist dein Name?");
- $name = $name->getContent();
- echo 'Hallo' . $name . ', von meinem Provider!';
- }
- }
- ]]></programlisting>
- <para>
- Dieses Kommando wirft eine Ausnahme wenn der aktuelle Client nicht in der
- Lage ist interaktive Anfragen zu behandeln. Im Falle des standardmäßigen
- Konsolen-Clients wird man aber danach gefragt den Namen einzugeben.
- </para>
- </sect5>
- <sect5
- id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.pretendable">
- <title>Die Ausführung einer Provider-Aktion vorbereiten</title>
- <para>
- Ein anderes interessantes Feature das man möglicherweise implementieren will
- ist die <emphasis>Vorbereitung</emphasis>. Vorbereitung ist die Fähigkeit
- des eigenen Providers sich "vorzubereiten", wie wenn er die angefragte
- Kombination von Aktion und Provider durchführt und dem Benutzer so viele
- Informationen wie möglich darüber zu geben was er tun
- <emphasis>würde</emphasis> ohne es wirklich zu tun. Das kann ein wichtiger
- Hinweis sein wenn große Änderungen in der Datenbank oder auf dem Dateisystem
- durchgeführt werden welche der Benutzer andernfalls nicht durchführen wollen
- würde.
- </para>
- <para>
- Voranstellbarkeit ist einfach zu implementieren. Es gibt zwei Teile zu
- diesem Feature: 1) Den Provider markieren, das er die Fähigkeit hat
- "vorzubereiten", und 2) die Anfrage prüfen und sicherstellen das die
- aktuelle Anfrage wirklich als "vorzubereiten" angefragt wurde. Dieses
- Feature wird im folgenden Code-Beispiel demonstriert.
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- extends Zend_Tool_Framework_Provider_Abstract
- implements Zend_Tool_Framework_Provider_Pretendable
- {
- public function say($name = 'Ralph')
- {
- if ($this->_registry->getRequest()->isPretend()) {
- echo 'Ich würde Hallo zu ' . $name . ' sagen.';
- } else {
- echo 'Hallo' . $name . ', von meinem Provider!';
- }
- }
- }
- ]]></programlisting>
- <para>
- Um den Provider im vorbereiteten Modus auszuführen muss nur folgendes
- aufgerufen werden:
- </para>
- <programlisting language="sh"><![CDATA[
- % zf --pretend say hello Ralph
- Ich würde Hallo zu Ralph sagen.
- ]]></programlisting>
- </sect5>
- <sect5
- id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.verbosedebug">
- <title>Verbose und Debug Modi</title>
- <para>
- Man kann Provider Aktionen auch in den Modi "verbose" oder "debug" laufen
- lassen. Die Semantik bezüglich dieser Aktionen muss man im Kontext des
- Providers implementieren. Man kann auf die Modi Debug oder Verbose wie
- folgt zugreifen:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- implements Zend_Tool_Framework_Provider_Interface
- {
- public function say($name = 'Ralph')
- {
- if($this->_registry->getRequest()->isVerbose()) {
- echo "Hello::say wurde aufgerufen\n";
- }
- if($this->_registry->getRequest()->isDebug()) {
- syslog(LOG_INFO, "Hello::say wurde aufgerufen\n");
- }
- }
- }
- ]]></programlisting>
- </sect5>
- <sect5
- id="zend.tool.extending.zend-tool-framework.providers-and-manifests.advanced.configstorage">
- <title>Auf die Benutzerkonfiguration und den Speicher zugreifen</title>
- <para>
- Bei Verwendung der Umgebungsvariable <property>ZF_CONFIG_FILE</property>
- oder von .zf.ini im Heimverzeichnis können Konfigurationsparameter in jeden
- <classname>Zend_Tool</classname> Provider eingefügt werden. Der Zugriff auf
- diese Konfiguration ist über die Registry möglich welche dem Provider
- übergeben wird wenn man
- <classname>Zend_Tool_Framework_Provider_Abstract</classname> erweitert.
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- extends Zend_Tool_Framework_Provider_Abstract
- {
- public function say()
- {
- $username = $this->_registry->getConfig()->username;
- if(!empty($username)) {
- echo "Hallo $username!";
- } else {
- echo "Hallo!";
- }
- }
- }
- ]]></programlisting>
- <para>
- Die zurückgegebene Konfiguration ist vom Typ
- <classname>Zend_Tool_Framework_Client_Config</classname> allerdings
- verweisen die magischen Methoden <methodname>__get()</methodname> und
- <methodname>__set()</methodname> intern auf eine
- <classname>Zend_Config</classname> oder den angegebenen Konfigurationstyp.
- </para>
- <para>
- Der Speicher erlaubt es notwendige Daten für eine spätere Referenz zu
- speichern. Das kann für Aufgaben bei der Ausführung von Batches nützlich
- sein oder für das wiederausführen von Aufgaben. Man kann auf den Speicher
- auf dem gleichen Weg zugreifen wie auf die Konfiguration:
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- extends Zend_Tool_Framework_Provider_Abstract
- {
- public function say()
- {
- $aValue = $this->_registry->getStorage()->get("myUsername");
- echo "Hallo $aValue!";
- }
- }
- ]]></programlisting>
- <para>
- Die <acronym>API</acronym> des Speichers ist sehr einfach:
- </para>
- <programlisting language="php"><![CDATA[
- class Zend_Tool_Framework_Client_Storage
- {
- public function setAdapter($adapter);
- public function isEnabled();
- public function put($name, $value);
- public function get($name, $defaultValue=null);
- public function has($name);
- public function remove($name);
- public function getStreamUri($name);
- }
- ]]></programlisting>
- <important>
- <para>
- Wenn man Provider erstellt welche Konfigurations-fähig oder
- Speicher-fähig sind muss man daran denken dass man prüfen muss ob die
- notwendigen Benutzerkonfigurations- oder Speicher-Schlüssel wirklich
- für diesen Benutzer existieren. Man wird keine fatalen Fehler erhalten
- wenn keiner von Ihnen angegeben wurde, da leere Schlüssel bei der
- Anfrage erstellt werden.
- </para>
- </important>
- </sect5>
- </sect4>
- </sect3>
- </sect2>
- <sect2 id="zend.tool.extending.zend-tool-project">
- <title>Zend_Tool_Project Erweiterungen</title>
- <para>
- <classname>Zend_Tool_Project</classname> bietet ein reiches Set an Funktionalitäten
- und Möglichkeiten welche die Aufgabe der Erstellung neuer Provider, speziell jener
- welche auf ein Projekt abzielen, einfacher und besser managebar.
- </para>
- <sect3 id="zend.tool.extending.zend-tool-project.architecture">
- <title>Architektur-Übersicht</title>
- <para>
- Das selbe Konzept gilt auch für Zend Framework Projekte. In Zend Framework Projekten
- hat man Controller, Aktionen, Views, Modelle, Datenbanken und so weiter. Im Sinn
- von <classname>Zend_Tool</classname> benötigen wir einen Weg um diese Arten von
- Ressourcen zu verfolgen -- deshalb <classname>Zend_Tool_Project</classname>.
- </para>
- <para>
- <classname>Zend_Tool_Project</classname> ist in der Lage Projektressourcen während
- der Entwicklung eines Projekts zu verfolgen. Wenn man, zum Beispiel, in einem
- Kommando einen Controller erstellt, und im nächsten Kommando eine Aktion in diesem
- Controller erstellen will, muss <classname>Zend_Tool_Project</classname> über die
- Controllerdatei bescheid <emphasis>wissen</emphasis> die man erstellt hat, damit
- man (in der nächsten Aktion) in der Lage ist diese Aktion daran anzuhängen. Das ist
- was das Projekt aktuell hält und <emphasis>zustandsbehaftet</emphasis>.
- </para>
- <para>
- Ein andere wichtiger Punkt den man über Projekte verstehen sollte ist, dass
- Ressourcen typischerweise in einer hierarchischen Art orgainisiert sind. Dies zu
- wissen bedeutet das <classname>Zend_Tool_Project</classname> in der Lage ist das
- aktuelle Projekt in eine interne Repräsentation zu serialisieren welche es erlaubt
- nicht nur jederzeit festzustellen <emphasis>welche</emphasis> Ressourcen Teil eines
- Projekts sind, sondern auch <emphasis>wo</emphasis> Sie in Relation zu anderen
- stehen.
- </para>
- </sect3>
- <sect3 id="zend.tool.extending.zend-tool-project.providers">
- <title>Provider erstellen</title>
- <para>
- Projektspezifische Provider werden auf dem selben Weg erstellt wie reine Framework
- Provider, mit einer Ausnahme: Projektprovider müssen
- <classname>Zend_Tool_Project_Provider_Abstract</classname> erweitern. Diese Klasse
- kommt mit einigen signifikanten Funktionalitäten welche Entwicklern helfen
- existierende Projekte zu laden, das Profilobjekt zu erhalten, und in der Lage zu
- sein das Profil zu suchen, und später dann alle Änderungen im aktuellen
- Projektprofil zu speichern.
- </para>
- <programlisting language="php"><![CDATA[
- class My_Component_HelloProvider
- extends Zend_Tool_Project_Provider_Abstract
- {
- public function say()
- {
- $profile = $this->_loadExistingProfile();
- /* ... Projektarbeiten hier durchführen */
- $this->_storeProfile();
- }
- }
- ]]></programlisting>
- </sect3>
- <!--
- <sect3 id="zend.tool.extending.zend-tool-project.resources-and-contexts">
- <title>Creating Resources & Contexts</title>
- </sect3>
- -->
- </sect2>
- </sect1>
|