Update v1.0.6

This commit is contained in:
Bhanu Slathia
2016-02-16 23:22:09 +05:30
parent 62d04a0372
commit c710c20b9e
7620 changed files with 244752 additions and 1070312 deletions

View File

@@ -1,22 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View File

@@ -1,164 +0,0 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
.idea
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store

View File

@@ -1,32 +0,0 @@
ImapMailbox
Copyright (c) 2012 by Barbushin Sergey <barbushin@gmail.com>.
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.
* The names of the contributors may not 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 THE COPYRIGHT
OWNER OR CONTRIBUTORS 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.

View File

@@ -1,53 +0,0 @@
ImapMailbox is PHP class to access mailbox by POP3/IMAP/NNTP using IMAP extension
### Features
* Connect to mailbox by POP3/IMAP/NNTP (see [imap_open](http://php.net/imap_open))
* Get mailbox status (see [imap_check](http://php.net/imap_check))
* Receive emails (+attachments, +html body images)
* Search emails by custom criteria (see [imap_search](http://php.net/imap_search))
* Change email status (see [imap_setflag_full](http://php.net/imap_setflag_full))
* Delete email
### Installation by Composer
{
"require": {
"php-imap/php-imap": "~2.0"
}
}
Or
$ composer require php-imap/php-imap ~2.0
### Migration from `v1.*` to `v2.*`
Just add following code in the head of your script:
use PhpImap\Mailbox as ImapMailbox;
use PhpImap\IncomingMail;
use PhpImap\IncomingMailAttachment;
### Usage example
```php
$mailbox = new PhpImap\Mailbox('{imap.gmail.com:993/imap/ssl}INBOX', 'some@gmail.com', '*********', __DIR__);
$mails = array();
$mailsIds = $mailbox->searchMailBox('ALL');
if(!$mailsIds) {
die('Mailbox is empty');
}
$mailId = reset($mailsIds);
$mail = $mailbox->getMail($mailId);
var_dump($mail);
var_dump($mail->getAttachments());
```
### Recommended
* Google Chrome extension [PHP Console](https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef)
* Google Chrome extension [JavaScript Errors Notifier](https://chrome.google.com/webstore/detail/javascript-errors-notifie/jafmfknfnkoekkdocjiaipcnmkklaajd)

View File

@@ -1,29 +0,0 @@
{
"name": "php-imap/php-imap",
"description": "PHP class to access mailbox by POP3/IMAP/NNTP using IMAP extension",
"keywords": [
"PHP",
"IMAP",
"mail"
],
"homepage": "https://github.com/barbushin/php-imap",
"license": "BSD 3-Clause",
"type": "library",
"authors": [
{
"name": "Sergey Barbushin",
"homepage": "http://linkedin.com/in/barbushin",
"email": "barbushin@gmail.com"
}
],
"require": {
"php": ">=5.3.0",
"ext-imap": "*"
},
"autoload": {
"psr-4": {
"PhpImap\\": "src/PhpImap/"
}
},
"minimum-stability": "stable"
}

View File

@@ -1,66 +0,0 @@
<?php namespace PhpImap;
/**
* @see https://github.com/barbushin/php-imap
* @author Barbushin Sergey http://linkedin.com/in/barbushin
*/
class IncomingMail {
public $id;
public $date;
public $subject;
public $fromName;
public $fromAddress;
public $to = array();
public $toString;
public $cc = array();
public $replyTo = array();
public $messageId;
public $textPlain;
public $textHtml;
/** @var IncomingMailAttachment[] */
protected $attachments = array();
public function addAttachment(IncomingMailAttachment $attachment) {
$this->attachments[$attachment->id] = $attachment;
}
/**
* @return IncomingMailAttachment[]
*/
public function getAttachments() {
return $this->attachments;
}
/**
* Get array of internal HTML links placeholders
* @return array attachmentId => link placeholder
*/
public function getInternalLinksPlaceholders() {
return preg_match_all('/=["\'](ci?d:([\w\.%*@-]+))["\']/i', $this->textHtml, $matches) ? array_combine($matches[2], $matches[1]) : array();
}
public function replaceInternalLinks($baseUri) {
$baseUri = rtrim($baseUri, '\\/') . '/';
$fetchedHtml = $this->textHtml;
foreach($this->getInternalLinksPlaceholders() as $attachmentId => $placeholder) {
if(isset($this->attachments[$attachmentId])) {
$fetchedHtml = str_replace($placeholder, $baseUri . basename($this->attachments[$attachmentId]->filePath), $fetchedHtml);
}
}
return $fetchedHtml;
}
}
class IncomingMailAttachment {
public $id;
public $name;
public $filePath;
public $disposition;
}

View File

@@ -1,618 +0,0 @@
<?php namespace PhpImap;
use stdClass;
/**
* @see https://github.com/barbushin/php-imap
* @author Barbushin Sergey http://linkedin.com/in/barbushin
*/
class Mailbox {
protected $imapPath;
protected $imapLogin;
protected $imapPassword;
protected $imapOptions = 0;
protected $imapRetriesNum = 0;
protected $imapParams = array();
protected $serverEncoding;
protected $attachmentsDir;
public function __construct($imapPath, $login, $password, $attachmentsDir = null, $serverEncoding = 'UTF-8') {
$this->imapPath = $imapPath;
$this->imapLogin = $login;
$this->imapPassword = $password;
$this->serverEncoding = strtoupper($serverEncoding);
if($attachmentsDir) {
if(!is_dir($attachmentsDir)) {
throw new Exception('Directory "' . $attachmentsDir . '" not found');
}
$this->attachmentsDir = rtrim(realpath($attachmentsDir), '\\/');
}
}
/**
* Set custom connection arguments of imap_open method. See http://php.net/imap_open
* @param int $options
* @param int $retriesNum
* @param array $params
*/
public function setConnectionArgs($options = 0, $retriesNum = 0, array $params = null) {
$this->imapOptions = $options;
$this->imapRetriesNum = $retriesNum;
$this->imapParams = $params;
}
/**
* Get IMAP mailbox connection stream
* @param bool $forceConnection Initialize connection if it's not initialized
* @return null|resource
*/
public function getImapStream($forceConnection = true) {
static $imapStream;
if($forceConnection) {
if($imapStream && (!is_resource($imapStream) || !imap_ping($imapStream))) {
$this->disconnect();
$imapStream = null;
}
if(!$imapStream) {
$imapStream = $this->initImapStream();
}
}
return $imapStream;
}
protected function initImapStream() {
$imapStream = @imap_open($this->imapPath, $this->imapLogin, $this->imapPassword, $this->imapOptions, $this->imapRetriesNum, $this->imapParams);
if(!$imapStream) {
throw new Exception('Connection error: ' . imap_last_error());
}
return $imapStream;
}
protected function disconnect() {
$imapStream = $this->getImapStream(false);
if($imapStream && is_resource($imapStream)) {
imap_close($imapStream, CL_EXPUNGE);
}
}
/**
* Get information about the current mailbox.
*
* Returns the information in an object with following properties:
* Date - current system time formatted according to RFC2822
* Driver - protocol used to access this mailbox: POP3, IMAP, NNTP
* Mailbox - the mailbox name
* Nmsgs - number of mails in the mailbox
* Recent - number of recent mails in the mailbox
*
* @return stdClass
*/
public function checkMailbox() {
return imap_check($this->getImapStream());
}
/**
* Creates a new mailbox specified by mailbox.
*
* @return bool
*/
public function createMailbox() {
return imap_createmailbox($this->getImapStream(), imap_utf7_encode($this->imapPath));
}
/**
* Gets status information about the given mailbox.
*
* This function returns an object containing status information.
* The object has the following properties: messages, recent, unseen, uidnext, and uidvalidity.
*
* @return stdClass if the box doesn't exist
*/
public function statusMailbox() {
return imap_status($this->getImapStream(), $this->imapPath, SA_ALL);
}
/**
* Gets listing the folders
*
* This function returns an object containing listing the folders.
* The object has the following properties: messages, recent, unseen, uidnext, and uidvalidity.
*
* @return array listing the folders
*/
public function getListingFolders() {
$folders = imap_list($this->getImapStream(), $this->imapPath, "*");
foreach ($folders as $key => $folder)
{
$folder = str_replace($this->imapPath, "", imap_utf7_decode($folder));
$folders[$key] = $folder;
}
return $folders;
}
/**
* This function performs a search on the mailbox currently opened in the given IMAP stream.
* For example, to match all unanswered mails sent by Mom, you'd use: "UNANSWERED FROM mom".
* Searches appear to be case insensitive. This list of criteria is from a reading of the UW
* c-client source code and may be incomplete or inaccurate (see also RFC2060, section 6.4.4).
*
* @param string $criteria String, delimited by spaces, in which the following keywords are allowed. Any multi-word arguments (e.g. FROM "joey smith") must be quoted. Results will match all criteria entries.
* ALL - return all mails matching the rest of the criteria
* ANSWERED - match mails with the \\ANSWERED flag set
* BCC "string" - match mails with "string" in the Bcc: field
* BEFORE "date" - match mails with Date: before "date"
* BODY "string" - match mails with "string" in the body of the mail
* CC "string" - match mails with "string" in the Cc: field
* DELETED - match deleted mails
* FLAGGED - match mails with the \\FLAGGED (sometimes referred to as Important or Urgent) flag set
* FROM "string" - match mails with "string" in the From: field
* KEYWORD "string" - match mails with "string" as a keyword
* NEW - match new mails
* OLD - match old mails
* ON "date" - match mails with Date: matching "date"
* RECENT - match mails with the \\RECENT flag set
* SEEN - match mails that have been read (the \\SEEN flag is set)
* SINCE "date" - match mails with Date: after "date"
* SUBJECT "string" - match mails with "string" in the Subject:
* TEXT "string" - match mails with text "string"
* TO "string" - match mails with "string" in the To:
* UNANSWERED - match mails that have not been answered
* UNDELETED - match mails that are not deleted
* UNFLAGGED - match mails that are not flagged
* UNKEYWORD "string" - match mails that do not have the keyword "string"
* UNSEEN - match mails which have not been read yet
*
* @return array Mails ids
*/
public function searchMailbox($criteria = 'UNSEEN') {
$mailsIds = imap_search($this->getImapStream(), $criteria, SE_UID, $this->serverEncoding);
return $mailsIds ? $mailsIds : array();
}
/**
* Save mail body.
* @return bool
*/
public function saveMail($mailId, $filename = 'email.eml') {
return imap_savebody($this->getImapStream(), $filename, $mailId, "", FT_UID);
}
/**
* Marks mails listed in mailId for deletion.
* @return bool
*/
public function deleteMail($mailId) {
return imap_delete($this->getImapStream(), $mailId, FT_UID);
}
public function moveMail($mailId, $mailBox) {
return imap_mail_move($this->getImapStream(), $mailId, $mailBox, CP_UID) && $this->expungeDeletedMails();
}
/**
* Deletes all the mails marked for deletion by imap_delete(), imap_mail_move(), or imap_setflag_full().
* @return bool
*/
public function expungeDeletedMails() {
return imap_expunge($this->getImapStream());
}
/**
* Add the flag \Seen to a mail.
* @return bool
*/
public function markMailAsRead($mailId) {
return $this->setFlag(array($mailId), '\\Seen');
}
/**
* Remove the flag \Seen from a mail.
* @return bool
*/
public function markMailAsUnread($mailId) {
return $this->clearFlag(array($mailId), '\\Seen');
}
/**
* Add the flag \Flagged to a mail.
* @return bool
*/
public function markMailAsImportant($mailId) {
return $this->setFlag(array($mailId), '\\Flagged');
}
/**
* Add the flag \Seen to a mails.
* @return bool
*/
public function markMailsAsRead(array $mailId) {
return $this->setFlag($mailId, '\\Seen');
}
/**
* Remove the flag \Seen from some mails.
* @return bool
*/
public function markMailsAsUnread(array $mailId) {
return $this->clearFlag($mailId, '\\Seen');
}
/**
* Add the flag \Flagged to some mails.
* @return bool
*/
public function markMailsAsImportant(array $mailId) {
return $this->setFlag($mailId, '\\Flagged');
}
/**
* Causes a store to add the specified flag to the flags set for the mails in the specified sequence.
*
* @param array $mailsIds
* @param string $flag which you can set are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by RFC2060.
* @return bool
*/
public function setFlag(array $mailsIds, $flag) {
return imap_setflag_full($this->getImapStream(), implode(',', $mailsIds), $flag, ST_UID);
}
/**
* Cause a store to delete the specified flag to the flags set for the mails in the specified sequence.
*
* @param array $mailsIds
* @param string $flag which you can set are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by RFC2060.
* @return bool
*/
public function clearFlag(array $mailsIds, $flag) {
return imap_clearflag_full($this->getImapStream(), implode(',', $mailsIds), $flag, ST_UID);
}
/**
* Fetch mail headers for listed mails ids
*
* Returns an array of objects describing one mail header each. The object will only define a property if it exists. The possible properties are:
* subject - the mails subject
* from - who sent it
* to - recipient
* date - when was it sent
* message_id - Mail-ID
* references - is a reference to this mail id
* in_reply_to - is a reply to this mail id
* size - size in bytes
* uid - UID the mail has in the mailbox
* msgno - mail sequence number in the mailbox
* recent - this mail is flagged as recent
* flagged - this mail is flagged
* answered - this mail is flagged as answered
* deleted - this mail is flagged for deletion
* seen - this mail is flagged as already read
* draft - this mail is flagged as being a draft
*
* @param array $mailsIds
* @return array
*/
public function getMailsInfo(array $mailsIds) {
$mails = imap_fetch_overview($this->getImapStream(), implode(',', $mailsIds), FT_UID);
if(is_array($mails) && count($mails))
{
foreach($mails as &$mail)
{
if(isset($mail->subject)) {
$mail->subject = $this->decodeMimeStr($mail->subject, $this->serverEncoding);
}
if(isset($mail->from)) {
$mail->from = $this->decodeMimeStr($mail->from, $this->serverEncoding);
}
if(isset($mail->to)) {
$mail->to = $this->decodeMimeStr($mail->to, $this->serverEncoding);
}
}
}
return $mails;
}
/**
* Get information about the current mailbox.
*
* Returns an object with following properties:
* Date - last change (current datetime)
* Driver - driver
* Mailbox - name of the mailbox
* Nmsgs - number of messages
* Recent - number of recent messages
* Unread - number of unread messages
* Deleted - number of deleted messages
* Size - mailbox size
*
* @return object Object with info | FALSE on failure
*/
public function getMailboxInfo() {
return imap_mailboxmsginfo($this->getImapStream());
}
public function get_overview($mailId) {
$overview = imap_fetch_overview($this->getImapStream(), $mailId, FT_UID);
return $overview;
}
public function backup_getmail($mailId) {
$body = imap_body($this->getImapStream(), $mailId, 1.1);
return $body;
}
/**
* Gets mails ids sorted by some criteria
*
* Criteria can be one (and only one) of the following constants:
* SORTDATE - mail Date
* SORTARRIVAL - arrival date (default)
* SORTFROM - mailbox in first From address
* SORTSUBJECT - mail subject
* SORTTO - mailbox in first To address
* SORTCC - mailbox in first cc address
* SORTSIZE - size of mail in octets
*
* @param int $criteria
* @param bool $reverse
* @return array Mails ids
*/
public function sortMails($criteria = SORTARRIVAL, $reverse = true) {
return imap_sort($this->getImapStream(), $criteria, $reverse, SE_UID);
}
/**
* Get mails count in mail box
* @return int
*/
public function countMails() {
return imap_num_msg($this->getImapStream());
}
/**
* Retrieve the quota settings per user
* @return array - FALSE in the case of call failure
*/
protected function getQuota() {
return imap_get_quotaroot($this->getImapStream(), 'INBOX');
}
/**
* Return quota limit in KB
* @return int - FALSE in the case of call failure
*/
public function getQuotaLimit() {
$quota = $this->getQuota();
if(is_array($quota)) {
$quota = $quota['STORAGE']['limit'];
}
return $quota;
}
/**
* Return quota usage in KB
* @return int - FALSE in the case of call failure
*/
public function getQuotaUsage() {
$quota = $this->getQuota();
if(is_array($quota)) {
$quota = $quota['STORAGE']['usage'];
}
return $quota;
}
/**
* Get mail data
*
* @param $mailId
* @param bool $markAsSeen
* @return IncomingMail
*/
public function getMail($mailId, $markAsSeen = true) {
$head = imap_rfc822_parse_headers(imap_fetchheader($this->getImapStream(), $mailId, FT_UID));
$mail = new IncomingMail();
$mail->id = $mailId;
$mail->date = date('Y-m-d H:i:s', isset($head->date) ? strtotime(preg_replace('/\(.*?\)/', '', $head->date)) : time());
$mail->subject = isset($head->subject) ? $this->decodeMimeStr($head->subject, $this->serverEncoding) : null;
$mail->fromName = isset($head->from[0]->personal) ? $this->decodeMimeStr($head->from[0]->personal, $this->serverEncoding) : null;
$mail->fromAddress = strtolower($head->from[0]->mailbox . '@' . $head->from[0]->host);
if(isset($head->to)) {
$toStrings = array();
// dd($mail);
foreach($head->to as $to) {
if(!empty($to->mailbox) && !empty($to->host)) {
$toEmail = strtolower($to->mailbox . '@' . $to->host);
$toName = isset($to->personal) ? $this->decodeMimeStr($to->personal, $this->serverEncoding) : null;
$toStrings[] = $toName ? "$toName <$toEmail>" : $toEmail;
$mail->to[$toEmail] = $toName;
}
}
$mail->toString = implode(', ', $toStrings);
}
if(isset($head->cc)) {
foreach($head->cc as $cc) {
$mail->cc[strtolower($cc->mailbox . '@' . $cc->host)] = isset($cc->personal) ? $this->decodeMimeStr($cc->personal, $this->serverEncoding) : null;
}
}
if(isset($head->reply_to)) {
foreach($head->reply_to as $replyTo) {
$mail->replyTo[strtolower($replyTo->mailbox . '@' . $replyTo->host)] = isset($replyTo->personal) ? $this->decodeMimeStr($replyTo->personal, $this->serverEncoding) : null;
}
}
$mailStructure = imap_fetchstructure($this->getImapStream(), $mailId, FT_UID);
if(empty($mailStructure->parts)) {
$this->initMailPart($mail, $mailStructure, 0, $markAsSeen);
}
else {
foreach($mailStructure->parts as $partNum => $partStructure) {
$this->initMailPart($mail, $partStructure, $partNum + 1, $markAsSeen);
}
}
return $mail;
}
protected function initMailPart(IncomingMail $mail, $partStructure, $partNum, $markAsSeen = true) {
$options = FT_UID;
if(!$markAsSeen) {
$options |= FT_PEEK;
}
$data = $partNum ? imap_fetchbody($this->getImapStream(), $mail->id, $partNum, $options) : imap_body($this->getImapStream(), $mail->id, $options);
if($partStructure->encoding == 1) {
$data = imap_utf8($data);
}
elseif($partStructure->encoding == 2) {
$data = imap_binary($data);
}
elseif($partStructure->encoding == 3) {
$data = imap_base64($data);
}
elseif($partStructure->encoding == 4) {
$data = quoted_printable_decode($data);
}
$params = array();
if(!empty($partStructure->parameters)) {
foreach($partStructure->parameters as $param) {
$params[strtolower($param->attribute)] = $param->value;
}
}
if(!empty($partStructure->dparameters)) {
foreach($partStructure->dparameters as $param) {
$paramName = strtolower(preg_match('~^(.*?)\*~', $param->attribute, $matches) ? $matches[1] : $param->attribute);
if(isset($params[$paramName])) {
$params[$paramName] .= $param->value;
}
else {
$params[$paramName] = $param->value;
}
}
}
// attachments
$attachmentId = $partStructure->ifid
? trim($partStructure->id, " <>")
: (isset($params['filename']) || isset($params['name']) ? mt_rand() . mt_rand() : null);
if($attachmentId) {
if(empty($params['filename']) && empty($params['name'])) {
$fileName = $attachmentId . '.' . strtolower($partStructure->subtype);
}
else {
$fileName = !empty($params['filename']) ? $params['filename'] : $params['name'];
$fileName = $this->decodeMimeStr($fileName, $this->serverEncoding);
$fileName = $this->decodeRFC2231($fileName, $this->serverEncoding);
}
$attachment = new IncomingMailAttachment();
$attachment->id = $attachmentId;
$attachment->name = $fileName;
if($this->attachmentsDir) {
$replace = array(
'/\s/' => '_',
'/[^0-9a-zаіїє_\.]/iu' => '',
'/_+/' => '_',
'/(^_)|(_$)/' => '',
);
$fileSysName = preg_replace('~[\\\\/]~', '', $mail->id . '_' . $attachmentId . '_' . preg_replace(array_keys($replace), $replace, $fileName));
$attachment->filePath = $this->attachmentsDir .'../../../../../../public'. DIRECTORY_SEPARATOR . $fileSysName;
file_put_contents($attachment->filePath, $data);
}
$mail->addAttachment($attachment);
}
else {
if(!empty($params['charset'])) {
$data = $this->convertStringEncoding($data, $params['charset'], $this->serverEncoding);
}
if($partStructure->type == 0 && $data) {
if(strtolower($partStructure->subtype) == 'plain') {
$mail->textPlain .= $data;
}
else {
$mail->textHtml .= $data;
}
}
elseif($partStructure->type == 2 && $data) {
$mail->textPlain .= trim($data);
}
}
if(!empty($partStructure->parts)) {
foreach($partStructure->parts as $subPartNum => $subPartStructure) {
if($partStructure->type == 2 && $partStructure->subtype == 'RFC822') {
$this->initMailPart($mail, $subPartStructure, $partNum, $markAsSeen);
}
else {
$this->initMailPart($mail, $subPartStructure, $partNum . '.' . ($subPartNum + 1), $markAsSeen);
}
}
}
}
protected function decodeMimeStr($string, $charset = 'utf-8') {
$newString = '';
$elements = imap_mime_header_decode($string);
for($i = 0; $i < count($elements); $i++) {
if($elements[$i]->charset == 'default') {
$elements[$i]->charset = 'iso-8859-1';
}
$newString .= $this->convertStringEncoding($elements[$i]->text, $elements[$i]->charset, $charset);
}
return $newString;
}
function isUrlEncoded($string) {
$hasInvalidChars = preg_match( '#[^%a-zA-Z0-9\-_\.\+]#', $string );
$hasEscapedChars = preg_match( '#%[a-zA-Z0-9]{2}#', $string );
return !$hasInvalidChars && $hasEscapedChars;
}
protected function decodeRFC2231($string, $charset = 'utf-8') {
if(preg_match("/^(.*?)'.*?'(.*?)$/", $string, $matches)) {
$encoding = $matches[1];
$data = $matches[2];
if($this->isUrlEncoded($data)) {
$string = $this->convertStringEncoding(urldecode($data), $encoding, $charset);
}
}
return $string;
}
/**
* Converts a string from one encoding to another.
* @param string $string
* @param string $fromEncoding
* @param string $toEncoding
* @return string Converted string if conversion was successful, or the original string if not
*/
protected function convertStringEncoding($string, $fromEncoding, $toEncoding) {
$convertedString = null;
if($string && $fromEncoding != $toEncoding) {
$convertedString = @iconv($fromEncoding, $toEncoding . '//IGNORE', $string);
if(!$convertedString && extension_loaded('mbstring')) {
$convertedString = @mb_convert_encoding($string, $toEncoding, $fromEncoding);
}
}
return $convertedString ?: $string;
}
public function __destruct() {
$this->disconnect();
}
}
class Exception extends \Exception {
}

View File

@@ -1,8 +0,0 @@
<?php namespace PhpImap;
spl_autoload_register(function ($class) {
if(strpos($class, __NAMESPACE__) === 0) {
/** @noinspection PhpIncludeInspection */
require_once(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php');
}
});