ddeboer/imap

Object-oriented IMAP for PHP

1.0.7 2017-10-16 14:59 UTC

README

Build Status Scrutinizer Code Quality Code Coverage Latest Stable Version Total Downloads

A PHP 7.0+ library to read and process e-mails over IMAP.

This library requires IMAP, iconv and Multibyte String extensions installed.

Table of Contents

  1. Installation
  2. Usage
    1. Connect and Authenticate
    2. Mailboxes
    3. Messages
      1. Searching for Messages
      2. Message Properties and Operations
    4. Message Attachments
    5. Embedded Messages
  3. Mock the library
  4. Running the Tests

Installation

The recommended way to install the IMAP library is through Composer:

$ composer require ddeboer/imap

This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.

Usage

Connect and Authenticate

use Ddeboer\Imap\Server;

$server = new Server('imap.gmail.com');

// $connection is instance of \Ddeboer\Imap\Connection
$connection = $server->authenticate('my_username', 'my_password');

You can specify port, flags and parameters to the server:

$server = new Server(
    $hostname, // required
    $port,     // defaults to '993'
    $flags,    // defaults to '/imap/ssl/validate-cert'
    $parameters
);

Mailboxes

Retrieve mailboxes (also known as mail folders) from the mail server and iterate over them:

$mailboxes = $connection->getMailboxes();

foreach ($mailboxes as $mailbox) {
    // Skip container-only mailboxes
    // @see https://secure.php.net/manual/en/function.imap-getmailboxes.php
    if ($mailbox->getAttributes() & \LATT_NOSELECT) {
        continue;
    }

    // $mailbox is instance of \Ddeboer\Imap\Mailbox
    printf('Mailbox "%s" has %s messages', $mailbox->getName(), $mailbox->count());
}

Or retrieve a specific mailbox:

$mailbox = $connection->getMailbox('INBOX');

Delete a mailbox:

$connection->deleteMailbox($mailbox);

You can bulk set, or clear, any flag of mailbox messages (by UIDs):

$mailbox->setFlag('\\Seen \\Flagged', ['1:5', '7', '9']);
$mailbox->setFlag('\\Seen', '1,3,5,6:8');

$mailbox->clearFlag('\\Flagged', '1,3');

WARNING You must retrieve new Message instances in case of bulk modify flags to refresh the single Messages flags.

Messages

Retrieve messages (e-mails) from a mailbox and iterate over them:

$messages = $mailbox->getMessages();

foreach ($messages as $message) {
    // $message is instance of \Ddeboer\Imap\Message
}

Searching for Messages

use Ddeboer\Imap\SearchExpression;
use Ddeboer\Imap\Search\Email\To;
use Ddeboer\Imap\Search\Text\Body;

$search = new SearchExpression();
$search->addCondition(new To('me@here.com'));
$search->addCondition(new Body('contents'));

$messages = $mailbox->getMessages($search);

WARNING We are currently unable to have both spaces and double-quotes escaped together. Only spaces are currently escaped correctly. You can use Ddeboer\Imap\Search\RawExpression to write the complete search condition by yourself.

Messages can also be retrieved sorted as per imap_sort function:

$messages = $mailbox->getMessages(
    new Ddeboer\Imap\Search\LogicalOperator\All(),
    \SORTDATE, // Sort criteria
    true // Descending order
);

Message Properties and Operations

Get message number and unique message id in the form <...>:

$message->getNumber();
$message->getId();

Get other message properties:

$message->getSubject();
$message->getFrom();
$message->getTo();
$message->getDate();
$message->isAnswered();
$message->isDeleted();
$message->isDraft();
$message->isSeen();

Get message headers as a \Ddeboer\Imap\Message\Headers object:

$message->getHeaders();

Get message body as HTML or plain text:

$message->getBodyHtml();
$message->getBodyText();

Reading the message body keeps the message as unseen. If you want to mark the message as seen:

$message->maskAsSeen();

Or you can set, or clear, any flag:

$message->setFlag('\\Seen \\Flagged');
$message->clearFlag('\\Flagged');

Move a message to another mailbox:

$mailbox = $connection->getMailbox('another-mailbox');
$message->move($mailbox);
$connection->expunge();

Deleting messages:

$mailbox->getMessage(1)->delete();
$mailbox->getMessage(2)->delete();
$connection->expunge();

Message Attachments

Get message attachments (both inline and attached) and iterate over them:

$attachments = $message->getAttachments();

foreach ($attachments as $attachment) {
    // $attachment is instance of \Ddeboer\Imap\Message\Attachment
}

Download a message attachment to a local file:

// getDecodedContent() decodes the attachment’s contents automatically:
file_put_contents(
    '/my/local/dir/' . $attachment->getFilename(),
    $attachment->getDecodedContent()
);

Embedded Messages

Check if attachment is embedded message and get it:

$attachments = $message->getAttachments();

foreach ($attachments as $attachment) {
    if ($attachment->isEmbeddedMessage()) {
        $embeddedMessage = $attachment->getEmbeddedMessage();
        // $embeddedMessage is instance of \Ddeboer\Imap\Message\EmbeddedMessage
    }
}

An EmbeddedMessage has the same API as a normal Message, apart from flags and operations like copy, move or delete.

Mock the library

Mockability is granted by interfaces present for each API. Dig into MockabilityTest for an example of a mocked workflow.

Running the Tests

This library is functionally tested on Travis CI against a local Dovecot server.

If you have your own IMAP (test) account, you can run the tests locally by providing your IMAP credentials:

$ composer install
$ IMAP_SERVER_NAME="my.imap.server.com" IMAP_SERVER_PORT="60993" IMAP_USERNAME="johndoe" IMAP_PASSWORD="p4ssword" vendor/bin/phpunit

You can also copy phpunit.xml.dist file to a custom phpunit.xml and put these environment variables in it:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
    bootstrap="./vendor/autoload.php"
    colors="true"
    verbose="true"
>
    <testsuites>
        <testsuite name="ddeboer/imap">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist>
            <directory suffix=".php">./src</directory>
        </whitelist>
    </filter>
    <php>
        <env name="IMAP_SERVER_NAME" value="my.imap.server.com" />
        <env name="IMAP_SERVER_PORT" value="60993" />
        <env name="IMAP_USERNAME" value="johndoe" />
        <env name="IMAP_PASSWORD" value="p4ssword" />
    </php>
</phpunit>

WARNING Tests create new mailboxes without removing them.