| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 22756 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.mail.read">
- <title>Lesen von Mail Nachrichten</title>
- <para>
- <classname>Zend_Mail</classname> kann Mail Nachrichten von verschiedenen lokalen oder
- entfernen Mailspeichern lesen. Alle von diesen haben die selbe Basis <acronym>API</acronym>
- für das Zählen und Holen von Nachrichten und einige von Ihnen implementieren zusätzliche
- Interfaces für nicht so übliche Features. Für eine Übersicht der Features der
- implementierten Speicher kann in die folgende Tabelle gesehen werden.
- </para>
- <table id="zend.mail.read.table-1">
- <title>Übersicht der Lesefeatures für Mails</title>
- <tgroup cols="5">
- <thead>
- <row>
- <entry>Feature</entry>
- <entry>Mbox</entry>
- <entry>Maildir</entry>
- <entry>Pop3</entry>
- <entry><constant>IMAP</constant></entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>Speichertyp</entry>
- <entry>lokal</entry>
- <entry>lokal</entry>
- <entry>entfernt</entry>
- <entry>entfernt</entry>
- </row>
- <row>
- <entry>Nachrichten holen</entry>
- <entry>Yes</entry>
- <entry>Yes</entry>
- <entry>Yes</entry>
- <entry>Yes</entry>
- </row>
- <row>
- <entry><acronym>MIME</acronym>-Part holen</entry>
- <entry>emulated</entry>
- <entry>emulated</entry>
- <entry>emulated</entry>
- <entry>emulated</entry>
- </row>
- <row>
- <entry>Ordner</entry>
- <entry>Yes </entry>
- <entry>Yes</entry>
- <entry>No</entry>
- <entry>Yes</entry>
- </row>
- <row>
- <entry>Erstellen von Nachrichten/Ordnern</entry>
- <entry>No</entry>
- <entry>todo</entry>
- <entry>No</entry>
- <entry>todo</entry>
- </row>
- <row>
- <entry>Merker</entry>
- <entry>No</entry>
- <entry>Yes</entry>
- <entry>No</entry>
- <entry>Yes</entry>
- </row>
- <row>
- <entry>Quote</entry>
- <entry>No</entry>
- <entry>Yes</entry>
- <entry>No</entry>
- <entry>No</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <sect2 id="zend.mail.read-example">
- <title>Einfaches Beispiel für POP3</title>
- <programlisting language="php"><![CDATA[
- $mail = new Zend_Mail_Storage_Pop3(array('host' => 'localhost',
- 'user' => 'test',
- 'password' => 'test'));
- echo $mail->countMessages() . " Nachrichten gefunden\n";
- foreach ($mail as $message) {
- echo "Mail von '{$message->from}': {$message->subject}\n";
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.mail.read-open-local">
- <title>Öffnen eines lokalen Speichers</title>
- <para>
- Mbox und Maildir sind zwei unterstützte Formate für lokale Mailspeicher, beide in Ihrem
- einfachsten Format.
- </para>
- <para>
- Wenn von einer Mbox Datei gelesen werden soll muß nur der Dateiname an den Konstruktor
- von <classname>Zend_Mail_Storage_Mbox</classname> übergeben werden:
- </para>
- <programlisting language="php"><![CDATA[
- $mail = new Zend_Mail_Storage_Mbox(array('filename' =>
- '/home/test/mail/inbox'));
- ]]></programlisting>
- <para>Maildir ist sehr einfach benötigt aber einen Verzeichnisnamen:</para>
- <programlisting language="php"><![CDATA[
- $mail = new Zend_Mail_Storage_Maildir(array('dirname' =>
- '/home/test/mail/'));
- ]]></programlisting>
- <para>
- Beide Konstruktoren werfen eine <classname>Zend_Mail_Exception</classname> Ausnahme
- wenn der Speicher nicht gelesen werden kann.
- </para>
- </sect2>
- <sect2 id="zend.mail.read-open-remote">
- <title>Öffnen eines entfernten Speichers</title>
- <para>
- Für entfernte Speicher werden die zwei populärsten Protokolle unterstützt: Pop3 und
- Imap. Beide benötigen mindestens einen Host und einen Benutzer für das Verbinden und das
- Login. Das Standardpasswort ist ein leerer String, der Standardport wie im
- <acronym>RFC</acronym> Protokoll definiert.
- </para>
- <programlisting language="php"><![CDATA[
- // Verbinden mit Pop3
- $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com',
- 'user' => 'test',
- 'password' => 'test'));
- // Verbinden mit Imap
- $mail = new Zend_Mail_Storage_Imap(array('host' => 'example.com',
- 'user' => 'test',
- 'password' => 'test'));
- // Beispiel für einen nicht Standardport
- $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com',
- 'port' => 1120
- 'user' => 'test',
- 'password' => 'test'));
- ]]></programlisting>
- <para>
- Für beide Speicher werden <acronym>SSL</acronym> und TLS unterstützt. Wenn
- <acronym>SSL</acronym> verwendet wird, wird der Standardport laut <acronym>RFC</acronym>
- geändert.
- </para>
- <programlisting language="php"><![CDATA[
- // Beispiel für Zend_Mail_Storage_Pop3
- // funktioniert auch für Zend_Mail_Storage_Imap
- // SSL mit einem unterschiedlichen Port verwenden
- // (Standard ist 995 für Pop3 und 993 für Imap)
- $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com',
- 'user' => 'test',
- 'password' => 'test',
- 'ssl' => 'SSL'));
- // Verwenden von TLS
- $mail = new Zend_Mail_Storage_Pop3(array('host' => 'example.com',
- 'user' => 'test',
- 'password' => 'test',
- 'ssl' => 'TLS'));
- ]]></programlisting>
- <para>
- Beide Konstruktoren können eine <classname>Zend_Mail_Exception</classname> oder
- <classname>Zend_Mail_Protocol_Exception</classname> werfen (erweitert
- <classname>Zend_Mail_Exception</classname>), abhängig vom Typ des Fehlers.
- </para>
- </sect2>
- <sect2 id="zend.mail.read-fetching">
- <title>Nachrichten holen und einfache Methoden</title>
- <para>
- Wenn der Speicher einmal geöffnet wurde können Nachrichten geholt werden. Man benötigt
- die Nachrichtennummer, welche ein Zähler ist der mit 1 für die erste Nachricht beginnt.
- Um die Nachrichten zu holen muß die Methode <methodname>getMessage()</methodname>
- verwendet werden:
- </para>
- <programlisting language="php"><![CDATA[
- $message = $mail->getMessage($messageNum);
- ]]></programlisting>
- <para>
- Zugriff über Arrays ist auch möglich, unterstützt aber nicht jeden zusätzlichen
- Parameter der zu <methodname>getMessage()</methodname> hinzugefügt werden könnte:
- </para>
- <programlisting language="php"><![CDATA[
- $message = $mail[$messageNum];
- ]]></programlisting>
- <para>
- Um über alle Nachrichten zu iterieren wurde das Iterator Interface implementiert:
- </para>
- <programlisting language="php"><![CDATA[
- foreach ($mail as $messageNum => $message) {
- // mach was ...
- }
- ]]></programlisting>
- <para>
- Um die Nachrichten im Speicher zu zählen kann entweder die Methode
- <methodname>countMessages()</methodname> oder der Zugriff auf Arrays verwendet werden:
- </para>
- <programlisting language="php"><![CDATA[
- // Methode
- $maxMessage = $mail->countMessages();
- // Array Zugriff
- $maxMessage = count($mail);
- ]]></programlisting>
- <para>
- Um eine Mail zu entfernen kann die Methode <methodname>removeMessage()</methodname>
- oder auch der Array Zugriff verwendet werden:
- </para>
- <programlisting language="php"><![CDATA[
- // Methode
- $mail->removeMessage($messageNum);
- // Array Zugriff
- unset($mail[$messageNum]);
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.mail.read-message">
- <title>Arbeiten mit Nachrichten</title>
- <para>
- Nachdem die Nachrichten mit <methodname>getMessage()</methodname> geholt wurden, wird
- man die Kopfzeilen, den Inhalt oder einzelne Teile einer Mehrteiligen Nachricht holen
- wollen. Auf alle Kopfzeilen kann über die Eigenschaften oder die Methode
- <methodname>getHeader()</methodname>, wenn man mehr Kontrolle oder ungewöhnliche
- Kopfzeilen hat, zugegriffen werden. Die Kopfzeilen sind intern kleingeschrieben,
- weswegen die Groß- und Kleinschreibung der Kopfzeilen in der Mail Nachricht egal ist.
- Kopfzeilen mit einem Bindestrich können auch in camel-case Schreibweise geschrieben
- werden. Wenn für beide Schreibweisen kein Header gefunden wird, wird eine Ausnahme
- geworfen. Um das zu verhindern kann die <methodname>headerExists()</methodname> Methode
- verwendet werden um die Existenz einer Kopfzeile zu prüfen.
- </para>
- <programlisting language="php"><![CDATA[
- // Nachrichten Objekt holen
- $message = $mail->getMessage(1);
- // Betreff der Nachricht holen
- echo $message->subject . "\n";
- // Inhalts-Typ der Kopfzeile holen
- $type = $message->contentType;
- // Prüfen ob CC gesetzt ist:
- if( isset($message->cc) ) { // oder $message->headerExists('cc');
- $cc = $message->cc;
- }
- ]]></programlisting>
- <para>
- Wenn mehrere Kopfzeilen mit dem selben Namen vorhanden sind z.B. die empfangenen
- Kopfzeilen kann es gewünscht sein diese als Array statt als String zu haben, was mit der
- <methodname>getHeader()</methodname> Methode möglich ist.
- </para>
- <programlisting language="php"><![CDATA[
- // Kopfzeilen als Eigenschaft holen - das Ergebnis ist immer ein String,
- // mit Zeilenumbruch zwischen den einzelnen Vorkommen in der Nachricht
- $received = $message->received;
- // Das gleiche über die getHeader() Methode
- $received = $message->getHeader('received', 'string');
- // Besser ein Array mit einem einzelnen Eintrag für jedes Vorkommen
- $received = $message->getHeader('received', 'array');
- foreach ($received as $line) {
- // irgendwas tun
- }
- // Wenn kein Format definiert wurde wird die interne Repräsentation
- // ausgegeben (String für einzelne Kopfzeilen, Array für mehrfache)
- $received = $message->getHeader('received');
- if (is_string($received)) {
- // Nur eine empfangene Kopfzeile in der Nachricht gefunden
- }
- ]]></programlisting>
- <para>
- Die Methode <methodname>getHeaders()</methodname> gibt alle Kopfzeilen als Array mit den
- kleingeschriebenen Namen als Schlüssel und den Wert als Array für mehrere Kopfzeilen
- oder als String für einzelne Kopfzeilen.
- </para>
- <programlisting language="php"><![CDATA[
- // Alle Kopfzeilen wegschmeißen
- foreach ($message->getHeaders() as $name => $value) {
- if (is_string($value)) {
- echo "$name: $value\n";
- continue;
- }
- foreach ($value as $entry) {
- echo "$name: $entry\n";
- }
- }
- ]]></programlisting>
- <para>
- Wenn keine Nachricht aus mehreren Teilen vorlieg kann der Inhalt sehr einfach über
- <methodname>getContent()</methodname> geholt werden. Anders als die Kopfzeilen wird der
- Inhalt nur geholt wenn dies benötigt wird (wie spätes-holen).
- </para>
- <programlisting language="php"><![CDATA[
- // Inhalt der Nachricht für HTML ausgeben
- echo '<pre>';
- echo $message->getContent();
- echo '</pre>';
- ]]></programlisting>
- <para>
- Die Prüfung auf mehrteilige Nachrichten wird in der Methode
- <methodname>isMultipart()</methodname> gemacht. Wenn eine mehrteilige Nachricht vorliegt
- kann eine Instanz von <classname>Zend_Mail_Part</classname> mit der Methode
- <methodname>getPart()</methodname> geholt werden. <classname>Zend_Mail_Part</classname>
- ist die Basisklasse von <classname>Zend_Mail_Message</classname>, sie hat also die
- gleichen Methoden: <methodname>getHeader()</methodname>,
- <methodname>getHeaders()</methodname>, <methodname>getContent()</methodname>,
- <methodname>getPart()</methodname>, <methodname>isMultipart()</methodname> und die
- Eigenschaften der Kopfzeilen.
- </para>
- <programlisting language="php"><![CDATA[
- // Hole den ersten nicht geteilten Teil
- $part = $message;
- while ($part->isMultipart()) {
- $part = $message->getPart(1);
- }
- echo 'Der Typ des Teils ist ' . strtok($part->contentType, ';') . "\n";
- echo "Inhalt:\n";
- echo $part->getContent();
- ]]></programlisting>
- <para>
- <classname>Zend_Mail_Part</classname> implementiert auch den
- <classname>RecursiveIterator</classname>, welcher es sehr einfach macht alle Teile zu
- durchsuchen. Und für die einfache Ausgabe wurde auch die magische Methode
- <methodname>__toString()</methodname> implementiert, welche den Inhalt zurückgibt.
- </para>
- <programlisting language="php"><![CDATA[
- // Gibt den ersten text/plain Teil aus
- $foundPart = null;
- foreach (new RecursiveIteratorIterator($mail->getMessage(1)) as $part) {
- try {
- if (strtok($part->contentType, ';') == 'text/plain') {
- $foundPart = $part;
- break;
- }
- } catch (Zend_Mail_Exception $e) {
- // ignorieren
- }
- }
- if (!$foundPart) {
- echo 'kein reiner Text-Teil gefunden';
- } else {
- echo "Reiner Text-Teil: \n" . $foundPart;
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.mail.read-flags">
- <title>Auf Flags prüfen</title>
- <para>
- Maildir und IMAP unterstützen das Speichern von Flags. Die Klasse
- <classname>Zend_Mail_Storage</classname> hat Konstanten für alle bekannten maildir und
- IMAP System Flags, welche
- <classname>Zend_Mail_Storage::FLAG_<flagname></classname> heißen. Um auf Flags zu
- Prüfen hat <classname>Zend_Mail_Message</classname> eine Methode die
- <methodname>hasFlag()</methodname> heißt. Mit <methodname>getFlags()</methodname> erhält
- man alle gesetzten Flags.
- </para>
- <programlisting language="php"><![CDATA[
- // Finde ungelesene Nachrichten
- echo "Ungelesene Nachrichten:\n";
- foreach ($mail as $message) {
- if ($message->hasFlag(Zend_Mail_Storage::FLAG_SEEN)) {
- continue;
- }
- // Vorherige/Neue Nachrichten markieren
- if ($message->hasFlag(Zend_Mail_Storage::FLAG_RECENT)) {
- echo '! ';
- } else {
- echo ' ';
- }
- echo $message->subject . "\n";
- }
- // Prüfen auf bekannte Flags
- $flags = $message->getFlags();
- echo "Nachricht wurde markiert als: ";
- foreach ($flags as $flag) {
- switch ($flag) {
- case Zend_Mail_Storage::FLAG_ANSWERED:
- echo 'Beantwortet ';
- break;
- case Zend_Mail_Storage::FLAG_FLAGGED:
- echo 'Markiert ';
- break;
- // ...
- // Auf andere Flags prüfen
- // ...
- default:
- echo $flag . '(unbekanntes Flag) ';
- }
- }
- ]]></programlisting>
- <para>
- Da IMAP Benutzern oder auch Clients selbstdefinierte Flags erlaubt, können auch Flags
- empfangen werden die keine Konstante in <classname>Zend_Mail_Storage</classname> haben.
- Stattdessen werden sie als String zurückgegeben und können auf dem selben Weg mit
- <methodname>hasFlag()</methodname> geprüft werden.
- </para>
- <programlisting language="php"><![CDATA[
- // Nachricht auf vom Client definierte Flags $IsSpam, $SpamTested prüfen
- if (!$message->hasFlag('$SpamTested')) {
- echo 'Die Nachricht wurde nicht auf Spam geprüft';
- } else if ($message->hasFlag('$IsSpam')) {
- echo 'Diese Nachricht ist Spam';
- } else {
- echo 'Diese Nachricht ist Speck';
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.mail.read-folders">
- <title>Verwenden von Ordnern</title>
- <para>
- Alle Speicher, ausser Pop3, unterstützen Ordner, welche Mailboxen genannt werden. Das
- Interface das von allen Speichern implementiert wurde und Ordner unterstützt heißt
- <classname>Zend_Mail_Storage_Folder_Interface</classname>. Alle diese Klassen besitzen
- auch einen zusätzlichen optionalen Parameter welcher <property>folder</property> heißt,
- was der ausgewählt Ordner nach dem Login, im Konstruktor ist.
- </para>
- <para>
- Für den lokalen Speicher müssen die eigenen Klassen
- <classname>Zend_Mail_Storage_Folder_Mbox</classname> oder
- <classname>Zend_Mail_Storage_Folder_Maildir</classname> genannt verwendet werden. Beide
- benötigen einen Parameter der <property>dirname</property> heißt mit dem Namen des
- Basisverzeichnisses. Das Format für Maildir ist wie in Maildir++ definiert (mit einem
- Punkt als Standardbegrenzer), Mbox ist eine Verzeichnisstruktur mit Mbox Dateien. Wenn
- im Mbox Basisverzeichnis keine Mbox Datei vorhanden ist die INBOX heißt, muß ein anderer
- Ordner im Konstruktor gesetzt werden.
- </para>
- <para>
- <classname>Zend_Mail_Storage_Imap</classname> unterstützt Ordner schon standardmäßig.
- Beispiele für das Öffnen solcher Speicher:
- </para>
- <programlisting language="php"><![CDATA[
- // MBox mit Ordnern
- $mail = new Zend_Mail_Storage_Folder_Mbox(array('dirname' =>
- '/home/test/mail/'));
- // MBox mit standard Ordner der nicht INBOX heißt, funktioniert auch
- // mit Zend_Mail_Storage_Folder_Maildir und Zend_Mail_Storage_Imap
- $mail = new Zend_Mail_Storage_Folder_Mbox(array('dirname' =>
- '/home/test/mail/',
- 'folder' =>
- 'Archive'));
- // Maildir mit Ordnern
- $mail = new Zend_Mail_Storage_Folder_Maildir(array('dirname' =>
- '/home/test/mail/'));
- // Maildir mir Doppelpunkt als Begrenzung, wie in Maildir++ empfohlen
- $mail = new Zend_Mail_Storage_Folder_Maildir(array('dirname' =>
- '/home/test/mail/',
- 'delim' => ':'));
- // IMAP ist genauso mit und ohne Ordner
- $mail = new Zend_Mail_Storage_Imap(array('host' => 'example.com',
- 'user' => 'test',
- 'password' => 'test'));
- ]]></programlisting>
- <para>
- Mit der Methode getFolders($root = null) kann die Verzeichnisstruktur beginnend mit dem
- Basisverzeichnis oder einem angegebenen Ordner ausgegeben werden. Sie wird als Instanz
- von <classname>Zend_Mail_Storage_Folder</classname> zurückgegeben, welche
- <classname>RecursiveIterator</classname> implementiert und alle Kinder sind genauso
- Instanzen von <classname>Zend_Mail_Storage_Folder</classname>. Jede dieser Instanzen hat
- einen lokalen und einen globalen Namen der durch die Methoden
- <methodname>getLocalName()</methodname> und <methodname>getGlobalName()</methodname>
- zurückgegeben wird. Der globale Name ist der absolute Name des Basisordners (inklusive
- Begrenzer), der lokale Name ist der Name im Elternordner.
- </para>
- <table id="zend.mail.read-folders.table-1">
- <title>Namen für Nachrichtenordner</title>
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Globaler Name</entry>
- <entry>Lokaler Name</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>/INBOX</entry>
- <entry>INBOX</entry>
- </row>
- <row>
- <entry>/Archive/2005</entry>
- <entry>2005</entry>
- </row>
- <row>
- <entry>List.ZF.General</entry>
- <entry>General</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Wenn der Iterator verwendet wird ist der lokale Name der Schlüssel des aktuellen
- Elements. Der globale Name wird auch durch die magische Methode
- <methodname>__toString()</methodname> zurückgegeben. Gleiche Ordner können nicht
- ausgewählt werden, was bedeutet das Sie keine Nachrichten speichern können und die
- Auswahl von Ergebnisses führt zu einem Fehler. Das kann mit der Methode
- <methodname>isSelectable()</methodname> geprüft werden. Es ist also sehr einfach den
- ganzen Baum in einer Ansicht auszugeben:
- </para>
- <programlisting language="php"><![CDATA[
- $folders = new RecursiveIteratorIterator($this->mail->getFolders(),
- RecursiveIteratorIterator::SELF_FIRST);
- echo '<select name="folder">';
- foreach ($folders as $localName => $folder) {
- $localName = str_pad('', $folders->getDepth(), '-', STR_PAD_LEFT) .
- $localName;
- echo '<option';
- if (!$folder->isSelectable()) {
- echo ' disabled="disabled"';
- }
- echo ' value="' . htmlspecialchars($folder) . '">'
- . htmlspecialchars($localName) . '</option>';
- }
- echo '</select>';
- ]]></programlisting>
- <para>
- Der aktuell ausgewählte Ordner wird durch die Methode
- <methodname>getCurrentFolder()</methodname> zurückgegeben. Das Ändern von Ordnern wird
- mit der Methode <methodname>selectFolder()</methodname> durchgeführt, welche den
- globalen Namen als Parameter benötigt. Wenn das Schreiben von Begrenzern vermieden
- werden soll, können auch die Eigenschaften einer
- <classname>Zend_Mail_Storage_Folder</classname> Instanz verwendet werden:
- </para>
- <programlisting language="php"><![CDATA[
- // Abhängig vom Mail Speicher und seinen Einstellungen
- // $rootFolder->Archive->2005 ist das gleiche wie:
- // /Archive/2005
- // Archive:2005
- // INBOX.Archive.2005
- // ...
- $folder = $mail->getFolders()->Archive->2005;
- echo 'Der letzte Ordner war '
- . $mail->getCurrentFolder()
- . "neuer Ordner ist $folder\n";
- $mail->selectFolder($folder);
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.mail.read-advanced">
- <title>Fortgeschrittene Verwendung</title>
- <sect3 id="zend.mail.read-advanced.noop">
- <title>NOOP verwenden</title>
- <para>
- Wenn ein entfernter Speicher verwendet werden soll und einige lange Aufgaben
- anstehen kann es notwendig sein die Verbindung über noop am Leben zu halten:
- </para>
- <programlisting language="php"><![CDATA[
- foreach ($mail as $message) {
- // einige Berechnungen ...
- $mail->noop(); // am Leben halten
- // irgendwas anderes tun ...
- $mail->noop(); // am Leben halten
- }
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.mail.read-advanced.caching">
- <title>Instanzen cachen</title>
- <para>
- <classname>Zend_Mail_Storage_Mbox</classname>,
- <classname>Zend_Mail_Storage_Folder_Mbox</classname>,
- <classname>Zend_Mail_Storage_Maildir</classname> und
- <classname>Zend_Mail_Storage_Folder_Maildir</classname> implementieren die magischen
- Methoden <methodname>__sleep()</methodname> und <methodname>__wakeup()</methodname>
- was bedeutet das Sie serialisierbar sind. Das vermeidet das Parsen von Dateien oder
- Verzeichnisbäumen mehr als einmal. Der Nachteil ist das der Mbox oder Maildir
- Speicher sich nicht Ändern sollte. Einige einfache Prüfungen werden durchgeführt,
- wie das neuparsen der aktuellen Mbox Datei wenn sich der Bearbeitungszeitpunkt
- ändert oder das neuparsen der Verzeichnisstruktur wenn ein Ordner entfernt wurde
- (was immer noch zu einem Fehler führt, es kan aber im Nachhinein ein anderer Ordner
- gesucht werden). Es ist besser etwas wie eine Signaldatei für Änderungen zu haben,
- und diese zu Prüfen bevor eine gecachete Instanz verwendet wird.
- </para>
- <programlisting language="php"><![CDATA[
- // Es wird kein spezieller Cache Handler/Klasse verwendet
- // Code ändern damit er zum Cache Handler passt
- $signal_file = '/home/test/.mail.last_change';
- $mbox_basedir = '/home/test/mail/';
- $cache_id = 'Beispiel Nachrichten Cache ' . $mbox_basedir . $signal_file;
- $cache = new Your_Cache_Class();
- if (!$cache->isCached($cache_id) ||
- filemtime($signal_file) > $cache->getMTime($cache_id)) {
- $mail = new Zend_Mail_Storage_Folder_Pop3(array('dirname' =>
- $mbox_basedir));
- } else {
- $mail = $cache->get($cache_id);
- }
- // irgendwas machen ...
- $cache->set($cache_id, $mail);
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.mail.read-advanced.extending">
- <title>Prokoll Klassen erweitern</title>
- <para>
- Entfernte Speicher verwenden zwei Klassen:
- <classname>Zend_Mail_Storage_<Name></classname> und
- <classname>Zend_Mail_Protocol_<Name></classname>. Die Protkoll Klasse
- übersetzt die Protokollbefehle und antwortet von und zu <acronym>PHP</acronym>, wie
- Methoden für die Befehle oder Variablen mit verschiedenen Strukturen für Daten. Die
- andere/Haupt Klasse implementiert das Standard Interface.
- </para>
- <para>
- Wenn zusätzliche Protokoll Features benötigt werden kann die Protokoll Klasse
- erweitert werden und diese im Konstruktor der Basisklasse verwendet werden. Als
- Beispiel nehmen wir an das verschiedene Ports abgeklopft werden bevor auf POP3
- verbunden werden kann.
- </para>
- <programlisting language="php"><![CDATA[
- class Example_Mail_Exception extends Zend_Mail_Exception
- {
- }
- class Example_Mail_Protocol_Exception extends Zend_Mail_Protocol_Exception
- {
- }
- class Example_Mail_Protocol_Pop3_Knock extends Zend_Mail_Protocol_Pop3
- {
- private $host, $port;
- public function __construct($host, $port = null)
- {
- // kein automatisches Verbinden in dieser Klasse
- $this->host = $host;
- $this->port = $port;
- }
- public function knock($port)
- {
- $sock = @fsockopen($this->host, $port);
- if ($sock) {
- fclose($sock);
- }
- }
- public function connect($host = null, $port = null, $ssl = false)
- {
- if ($host === null) {
- $host = $this->host;
- }
- if ($port === null) {
- $port = $this->port;
- }
- parent::connect($host, $port);
- }
- }
- class Example_Mail_Pop3_Knock extends Zend_Mail_Storage_Pop3
- {
- public function __construct(array $params)
- {
- // ... Parameter hier prüfen! ...
- $protocol = new Example_Mail_Protocol_Pop3_Knock($params['host']);
- // Spezial "Ding" hier machen
- foreach ((array)$params['knock_ports'] as $port) {
- $protocol->knock($port);
- }
- // den richtigen Status erhalten
- $protocol->connect($params['host'], $params['port']);
- $protocol->login($params['user'], $params['password']);
- // Eltern initialisieren
- parent::__construct($protocol);
- }
- }
- $mail = new Example_Mail_Pop3_Knock(array('host' => 'localhost',
- 'user' => 'test',
- 'password' => 'test',
- 'knock_ports' =>
- array(1101, 1105, 1111)));
- ]]></programlisting>
- <para>
- Wie gesehen werden kann wird angenommen das man immer verbunden, eingeloggt und,
- wenn es unterstützt wird, ein Ordner im Konstruktor der Basisklasse ausgewählt ist.
- Das bedeutet, wenn eine eigene Protokollklasse verwendet wird muß immer
- sichergestellt werden dass das durchgeführt wird, da sonst die nächste Methode
- fehlschlagen wird wenn der Server das im aktuellen Status nicht zulässt.
- </para>
- </sect3>
- <sect3 id="zend.mail.read-advanced.quota">
- <title>Quote verwenden (seit 1.5)</title>
- <para>
- <classname>Zend_Mail_Storage_Writable_Maildir</classname> bietet Unterstützung für
- Maildir++ Quoten. Diese sind standardmäßig ausgeschaltet, aber es ist möglich Sie
- manuell zu verwenden, wenn automatische Checks nicht gewünscht sind (das bedeutet
- <methodname>appendMessage()</methodname>, <methodname>removeMessage()</methodname>
- und <methodname>copyMessage()</methodname> führen keine Checks durch und fügen
- keinen Eintrag zur maildirsize Datei hinzu). Wenn aktiviert, wird eine Ausnahme
- geworfen wenn versucht wird in maildir zu schreiben wenn es bereits voll ist und die
- Quote überschritten wurde.
- </para>
- <para>
- Es gibt drei Methoden die für Quoten verwendet werden:
- <methodname>getQuota()</methodname>, <methodname>setQuota()</methodname> und
- <methodname>checkQuota()</methodname>:
- </para>
- <programlisting language="php"><![CDATA[
- $mail = new Zend_Mail_Storage_Writable_Maildir(array('dirname' =>
- '/home/test/mail/'));
- $mail->setQuota(true); // true zum einschalten, false zum ausschalten
- echo 'Quotenprüfung ist jetzt ', $mail->getQuota() ? 'eingeschaltet'
- : 'ausgeschaltet', "\n";
- // Quotenprüfung kann verwendet werden
- // selbst wenn die Quotenprüfung ausgeschaltet ist
- echo 'Sie sind ', $mail->checkQuota() ? 'über der Quote'
- : 'nicht über der Quote', "\n";
- ]]></programlisting>
- <para>
- <methodname>checkQuota()</methodname> kann eine viel detailiertere Antwort
- zurückgeben:
- </para>
- <programlisting language="php"><![CDATA[
- $quota = $mail->checkQuota(true);
- echo 'Sie sind ', $quota['over_quota'] ? 'über der Quote'
- : 'nicht über der Quote', "\n";
- echo 'Sie haben ',
- $quota['count'],
- ' von ',
- $quota['quota']['count'],
- ' Nachrichten und verwenden ';
- echo $quota['size'], ' von ', $quota['quota']['size'], ' Oktets';
- ]]></programlisting>
- <para>
- Wenn man eigene Quoten spezifizieren will statt die bereits in der maildirsize
- Datei spezifizierte zu verwenden kann das mit <methodname>setQuota()</methodname>
- getan werden:
- </para>
- <programlisting language="php"><![CDATA[
- // message count and octet size supported, order does matter
- $quota = $mail->setQuota(array('size' => 10000, 'count' => 100));
- ]]></programlisting>
- <para>
- Wenn eigene Quotenchecks hinzugefügt werden sollen können einzelne Buchstaben als
- Schlüssel verwendet werden und Sie werden reserviert (aber logischerweise nicht
- geprüft). Es ist auch möglich
- <classname>Zend_Mail_Storage_Writable_Maildir</classname> zu erweitern um eigene
- Quoten zu definieren wenn die maildirsize Datei fehlt (was in Maildir++ vorkommen
- kann):
- </para>
- <programlisting language="php"><![CDATA[
- class Example_Mail_Storage_Maildir extends Zend_Mail_Storage_Writable_Maildir {
- // getQuota wird mit $fromStorage = true durch die Quotenprüfung aufgerufen
- public function getQuota($fromStorage = false) {
- try {
- return parent::getQuota($fromStorage);
- } catch (Zend_Mail_Storage_Exception $e) {
- if (!$fromStorage) {
- // unbekannter Fehler:
- throw $e;
- }
- // Die maildirsize Datei muß fehlen
- list($count, $size) = get_quota_from_somewhere_else();
- return array('count' => $count, 'size' => $size);
- }
- }
- }
- ]]></programlisting>
- </sect3>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|