<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="learning.plugins.usage">
    <title>Verwenden von Plugins</title>

    <para>
        Komponenten die Plugins verwenden, verwenden typischerweise
        <classname>Zend_Loader_PluginLoader</classname> um Ihre Arbeit zu tun. Diese Klasse
        registriert Plugins indem ein oder mehrere "Präfix Pfade" spezifiziert werden. Diese
        Komponente ruft anschließend die <methodname>load()</methodname> Methode des PluginLoader's
        auf, und übergibt Ihm den Kurznamen des Plugins. Der PluginLoader wird anschließend jeden
        Präfix Pfad abfragen um zu sehen ob eine Klasse passt die dem Kurznamen entspricht.
        Präfix Pfade werden also LIFO Reihenfolge (Last In, First Out) durchsucht, deshalb werden
        jene Präfix Pfade abgeglichen die zuletzt registriert wurden -- was es erlaubt existierende
        Plugins zu überladen.
    </para>

    <para>
        Einige Beispiele werden das alles etwas aufklären.
    </para>

    <example id="learning.plugins.usage.basic">
        <title>Grundsätzliches Plugin Beispiel: Hinzufügen eines einzelnen Präfix Pfades</title>

        <para>
            In diesem Beispiel nehmen wir an das einige Prüfungen geschrieben und im Verzeichnis
            <filename>foo/plugins/validators/</filename> wurden, und das alle Klassen den
            Klassenpräfix "Foo_Validate_" teilen; diese zwei Teile von Information formen unseren
            "Präfix Pfad". Weiters nehmen wir an das wir zwei Prüfungen haben, einen der "Even"
            genannt wird (und sicherstellt das eine Zahl die geprüft wird gerade ist), und eine
            andere die "Dozens" genannt wird (und sicherstellt das eine Zahl ein Vielfaches von 12
            ist). Die drei könnten wie folgt anschauen:
        </para>

        <programlisting language="text"><![CDATA[
foo/
|-- plugins/
|   |-- validators/
|   |   |-- Even.php
|   |   |-- Dozens.php
]]></programlisting>

        <para>
            Jetzt informieren wir eine <classname>Zend_Form_Element</classname> Instanz über diesen
            Präfix Pfad. <classname>Zend_Form_Element</classname>'s
            <methodname>addPrefixPath()</methodname> Methode erwartet ein drittes Argument welches
            den Typ des Plugins zeigt für den der Pfad registriert wird; in diesem Fall ist es ein
            "validate" Plugin.
        </para>

        <programlisting language="php"><![CDATA[
$element->addPrefixPath('Foo_Validate', 'foo/plugins/validators/', 'validate');
]]></programlisting>

        <para>
            Jetzt können wir dem Element einfach den kurzen Namen der Prüfung angeben die wir
            verwenden wollen. Im folgenden Beispiel verwenden wir einen Mix aus Standardprüfungen
            ("NotEmpty", "Int") und eigenen Prüfungen ("Even", "Dozens").
        </para>

        <programlisting language="php"><![CDATA[
$element->addValidator('NotEmpty')
        ->addValidator('Int')
        ->addValidator('Even')
        ->addValidator('Dozens');
]]></programlisting>

        <para>
            Wenn das Element geprüft werden soll, ruft es die Plugin Klasse vom PluginLoader ab.
            Die ersten zwei Prüfungen werden zu <classname>Zend_Validate_NotEmpty</classname> und
            <classname>Zend_Validate_Int</classname> aufgelöst; die nächsten zwei werden zu
            <classname>Foo_Validate_Even</classname> und <classname>Foo_Validate_Dozens</classname>
            aufgelöst.
        </para>
    </example>

    <note>
        <title>Was passiert wenn ein Plugin nicht gefunden wird?</title>

        <para>
            Was passiert wenn ein Plugin angefragt wird, aber der PluginLoader nicht in der Lage ist
            eine zu Ihm passende Klasse zu finden? Im obigen Beispiel, zum Beispiel, wenn wir das
            Plugin "Bar" mit dem Element registrieren, was würde dann passieren?
        </para>

        <para>
            Der Plugin Loader durchsucht jeden Präfix Pfad, prüft ob eine Datei gefunden wird die
            in diesem Pfad auf den Plugin Namen passt. Wenn die Datei nicht gefunden wird, geht er
            auf den nächsten Präfix Pfad weiter.
        </para>

        <para>
            Sobald der Stack von Präfix Pfaden erschöpft ist, und keine passende Datei gefunden
            wurde, wirft es eine <exceptionname>Zend_Loader_PluginLoader_Exception</exceptionname>.
        </para>
    </note>

    <example id="learning.plugins.usage.override">
        <title>Fortgeschrittene Plugin Verwendung: Überladen existierender Plugins</title>

        <para>
            Eine Stärke des PluginLoaders ist dessen Verwendung eines LIFO Stacks welche es erlaubt
            existierende Plugins zu überladen indem eine eigene Version lokal mit einem anderen
            Präfix Pfad erstellt wird, und der Präfix Pfad später im Stack registriert wird.
        </para>

        <para>
            Nehmen wir zum Beispiel <classname>Zend_View_Helper_FormButton</classname> an (View
            Helfer sind eine Form von Plugins). Dieser View Helfer akzeptiert drei Argumente, ein
            Elementname (der auch als DOM Identifikator des Elements verwendet wird), einen Wert
            (der als Button Label verwendet wird), und ein optionales Array an Attributen. Der
            Helfer erzeugt dann das <acronym>HTML</acronym> Markup für ein Formular Eingabeelement.
        </para>

        <para>
            Sagen wir, dass der Helfer stattdessen ein echtes <acronym>HTML</acronym>
            <constant>button</constant> Element erzeugen soll; dass wir nicht wollen das der Helfer
            einen DOM Identifikator erzeugt, sondern statt dessen den Wert für einen CSS Klassen
            Selektor; und das wir kein Interesse an der behandling eigener Attribute haben. Man
            könnte dies auf verschiedenen wegen erreichen. In beiden Fällen erstellen wir eine
            eigene View Helfer Klasse die das Verhalten implementiert welches wir wollen; der
            Unterschied liegt darin wie wir Sie benennen und aufrufen wollen.
        </para>

        <para>
            Unser erstes Beispiel wird der Name des Elements mit einem eindeutigen Namen sein:
            <classname>Foo_View_Helper_CssButton</classname> welcher den Plugin Namen "CssButton"
            impliziert. Wärend das ein recht brauchbarer Ansatz ist, wirft es einige Probleme auf:
            Wenn man bereits einen Button View Helfer im eigenen Code verwendet, muss man jetzt
            einges umarbeiten; alternativ, wenn ein anderer Entwickler damit beginnt Code für diese
            Anwendung zu schreiben, mus er unbeabsichtlicher Weise den Button View Helfer verwenden
            statt den neuen View Helfer.
        </para>

        <para>
            Deshalb ist es better den Plugin Namen "Button" zu verwenden was uns den Klassennamen
            <classname>Foo_View_Helper_Button</classname> gibt. Wir registrieren den Präfix Pfad in
            der View:
        </para>

        <programlisting language="php"><![CDATA[
// Zend_View::addHelperPath() verwendet den PluginLoader; Trotzdem invertiert
// er die Argumente, da er den Standardwert "Zend_View_Helper" für den Plugin
// Präfix anbietet.
//
// Anbei nehmen wir an das die eigene Klasse im Verzeichnis
// 'foo/view/helpers/' ist.
$view->addHelperPath('foo/view/helpers', 'Foo_View_Helper');
]]></programlisting>

        <para>
            Sobald das getan wurde, wird überall wo wir den "Button" Helfer verwenden auf die
            eigene <classname>Foo_View_Helper_Button</classname> Klasse verwiesen!
        </para>
    </example>
</sect1>
