6.0.0-git
2024-04-25
Last Modified 2007-10-19 by Guest

How to use the MIME API

Creating MIME messages

Scenario: We have a text block (such as text/calendar data) which needs to be added as a MIME part to an email message. We then need to add a couple of additional headers to this message and finally read it back as a string.

For Message Body:


require_once 'Horde/MIME/Message.php';

$message = &new MIME_Message();

$part = $new MIME_Part('text/plain', $message_text);

$message->addPart($part);

For text/calendar attachment:


$part = &new MIME_Part('text/calendar', $text_calendar_data);

$message->addPart($part);

For Headers:


require_once 'Horde/MIME/Headers.php';

$headers = &new MIME_Headers();

$headers->addHeader('Header 1', $Header_1_Value);

$headers->addHeader('Header 2', $Header_2_Value);

$headers->addMIMEHeaders($message);

To return the message as a string:


$string = $headers->toString() . "\n\n" . $message->toString();

Creating and Sending E-Mail with an attachment by using MIME Mail


// Why this? I don't know! perhaps because using the HORDE BASE libs and there by get the mail_driver

@define('AUTH_HANDLER', true);

// Please find your horde base directory, absolute or relative its all up to you.

@define('HORDE_BASE', '/var/www/localhost/htdocs/horde/');

require_once HORDE_BASE . '/lib/base.php';

require_once HORDE_BASE . '/lib/version.php';

// This are the main library for this example

require_once 'Horde/MIME.php';

require_once 'Horde/MIME/Mail.php';

// Various variables for our mail

$email_to = 'a.guy.called.gerald@localhost';

$email_from = 'nobody@localhost';

$subject = 'Simple horde MIME Mail test';

$file_attachment = '/tmp/some_file.zip';

$body = "If you can read this and got the attached file, you are on good track with horde MIME library.";

// New MIME_Mail Object

$Mail = &new MIME_Mail();

// Set the header date

$Mail->addHeader('Date', date('r'));

// Set the from address

$Mail->addHeader('From', $email_from);

// Set the subject of the mail

$Mail->addHeader('Subject', $subject);

// Set the text message body

$Mail->setBody($body);

// Add the file as an attachment, set the file name and what kind of mime it is,

// Haven't tried this yet, but i assume that the two last parameters can be left out for automatic detection 

$Mail->addAttachment($file_attachment, 'some_file.zip', 'application/x-zip-compressed');

// Add a recipients

$Mail->addRecipients($email_to);

// Get the mail driver

$mail_driver = $conf['mailer']['type'];

$mail_params = $conf['mailer']['params'];

if ($mail_driver == 'smtp' && $mail_params['auth'] &&

    empty($mail_params['username'])) {

    if (Auth::getAuth()) {

        $mail_params['username'] = Auth::getAuth();

        $mail_params['password'] = Auth::getCredential('password');

    }

}

// Send the mail

if (!is_a($sent = $Mail->send($mail_driver, $mail_params), 'PEAR_Error')) {

    print "E-Mail sent\n";

} else {

    print "E-Mail not sent\n";

}

Parsing a MIME message

Scenario: We have an existing text string which contains a valid MIME email message. We need to parse this string in order to read back the body of a specific MIME part with a certain content type.


require_once 'Horde/MIME/Structure.php';

$message = &MIME_Structure::parseTextMIMEMessage($message_text);

$part = $message->getPart($mime_id);

To determine the structure of the MIME message, e.g. to find out the MIME ID we are looking for:


$map = $message->contentTypeMap();

$map is an array with key being the MIME IDs and values being the Content Types of that IDs.

Using MIME Viewers

Scenario: Continuing the previous example we want to render the text/calendar part to HTML. This code currently only works inside of a Horde application because it relies on the registry and Horde's configuration files.


require HORDE_BASE . '/config/mime_drivers.php';

require_once 'Horde/MIME/Viewer.php';

$viewer = &MIME_Viewer::factory($part);

$html = $viewer->render();

Reading message headers

Scenario: We want to read a certain message from a certain message on the mail server, for example to search for messages with a known header.


/* Load libraries. */

require_once 'Horde/MIME/Headers.php';

require_once 'Horde/NLS.php';

/* Custom MIME_Headers class because we need to implement _getStream(). */

class MyHeaders extends MIME_Headers {

    function &_getStream()

    {

        return imap_open('{localhost/imap}INBOX', 'username', 'password');

    }

}

/* Get message subject. */

$headers = &new MyHeaders($message_uid);

$headers->buildHeaders();

$subject = $headers->getValue('Subject');

Complete example script

This is a complete example script that parses all messages of an INBOX for any CSV attachments, extract these attachments from the messages, saves them in a folder, and deletes the parsed message. The script can also be downloaded from the AttachedFiles area of this page.


#!/usr/bin/php

<?php

/* IMAP/POP3 server settings. */

$imap_user = '';

$imap_pass = '';

$imap_host = 'localhost';

$imap_protocol = 'imap/notls';

/* Directory where the CSV attachments get stored WITH trailing slash. */

$target_dir = '/home/jan/csv/';

/* Search string for potential messages.

 * Might be optimized by using something like 'SUBJECT "Always the same"'. */

$imap_search = 'ALL';

/* Possible mime types of CSV attachments. */

$csv_mimetypes = array('text/plain',

                       'text/x-comma-separated-values',

                       'application/csv',

                       'application/vnd.ms-excel');

/* If necessary set the include path to the location where PEAR and the Horde

 * packages are installed. */

// ini_set('include_path', '/usr/share/php');

/****************************************************************************/

/**

 * Shows all IMAP errors and exits.

 */

function error_out()

{

    $errors = imap_errors();

    if ($errors) {

        foreach ($errors as $error) {

            echo $error . "\n";

        }

    }

    exit;

}

/* Load libraries. */

require_once 'Horde/CLI.php';

require_once 'Horde/MIME/Structure.php';

require_once 'Horde/MIME/Headers.php';

require_once 'Horde/NLS.php';

/* Setup CLI. */

if (!Horde_CLI::runningFromCLI()) {

    exit("Must be run from the command line\n");

}

Horde_CLI::init();

/* Custom MIME_Headers class. */

class MyHeaders extends MIME_Headers {

    function &_getStream()

    {

        return $GLOBALS['imap'];

    }

}

/* Open IMAP connection. */

$imap = imap_open(sprintf('{%s/%s}INBOX', $imap_host, $imap_protocol),

                  $imap_user, $imap_pass);

if (!$imap) {

    error_out();

}

/* Regexp for target filename. */

$regexp = '/_(\d+).csv$/';

/* Get all messages from the folder. */

$messages = imap_search($imap, $imap_search, FT_UID);

foreach ($messages as $uid) {

    $struct = imap_fetchstructure($imap, $uid, FT_UID);

    /* Is this no multipart message? */

    if ($struct->type != 1) {

        continue;

    }

    /* Parse message structure. */

    $body = imap_fetchheader($imap, $uid, FT_UID) .

            imap_body($imap, $uid, FT_UID);

    $message = &MIME_Structure::parseTextMIMEMessage($body);

    $map = $message->contentTypeMap();

    /* Search for message with possible CSV attachment. */

    foreach ($map as $mime_id => $mime_type) {

        if (!in_array($mime_type, $csv_mimetypes)) {

            continue;

        }

        $mime_part = $message->getPart($mime_id);

        $filename = $mime_part->getName(true);

        if (String::lower(substr($filename, -4)) != '.csv') {

            continue;

        }

        /* CSV file found. */

        $content = $mime_part->transferDecode();

        /* Get message subject. */

        $headers = &new MyHeaders($uid);

        $headers->buildHeaders();

        $subject = $headers->getValue('Subject');

        if (empty($subject)) {

            $subject = $filename;

        } else {

            $subject .= '.csv';

        }

        /* Find unique file name. */

        $filename = preg_replace('/[^a-z0-9_\-\.]/i', '_', $subject);

        while (file_exists($target_dir . $filename)) {

            if (preg_match($regexp, $filename, $match)) {

                $filename = preg_replace($regexp, '_' . ($match[1] + 1) . '.csv', $filename);

            } else {

                $filename = substr($filename, 0, -4) . '_1.csv';

            }

        }

        

        /* Write CSV file. */

        $fp = fopen($target_dir . $filename, 'w');

        if (!$fp) {

            exit("Can't open file '" . $target_dir . $filename . "' for writing.\n");

        }

        fwrite($fp, $content);

        fclose($fp);

        /* Delete message. */

        imap_delete($imap, $uid, FT_UID);

    }

}

/* Purge and close mailbox. */

// imap_expunge($imap);

imap_close($imap);

error_out();