Skip to content

Commit

Permalink
Fixed some issues, improved library and PHPUnit tests
Browse files Browse the repository at this point in the history
- Updated README
- Move phpunit to require-dev
- Add note about installing dev dependencies in README
- Replaced spaces with tabs
- Added PHPUnit tests for MIME decoding
- Updated formatting of PHPUnit function testParsedDateTimeWithEmptyHeaderDate()
- Issue #209: Function to parse datetime correctly RFC2822
- Issue #280: Added 'Sender' to headers and added additional if-conditions 
- Issue #115: getMail() method returns an object even for nonexistent mail ID
- Issue #273: Added connection check to example
- Issue #227: Added Failed-Recipients to IncomingMailHeader
- Issue #140, #246: Improved exception handling and added PHPUnit test
- Issue #140: Added PHPUnit test for testing ConnectionException
- Issue #140: Improved exception / error handling and improved / added PHPUnit tests
- Issue #154: Added ability to change the imap_search option from SE_UID to SE_FREE and added PHPUnit tests
- Issue #306: Added support for US-ASCII and added ability to disable serverEncoding for searchMailbox()
- Imported missing namespaces to avoid 'unknown class' error messages
- Issue #86: Simplified and improved one replace regex for attachment file names
- Issue #247: Improved grabbing of fromName, fromHost, senderName and senderHost
- Issue #39, #71, #229: Fixed body content gets incorrectly processed as attachments
- Issue #122, #150, #167: Added ability to skip processing of attachments to increase performance, when attachments are not required
- PR #284: Added missing PHPUnit tests
- Issue #122, #150, #167: Lazy load message text and attachments data
  • Loading branch information
Sebbo94BY committed May 5, 2019
2 parents 8c7c011 + 343531e commit ff84254
Show file tree
Hide file tree
Showing 9 changed files with 821 additions and 124 deletions.
88 changes: 81 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
[![Build Status](https://travis-ci.org/barbushin/php-imap.svg?branch=master)](https://travis-ci.org/barbushin/php-imap)
[![Supported PHP Version](https://img.shields.io/packagist/php-v/php-imap/php-imap/3.0.8.svg)](README.md)

Initially released in December 2012, the PHP IMAP Mailbox is a powerful and open source library to connect to a mailbox by POP3, IMAP and NNTP using the PHP IMAP extension. This library allows you to fetch emails from your email server. Extend the functionality or create powerful web applications to handle your incoming emails.

### Features

* Connect to mailbox by POP3/IMAP/NNTP, using [PHP IMAP extension](http://php.net/manual/book.imap.php)
Expand All @@ -22,32 +24,104 @@

### Installation by Composer

Install the [latest available release](https://github.com/barbushin/php-imap/releases):

$ composer require php-imap/php-imap


Install the latest available and stable source code from `master`, which is may not released / tagged yet:

$ composer require php-imap/php-imap

Install the latest available and may unstable source code from `develop`, which is may not properly tested yet:

$ composer require php-imap/php-imap:dev-develop

### PHPUnit Tests

You can run all PHPUnit tests by running the following command (inside of the installed `php-imap` directory): `php vendor/bin/phpunit --testdox`

Before you can run the PHPUnit tests you may need to run `composer install` to install all (development) dependencies.

### Integration with frameworks

* Symfony - https://github.com/secit-pl/imap-bundle

### Usage example
### Getting Started Example

Below, you'll find an example code how you can use this library. For further information and other examples, you may take a look at the [wiki](https://github.com/barbushin/php-imap/wiki).

```php
// 4. argument is the directory into which attachments are to be saved:
$mailbox = new PhpImap\Mailbox('{imap.gmail.com:993/imap/ssl}INBOX', 'some@gmail.com', '*********', __DIR__);
// Create PhpImap\Mailbox instance for all further actions
$mailbox = new PhpImap\Mailbox(
'{imap.gmail.com:993/imap/ssl}INBOX', // IMAP server and mailbox folder
'some@gmail.com', // Username for the before configured mailbox
'*********', // Password for the before configured username
__DIR__, // Directory, where attachments will be saved (optional)
'UTF-8' // Server encoding (optional)
);

try {
// Get all emails (messages)
// PHP.net imap_search criteria: http://php.net/manual/en/function.imap-search.php
$mailsIds = $mailbox->searchMailbox('ALL');
} catch(PhpImap\ConnectionException $ex) {
echo "IMAP connection failed: " . $ex;
die();
}

// Read all messaged into an array:
$mailsIds = $mailbox->searchMailbox('ALL');
// If $mailsIds is empty, no emails could be found
if(!$mailsIds) {
die('Mailbox is empty');
}

// Get the first message and save its attachment(s) to disk:
// Get the first message
// If '__DIR__' was defined in the first line, it will automatically
// save all attachments to the specified directory
$mail = $mailbox->getMail($mailsIds[0]);

// Print all information of $mail
print_r($mail);

// Print all attachements of $mail
echo "\n\nAttachments:\n";
print_r($mail->getAttachments());
```

Method imap() allows to call any imap function in a context of the the instance

```php
// Call imap_check();
// http://php.net/manual/en/function.imap-check.php
$info = $mailbox->imap('check'); //

// Show current time for the mailbox
$currentServerTime = isset($info->Date) && $info->Date ? date('Y-m-d H:i:s', strtotime($info->Date)) : 'Unknown';

echo $currentServerTime;
```

Some request require much time and resources:

```php
// If you don't need to grab attachments you can significantly increase performance of your application
$mailbox->setAttachmentsIgnore(true);

// get the list of folders/mailboxes
$folders = $mailbox->getMailboxes('*');

// loop through mailboxs
foreach($folders as $folder) {

// switch to particular mailbox
$mailbox->switchMailbox($folder['fullpath']);

// search in particular mailbox
$mails_ids[$folder['fullpath']] = $mailbox->searchMailbox('SINCE "1 Jan 2018" BEFORE "28 Jan 2018"');
}

print_r($mails_ids);
```

### Recommended

* Google Chrome extension [PHP Console](https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef)
Expand Down
58 changes: 58 additions & 0 deletions src/PhpImap/DataPartInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php namespace PhpImap;

/**
* @see https://github.com/barbushin/php-imap
* @author nickl- http://github.com/nickl-
*/
class DataPartInfo {

const TEXT_PLAIN = 0;
const TEXT_HTML = 1;

public $id;
public $encoding;
public $charset;
public $part;
public $mail;
public $options;
private $data;

public function __construct($mail, $id, $part, $encoding, $options) {
$this->mail = $mail;
$this->id = $id;
$this->part = $part;
$this->encoding = $encoding;
$this->options = $options;
}

function fetch() {
if(isset($this->data)) {
return $this->data;
}
if($this->part == 0) {
$this->data = $this->mail->imap('body', [$this->id, $this->options]);
}
else {
$this->data = $this->mail->imap('fetchbody', [$this->id, $this->part, $this->options]);
}
switch($this->encoding) {
case ENC8BIT:
$this->data = imap_utf8($this->data);
break;
case ENCBINARY:
$this->data = imap_binary($this->data);
break;
case ENCBASE64:
$this->data = preg_replace('~[^a-zA-Z0-9+=/]+~s', '', $this->data); // https://github.com/barbushin/php-imap/issues/88
$this->data = imap_base64($this->data);
break;
case ENCQUOTEDPRINTABLE:
$this->data = quoted_printable_decode($this->data);
break;
}
if(isset($this->charset)) {
$this->data = $this->mail->convertStringEncoding($this->data, $this->charset, $this->mail->getServerEncoding());
}
return $this->data;
}
}
10 changes: 10 additions & 0 deletions src/PhpImap/Exceptions/ConnectionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace PhpImap\Exceptions;

use Exception;

/**
* @see https://github.com/barbushin/php-imap
* @author Barbushin Sergey http://linkedin.com/in/barbushin
*/
class ConnectionException extends Exception {}
10 changes: 10 additions & 0 deletions src/PhpImap/Exceptions/InvalidParameterException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace PhpImap\Exceptions;

use Exception;

/**
* @see https://github.com/barbushin/php-imap
* @author Barbushin Sergey http://linkedin.com/in/barbushin
*/
class InvalidParameterException extends Exception {}
33 changes: 30 additions & 3 deletions src/PhpImap/IncomingMail.php
Original file line number Diff line number Diff line change
@@ -1,23 +1,50 @@
<?php namespace PhpImap;

use PhpImap\IncomingMailHeader;
use PhpImap\IncomingMailAttachment;

/**
* @see https://github.com/barbushin/php-imap
* @author Barbushin Sergey http://linkedin.com/in/barbushin
*
* @property-read string $textPlain lazy plain message body
* @property-read string $textHtml lazy html message body
*/
class IncomingMail extends IncomingMailHeader {

public $textPlain;
public $textHtml;
/** @var IncomingMailAttachment[] */
protected $attachments = array();
protected $dataInfo = array([],[]);

public function setHeader(IncomingMailHeader $header) {
foreach(get_object_vars($header) as $property => $value) {
$this->$property = $value;
}
}

public function addAttachment(IncomingMailAttachment $attachment) {
public function addDataPartInfo(DataPartInfo $dataInfo, $type) {
$this->dataInfo[$type][] = $dataInfo;
}

public function __get ($name) {
$type = false;
if($name == 'textPlain') {
$type = DataPartInfo::TEXT_PLAIN;
}
if($name == 'textHtml') {
$type = DataPartInfo::TEXT_HTML;
}
if(false === $type) {
trigger_error("Undefined property: IncomingMail::$name");
}
$this->$name = '';
foreach($this->dataInfo[$type] as $data) {
$this->$name .= trim($data->fetch());
}
return $this->$name;
}

public function addAttachment(IncomingMailAttachment $attachment) {
$this->attachments[$attachment->id] = $attachment;
}

Expand Down
37 changes: 36 additions & 1 deletion src/PhpImap/IncomingMailAttachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,47 @@
/**
* @see https://github.com/barbushin/php-imap
* @author Barbushin Sergey http://linkedin.com/in/barbushin
*
* @property-read string $filePath lazy attachment data file
*/
class IncomingMailAttachment {

public $id;
public $contentId;
public $name;
public $filePath;
public $disposition;
private $file_path;
private $dataInfo;

public function __get ($name) {
if($name !== 'filePath') {
trigger_error("Undefined property: IncomingMailAttachment::$name");
}

if(!isset($this->file_path)) {
return false;
}

$this->filePath = $this->file_path;

if(@file_exists($this->file_path)) {
return $this->filePath;
}

if(false === file_put_contents($this->filePath, $this->dataInfo->fetch())) {
unset($this->filePath);
unset($this->file_path);
return false;
}

return $this->filePath;
}

public function setFilePath($filePath) {
$this->file_path = $filePath;
}

public function addDataPartInfo(DataPartInfo $dataInfo) {
$this->dataInfo = $dataInfo;
}
}
7 changes: 6 additions & 1 deletion src/PhpImap/IncomingMailHeader.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ class IncomingMailHeader {
public $priority;
public $importance;
public $sensitivity;
public $autoSubmitted;
public $autoSubmitted;
public $precedence;
public $failedRecipients;
public $subject;

public $fromHost;
public $fromName;
public $fromAddress;
public $senderHost;
public $senderName;
public $senderAddress;

public $to = array();
public $toString;
Expand Down

0 comments on commit ff84254

Please sign in to comment.