Aus den Inhalten eines IMAP-Ordners eine HTML-Seite erstellen

Wie man mit den IMAP-Funktionen von php eine automatisch generierte HTML-Seite erstellt

Die Aufgabe

Nicht immer hat man Zugriff auf sein CMS, aber E-Mails verschicken kann man (fast) immer. Wäre es nicht nett, wenn man eine Seite erstellen könnte, die sich automatisch aus dem Inhalt eines bestimmten Postfach-Ordners generiert?

Wie es geht

Der Autor hat in den letzten Jahren z.B. 30 Einsendungen an die Sendung Genial daneben getätigt (von denen leider noch keine einzige angenommen wurde). Diese Mails liegen alle noch im Gesendet-Ordner und haben den Empfänger "fragen@genialdaneben.de".

Wir öffnen also den Ordner "Sent" und suchen nach allen E-Mails mit diesem Empfänger; daraus bauen wir uns unseren HTML-Content:

<?php
$folder = 'Sent';
$server = 'mail.example.com';
$user = 'Benutzername';
$port = '123';
$pass = '********';
$mail = 'fragen@genialdaneben.de';

$mbox = imap_open('{'."$server:$port/notls"."}$folder",$user,$pass);

# Suche nach Nachrichten
$search_arr = imap_search($mbox,'TO "'.$mail.'"');

# Array mit den gefundenen IDs zum Suchstring zusammenfügen
$search_list = join(',',$search_arr);

# und mit diesem String eine Übersicht holen
$result = imap_fetch_overview($mbox,"$search_list",0);

# wir haben nicht nach Datum absteigend sortieren lassen.
# Stattdessen sortieren wir das Array absteigend nach den Keys:
krsort($result);

# wir erstellen eine Linkliste mit den Subjects mit Sprungmarken:
$toc='<a name="toc"></a>
        <ul>';

$messages='';

$i=1;

foreach($result as $overview)
{
    # Manche Subjects sind encodiert, daher holen wir uns das Array
    $subject_arr = imap_mime_header_decode($overview->subject);

    $struct = imap_fetchstructure($mbox,$overview->msgno);

    # die Kodierungsinformationen stecken hier
    $parameters=$struct->parameters;

    # in den Parameters stehen nicht nur Kodierungsinfos, daher:
    foreach($parameters as $key => $val)
    {
        if('charset' == $val->attribute)
        {
            $encoding = $val->value;
        }
    }

    # Betreff ggf. zusammenfügen, falls enkodiert
    $subject = $subject_arr[0]->text.(''!=$subject_arr[1]->text?' '.$subject_arr[1]->text:'');

    # zur Linkliste hinzufügen
    $toc .= '<li><a href="#m'.$overview->msgno.'">'.$subject.'</a></li>';

    # Das Datum in Unix-Timestamp umwandeln ...
    $date_ux = strtotime($overview->date);

    # ... und wieder in einen lesbaren String:
    $date_str = date('d.m.Y',$date_ux);

    $messages.='
    <a name="m'.$overview->msgno.'"></a>
    <h2>'.
        "$i$subject ".'<span class="date">'.$date_str."</span>
    </h2>";

     $body = imap_body($mbox,$overview->msgno);

    if('UTF-8' == $encoding)
    {
        $body = utf8_decode($body);
    }

    # Signatur entfernen:
    $body = preg_replace("/^-- \r\n.*/ims",'',$body);

    $body = nl2br(htmlentities($body));

    $messages.='<p>'.$body.'</p>
        <a href="#toc">[^ nach oben]</a>';

    $i++;
}

$toc.='</ul>';

imap_close($mbox);

echo $toc;

echo $messages;

?>
</body>
</html>

Diskussion/Was fehlt

Attachment-Handling: Der Code ist so offen gehalten, dass man schnell Ordner und Empfänger wechseln kann. Allerdings rechnet der Code nicht mit Attachments! Sollten sich Anhänge an den gefundenen E-Mails befinden, werden die mit ausgegeben, was bei entsprechender Größe zu Ladeproblemen führen kann. Daher sollten entsprechend Routinen eingebaut werden, um die Attachments erst gar nicht zu laden (nach imap_fetchstructure() den Parameter parts prüfen und dann ggf. imap_bodystruct() verwenden!)

Caching/Ladezeiten: Die Seite lädt nicht sonderlich flott. Schlau wäre es, die Ergebnisse in eine Datei schreiben und nur bei Bedarf (wenn z.B. imap_search() neue Ergebnisse bringt) aktualisieren zu lassen.

Quellen

  1. PHP Manual: IMAP-Funktionen
    http://www.php.net/manual/de/ref.imap.php