<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: 22743 -->
<sect1 id="zend.validate.introduction">
    <title>Einführung</title>

    <para>
        Die Komponente <classname>Zend_Validate</classname> bietet ein Reihe von häufig benötigten
        Prüfungen. Sie bietet auch einen einfachen Verkettungsmechanismus für Prüfungen, mit welchem
        mehrfache Prüfungen in einer benutzerdefinierten Reihenfolge auf einen einzelnen Wert
        angewendet werden können.
    </para>

    <sect2 id="zend.validate.introduction.definition">
        <title>Was ist eine Prüfung?</title>

        <para>
            Eine Prüfung untersucht ihre Eingabe hinsichtlich einiger Anforderungen und produziert
            ein boolesches Ergebnis - wenn die Eingabe erfolgreich gegen die Anforderungen geprüft
            werden konnte. Wenn die Eingabe den Anforderungen nicht entspricht, kann die Prüfung
            zusätzliche Informationen darüber bieten, welche der Anforderungen die Eingabe nicht
            entspricht.
        </para>

        <para>
            Zum Beispiel könnte eine Webanwendung erfordern, dass ein Benutzername zwischen sechs
            und zwölf Zeichen lang sein soll und nur alphanumerische Zeichen enthalten soll. Eine
            Prüfung kann dafür verwendet werden um sicherzustellen, dass Benutzernamen diesen
            Anforderungen entsprechen. Wenn ein gewählter Benutzername einer oder beiden
            Anforderungen nicht entspricht, wäre es nützlich zu wissen, welche der Anforderungen der
            Benutzername nicht entsprochen hat.
        </para>
    </sect2>

    <sect2 id="zend.validate.introduction.using">
        <title>Standardnutzung von Prüfungen</title>

        <para>
            Prüfungen auf diesem Weg definiert zu haben, bietet die Grundlage für
            <classname>Zend_Validate_Interface</classname>, welche zwei Methoden definiert,
            <methodname>isValid()</methodname> und <methodname>getMessages()</methodname>. Die
            Methode <methodname>isValid()</methodname> führt eine Prüfung über die angegebenen Werte
            aus und gibt nur dann <constant>TRUE</constant> zurück, wenn der Wert gegenüber den
            Kriterien der Prüfung entsprochen hat.
        </para>

        <para>
            Wenn <methodname>isValid()</methodname> <constant>FALSE</constant> zurück gibt, bietet
            <methodname>getMessages()</methodname> ein Array von Nachrichten, welches die Gründe für
            die fehlgeschlagene Prüfung beschreiben. Die Arrayschlüssel sind kurze Strings, welche die
            Gründe für eine fehlgeschlagene Prüfung identifizieren und die Arraywerte sind die
            entsprechend menschenlesbaren String-Nachrichten. Die Schlüssel und Werte sind
            klassenabhängig; jede Prüfklasse definiert ihr eigenes Set von Nachrichten für
            fehlgeschlagene Prüfungen und die eindeutigen Schlüssel, welche diese identifizieren. Jede
            Klasse hat also eine const Definition die jedem Identifikator für eine
            fehlgeschlagene Prüfung entspricht.
        </para>

        <note>
            <para>
                Die Methode <methodname>getMessages()</methodname> gibt die Information für Prüfungsfehler
                nur für den zuletzt durchgeführten Aufruf von <methodname>isValid()</methodname>
                zurück. Jeder Aufruf von <methodname>isValid()</methodname> löscht jegliche
                Nachricht und Fehler, welche durch vorhergehende Aufrufe von
                <methodname>isValid()</methodname> vorhanden waren, weil normalerweise jeder Aufruf von
                <methodname>isValid()</methodname> für einen unterschiedlichen Eingabewert gemacht
                wird.
            </para>
        </note>

        <para>
            Das folgende Beispiel zeigt die Prüfung einer E-Mail Adresse:
        </para>

        <programlisting language="php"><![CDATA[
$validator = new Zend_Validate_EmailAddress();

if ($validator->isValid($email)) {
    //
    // E-Mail scheint gültig zu sein
    //
} else {
    //
    // E-Mail ist ungültig; drucke die Gründe
    //
    foreach ($validator->getMessages() as $messageId => $message) {
        echo "Validation failure '$messageId': $message\n";
    }
}
]]></programlisting>
    </sect2>

    <sect2 id="zend.validate.introduction.messages">
        <title>Nachrichten anpassen</title>

        <para>
            Prüfklassen bieten eine Methode <methodname>setMessage()</methodname>, mit der das
            Format der Nachricht definiert werden kann, die von
            <methodname>getMessages()</methodname> im Fall einer fehlerhaften Prüfung zurückgegeben
            wird. Das erste Argument dieser Methode ist ein String, der die Fehlernachricht enthält.
            Es können Kürzel in den String eingebaut werden, welche mit den für die Prüfung
            relevanten Daten aufgefüllt werden. Das Kürzel <emphasis>%value%</emphasis> wird von
            allen Prüfungen unterstützt; es ist verbunden mit dem Wert der an
            <methodname>isValid()</methodname> übergeben wird. Andere Kürzel können in jeder Prüfklasse
            von Fall zu Fall unterstützt werden. Zum Beispiel ist
            <emphasis>%max%</emphasis> das Kürzel, welches von
            <classname>Zend_Validate_LessThan</classname> unterstützt wird. Die
            <methodname>getMessageVariables()</methodname> Methode gibt ein Array von variablen
            Kürzeln zurück, welche vom Prüfer unterstützt werden.
        </para>

        <para>
            Das zweite optionale Argument ist ein String, der das Template der fehlerhaften
            Prüfnachricht identifiziert, die gesetzt werden soll. Das ist nützlich wenn eine
            Prüfklasse mehr als einen Grund für einen Fehlschlag definiert. Wenn das zweite Argument
            nicht angegeben wird, nimmt <methodname>setMessage()</methodname> an, dass die
            spezifizierte Nachricht für das erste Messagetemplate verwendet werden soll, das in der
            Prüfklasse definiert ist. Viele Prüfklassen haben nur ein Template für eine
            Fehlernachricht definiert, sodass es nicht notwendig ist anzugeben, welches Template für
            Fehlernachrichten geändert werden soll.
        </para>

        <programlisting language="php"><![CDATA[
$validator = new Zend_Validate_StringLength(8);

$validator->setMessage(
    'Der String \'%value%\' ist zu kurz; er muss mindestens %min% ' .
    'Zeichen sein',
    Zend_Validate_StringLength::TOO_SHORT);

if (!$validator->isValid('word')) {
    $messages = $validator->getMessages();
    echo $messages[0];

    // "Der String 'word' ist zu kurz; er muss mindestens 8 Zeichen sein"
}
]]></programlisting>

        <para>
            Es können mehrere Nachrichten durch Verwendung der Methode
            <methodname>setMessages()</methodname> gesetzt werden. Dessen Argument ist ein Array,
            welches Schlüssel/Nachrichten Paare enthält.
        </para>

        <programlisting language="php"><![CDATA[
$validator = new Zend_Validate_StringLength(array('min' => 8, 'max' => 12));

$validator->setMessages( array(
    Zend_Validate_StringLength::TOO_SHORT =>
        'Der String \'%value%\' ist zu kurz',
    Zend_Validate_StringLength::TOO_LONG  =>
        'Der String \'%value%\' ist zu lang'
));
]]></programlisting>

        <para>
            Wenn die Anwendung mehr Flexibilität benötigt in der Art und Weise wie Prüffehler
            gemeldet werden, kann auf die Eigenschaften durch denselben Namen zugegriffen
            werden, wie mit dem Nachrichtenkürzel, das von einer Prüfklasse unterstützt wird.
            Die Eigenschaft <property>value</property> ist immer in einem Prüfer vorhanden; Das ist
            der Wert, der als Argument von <methodname>isValid()</methodname> definiert wurde. Andere
            Eigenschaften können von Fall zu Fall in jeder Prüfklasse unterstützt werden.
        </para>

        <programlisting language="php"><![CDATA[
$validator = new Zend_Validate_StringLength(array('min' => 8, 'max' => 12));

if (!validator->isValid('word')) {
    echo 'Wort fehlgeschlaten: '
        . $validator->value
        . '; die Länge ist nicht zwischen '
        . $validator->min
        . ' und '
        . $validator->max
        . "\n";
}
]]></programlisting>
    </sect2>

    <sect2 id="zend.validate.introduction.static">
        <title>Verwenden der statischen is() Methode</title>

        <para>
            Wenn es unpassend ist, eine gegebenen Prüfklasse zu laden und eine Instanz
            des Prüfers zu erstellen, kann die statische Methode
            <methodname>Zend_Validate::is()</methodname> als alternativer Stil des Aufrufs
            verwendet werden. Das erste Argument dieser Methode ist ein Datenwert, der an die
            Methode <methodname>isValid()</methodname> übergeben werden würde. Das zweite Argument
            ist ein String, welcher mit dem Basisnamen der Prüfklasse übereinstimmt, relativ zum
            Namensraum von <classname>Zend_Validate</classname>. Die Methode
            <methodname>is()</methodname> lädt die Klasse automatisch, erstellt eine Instanz und
            wendet die Methode <methodname>isValid()</methodname> auf die Eingabedaten an.
        </para>

        <programlisting language="php"><![CDATA[
if (Zend_Validate::is($email, 'EmailAddress')) {
    // Ja, die Email Adresse scheint gültig zu sein
}
]]></programlisting>


        <para>
            Es kann auch ein Array von Konstruktor-Argumenten übergeben werden, wenn diese für die
            Prüfung benötigt werden.
        </para>

        <programlisting language="php"><![CDATA[
if (Zend_Validate::is($value, 'Between', array('min' => 1, 'max' => 12))) {
    // Ja, $value ist zwischen 1 und 12
}
]]></programlisting>

        <para>
            Die Methode <methodname>is()</methodname> gibt einen booleschen Wert zurück, denselben
            wie die Methode <methodname>isValid()</methodname>. Wird die statische
            Methode <methodname>is()</methodname> verwendet, sind Nachrichten für Prüffehler nicht
            vorhanden.
        </para>

        <para>
            Die statische Verwendung kann für das ad hoc Verwenden eines Prüfers bequem sein,
            aber wenn ein Prüfer für mehrere Eingaben verwendet werden soll, ist es effizienter
            die nicht statische Verwendung zu benutzen, indem eine Instanz des Prüfobjekts
            erstellt wird und dessen Methode <methodname>isValid()</methodname> aufgerufen wird.
        </para>

        <para>
            Die Klasse <classname>Zend_Filter_Input</classname> erlaubt es, auch mehrfache Filter und
            Prüfklassen zu instanzieren und bei Bedarf aufzurufen, um Sets von Eingabedaten zu
            bearbeiten. Siehe <link linkend="zend.filter.input">Zend_Filter_Input</link>.
        </para>

        <sect3 id="zend.validate.introduction.static.namespaces">
            <title>Namespaces</title>

            <para>
                Wenn man mit selbst definierten Prüfungen arbeitet, dann kann man an
                <methodname>Zend_Validate::is()</methodname> einen vierten Parameter übergeben
                welcher der Namespace ist, an dem die eigene Prüfung gefunden werden kann.
            </para>

            <programlisting language="php"><![CDATA[
if (Zend_Validate::is($value, 'MyValidator', array('min' => 1, 'max' => 12),
                      array('FirstNamespace', 'SecondNamespace')) {
    // Ja, $value ist in Ordnung
}
]]></programlisting>

            <para>
                <classname>Zend_Validate</classname> erlaubt es auch, standardmäßige Namespaces zu
                setzen. Das bedeutet, dass man sie einmal in der Bootstrap setzt und sie nicht mehr
                bei jedem Aufruf von <methodname>Zend_Validate::is()</methodname> angeben muss. Der
                folgende Codeschnipsel ist identisch mit dem vorherigen.
            </para>

            <programlisting language="php"><![CDATA[
Zend_Validate::setDefaultNamespaces(array('FirstNamespace', 'SecondNamespace'));
if (Zend_Validate::is($value, 'MyValidator', array('min' => 1, 'max' => 12)) {
    // Yes, $value is ok
}

if (Zend_Validate::is($value,
                      'OtherValidator',
                      array('min' => 1, 'max' => 12)) {
    // Yes, $value is ok
}
]]></programlisting>

            <para>
                Der Bequemlichkeit halber gibt es die folgenden Methoden, welche die Behandlung von
                Namespaces erlauben:
            </para>

            <itemizedlist>
                <listitem>
                    <para>
                        <emphasis><methodname>Zend_Validate::getDefaultNamespaces()</methodname></emphasis>:
                        Gibt alle standardmäßigen Namespaces als Array zurück.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <emphasis><methodname>Zend_Validate::setDefaultNamespaces()</methodname></emphasis>:
                        Setzt neue standardmäßige Namespaces und überschreibt alle vorher
                        gesetzten. Es wird entweder ein String für einen einzelnen Namespace
                        akzeptiert oder ein Array für mehrere Namespaces.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <emphasis><methodname>Zend_Validate::addDefaultNamespaces()</methodname></emphasis>:
                        Fügt zusätzliche Namespaces zu den bereits gesetzten hinzu. Es wird
                        entweder ein String für einen einzelnen Namespace akzeptiert oder ein
                        Array für mehrere Namespaces.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <emphasis><methodname>Zend_Validate::hasDefaultNamespaces()</methodname></emphasis>:
                        Gibt <constant>TRUE</constant> zurück, wenn ein oder mehrere standardmäßige
                        Namespaces gesetzt sind und <constant>FALSE</constant>, wenn keine
                        standardmäßigen Namespaces gesetzt sind.
                    </para>
                </listitem>
            </itemizedlist>
        </sect3>
    </sect2>

    <sect2 id="zend.validate.introduction.translation">
        <title>Meldungen übersetzen</title>

        <para>
            Prüfungsklassen bieten eine Methode <methodname>setTranslator()</methodname>, mit der man
            eine Instanz von <classname>Zend_Translate</classname> definieren kann, die Nachrichten
            im Falle eines Prüfungsfehlers übersetzt. Die <methodname>getTranslator()</methodname>
            Methode gibt die gesetzte Übersetzungsinstanz zurück.
        </para>

        <programlisting language="php"><![CDATA[
$validator = new Zend_Validate_StringLength(array('min' => 8, 'max' => 12));
$translate = new Zend_Translate(
    array(
        'adapter' => 'array',
        'content' => array(
            Zend_Validate_StringLength::TOO_SHORT => 'Übersetzt \'%value%\''
        ),
        'locale'  => 'en'
    )
);

$validator->setTranslator($translate);
]]></programlisting>

        <para>
            Mit der statischen Methode <methodname>setDefaultTranslator()</methodname> kann eine
            Instanz von <classname>Zend_Translate</classname> gesetzt werden und mit
            <methodname>getDefaultTranslator()</methodname> empfangen. Das verhindert, dass man den
            Übersetzer manuell für alle Prüfungsklassen setzen muss und vereinfacht den Code.
        </para>

        <programlisting language="php"><![CDATA[
$translate = new Zend_Translate(
    array(
        'adapter' => 'array',
        'content' => array(
            Zend_Validate_StringLength::TOO_SHORT => 'Übersetzt \'%value%\''
        ),
        'locale'  => 'en'
    )
);
Zend_Validate::setDefaultTranslator($translate);
]]></programlisting>

        <note>
            <para>
                Wenn man ein anwendungsweites Gebietsschema in der Registry gesetzt hat, wird
                dieses Gebietsschema als standardmäßiger Übersetzer verwendet.
            </para>
        </note>

        <para>
            Manchmal ist es notwendig, den Übersetzer in einer Prüfklasse auszuschalten. Um das zu
            tun, kann die Methode <methodname>setDisableTranslator()</methodname> verwendet werden,
            welche einen booleschen Wert akzeptiert und
            <methodname>translatorIsDisabled()</methodname>, um den gesetzten Wert zu erhalten.
        </para>

        <programlisting language="php"><![CDATA[
$validator = new Zend_Validate_StringLength(array('min' => 8, 'max' => 12));
if (!$validator->isTranslatorDisabled()) {
    $validator->setDisableTranslator();
}
]]></programlisting>

        <para>
            Es ist auch möglich einen Übersetzer zu verwenden, statt eigene Meldungen mit
            <methodname>setMessage()</methodname> zu setzen. Aber wenn man das tut, sollte man im
            Kopf behalten, dass der Übersetzer auch mit den Meldungen arbeitet, die man selbst gesetzt
            hat.
        </para>
    </sect2>
</sect1>
