<sect1 id="zend.mail.read">
    <title>Lettura di messaggi e-mail</title>

    <para>
        <code>Zend_Mail</code> può leggere messaggi e-mail da diversi sistemi di salvataggio locali o remoti.
        Ciascuno di essi ha le stesse API alla base per contare e leggere i messaggi ed alcuni implementano interfacce aggiuntive per funzionalità non così comuni.
        Per una panoramica delle funzionalità dei sistemi di raccolta consultare la tabella seguente.
    </para>

    <table id="zend.mail.read.table-1">
        <title>Panoramica delle caratteristiche dei sistemi di lettura di e-mail</title>
        <tgroup cols="5">
            <thead>
                <row>
                    <entry>Funzionalità</entry>
                    <entry>Mbox</entry>
                    <entry>Maildir</entry>
                    <entry>Pop3</entry>
                    <entry>IMAP</entry>
                </row>
            </thead>
            <tbody>
                <row>
                    <entry>Tipo di salvataggio</entry>
                    <entry>locale</entry>
                    <entry>locale</entry>
                    <entry>remoto</entry>
                    <entry>remoto</entry>
                </row>
                <row>
                    <entry>Estrazione dei messaggi</entry>
                    <entry>Yes</entry>
                    <entry>Yes</entry>
                    <entry>Yes</entry>
                    <entry>Yes</entry>
                </row>
                <row>
                    <entry>Estrazione delle parti mime</entry>
                    <entry>emulata</entry>
                    <entry>emulata</entry>
                    <entry>emulata</entry>
                    <entry>emulata</entry>
                </row>
                <row>
                    <entry>Cartelle</entry>
                    <entry>Si</entry>
                    <entry>Si</entry>
                    <entry>No</entry>
                    <entry>Si</entry>
                </row>
                <row>
                    <entry>Creazione messaggio/cartella</entry>
                    <entry>No</entry>
                    <entry>Da fare</entry>
                    <entry>No</entry>
                    <entry>Da fare</entry>
                </row>
                <row>
                    <entry>Flags</entry>
                    <entry>No</entry>
                    <entry>Si</entry>
                    <entry>No</entry>
                    <entry>Si</entry>
                </row>
            </tbody>
        </tgroup>
    </table>

    <sect2 id="zend.mail.read-example">
        <title>Semplice esempio usando Pop3</title>

        <programlisting role="php"><![CDATA[<?php
$mail = new Zend_Mail_Storage_Pop3(array('host'     => 'localhost',
                                         'user'     => 'test',
                                         'password' => 'test'));

echo $mail->countMessages() . " messaggi trovati\n";
foreach ($mail as $message) {
    echo "E-mail da '{$message->from}': {$message->subject}\n";
}]]>
        </programlisting>

    </sect2>
    <sect2 id="zend.mail.read-open-local">
        <title>Apertura di un sistema di salvataggio locale</title>

        <para>
            Mbox e Maildir sono due formati supportati per lo salvataggio locale delle e-mail, entrambi nel loro formato più semplice.
        </para>
        <para>
            Se si desidera leggere da un file Mbox è sufficiente fornire il nome del file al costruttore di <code>Zend_Mail_Storage_Mbox</code>:
        </para>

        <programlisting role="php"><![CDATA[<?php
$mail = new Zend_Mail_Storage_Mbox(array('filename' => '/home/test/mail/inbox'));]]>
        </programlisting>

        <para>Maildir è molto simile ma necessita il nome di una cartella:</para>

        <programlisting role="php"><![CDATA[<?php
$mail = new Zend_Mail_Storage_Maildir(array('dirname' => '/home/test/mail/'));]]>
        </programlisting>

        <para>Entrambi i costruttori generano un'eccezione <code>Zend_Mail_Exception</code> se l'archivio non può essere letto.</para>

    </sect2>

    <sect2 id="zend.mail.read-open-remote">
        <title>Apertura di un sistema di salvataggio remoto</title>

        <para>
            Per quanto riguarda i sistemi di salvataggio remoto i due protocolli più popolari sono entrambi supportati: Pop3 e Imap.
            Entrambi necessitano almeno di un host ed un utente per connettersi ed autenticarsi.
            La password predefinita è una stringa vuota, la porta predefinita quella specificata nel protocollo RFC.
        </para>

        <programlisting role="php"><![CDATA[<?php
// connessione con Pop3
$mail = new Zend_Mail_Storage_Pop3(array('host'     => 'example.com'
                                         'user'     => 'test',
                                         'password' => 'test'));

// connessione con Imap
$mail = new Zend_Mail_Storage_Imap(array('host'     => 'example.com'
                                         'user'     => 'test',
                                         'password' => 'test'));

// esempio di una porta non standard
$mail = new Zend_Mail_Storage_Pop3(array('host'     => 'example.com',
                                         'port'     => 1120
                                         'user'     => 'test',
                                         'password' => 'test'));]]>
        </programlisting>

        <para>
            Per entrambi i protocolli sono supportate le connessioni SSL e TSL.
            Se si utilizza SSL, la porta predefinita cambia come specificato in RFC.
        </para>

        <programlisting role="php"><![CDATA[<?php
// esempi per Zend_Mail_Storage_Pop3, gli stessi funzionano per Zend_Mail_Storage_Imap

// utilizzo di SSL su una porta differente
// (i valori predefiniti sono 995 per Pop3 e 993 per Imap)
$mail = new Zend_Mail_Storage_Pop3(array('host'     => 'example.com'
                                         'user'     => 'test',
                                         'password' => 'test',
                                         'ssl'      => 'SSL'));

// use TLS
$mail = new Zend_Mail_Storage_Pop3(array('host'     => 'example.com'
                                         'user'     => 'test',
                                         'password' => 'test',
                                         'ssl'      => 'TLS'));]]>
        </programlisting>

        <para>
            Entrambi i costruttori possono restituire un'eccezione <code>Zend_Mail_Exception</code> o <code>Zend_Mail_Protocol_Exception</code>, a seconda del tipo di errore.
        </para>

    </sect2>

    <sect2 id="zend.mail.read-fetching">
        <title>Lettura dei messaggi e semplici metodi</title>

        <para>
            Una volta aperta la connessione, è possibile estrarre i messaggi.
            E' necessario il numero di messaggi, che rappresenta un contatore che parte da 1 per il primo messaggio.
            Per estrarre il messaggio si utilizza il metodo <code>getMessage()</code>:
        </para>

        <programlisting role="php"><![CDATA[<?php
$message = $mail->getMessage($messageNum);]]>
        </programlisting>

        <para>
            L'accesso sotto forma di array è supportato, ma non consente di specificare alcun parametro aggiuntivo al metodo <code>getMessage()</code>.
            Se questo non è un problema e si può vivere anche solo con i valori predefiniti, allora si può usare:
        </para>

        <programlisting role="php"><![CDATA[<?php
$message = $mail[$messageNum];]]>
        </programlisting>

        <para>L'interfaccia Iterator è implementata e consente di scorrere tutti i messaggi:</para>

        <programlisting role="php"><![CDATA[<?php
foreach ($mail as $messageNum => $message) {
    // fai qualcosa ...
}]]>
        </programlisting>

        <para>
            Per contare i messaggi salvati è possibile usare sia il metodo <code>countMessages()</code> sia l'accesso del tipo array:
        </para>

        <programlisting role="php"><![CDATA[<?php
// metodo
$maxMessage = $mail->countMessages();

// accesso array
$maxMessage = count($mail);]]>
        </programlisting>

        <para>Per rimuovere un'e-mail si utilizzi il metodo <code>removeMessage()</code> o, nuovamente, l'accesso del tipo array:</para>

        <programlisting role="php"><![CDATA[<?php
// metodo
$mail->removeMessage($messageNum);

// accesso array
unset($mail[$messageNum]);]]>
        </programlisting>

    </sect2>

    <sect2 id="zend.mail.read-message">
        <title>Interazione con i messaggi</title>

        <para>
            Dopo aver estratto i messaggi <code>getMessage()</code> potrebbe essere necessario estrarre le intestazioni, il contenuto o singole parti di un messaggio multipart.
            Tutte le intestazioni sono accessibili come proprietà o grazie al metodo <code>getHeader()</code> se è necessario maggiore controllo o in caso di nomi di intestazioni poco comuni.
            Internamente, tutte le intestazioni sono convertite in minuscolo dunque il caso del testo nel nome non è importante. Inoltre, le intestazioni che contengono un trattino "-" possono essere scritte con la notazione CamelCase.
        </para>

        <programlisting role="php"><![CDATA[<?php
// recupera l'oggetto messaggio
$message = $mail->getMessage(1);

// stampa l'oggetto del messaggio
echo $message->subject . "\n";

// recupera l'intestazione content-type
$type = $message->contentType;]]>
        </programlisting>

        <para>
            In caso di più intestazioni con lo stesso nome, esempio l'intestazione <code>Received</code>, è possibile recuperare il valore come array invece che stringa con il metodo <code>getHeader()</code>.
        </para>

        <programlisting role="php"><![CDATA[<?php
// recupera l'intestazione come proprietà
// il risultato è sempre una stringa,
// dove le diverse occorrenze sono separate dal carattere carattere newline (\n)
$received = $message->received;

// stesso risultato usando il metodo getHeader()
$received = $message->getHeader('received', 'string');

// o, meglio, un array contenente un elemento per ogni occorrenza
$received = $message->getHeader('received', 'array');
foreach ($received as $line) {
    // fai qualcosa
}

// se non si definisce un formato si ottiene la rappresentazione interna
// (stringa per singole intestazioni, array per multipli)
$received = $message->getHeader('received');
if (is_string($received)) {
    // trovata una sola intestazione received nel messaggio
}]]>
        </programlisting>

        <para>
            Il metodo <code>getHeaders()</code> restituisce tutte le intestazioni come array.
            Per ogni elemento, la chiave corrisponde al nome dell'intestazione in minuscolo, il valore è un array nel caso di intestazioni multiple, una stringa per intestazioni singole.
        </para>

        <programlisting role="php"><![CDATA[<?php
// stampa tutte le intestazioni
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>
            Se il messaggio non è di tipo multipart la sua lettura è immediata con il metodo <code>getContent()</code>.
            A differenza delle intestazioni, il contenuto è caricato solo in caso di necessità (late-fetch).
        </para>

        <programlisting role="php"><![CDATA[<?php
// stampa il contenuto del messaggio
echo '<pre>';
echo $message->getContent();
echo '</pre>';]]>
        </programlisting>

        <para>
            La verifica di un messaggio multipart avviene con il metodo <code>isMultipart()</code>.
            In caso positivo, è possibile ottenere un'istanza di <code>Zend_Mail_Part</code> con il metodo <code>getPart()</code>. <code>Zend_Mail_Part</code> è la classe alla base di <code>Zend_Mail_Message</code>, quindi si ha accesso agli stessi metodi: <code>getHeader()</code>, <code>getHeaders()</code>, <code>getContent()</code>, <code>getPart()</code>, <code>isMultipart</code> e le proprietà per le intestazioni.
        </para>

        <programlisting role="php"><![CDATA[<?php
// recupera la prima parte non multipart
$part = $message;
while ($part->isMultipart()) {
    $part = $message->getPart(1);
}
echo 'Il tipo di questa parte è ' . strtok($part->contentType, ';') . "\n";
echo "Contenuto:\n";
echo $part->getContent();]]>
        </programlisting>

        <para>
            <code>Zend_Mail_Part</code> implementa <code>RecursiveIterator</code> che semplifica l'iterazione di tutte le parti. Inoltre, per agevolare l'ouput, implementa il metodo magico <code>__toString()</code> che restituisce il contenuto.
        </para>

        <programlisting role="php"><![CDATA[<?php
// stampa la prima parte text/plain
$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) {
        // ignora
    }
}
if (!$foundPart) {
    echo 'Nessuna parte solo testo trovata';
} else {
    echo "Parte solo testo: \n" . $foundPart;
}]]>
        </programlisting>

    </sect2>
    <sect2 id="zend.mail.read-flags">
        <title>Controllo dei contrassegni</title>

        <para>
            Maildir e IMAP supportano il salvataggio dei contrassegni.
            La classe Zend_Mail_Storage include costanti per tutti i tipi di contrassegno IMAP e maildir conosciuti, chiamati <code>Zend_Mail_Storage::FLAG_&lt;flagname&gt;</code>.
            <code>Zend_Mail_Message</code> contiene un metodo chiamato <code>hasFlag()</code> per eseguire un controllo dei contrassegni. Il metodo <code>getFlags()</code> restituisce invece tutti i contrassegni impostati.
        </para>

        <programlisting role="php"><![CDATA[<?php
// cerca i messaggi non letti
echo "E-mail da leggere:\n";
foreach ($mail as $message) {
    if ($message->hasFlag(Zend_Mail_Storage::FLAG_SEEN)) {
        continue;
    }
    // distingui le e-mail recenti/nuove
    if ($message->hasFlag(Zend_Mail_Storage::FLAG_RECENT)) {
        echo '! ';
    } else {
        echo '  ';
    }
    echo $message->subject . "\n";
}


// verifica i contrassegni conosciuti
$flags = $message->getFlags();
echo "Il messaggio è contrassegnato come: ";
foreach ($flags as $flag) {
    switch ($flag) {
        case Zend_Mail_Storage::FLAG_ANSWERED:
            echo 'Risposto ';
            break;
        case Zend_Mail_Storage::FLAG_FLAGGED:
            echo 'Contrassegnato ';
            break;

        // ...
        // verifica altri contrassegni
        // ...

        default:
            echo $flag . '(contrassegno sconosciuto) ';
    }
}]]>
        </programlisting>

        <para>
            Poiché IMAP permette all'utente o al client di definire contrassegni personalizzati, potrebbero esistere contrassegni senza una costante corrispondente in <code>Zend_Mail_Storage</code>.
            In questo caso i valori sono restituiti come stringa e possono essere verificati allo stesso modo con <code>hasFlag()</code>.
        </para>

        <programlisting role="php"><![CDATA[<?php
// verifica il messaggio alla ricerca dei contrassegni
// $IsSpam, $SpamTested impostati dal client
if (!$message->hasFlag('$SpamTested')) {
    echo 'Messaggio non verificato dal controllo anti spam';
} else if ($message->hasFlag('$IsSpam')) {
    echo 'Questo messaggio è spam';
} else {
    echo 'Questo messaggio è sicuro';
}]]>
        </programlisting>

    </sect2>
    <sect2 id="zend.mail.read-folders">
        <title>Utilizzo delle cartelle</title>

        <para>
            Tutti i sistemi di salvataggio, eccetto Pop3, supportano le cartelle anche chiamate mailbox.
            L'interfaccia implementata dai sistemi che supportano le cartelle si chiama <code>Zend_Mail_Storage_Folder_Interface</code>. Inoltre, tutte queste classi contengono un parametro opzionale aggiuntivo chiamato <code>folder</code> che rappresenta la cartella selezionata dopo l'autenticazione, nel costruttore.
        </para>
        <para>
            Per i sistemi di salvataggio locali è necessario usare delle classi a parte chiamate <code>Zend_Mail_Storage_Folder_Mbox</code> o <code>Zend_Mail_Storage_Folder_Maildir</code>.
            Entrambe necessitano di un parametro chiamato <code>dirname</code> che corrisponde alla cartella principale.
            Il formato per maildir è definito in maildir++ (con un punto come delimitatore predefinito), in Mbox è una gerarchia di directory contenenti file Mbox. Se nella cartella principale di Mbox non è presente un file Mbox chiamato INBOX, allora è necessario specificare un'altra cartella nel costruttore.
        </para>
        <para>
            Il supporto alle cartelle è nativo in <code>Zend_Mail_Storage_Imap</code>.
            Alcuni esempi per aprire questi sistemi di salvataggio:
        </para>

        <programlisting role="php"><![CDATA[<?php
// mbox con cartelle
$mail = new Zend_Mail_Storage_Folder_Mbox(array('dirname' => '/home/test/mail/'));

// mbox con una cartella predefinita non chiamata INBOX,
// funziona anche con Zend_Mail_Storage_Folder_Maildir e Zend_Mail_Storage_Imap
$mail = new Zend_Mail_Storage_Folder_Mbox(array('dirname' => '/home/test/mail/',
                                                'folder'  => 'Archive'));

// maildir con cartelle
$mail = new Zend_Mail_Storage_Folder_Maildir(array('dirname' => '/home/test/mail/'));

// maildir con due punti come delimitatore, come suggerito in Maildir++
$mail = new Zend_Mail_Storage_Folder_Maildir(array('dirname' => '/home/test/mail/'
                                                   'delim'   => ':'));

// imap è lo stesso con o senza cartelle
$mail = new Zend_Mail_Storage_Imap(array('host'     => 'example.com'
                                         'user'     => 'test',
                                         'password' => 'test'));]]>
        </programlisting>

        <para>
            Con il metodo getFolders($root = null) si ottiene la gerarchia delle cartelle a partire dalla cartella root o da quella specificata.
            Restituisce un'istanza di <code>Zend_Mail_Storage_Folder</code>, che implementa <code>RecursiveIterator</code> e tutte le sottocartelle sono a loro volta istanze di <code>Zend_Mail_Storage_Folder</code>.
            Ciascuna di queste istanze contiene un nome locale e globale restituiti rispettivamente dai metodi <code>getLocalName()</code> e <code>getGlobalName()</code>.
            Il nome globale è il nome assoluto a partire dalla cartella principale (inclusi i delimitatori), il nome locale è invece il nome specifico assunto nella cartella di livello superiore.
        </para>

        <table id="zend.mail.read-folders.table-1">
            <title>Nomi delle cartelle e-mail</title>
            <tgroup cols="2">
                <thead>
                    <row>
                        <entry>Nome Globale</entry>
                        <entry>Nome Locale</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>
            Se si utilizza un iteratore la chiave dell'elemento corrente corrisponde al nome locale.
            Il nome globale è anche restituito dal metodo magico <code>__toString()</code>.
            Alcune cartelle non sono selezionabili, ovvero non è possibile salvare all'interno dei messaggi e se selezionate il risultato è un errore. E' possibile eseguire un controllo con il metodo <code>isSelectable()</code>.
            E' molto semplice stampare la visualizzazione dell'intero albero delle cartelle:
        </para>

        <programlisting role="php"><![CDATA[<?php
$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>
            Il metodo <code>getCurrentFolder()</code> restituisce la cartella corrente selezionata.
            Per cambiare la cartella utilizzare il metodo <code>selectFolder()</code>, che necessita del nome globale come parametro. Per evitare di scrivere i delimitatori è possibile utilizzare le proprietà di un'istanza  <code>Zend_Mail_Storage_Folder</code>:
        </para>

        <programlisting role="php"><![CDATA[<?php
// a seconda del sistema di salvataggio e delle impostazioni $rootFolder->Archive->2005
// è identico a:
//  /Archive/2005
//  Archive:2005
//  INBOX.Archive.2005
//  ...
$folder = $mail->getFolders()->Archive->2005;
echo "L'ultima cartella era " . $mail->getCurrentFolder() . " la nuova cartella è $folder\n";
$mail->selectFolder($folder);]]>
        </programlisting>

    </sect2>
    <sect2 id="zend.mail.read-advanced">
        <title>Utilizzo avanzato</title>

        <sect3 id="zend.mail.read-advanced.noop">
            <title>Utilizzo di NOOP</title>

            <para>
                Se si utilizza un sistema di salvataggio remoto e si devono eseguire alcune attività di lunga durata, è necessario mantenere attiva la connessione via noop:
            </para>

            <programlisting role="php"><![CDATA[<?php
foreach ($mail as $message) {

    // esegui qualche elaborazione ...

    $mail->noop(); // keep alive

    // esegui qualche altra elaborazione ...

    $mail->noop(); // keep alive
}]]>
            </programlisting>

        </sect3>
        <sect3 id="zend.mail.read-advanced.caching">
            <title>Salvataggio in cache delle istanze</title>

            <para>
                <code>Zend_Mail_Storage_Mbox</code>, <code>Zend_Mail_Storage_Folder_Mbox</code>, <code>Zend_Mail_Storage_Maildir</code> e <code>Zend_Mail_Storage_Folder_Maildir</code> implementano i metodi magici <code>__sleep()</code> e <code>__wakeup()</code>, dunque sono serializzabili. Questo evita di eseguire la lettura dei file o delle cartelle più di una volta.
                Lo svantaggio è che la struttura Mbox o Maildir non deve cambiare. Sono eseguiti alcuni semplici controlli, come ad esempio la rilettura del file Mbox corrente in caso di variazione della data di ultima modifica o la rilettura della struttura delle cartelle se una cartella è scomparsa (l'errore persiste, ma è possibile cercare una nuova cartella successivamente).
                Ad ogni modo, è meglio mantenere qualcosa come un file indicatore dei cambiamenti e verificarlo prima di utilizzare un'istanza salvata in cache.
            </para>

            <programlisting role="php"><![CDATA[<?php
// non c'è alcuna classe/gestore per la cache specificato qui,
// modificare il codice con il gestore di cache in uso
$signal_file = '/home/test/.mail.last_change';
$mbox_basedir = '/home/test/mail/';
$cache_id = 'esempio di email in 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);
}

// fai qualcosa ...

$cache->set($cache_id, $mail);]]>
            </programlisting>

        </sect3>
        <sect3 id="zend.mail.read-advanced.extending">
            <title>Estensione delle classi dei protocolli</title>

            <para>
                I sistemi di salvataggio remoti utilizzano due classi: <code>Zend_Mail_Storage_&lt;Name&gt;</code> e <code>Zend_Mail_Protocol_&lt;Name&gt;</code>.
                La classe protocol traduce i comandi e le risposte da e in PHP, come ad esempio i metodi per i comandi o le variabili con strutture di dati differenti.
                L'altra classe principale implementa l'interfaccia comune.
            </para>

            <para>
                Per aggiungere ulteriori funzionalità ad un protocollo è possibile estendere la classe ed utilizzarla nel costruttore della classe principale.
                Per esempio si assuma di dover utilizzare una porta differente per aprire una connessione POP3.
            </para>

            <programlisting role="php"><![CDATA[<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Mail_Storage_Pop3');

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)
    {
        // nessuna connessione automatica in questa classe
        $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)
    {
        // ... verifica qui $params! ...
        $protocol = new Example_Mail_Protocol_Pop3_Knock($params['host']);

        // esegui i nostri comandi "speciali"
        foreach ((array)$params['knock_ports'] as $port) {
            $protocol->knock($port);
        }

        // recupera lo status corretto
        $protocol->connect($params['host'], $params['port']);
        $protocol->login($params['user'], $params['password']);

        // inizializza la classe genitore
        parent::__construct($protocol);
    }
}

$mail = new Example_Mail_Pop3_Knock(array('host'        => 'localhost',
                                          'user'        => 'test',
                                          'password'    => 'test',
                                          'knock_ports' => array(1101, 1105, 1111)));]]>
            </programlisting>

            <para>
                Come è possibile notare si suppone sempre di essere connessi, autenticati e, se supportato, una cartella è selezionata nel costruttore della classe principale.
                Quindi, se si assegna una classe protocollo personalizzata è necessario assicurarsi che tutto questo sia avvenuto correttamente o il metodo seguente non andrà a buon fine se il server non lo permette nello status corrente.
            </para>

        </sect3>
    </sect2>
</sect1>

<!--
vim:se ts=4 sw=4 et:
-->
