email-configuration-bug-fix-patch

Installed "tedivm/fetch": "0.6.*" package to configure email fetcing.
This commit is contained in:
Manish Verma
2016-11-04 11:15:57 +05:30
parent 7fecdb1df9
commit 57efc24003
27 changed files with 2544 additions and 93 deletions

3
vendor/tedivm/fetch/.coveralls.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
src_dir: src
coverage_clover: build/logs/clover.xml
json_path: build/logs/coveralls-upload.json

9
vendor/tedivm/fetch/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
.vagrant
/.idea
/.settings
/.buildpath
/.project
/composer.lock
/vendor
/report
/build

21
vendor/tedivm/fetch/.travis.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- hhvm
before_script:
- composer self-update && composer install --dev
- vendor/tedivm/dovecottesting/SetupEnvironment.sh
script: ./tests/runTests.sh
after_script:
- php vendor/bin/coveralls -v
matrix:
allow_failures:
- php: hhvm

54
vendor/tedivm/fetch/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,54 @@
# Contributions Welcome!
Pull Requests and Community Contributions are the bread and butter of open source software. Every contribution- from bug
reports to feature requests, typos to full new features- are greatly appreciated.
## Important Guidelines
* One Item Per Pull Request or Issue. This makes it much easier to review code and merge it back in, and prevents issues
with one request from blocking another.
* Code Coverage is extremely important, and pull requests are much more likely to be accepted if testing is also improved.
New code should be properly tested, and all tests must pass.
* Read the LICENSE document and make sure you understand it, because your code is going to be released under it.
* Be prepared to make revisions. Don't be discouraged if you're asked to make changes, as that is just another step
towards refining the code and getting it merged back in.
* Remember to add the relevant documentation, particular the docblock comments.
## Code Styling
This project follows the PSR standards set forth by the [PHP Framework Interop Group](http://www.php-fig.org/).
* [PSR-0: Class and file naming conventions](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)
* [PSR-1: Basic coding standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)
* [PSR-2: Coding style guide](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
All code most follow these standards to be accepted. The easiest way to accomplish this is to run php-cs-fixer once the
new changes are finished. The php-cs-fixer package is installed as a development dependency of this project.
composer install --dev
vendor/bin/php-cs-fixer fix ./ --level="all" -vv
## Running the test suite
First install dependencies using Composer. It's important to include the dev packages:
composer install --dev
The "runTests.sh" script runs the full test suite- phpunit, php-cs-fixer, as well as any environmental setup:
tests/runTests.sh
To call phpunit directly:
vendor/bin/phpunit
To call php-cs-fixer directly:
vendor/bin/php-cs-fixer fix ./ --level="all" -vv --dry-run

24
vendor/tedivm/fetch/LICENSE vendored Normal file
View File

@@ -0,0 +1,24 @@
Copyright (c) 2009, Robert Hafner
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Stash Project nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Robert Hafner BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

63
vendor/tedivm/fetch/README.md vendored Normal file
View File

@@ -0,0 +1,63 @@
# Fetch [![Build Status](https://travis-ci.org/tedious/Fetch.svg?branch=master)](https://travis-ci.org/tedious/Fetch)
[![License](http://img.shields.io/packagist/l/tedivm/fetch.svg)](https://github.com/tedious/fetch/blob/master/LICENSE)
[![Latest Stable Version](http://img.shields.io/github/release/tedious/fetch.svg)](https://packagist.org/packages/tedivm/fetch)
[![Coverage Status](http://img.shields.io/coveralls/tedious/Fetch.svg)](https://coveralls.io/r/tedious/Fetch?branch=master)
[![Total Downloads](http://img.shields.io/packagist/dt/tedivm/fetch.svg)](https://packagist.org/packages/tedivm/fetch)
Fetch is a library for reading email and attachments, primarily using the POP
and IMAP protocols.
## Installing
### Composer
Installing Fetch can be done through a variety of methods, although Composer is
recommended.
Until Fetch reaches a stable API with version 1.0 it is recommended that you
review changes before even Minor updates, although bug fixes will always be
backwards compatible.
```
"require": {
"tedivm/fetch": "0.5.*"
}
```
### Pear
Fetch is also available through Pear.
```
$ pear channel-discover pear.tedivm.com
$ pear install tedivm/Fetch
```
### Github
Releases of Fetch are available on [Github](https://github.com/tedious/Fetch/releases).
## Sample Usage
This is just a simple code to show how to access messages by using Fetch. It uses Fetch
own autoload, but it can (and should be, if applicable) replaced with the one generated
by composer.
$server = new \Fetch\Server('imap.example.com', 993);
$server->setAuthentication('dummy', 'dummy');
$messages = $server->getMessages();
/** @var $message \Fetch\Message */
foreach ($messages as $message) {
echo "Subject: {$message->getSubject()}\nBody: {$message->getMessageBody()}\n";
}
## License
Fetch is licensed under the BSD License. See the LICENSE file for details.

25
vendor/tedivm/fetch/autoload.php vendored Normal file
View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Fetch package.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
spl_autoload_register(function ($class) {
$base = '/src/';
if (strpos($class, 'Fetch\Test') === 0) {
$base = '/tests/';
}
$file = __DIR__.$base.strtr($class, '\\', '/').'.php';
if (file_exists($file)) {
require $file;
return true;
}
});

28
vendor/tedivm/fetch/composer.json vendored Normal file
View File

@@ -0,0 +1,28 @@
{
"name": "tedivm/fetch",
"description": "A PHP IMAP Library",
"keywords": ["email","imap","pop3"],
"homepage": "http://github.com/tedious/Fetch",
"type": "library",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Robert Hafner",
"email": "tedivm@tedivm.com"
}
],
"require": {
"php": ">=5.3.0",
"ext-imap": "*"
},
"require-dev": {
"tedivm/dovecottesting": "1.2.3",
"phpunit/phpunit": "4.2.*",
"fabpot/php-cs-fixer": "0.5.*",
"satooshi/php-coveralls": "dev-master"
},
"autoload": {
"psr-0": {"Fetch": "src/"}
}
}

27
vendor/tedivm/fetch/phpunit.xml.dist vendored Normal file
View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="tests/bootstrap.php"
>
<testsuites>
<testsuite name="Fetch Test Suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src/Fetch/</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
</logging>
</phpunit>

View File

@@ -0,0 +1,231 @@
<?php
/*
* This file is part of the Fetch package.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Fetch;
/**
* This library is a wrapper around the Imap library functions included in php. This class wraps around an attachment
* in a message, allowing developers to easily save or display attachments.
*
* @package Fetch
* @author Robert Hafner <tedivm@tedivm.com>
*/
class Attachment
{
/**
* This is the structure object for the piece of the message body that the attachment is located it.
*
* @var \stdClass
*/
protected $structure;
/**
* This is the unique identifier for the message this attachment belongs to.
*
* @var int
*/
protected $messageId;
/**
* This is the ImapResource.
*
* @var resource
*/
protected $imapStream;
/**
* This is the id pointing to the section of the message body that contains the attachment.
*
* @var int
*/
protected $partId;
/**
* This is the attachments filename.
*
* @var string
*/
protected $filename;
/**
* This is the size of the attachment.
*
* @var int
*/
protected $size;
/**
* This stores the data of the attachment so it doesn't have to be retrieved from the server multiple times. It is
* only populated if the getData() function is called and should not be directly used.
*
* @internal
* @var array
*/
protected $data;
/**
* This function takes in an ImapMessage, the structure object for the particular piece of the message body that the
* attachment is located at, and the identifier for that body part. As a general rule you should not be creating
* instances of this yourself, but rather should get them from an ImapMessage class.
*
* @param Message $message
* @param \stdClass $structure
* @param string $partIdentifier
*/
public function __construct(Message $message, $structure, $partIdentifier = null)
{
$this->messageId = $message->getUid();
$this->imapStream = $message->getImapBox()->getImapStream();
$this->structure = $structure;
if (isset($partIdentifier))
$this->partId = $partIdentifier;
$parameters = Message::getParametersFromStructure($structure);
if (isset($parameters['filename'])) {
$this->filename = $parameters['filename'];
} elseif (isset($parameters['name'])) {
$this->filename = $parameters['name'];
}
$this->size = $structure->bytes;
$this->mimeType = Message::typeIdToString($structure->type);
if (isset($structure->subtype))
$this->mimeType .= '/' . strtolower($structure->subtype);
$this->encoding = $structure->encoding;
}
/**
* This function returns the data of the attachment. Combined with getMimeType() it can be used to directly output
* data to a browser.
*
* @return string
*/
public function getData()
{
if (!isset($this->data)) {
$messageBody = isset($this->partId) ?
imap_fetchbody($this->imapStream, $this->messageId, $this->partId, FT_UID)
: imap_body($this->imapStream, $this->messageId, FT_UID);
$messageBody = Message::decode($messageBody, $this->encoding);
$this->data = $messageBody;
}
return $this->data;
}
/**
* This returns the filename of the attachment, or false if one isn't given.
*
* @return string
*/
public function getFileName()
{
return (isset($this->filename)) ? $this->filename : false;
}
/**
* This function returns the mimetype of the attachment.
*
* @return string
*/
public function getMimeType()
{
return $this->mimeType;
}
/**
* This returns the size of the attachment.
*
* @return int
*/
public function getSize()
{
return $this->size;
}
/**
* This function returns the object that contains the structure of this attachment.
*
* @return \stdClass
*/
public function getStructure()
{
return $this->structure;
}
/**
* This function saves the attachment to the passed directory, keeping the original name of the file.
*
* @param string $path
* @return bool
*/
public function saveToDirectory($path)
{
$path = rtrim($path, '/') . '/';
if (is_dir($path))
return $this->saveAs($path . $this->getFileName());
return false;
}
/**
* This function saves the attachment to the exact specified location.
*
* @param string $path
* @return bool
*/
public function saveAs($path)
{
$dirname = dirname($path);
if (file_exists($path)) {
if (!is_writable($path)) {
return false;
}
} elseif (!is_dir($dirname) || !is_writable($dirname)) {
return false;
}
if (($filePointer = fopen($path, 'w')) == false) {
return false;
}
switch ($this->encoding) {
case 3: //base64
$streamFilter = stream_filter_append($filePointer, 'convert.base64-decode', STREAM_FILTER_WRITE);
break;
case 4: //quoted-printable
$streamFilter = stream_filter_append($filePointer, 'convert.quoted-printable-decode', STREAM_FILTER_WRITE);
break;
default:
$streamFilter = null;
}
$result = imap_savebody($this->imapStream, $filePointer, $this->messageId, $this->partId ?: 1, FT_UID);
if ($streamFilter) {
stream_filter_remove($streamFilter);
}
fclose($filePointer);
return $result;
}
}

View File

@@ -0,0 +1,738 @@
<?php
/*
* This file is part of the Fetch package.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Fetch;
use Exception;
/**
* This library is a wrapper around the Imap library functions included in php. This class represents a single email
* message as retrieved from the Imap.
*
* @package Fetch
* @author Robert Hafner <tedivm@tedivm.com>
*/
class Message
{
/**
* This is the connection/mailbox class that the email came from.
*
* @var Server
*/
protected $imapConnection;
/**
* This is the unique identifier for the message. This corresponds to the imap "uid", which we use instead of the
* sequence number.
*
* @var int
*/
protected $uid;
/**
* This is a reference to the Imap stream generated by 'imap_open'.
*
* @var resource
*/
protected $imapStream;
/**
* This as an object which contains header information for the message.
*
* @var \stdClass
*/
protected $headers;
/**
* This is an object which contains various status messages and other information about the message.
*
* @var \stdClass
*/
protected $messageOverview;
/**
* This is an object which contains information about the structure of the message body.
*
* @var \stdClass
*/
protected $structure;
/**
* This is an array with the index being imap flags and the value being a boolean specifying whether that flag is
* set or not.
*
* @var array
*/
protected $status = array();
/**
* This is an array of the various imap flags that can be set.
*
* @var string
*/
protected static $flagTypes = array('recent', 'flagged', 'answered', 'deleted', 'seen', 'draft');
/**
* This holds the plantext email message.
*
* @var string
*/
protected $plaintextMessage;
/**
* This holds the html version of the email.
*
* @var string
*/
protected $htmlMessage;
/**
* This is the date the email was sent.
*
* @var int
*/
protected $date;
/**
* This is the subject of the email.
*
* @var string
*/
protected $subject;
/**
* This is the size of the email.
*
* @var int
*/
protected $size;
/**
* This is an array containing information about the address the email came from.
*
* @var string
*/
protected $from;
/**
* This is an array containing information about the address the email was sent from.
*
* @var string
*/
protected $sender;
/**
* This is an array of arrays that contains information about the addresses the email was sent to.
*
* @var array
*/
protected $to;
/**
* This is an array of arrays that contains information about the addresses the email was cc'd to.
*
* @var array
*/
protected $cc;
/**
* This is an array of arrays that contains information about the addresses the email was bcc'd to.
*
* @var array
*/
protected $bcc;
/**
* This is an array of arrays that contain information about the addresses that should receive replies to the email.
*
* @var array
*/
protected $replyTo;
/**
* This is an array of ImapAttachments retrieved from the message.
*
* @var Attachment[]
*/
protected $attachments = array();
/**
* Contains the mailbox that the message resides in.
*
* @var string
*/
protected $mailbox;
/**
* This value defines the encoding we want the email message to use.
*
* @var string
*/
public static $charset = 'UTF-8';
/**
* This value defines the flag set for encoding if the mb_convert_encoding
* function can't be found, and in this case iconv encoding will be used.
*
* @var string
*/
public static $charsetFlag = '//TRANSLIT';
/**
* These constants can be used to easily access available flags
*/
const FLAG_RECENT = 'recent';
const FLAG_FLAGGED = 'flagged';
const FLAG_ANSWERED = 'answered';
const FLAG_DELETED = 'deleted';
const FLAG_SEEN = 'seen';
const FLAG_DRAFT = 'draft';
/**
* This constructor takes in the uid for the message and the Imap class representing the mailbox the
* message should be opened from. This constructor should generally not be called directly, but rather retrieved
* through the apprioriate Imap functions.
*
* @param int $messageUniqueId
* @param Server $mailbox
*/
public function __construct($messageUniqueId, Server $connection)
{
$this->imapConnection = $connection;
$this->mailbox = $connection->getMailBox();
$this->uid = $messageUniqueId;
$this->imapStream = $this->imapConnection->getImapStream();
if($this->loadMessage() !== true)
throw new \RuntimeException('Message with ID ' . $messageUniqueId . ' not found.');
}
/**
* This function is called when the message class is loaded. It loads general information about the message from the
* imap server.
*
*/
protected function loadMessage()
{
/* First load the message overview information */
if(!is_object($messageOverview = $this->getOverview()))
return false;
$this->subject = isset($messageOverview->subject) ? $messageOverview->subject : null;
$this->date = strtotime($messageOverview->date);
$this->size = $messageOverview->size;
foreach (self::$flagTypes as $flag)
$this->status[$flag] = ($messageOverview->$flag == 1);
/* Next load in all of the header information */
$headers = $this->getHeaders();
if (isset($headers->to))
$this->to = $this->processAddressObject($headers->to);
if (isset($headers->cc))
$this->cc = $this->processAddressObject($headers->cc);
if (isset($headers->bcc))
$this->bcc = $this->processAddressObject($headers->bcc);
if (isset($headers->sender))
$this->sender = $this->processAddressObject($headers->sender);
$this->from = isset($headers->from) ? $this->processAddressObject($headers->from) : array('');
$this->replyTo = isset($headers->reply_to) ? $this->processAddressObject($headers->reply_to) : $this->from;
/* Finally load the structure itself */
$structure = $this->getStructure();
if (!isset($structure->parts)) {
// not multipart
$this->processStructure($structure);
} else {
// multipart
foreach ($structure->parts as $id => $part)
$this->processStructure($part, $id + 1);
}
return true;
}
/**
* This function returns an object containing information about the message. This output is similar to that over the
* imap_fetch_overview function, only instead of an array of message overviews only a single result is returned. The
* results are only retrieved from the server once unless passed true as a parameter.
*
* @param bool $forceReload
* @return \stdClass
*/
public function getOverview($forceReload = false)
{
if ($forceReload || !isset($this->messageOverview)) {
// returns an array, and since we just want one message we can grab the only result
$results = imap_fetch_overview($this->imapStream, $this->uid, FT_UID);
$this->messageOverview = array_shift($results);
if ( ! isset($this->messageOverview->date)) {
$this->messageOverview->date = null;
}
}
return $this->messageOverview;
}
/**
* This function returns an object containing the headers of the message. This is done by taking the raw headers
* and running them through the imap_rfc822_parse_headers function. The results are only retrieved from the server
* once unless passed true as a parameter.
*
* @param bool $forceReload
* @return \stdClass
*/
public function getHeaders($forceReload = false)
{
if ($forceReload || !isset($this->headers)) {
// raw headers (since imap_headerinfo doesn't use the unique id)
$rawHeaders = imap_fetchheader($this->imapStream, $this->uid, FT_UID);
// convert raw header string into a usable object
$headerObject = imap_rfc822_parse_headers($rawHeaders);
// to keep this object as close as possible to the original header object we add the udate property
if (isset($headerObject->date)) {
$headerObject->udate = strtotime($headerObject->date);
} else {
$headerObject->date = null;
$headerObject->udate = null;
}
$this->headers = $headerObject;
}
return $this->headers;
}
/**
* This function returns an object containing the structure of the message body. This is the same object thats
* returned by imap_fetchstructure. The results are only retrieved from the server once unless passed true as a
* parameter.
*
* @param bool $forceReload
* @return \stdClass
*/
public function getStructure($forceReload = false)
{
if ($forceReload || !isset($this->structure)) {
$this->structure = imap_fetchstructure($this->imapStream, $this->uid, FT_UID);
}
return $this->structure;
}
/**
* This function returns the message body of the email. By default it returns the plaintext version. If a plaintext
* version is requested but not present, the html version is stripped of tags and returned. If the opposite occurs,
* the plaintext version is given some html formatting and returned. If neither are present the return value will be
* false.
*
* @param bool $html Pass true to receive an html response.
* @return string|bool Returns false if no body is present.
*/
public function getMessageBody($html = false)
{
if ($html) {
if (!isset($this->htmlMessage) && isset($this->plaintextMessage)) {
$output = nl2br($this->plaintextMessage);
return $output;
} elseif (isset($this->htmlMessage)) {
return $this->htmlMessage;
}
} else {
if (!isset($this->plaintextMessage) && isset($this->htmlMessage)) {
$output = preg_replace('/\<br(\s*)?\/?\>/i', PHP_EOL, trim($this->htmlMessage) );
$output = strip_tags($output);
return $output;
} elseif (isset($this->plaintextMessage)) {
return $this->plaintextMessage;
}
}
return false;
}
/**
* This function returns either an array of email addresses and names or, optionally, a string that can be used in
* mail headers.
*
* @param string $type Should be 'to', 'cc', 'bcc', 'from', 'sender', or 'reply-to'.
* @param bool $asString
* @return array|string|bool
*/
public function getAddresses($type, $asString = false)
{
$type = ( $type == 'reply-to' ) ? 'replyTo' : $type;
$addressTypes = array('to', 'cc', 'bcc', 'from', 'sender', 'replyTo');
if (!in_array($type, $addressTypes) || !isset($this->$type) || count($this->$type) < 1)
return false;
if (!$asString) {
if ($type == 'from')
return $this->from[0];
elseif ($type == 'sender')
return $this->sender[0];
return $this->$type;
} else {
$outputString = '';
foreach ($this->$type as $address) {
if (isset($set))
$outputString .= ', ';
if (!isset($set))
$set = true;
$outputString .= isset($address['name']) ?
$address['name'] . ' <' . $address['address'] . '>'
: $address['address'];
}
return $outputString;
}
}
/**
* This function returns the date, as a timestamp, of when the email was sent.
*
* @return int
*/
public function getDate()
{
return isset($this->date) ? $this->date : false;
}
/**
* This returns the subject of the message.
*
* @return string
*/
public function getSubject()
{
return isset($this->subject) ? $this->subject : null;
}
/**
* This function marks a message for deletion. It is important to note that the message will not be deleted form the
* mailbox until the Imap->expunge it run.
*
* @return bool
*/
public function delete()
{
return imap_delete($this->imapStream, $this->uid, FT_UID);
}
/**
* This function returns Imap this message came from.
*
* @return Server
*/
public function getImapBox()
{
return $this->imapConnection;
}
/**
* This function takes in a structure and identifier and processes that part of the message. If that portion of the
* message has its own subparts, those are recursively processed using this function.
*
* @param \stdClass $structure
* @param string $partIdentifier
*/
protected function processStructure($structure, $partIdentifier = null)
{
$parameters = self::getParametersFromStructure($structure);
if ((isset($parameters['name']) || isset($parameters['filename']))
|| (isset($structure->subtype) && strtolower($structure->subtype) == 'rfc822')
) {
$attachment = new Attachment($this, $structure, $partIdentifier);
$this->attachments[] = $attachment;
} elseif ($structure->type == 0 || $structure->type == 1) {
$messageBody = isset($partIdentifier) ?
imap_fetchbody($this->imapStream, $this->uid, $partIdentifier, FT_UID)
: imap_body($this->imapStream, $this->uid, FT_UID);
$messageBody = self::decode($messageBody, $structure->encoding);
if (!empty($parameters['charset']) && $parameters['charset'] !== self::$charset) {
$mb_converted = false;
if (function_exists('mb_convert_encoding')) {
try {
$messageBody = mb_convert_encoding($messageBody, self::$charset, $parameters['charset']);
$mb_converted = true;
} catch (Exception $e) {
// @TODO Handle exception
}
}
if (!$mb_converted) {
try {
$messageBody = iconv($parameters['charset'], self::$charset . self::$charsetFlag, $messageBody);
} catch (Exception $e) {
// @TODO Handle exception
}
}
}
if (strtolower($structure->subtype) === 'plain' || ($structure->type == 1 && strtolower($structure->subtype) !== 'alternative')) {
if (isset($this->plaintextMessage)) {
$this->plaintextMessage .= PHP_EOL . PHP_EOL;
} else {
$this->plaintextMessage = '';
}
$this->plaintextMessage .= trim($messageBody);
} elseif (strtolower($structure->subtype) === 'html') {
if (isset($this->htmlMessage)) {
$this->htmlMessage .= '<br><br>';
} else {
$this->htmlMessage = '';
}
$this->htmlMessage .= $messageBody;
}
}
if (isset($structure->parts)) { // multipart: iterate through each part
foreach ($structure->parts as $partIndex => $part) {
$partId = $partIndex + 1;
if (isset($partIdentifier))
$partId = $partIdentifier . '.' . $partId;
$this->processStructure($part, $partId);
}
}
}
/**
* This function takes in the message data and encoding type and returns the decoded data.
*
* @param string $data
* @param int|string $encoding
* @return string
*/
public static function decode($data, $encoding)
{
if (!is_numeric($encoding)) {
$encoding = strtolower($encoding);
}
switch (true) {
case $encoding === 'quoted-printable':
case $encoding === 4:
return quoted_printable_decode($data);
case $encoding === 'base64':
case $encoding === 3:
return base64_decode($data);
default:
return $data;
}
}
/**
* This function returns the body type that an imap integer maps to.
*
* @param int $id
* @return string
*/
public static function typeIdToString($id)
{
switch ($id) {
case 0:
return 'text';
case 1:
return 'multipart';
case 2:
return 'message';
case 3:
return 'application';
case 4:
return 'audio';
case 5:
return 'image';
case 6:
return 'video';
default:
case 7:
return 'other';
}
}
/**
* Takes in a section structure and returns its parameters as an associative array.
*
* @param \stdClass $structure
* @return array
*/
public static function getParametersFromStructure($structure)
{
$parameters = array();
if (isset($structure->parameters))
foreach ($structure->parameters as $parameter)
$parameters[strtolower($parameter->attribute)] = $parameter->value;
if (isset($structure->dparameters))
foreach ($structure->dparameters as $parameter)
$parameters[strtolower($parameter->attribute)] = $parameter->value;
return $parameters;
}
/**
* This function takes in an array of the address objects generated by the message headers and turns them into an
* associative array.
*
* @param array $addresses
* @return array
*/
protected function processAddressObject($addresses)
{
$outputAddresses = array();
if (is_array($addresses))
foreach ($addresses as $address) {
$currentAddress = array();
$currentAddress['address'] = $address->mailbox . '@' . $address->host;
if (isset($address->personal))
$currentAddress['name'] = $address->personal;
$outputAddresses[] = $currentAddress;
}
return $outputAddresses;
}
/**
* This function returns the unique id that identifies the message on the server.
*
* @return int
*/
public function getUid()
{
return $this->uid;
}
/**
* This function returns the attachments a message contains. If a filename is passed then just that ImapAttachment
* is returned, unless
*
* @param null|string $filename
* @return array|bool|Attachment[]
*/
public function getAttachments($filename = null)
{
if (!isset($this->attachments) || count($this->attachments) < 1)
return false;
if (!isset($filename))
return $this->attachments;
$results = array();
foreach ($this->attachments as $attachment) {
if ($attachment->getFileName() == $filename)
$results[] = $attachment;
}
switch (count($results)) {
case 0:
return false;
case 1:
return array_shift($results);
default:
return $results;
break;
}
}
/**
* This function checks to see if an imap flag is set on the email message.
*
* @param string $flag Recent, Flagged, Answered, Deleted, Seen, Draft
* @return bool
*/
public function checkFlag($flag = 'flagged')
{
return (isset($this->status[$flag]) && $this->status[$flag] === true);
}
/**
* This function is used to enable or disable a flag on the imap message.
*
* @param string $flag Flagged, Answered, Deleted, Seen, Draft
* @param bool $enable
* @throws \InvalidArgumentException
* @return bool
*/
public function setFlag($flag, $enable = true)
{
if (!in_array($flag, self::$flagTypes) || $flag == 'recent')
throw new \InvalidArgumentException('Unable to set invalid flag "' . $flag . '"');
$imapifiedFlag = '\\' . ucfirst($flag);
if ($enable === true) {
$this->status[$flag] = true;
return imap_setflag_full($this->imapStream, $this->uid, $imapifiedFlag, ST_UID);
} else {
unset($this->status[$flag]);
return imap_clearflag_full($this->imapStream, $this->uid, $imapifiedFlag, ST_UID);
}
}
/**
* This function is used to move a mail to the given mailbox.
*
* @param $mailbox
*
* @return bool
*/
public function moveToMailBox($mailbox)
{
$currentBox = $this->imapConnection->getMailBox();
$this->imapConnection->setMailBox($this->mailbox);
$returnValue = imap_mail_copy($this->imapStream, $this->uid, $mailbox, CP_UID | CP_MOVE);
imap_expunge($this->imapStream);
$this->mailbox = $mailbox;
$this->imapConnection->setMailBox($currentBox);
return $returnValue;
}
}

458
vendor/tedivm/fetch/src/Fetch/Server.php vendored Normal file
View File

@@ -0,0 +1,458 @@
<?php
/*
* This file is part of the Fetch package.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Fetch;
/**
* This library is a wrapper around the Imap library functions included in php. This class in particular manages a
* connection to the server (imap, pop, etc) and allows for the easy retrieval of stored messages.
*
* @package Fetch
* @author Robert Hafner <tedivm@tedivm.com>
*/
class Server
{
/**
* When SSL isn't compiled into PHP we need to make some adjustments to prevent soul crushing annoyances.
*
* @var bool
*/
public static $sslEnable = true;
/**
* These are the flags that depend on ssl support being compiled into imap.
*
* @var array
*/
public static $sslFlags = array('ssl', 'validate-cert', 'novalidate-cert', 'tls', 'notls');
/**
* This is used to prevent the class from putting up conflicting tags. Both directions- key to value, value to key-
* are checked, so if "novalidate-cert" is passed then "validate-cert" is removed, and vice-versa.
*
* @var array
*/
public static $exclusiveFlags = array('validate-cert' => 'novalidate-cert', 'tls' => 'notls');
/**
* This is the domain or server path the class is connecting to.
*
* @var string
*/
protected $serverPath;
/**
* This is the name of the current mailbox the connection is using.
*
* @var string
*/
protected $mailbox = '';
/**
* This is the username used to connect to the server.
*
* @var string
*/
protected $username;
/**
* This is the password used to connect to the server.
*
* @var string
*/
protected $password;
/**
* This is an array of flags that modify how the class connects to the server. Examples include "ssl" to enforce a
* secure connection or "novalidate-cert" to allow for self-signed certificates.
*
* @link http://us.php.net/manual/en/function.imap-open.php
* @var array
*/
protected $flags = array();
/**
* This is the port used to connect to the server
*
* @var int
*/
protected $port;
/**
* This is the set of options, represented by a bitmask, to be passed to the server during connection.
*
* @var int
*/
protected $options = 0;
/**
* This is the resource connection to the server. It is required by a number of imap based functions to specify how
* to connect.
*
* @var resource
*/
protected $imapStream;
/**
* This is the name of the service currently being used. Imap is the default, although pop3 and nntp are also
* options
*
* @var string
*/
protected $service = 'imap';
/**
* This constructor takes the location and service thats trying to be connected to as its arguments.
*
* @param string $serverPath
* @param null|int $port
* @param null|string $service
*/
public function __construct($serverPath, $port = 143, $service = 'imap')
{
$this->serverPath = $serverPath;
$this->port = $port;
switch ($port) {
case 143:
$this->setFlag('novalidate-cert');
break;
case 993:
$this->setFlag('ssl');
break;
}
$this->service = $service;
}
/**
* This function sets the username and password used to connect to the server.
*
* @param string $username
* @param string $password
*/
public function setAuthentication($username, $password)
{
$this->username = $username;
$this->password = $password;
}
/**
* This function sets the mailbox to connect to.
*
* @param string $mailbox
* @return bool
*/
public function setMailBox($mailbox = '')
{
if (!$this->hasMailBox($mailbox)) {
return false;
}
$this->mailbox = $mailbox;
if (isset($this->imapStream)) {
$this->setImapStream();
}
return true;
}
public function getMailBox()
{
return $this->mailbox;
}
/**
* This function sets or removes flag specifying connection behavior. In many cases the flag is just a one word
* deal, so the value attribute is not required. However, if the value parameter is passed false it will clear that
* flag.
*
* @param string $flag
* @param null|string|bool $value
*/
public function setFlag($flag, $value = null)
{
if (!self::$sslEnable && in_array($flag, self::$sslFlags))
return;
if (isset(self::$exclusiveFlags[$flag])) {
$kill = self::$exclusiveFlags[$flag];
} elseif ($index = array_search($flag, self::$exclusiveFlags)) {
$kill = $index;
}
if (isset($kill) && false !== $index = array_search($kill, $this->flags))
unset($this->flags[$index]);
$index = array_search($flag, $this->flags);
if (isset($value) && $value !== true) {
if ($value == false && $index !== false) {
unset($this->flags[$index]);
} elseif ($value != false) {
$match = preg_grep('/' . $flag . '/', $this->flags);
if (reset($match)) {
$this->flags[key($match)] = $flag . '=' . $value;
} else {
$this->flags[] = $flag . '=' . $value;
}
}
} elseif ($index === false) {
$this->flags[] = $flag;
}
}
/**
* This funtion is used to set various options for connecting to the server.
*
* @param int $bitmask
* @throws \Exception
*/
public function setOptions($bitmask = 0)
{
if (!is_numeric($bitmask))
throw new \RuntimeException('Function requires numeric argument.');
$this->options = $bitmask;
}
/**
* This function gets the current saved imap resource and returns it.
*
* @return resource
*/
public function getImapStream()
{
if (!isset($this->imapStream))
$this->setImapStream();
return $this->imapStream;
}
/**
* This function takes in all of the connection date (server, port, service, flags, mailbox) and creates the string
* thats passed to the imap_open function.
*
* @return string
*/
public function getServerString()
{
$mailboxPath = $this->getServerSpecification();
if (isset($this->mailbox))
$mailboxPath .= $this->mailbox;
return $mailboxPath;
}
/**
* Returns the server specification, without adding any mailbox.
*
* @return string
*/
protected function getServerSpecification()
{
$mailboxPath = '{' . $this->serverPath;
if (isset($this->port))
$mailboxPath .= ':' . $this->port;
if ($this->service != 'imap')
$mailboxPath .= '/' . $this->service;
foreach ($this->flags as $flag) {
$mailboxPath .= '/' . $flag;
}
$mailboxPath .= '}';
return $mailboxPath;
}
/**
* This function creates or reopens an imapStream when called.
*
*/
protected function setImapStream()
{
if (isset($this->imapStream)) {
if (!imap_reopen($this->imapStream, $this->getServerString(), $this->options, 1))
throw new \RuntimeException(imap_last_error());
} else {
$imapStream = imap_open($this->getServerString(), $this->username, $this->password, $this->options, 1);
if ($imapStream === false)
throw new \RuntimeException(imap_last_error());
$this->imapStream = $imapStream;
}
}
/**
* This returns the number of messages that the current mailbox contains.
*
* @return int
*/
public function numMessages()
{
return imap_num_msg($this->getImapStream());
}
/**
* This function returns an array of ImapMessage object for emails that fit the criteria passed. The criteria string
* should be formatted according to the imap search standard, which can be found on the php "imap_search" page or in
* section 6.4.4 of RFC 2060
*
* @link http://us.php.net/imap_search
* @link http://www.faqs.org/rfcs/rfc2060
* @param string $criteria
* @param null|int $limit
* @return array An array of ImapMessage objects
*/
public function search($criteria = 'ALL', $limit = null)
{
if ($results = imap_search($this->getImapStream(), $criteria, SE_UID)) {
if (isset($limit) && count($results) > $limit)
$results = array_slice($results, 0, $limit);
$messages = array();
foreach ($results as $messageId)
$messages[] = new Message($messageId, $this);
return $messages;
} else {
return array();
}
}
/**
* This function returns the recently received emails as an array of ImapMessage objects.
*
* @param null|int $limit
* @return array An array of ImapMessage objects for emails that were recently received by the server.
*/
public function getRecentMessages($limit = null)
{
return $this->search('Recent', $limit);
}
/**
* Returns the emails in the current mailbox as an array of ImapMessage objects.
*
* @param null|int $limit
* @return Message[]
*/
public function getMessages($limit = null)
{
$numMessages = $this->numMessages();
if (isset($limit) && is_numeric($limit) && $limit < $numMessages)
$numMessages = $limit;
if ($numMessages < 1)
return array();
$stream = $this->getImapStream();
$messages = array();
for ($i = 1; $i <= $numMessages; $i++) {
$uid = imap_uid($stream, $i);
$messages[] = new Message($uid, $this);
}
return $messages;
}
/**
* Returns the emails in the current mailbox as an array of ImapMessage objects
* ordered by some ordering
*
* @see http://php.net/manual/en/function.imap-sort.php
* @param int $orderBy
* @param bool $reverse
* @param int $limit
* @return Message[]
*/
public function getOrderedMessages($orderBy, $reverse, $limit)
{
$msgIds = imap_sort($this->getImapStream(), $orderBy, $reverse ? 1 : 0, SE_UID);
return array_map(array($this, 'getMessageByUid'), array_slice($msgIds, 0, $limit));
}
/**
* Returns the requested email or false if it is not found.
*
* @param int $uid
* @return Message|bool
*/
public function getMessageByUid($uid)
{
try {
$message = new \Fetch\Message($uid, $this);
return $message;
} catch (\Exception $e) {
return false;
}
}
/**
* This function removes all of the messages flagged for deletion from the mailbox.
*
* @return bool
*/
public function expunge()
{
return imap_expunge($this->getImapStream());
}
/**
* Checks if the given mailbox exists.
*
* @param $mailbox
*
* @return bool
*/
public function hasMailBox($mailbox)
{
return (boolean) imap_getmailboxes(
$this->getImapStream(),
$this->getServerString(),
$this->getServerSpecification() . $mailbox
);
}
/**
* Creates the given mailbox.
*
* @param $mailbox
*
* @return bool
*/
public function createMailBox($mailbox)
{
return imap_createmailbox($this->getImapStream(), $this->getServerSpecification() . $mailbox);
}
/**
* List available mailboxes
*
* @param string $pattern
*
* @return array
*/
public function listMailBoxes($pattern = '*')
{
return imap_list($this->getImapStream(), $this->getServerSpecification(), $pattern);
}
}

View File

@@ -0,0 +1,118 @@
<?php
/*
* This file is part of the Fetch library.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Fetch\Test;
/**
* @package Fetch
* @author Robert Hafner <tedivm@tedivm.com>
*/
class AttachmentTest extends \PHPUnit_Framework_TestCase
{
public static function getAttachments($MessageId)
{
$server = ServerTest::getServer();
$message = new \Fetch\Message($MessageId, $server);
$attachments = $message->getAttachments();
$returnAttachments = array();
foreach($attachments as $attachment)
$returnAttachments[$attachment->getFileName()] = $attachment;
return $returnAttachments;
}
public function testGetData()
{
$attachments = static::getAttachments('6');
$attachment_RCA = $attachments['RCA_Indian_Head_test_pattern.JPG.zip'];
$md5_RCA = '3e9b6f02551590a7bcfff5d50b5b7b20';
$this->assertEquals($md5_RCA, md5($attachment_RCA->getData()));
$attachment_TestCard = $attachments['Test_card.png.zip'];
$md5_TestCard = '94c40bd83fbfa03b29bf1811f9aaccea';
$this->assertEquals($md5_TestCard, md5($attachment_TestCard->getData()));
}
public function testGetMimeType()
{
$attachments = static::getAttachments('6');
$attachment_RCA = $attachments['RCA_Indian_Head_test_pattern.JPG.zip'];
$mimetype_RCA = 'application/zip';
$this->assertEquals($mimetype_RCA, $attachment_RCA->getMimeType());
$attachment_TestCard = $attachments['Test_card.png.zip'];
$mimetype_TestCard = 'application/zip';
$this->assertEquals($mimetype_TestCard, $attachment_TestCard->getMimeType());
}
public function testGetSize()
{
$attachments = static::getAttachments('6');
$attachment_RCA = $attachments['RCA_Indian_Head_test_pattern.JPG.zip'];
$size_RCA = 378338;
$this->assertEquals($size_RCA, $attachment_RCA->getSize());
$attachment_TestCard = $attachments['Test_card.png.zip'];
$size_TestCard = 32510;
$this->assertEquals($size_TestCard, $attachment_TestCard->getSize());
}
public function testGetStructure()
{
$attachments = static::getAttachments('6');
$attachment_RCA = $attachments['RCA_Indian_Head_test_pattern.JPG.zip'];
$structure_RCA = $attachment_RCA->getStructure();
$this->assertObjectHasAttribute('type', $structure_RCA);
$this->assertEquals(3, $structure_RCA->type);
$this->assertObjectHasAttribute('subtype', $structure_RCA);
$this->assertEquals('ZIP', $structure_RCA->subtype);
$this->assertObjectHasAttribute('bytes', $structure_RCA);
$this->assertEquals(378338, $structure_RCA->bytes);
}
public function testSaveToDirectory()
{
$attachments = static::getAttachments('6');
$attachment_RCA = $attachments['RCA_Indian_Head_test_pattern.JPG.zip'];
$tmpdir = rtrim(sys_get_temp_dir(), '/') . '/';
$filepath = $tmpdir . 'RCA_Indian_Head_test_pattern.JPG.zip';
$this->assertTrue($attachment_RCA->saveToDirectory($tmpdir));
$this->assertFileExists($filepath);
$this->assertEquals(md5(file_get_contents($filepath)), md5($attachment_RCA->getData()));
$attachments = static::getAttachments('6');
$attachment_RCA = $attachments['RCA_Indian_Head_test_pattern.JPG.zip'];
$this->assertFalse($attachment_RCA->saveToDirectory('/'), 'Returns false when attempting to save without filesystem permission.');
$attachments = static::getAttachments('6');
$attachment_RCA = $attachments['RCA_Indian_Head_test_pattern.JPG.zip'];
$this->assertFalse($attachment_RCA->saveToDirectory($filepath), 'Returns false when attempting to save over a file.');
}
public static function tearDownAfterClass()
{
$tmpdir = rtrim(sys_get_temp_dir(), '/') . '/';
$filepath = $tmpdir . 'RCA_Indian_Head_test_pattern.JPG.zip';
unlink($filepath);
}
}

View File

@@ -0,0 +1,252 @@
<?php
/*
* This file is part of the Fetch library.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Fetch\Test;
use Fetch\Message;
/**
* @package Fetch
* @author Robert Hafner <tedivm@tedivm.com>
*/
class MessageTest extends \PHPUnit_Framework_TestCase
{
public static function getMessage($id)
{
$server = ServerTest::getServer();
return new \Fetch\Message($id, $server);
}
public function testConstructMessage()
{
$message = static::getMessage(3);
$this->assertInstanceOf('\Fetch\Message', $message);
}
public function testGetOverview()
{
$message = static::getMessage(3);
$overview = $message->getOverview();
$this->assertEquals('Welcome', $overview->subject, 'Subject available from overview');
$this->assertEquals('tedivm@tedivm.com', $overview->from, 'From available from overview');
$this->assertEquals('testuser@tedivm.com', $overview->to, 'To available from overview');
$this->assertEquals(1465, $overview->size, 'Size available from overview');
$this->assertEquals(0, $overview->flagged, 'Flagged available from overview');
$this->assertEquals(1, $overview->seen, 'Seen available from overview');
}
public function testGetHeaders()
{
$message = static::getMessage(3);
$headers = $message->getHeaders();
$this->assertEquals('Sun, 1 Dec 2013 21:14:03 -0800 (PST)', $headers->date, 'Headers contain the right date.');
$this->assertEquals('testuser@tedivm.com', $headers->toaddress, 'Headers contain toaddress.');
$this->assertEquals('tedivm@tedivm.com', $headers->fromaddress, 'Headers contain fromaddress');
}
public function testGetStructure()
{
}
public function testGetMessageBody()
{
// easiest way to deal with php encoding issues is simply not to.
$plaintextTest = 'f9377a89c9c935463a2b35c92dd61042';
$convertedHtmlTest = '11498bcf191900d634ff8772a64ca523';
$pureHtmlTest = '6a366ddecf080199284146d991d52169';
$message = static::getMessage(3);
$messageNonHTML = $message->getMessageBody();
$this->assertEquals($plaintextTest, md5($messageNonHTML), 'Message returns as plaintext.');
$messageHTML = $message->getMessageBody(true);
$this->assertEquals($convertedHtmlTest, md5($messageHTML), 'Message converts from plaintext to HTML when requested.');
$message = static::getMessage(4);
$messageHTML = $message->getMessageBody(true);
$this->assertEquals($pureHtmlTest, md5($messageHTML), 'Message returns as HTML.');
}
public function testGetAddresses()
{
$message = static::getMessage(3);
$addresses = $message->getAddresses('to');
$this->assertEquals('testuser@tedivm.com', $addresses[0]['address'], 'Retrieving to user from address array.');
$addressString = $message->getAddresses('to', true);
$this->assertEquals('testuser@tedivm.com', $addressString, 'Returning To address as string.');
$addresses = $message->getAddresses('from');
$this->assertEquals('tedivm@tedivm.com', $addresses['address'], 'Returning From address as an address array.');
$addressString = $message->getAddresses('from', true);
$this->assertEquals('tedivm@tedivm.com', $addressString, 'Returning From address as string.');
}
public function testGetDate()
{
$message = static::getMessage(3);
$this->assertEquals(1385961243, $message->getDate(), 'Returns date as timestamp.');
}
public function testGetSubject()
{
$message = static::getMessage(3);
$this->assertEquals('Welcome', $message->getSubject(), 'Returns Subject.');
}
public function testDelete()
{
}
public function testGetImapBox()
{
$server = ServerTest::getServer();
$message = new \Fetch\Message('3', $server);
$this->assertEquals($server, $message->getImapBox(), 'getImapBox returns Server used to create Message.');
}
public function testGetUid()
{
$message = static::getMessage('3');
$this->assertEquals(3, $message->getUid(), 'Message returns UID');
}
public function testGetAttachments()
{
$messageWithoutAttachments = static::getMessage('3');
$this->assertFalse($messageWithoutAttachments->getAttachments(), 'getAttachments returns false when no attachments present.');
$messageWithAttachments = static::getMessage('6');
$attachments = $messageWithAttachments->getAttachments();
$this->assertCount(2, $attachments);
foreach($attachments as $attachment)
$this->assertInstanceOf('\Fetch\Attachment', $attachment, 'getAttachments returns Fetch\Attachment objects.');
$attachment = $messageWithAttachments->getAttachments('Test_card.png.zip');
$this->assertInstanceOf('\Fetch\Attachment', $attachment, 'getAttachment returns specified Fetch\Attachment object.');
}
public function testCheckFlag()
{
$message = static::getMessage('3');
$this->assertFalse($message->checkFlag('flagged'));
$this->assertTrue($message->checkFlag('seen'));
}
public function testSetFlag()
{
$message = static::getMessage('3');
$this->assertFalse($message->checkFlag('answered'), 'Message is not answered.');
$this->assertTrue($message->setFlag('answered'), 'setFlag returned true.');
$this->assertTrue($message->checkFlag('answered'), 'Message was successfully answered.');
$this->assertTrue($message->setFlag('answered', false), 'setFlag returned true.');
$this->assertFalse($message->checkFlag('answered'), 'Message was successfully unanswered.');
$message = static::getMessage('2');
$this->assertFalse($message->checkFlag('flagged'), 'Message is not flagged.');
$this->assertTrue($message->setFlag('flagged'), 'setFlag returned true.');
$this->assertTrue($message->checkFlag('flagged'), 'Message was successfully flagged.');
$message = static::getMessage('2');
$this->assertTrue($message->setFlag('flagged', false), 'setFlag returned true.');
$this->assertFalse($message->checkFlag('flagged'), 'Message was successfully unflagged.');
}
public function testMoveToMailbox()
{
$server = ServerTest::getServer();
// Testing by moving message from "Test Folder" to "Sent"
// Count Test Folder
$server->setMailBox('Test Folder');
$testFolderNumStart = $server->numMessages();
// Get message from Test Folder
$message = $server->getMessageByUid(1);
$this->assertInstanceOf('\Fetch\Message', $message, 'Server returned Message.');
// Switch to Sent folder, count messages
$server->setMailBox('Sent');
$sentFolderNumStart = $server->numMessages();
// Switch to "Flagged" folder in order to test that function properly returns to it
$this->assertTrue($server->setMailBox('Flagged Email'));
// Move the message!
$this->assertTrue($message->moveToMailBox('Sent'));
// Make sure we're still in the same folder
$this->assertEquals('Flagged Email', $server->getMailBox(), 'Returned Server back to right mailbox.');
$this->assertAttributeEquals('Sent', 'mailbox', $message, 'Message mailbox changed to new location.');
// Make sure Test Folder lost a message
$this->assertTrue($server->setMailBox('Test Folder'));
$this->assertEquals($testFolderNumStart - 1, $server->numMessages(), 'Message moved out of Test Folder.');
// Make sure Sent folder gains one
$this->assertTrue($server->setMailBox('Sent'));
$this->assertEquals($sentFolderNumStart + 1, $server->numMessages(), 'Message moved into Sent Folder.');
}
public function testDecode()
{
$quotedPrintableDecoded = "Now's the time for all folk to come to the aid of their country.";
$quotedPrintable = <<<'ENCODE'
Now's the time =
for all folk to come=
to the aid of their country.
ENCODE;
$this->assertEquals($quotedPrintableDecoded, Message::decode($quotedPrintable, 'quoted-printable'), 'Decodes quoted printable');
$this->assertEquals($quotedPrintableDecoded, Message::decode($quotedPrintable, 4), 'Decodes quoted printable');
$testString = 'This is a test string';
$base64 = base64_encode($testString);
$this->assertEquals($testString, Message::decode($base64, 'base64'), 'Decodes quoted base64');
$this->assertEquals($testString, Message::decode($base64, 3), 'Decodes quoted base64');
$notEncoded = '> w - www.somesite.com.au<http://example.com/track/click.php?u=30204369&id=af4110cab28e464cb0702723bc84b3f3>';
$this->assertEquals($notEncoded, Message::decode($notEncoded, 0), 'Nothing to decode');
}
public function testTypeIdToString()
{
$types = array();
$types[0] = 'text';
$types[1] = 'multipart';
$types[2] = 'message';
$types[3] = 'application';
$types[4] = 'audio';
$types[5] = 'image';
$types[6] = 'video';
$types[7] = 'other';
$types[8] = 'other';
$types[32] = 'other';
foreach($types as $id => $type)
$this->assertEquals($type, Message::typeIdToString($id));
}
public function testGetParametersFromStructure()
{
}
}

View File

@@ -0,0 +1,225 @@
<?php
/*
* This file is part of the Fetch library.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Fetch\Test;
use Fetch\Server;
/**
* @package Fetch
* @author Robert Hafner <tedivm@tedivm.com>
*/
class ServerTest extends \PHPUnit_Framework_TestCase
{
public static $num_messages_inbox = 12;
/**
* @dataProvider flagsDataProvider
* @param string $expected server string with %host% placeholder
* @param integer $port to use (needed to test behavior on port 143 and 993 from constructor)
* @param array $flags to set/unset ($flag => $value)
*/
public function testFlags($expected, $port, $flags)
{
$server = new Server(TESTING_SERVER_HOST, $port);
foreach ($flags as $flag => $value) {
$server->setFlag($flag, $value);
}
$this->assertEquals(str_replace('%host%', TESTING_SERVER_HOST, $expected), $server->getServerString());
}
public function testFlagOverwrite()
{
$server = static::getServer();
$server->setFlag('TestFlag', 'true');
$this->assertAttributeContains('TestFlag=true', 'flags', $server);
$server->setFlag('TestFlag', 'false');
$this->assertAttributeContains('TestFlag=false', 'flags', $server);
}
public function flagsDataProvider()
{
return array(
array('{%host%:143/novalidate-cert}', 143, array()),
array('{%host%:143/validate-cert}', 143, array('validate-cert' => true)),
array('{%host%:143}', 143, array('novalidate-cert' => false)),
array('{%host%:993/ssl}', 993, array()),
array('{%host%:993}', 993, array('ssl' => false)),
array('{%host%:100/tls}', 100, array('tls' => true)),
array('{%host%:100/tls}', 100, array('tls' => true, 'tls' => true)),
array('{%host%:100/notls}', 100, array('tls' => true, 'notls' => true)),
array('{%host%:100}', 100, array('ssl' => true, 'ssl' => false)),
array('{%host%:100/user=foo}', 100, array('user' => 'foo')),
array('{%host%:100/user=foo}', 100, array('user' => 'foo', 'user' => 'foo')),
array('{%host%:100/user=bar}', 100, array('user' => 'foo', 'user' => 'bar')),
array('{%host%:100}', 100, array('user' => 'foo', 'user' => false)),
);
}
/**
* @dataProvider connectionDataProvider
* @param integer $port to use (needed to test behavior on port 143 and 993 from constructor)
* @param array $flags to set/unset ($flag => $value)
* @param string $message Assertion message
*/
public function testConnection($port, $flags, $message)
{
$server = new Server(TESTING_SERVER_HOST, $port);
$server->setAuthentication(TEST_USER, TEST_PASSWORD);
foreach ($flags as $flag => $value) {
$server->setFlag($flag, $value);
}
$imapSteam = $server->getImapStream();
$this->assertInternalType('resource', $imapSteam, $message);
}
public function connectionDataProvider()
{
return array(
array(143, array(), 'Connects with default settings.'),
array(993, array('novalidate-cert' => true), 'Connects over SSL (self signed).'),
);
}
public function testNumMessages()
{
$server = static::getServer();
$numMessages = $server->numMessages();
$this->assertEquals(self::$num_messages_inbox, $numMessages);
}
public function testGetMessages()
{
$server = static::getServer();
$messages = $server->getMessages(5);
$this->assertCount(5, $messages, 'Five messages returned');
foreach ($messages as $message) {
$this->assertInstanceOf('\Fetch\Message', $message, 'Returned values are Messages');
}
}
public function testGetMessagesOrderedByDateAsc()
{
$server = static::getServer();
$messages = $server->getOrderedMessages(SORTDATE, false, 2);
$this->assertCount(2, $messages, 'Two messages returned');
$this->assertGreaterThan($messages[0]->getDate(), $messages[1]->getDate(), 'Messages in ascending order');
}
public function testGetMessagesOrderedByDateDesc()
{
$server = static::getServer();
$messages = $server->getOrderedMessages(SORTDATE, true, 2);
$this->assertCount(2, $messages, 'Two messages returned');
$this->assertLessThan($messages[0]->getDate(), $messages[1]->getDate(), 'Messages in descending order');
}
public function testGetMailBox()
{
$server = static::getServer();
$this->assertEquals('', $server->getMailBox());
$this->assertTrue($server->setMailBox('Sent'));
$this->assertEquals('Sent', $server->getMailBox());
}
public function testSetMailBox()
{
$server = static::getServer();
$this->assertTrue($server->setMailBox('Sent'));
$this->assertEquals('Sent', $server->getMailBox());
$this->assertTrue($server->setMailBox('Flagged Email'));
$this->assertEquals('Flagged Email', $server->getMailBox());
$this->assertFalse($server->setMailBox('Cheese'));
$this->assertTrue($server->setMailBox(''));
$this->assertEquals('', $server->getMailBox());
}
public function testHasMailBox()
{
$server = static::getServer();
$this->assertTrue($server->hasMailBox('Sent'), 'Has mailbox "Sent"');
$this->assertTrue($server->hasMailBox('Flagged Email'), 'Has mailbox "Flagged Email"');
$this->assertFalse($server->hasMailBox('Cheese'), 'Does not have mailbox "Cheese"');
}
public function testListMailBoxes()
{
$server = static::getServer();
$spec = sprintf('{%s:143/novalidate-cert}', TESTING_SERVER_HOST);
$list = $server->listMailboxes('*');
$this->assertContains($spec.'Sent', $list, 'Has mailbox "Sent"');
$this->assertNotContains($spec.'Cheese', $list, 'Does not have mailbox "Cheese"');
}
public function testCreateMailbox()
{
$server = static::getServer();
$this->assertFalse($server->hasMailBox('Cheese'), 'Does not have mailbox "Cheese"');
$this->assertTrue($server->createMailBox('Cheese'), 'createMailbox returns true.');
$this->assertTrue($server->hasMailBox('Cheese'), 'Mailbox "Cheese" was created');
}
/**
* @expectedException \RuntimeException
*/
public function testSetOptionsException()
{
$server = static::getServer();
$server->setOptions('purple');
}
public function testSetOptions()
{
$server = static::getServer();
$server->setOptions(5);
$this->assertAttributeEquals(5, 'options', $server);
}
public function testExpunge()
{
$server = static::getServer();
$message = $server->getMessageByUid(12);
$this->assertInstanceOf('\Fetch\Message', $message, 'Message exists');
$message->delete();
$this->assertInstanceOf('\Fetch\Message', $server->getMessageByUid(12), 'Message still present after being deleted but before being expunged.');
$server->expunge();
$this->assertFalse($server->getMessageByUid(12), 'Message successfully expunged');
}
public static function getServer()
{
$server = new Server(TESTING_SERVER_HOST, 143);
$server->setAuthentication(TEST_USER, TEST_PASSWORD);
return $server;
}
}

40
vendor/tedivm/fetch/tests/bootstrap.php vendored Normal file
View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Fetch library.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
error_reporting(-1);
define('TESTING', true);
define('TEST_USER', 'testuser');
define('TEST_PASSWORD', 'applesauce');
date_default_timezone_set('UTC');
if (getenv('TRAVIS')) {
define('TESTING_ENVIRONMENT', 'TRAVIS');
define('TESTING_SERVER_HOST', '127.0.0.1');
} else {
define('TESTING_ENVIRONMENT', 'VAGRANT');
define('TESTING_SERVER_HOST', '172.31.1.2');
}
$filename = __DIR__ .'/../vendor/autoload.php';
if (!file_exists($filename)) {
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" . PHP_EOL;
echo " You need to execute `composer install` before running the tests. " . PHP_EOL;
echo " Vendors are required for complete test execution. " . PHP_EOL;
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" . PHP_EOL . PHP_EOL;
$filename = __DIR__ .'/../autoload.php';
require_once $filename;
} else {
$loader = require $filename;
$loader->add('Fetch\\Test', __DIR__);
}

17
vendor/tedivm/fetch/tests/runTests.sh vendored Normal file
View File

@@ -0,0 +1,17 @@
#/usr/bin/env/sh
set -e
if [ ! -n "$TRAVIS" ]; then
./vendor/tedivm/dovecottesting/SetupEnvironment.sh
sleep 5
fi
echo 'Running unit tests.'
./vendor/bin/phpunit --verbose --coverage-clover build/logs/clover.xml
echo ''
echo ''
echo ''
echo 'Testing for Coding Styling Compliance.'
echo 'All code should follow PSR standards.'
./vendor/bin/php-cs-fixer fix ./ --level="all" -vv --dry-run