Uploading and preparing the repository to the dev version.

Original unminified source code (dev folder - js, css, less) (fixes #6)
Grunt build system
Multiple identities correction (fixes #9)
Compose html editor (fixes #12)
New general settings - Loading Description
New warning about default admin password
Split general and login screen settings
This commit is contained in:
RainLoop Team 2013-11-16 02:21:12 +04:00
parent afad45137e
commit 4cc2207513
846 changed files with 99453 additions and 2123 deletions

View file

@ -0,0 +1,188 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class Attachment
{
/**
* @var resource
*/
private $rResource;
/**
* @var string
*/
private $sFileName;
/**
* @var int
*/
private $iFileSize;
/**
* @var string
*/
private $sCID;
/**
* @var bool
*/
private $bIsInline;
/**
* @var bool
*/
private $bIsLinked;
/**
* @var array
*/
private $aCustomContentTypeParams;
/**
* @var string
*/
private $sContentLocation;
/**
* @access private
*/
private function __construct($rResource, $sFileName, $iFileSize, $bIsInline, $bIsLinked, $sCID,
$aCustomContentTypeParams = array(), $sContentLocation = '')
{
$this->rResource = $rResource;
$this->sFileName = $sFileName;
$this->iFileSize = $iFileSize;
$this->bIsInline = $bIsInline;
$this->bIsLinked = $bIsLinked;
$this->sCID = $sCID;
$this->aCustomContentTypeParams = $aCustomContentTypeParams;
$this->sContentLocation = $sContentLocation;
}
/**
* @param resource $rResource
* @param string $sFileName = ''
* @param int $iFileSize = 0
* @param bool $bIsInline = false
* @param bool $bIsLinked = false
* @param string $sCID = ''
* @param array $aCustomContentTypeParams = array()
* @param string $sContentLocation = ''
*
* @return \MailSo\Mime\Attachment
*/
public static function NewInstance($rResource, $sFileName = '', $iFileSize = 0, $bIsInline = false,
$bIsLinked = false, $sCID = '', $aCustomContentTypeParams = array(), $sContentLocation = '')
{
return new self($rResource, $sFileName, $iFileSize, $bIsInline, $bIsLinked, $sCID, $aCustomContentTypeParams, $sContentLocation);
}
/**
* @return resource
*/
public function Resource()
{
return $this->rResource;
}
/**
* @return string
*/
public function ContentType()
{
return \MailSo\Base\Utils::MimeContentType($this->sFileName);
}
/**
* @return array
*/
public function CustomContentTypeParams()
{
return $this->aCustomContentTypeParams;
}
/**
* @return string
*/
public function CID()
{
return $this->sCID;
}
/**
* @return string
*/
public function ContentLocation()
{
return $this->sContentLocation;
}
/**
* @return string
*/
public function FileName()
{
return $this->sFileName;
}
/**
* @return int
*/
public function FileSize()
{
return $this->iFileSize;
}
/**
* @return bool
*/
public function IsInline()
{
return $this->bIsInline;
}
/**
* @return bool
*/
public function IsImage()
{
return 'image' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
}
/**
* @return bool
*/
public function IsArchive()
{
return 'archive' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
}
/**
* @return bool
*/
public function IsPdf()
{
return 'pdf' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
}
/**
* @return bool
*/
public function IsDoc()
{
return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
}
/**
* @return bool
*/
public function IsLinked()
{
return $this->bIsLinked && 0 < \strlen($this->sCID);
}
}

View file

@ -0,0 +1,62 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class AttachmentCollection extends \MailSo\Base\Collection
{
/**
* @access protected
*/
protected function __construct()
{
parent::__construct();
}
/**
* @return \MailSo\Mime\AttachmentCollection
*/
public static function NewInstance()
{
return new self();
}
/**
* @return array
*/
public function LinkedAttachments()
{
return $this->FilterList(function ($oItem) {
return $oItem && $oItem->IsLinked();
});
}
/**
* @return array
*/
public function UnlinkedAttachments()
{
return $this->FilterList(function ($oItem) {
return $oItem && !$oItem->IsLinked();
});
}
/**
* @return int
*/
public function SizeOfAttachments()
{
$iResult = 0;
$this->ForeachList(function ($oItem) use (&$iResult) {
if ($oItem)
{
$iResult += $oItem->FileSize();
}
});
return $iResult;
}
}

View file

@ -0,0 +1,276 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class Email
{
/**
* @var string
*/
private $sDisplayName;
/**
* @var string
*/
private $sEmail;
/**
* @var string
*/
private $sRemark;
/**
* @access private
*
* @param string $sEmail
* @param string $sDisplayName = ''
* @param string $sRemark = ''
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
private function __construct($sEmail, $sDisplayName = '', $sRemark = '')
{
if (!\MailSo\Base\Validator::NotEmptyString($sEmail, true))
{
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
}
$this->sEmail = \trim($sEmail);
$this->sDisplayName = \trim($sDisplayName);
$this->sRemark = \trim($sRemark);
}
/**
* @param string $sEmail
* @param string $sDisplayName = ''
* @param string $sRemark = ''
*
* @return \MailSo\Mime\Email
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public static function NewInstance($sEmail, $sDisplayName = '', $sRemark = '')
{
return new self($sEmail, $sDisplayName, $sRemark);
}
/**
* @param string $sEmailAddress
* @return \MailSo\Mime\Email
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public static function Parse($sEmailAddress)
{
if (!\MailSo\Base\Validator::NotEmptyString($sEmailAddress, true))
{
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
}
$sName = '';
$sEmail = '';
$sComment = '';
$bInName = false;
$bInAddress = false;
$bInComment = false;
$iStartIndex = 0;
$iEndIndex = 0;
$iCurrentIndex = 0;
while ($iCurrentIndex < \strlen($sEmailAddress))
{
switch ($sEmailAddress{$iCurrentIndex})
{
// case '\'':
case '"':
// $sQuoteChar = $sEmailAddress{$iCurrentIndex};
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
$bInName = true;
$iStartIndex = $iCurrentIndex;
}
else if ((!$bInAddress) && (!$bInComment))
{
$iEndIndex = $iCurrentIndex;
$sName = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInName = false;
}
break;
case '<':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
if ($iCurrentIndex > 0 && \strlen($sName) == 0)
{
$sName = \substr($sEmailAddress, 0, $iCurrentIndex);
}
$bInAddress = true;
$iStartIndex = $iCurrentIndex;
}
break;
case '>':
if ($bInAddress)
{
$iEndIndex = $iCurrentIndex;
$sEmail = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInAddress = false;
}
break;
case '(':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
$bInComment = true;
$iStartIndex = $iCurrentIndex;
}
break;
case ')':
if ($bInComment)
{
$iEndIndex = $iCurrentIndex;
$sComment = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInComment = false;
}
break;
case '\\':
$iCurrentIndex++;
break;
}
$iCurrentIndex++;
}
if (strlen($sEmail) == 0)
{
$aRegs = array('');
if (\preg_match('/[^@\s]+@\S+/i', $sEmailAddress, $aRegs) && isset($aRegs[0]))
{
$sEmail = $aRegs[0];
}
else
{
$sName = $sEmailAddress;
}
}
if ((\strlen($sEmail) > 0) && (\strlen($sName) == 0) && (strlen($sComment) == 0))
{
$sName = \str_replace($sEmail, '', $sEmailAddress);
}
$sEmail = \trim(\trim($sEmail), '<>');
$sName = \trim(\trim($sName), '"');
$sName = \trim($sName, '\'');
$sComment = \trim(\trim($sComment), '()');
// Remove backslash
$sName = \preg_replace('/\\\\(.)/s', '$1', $sName);
$sComment = \preg_replace('/\\\\(.)/s', '$1', $sComment);
return Email::NewInstance($sEmail, $sName, $sComment);
}
/**
* @return string
*/
public function GetEmail()
{
return $this->sEmail;
}
/**
* @return string
*/
public function GetDisplayName()
{
return $this->sDisplayName;
}
/**
* @return string
*/
public function GetRemark()
{
return $this->sRemark;
}
/**
* @return string
*/
public function GetAccountName()
{
return \MailSo\Base\Utils::GetAccountNameFromEmail($this->sEmail);
}
/**
* @return string
*/
public function GetDomain()
{
return \MailSo\Base\Utils::GetDomainFromEmail($this->sEmail);
}
/**
* @return array
*/
public function ToArray()
{
return array($this->sDisplayName, $this->sEmail, $this->sRemark);
}
/**
* @param bool $bConvertSpecialsName = false
*
* @return string
*/
public function ToString($bConvertSpecialsName = false)
{
$sReturn = '';
$sRemark = \str_replace(')', '\)', $this->sRemark);
$sDisplayName = \str_replace('"', '\"', $this->sDisplayName);
if ($bConvertSpecialsName)
{
$sDisplayName = 0 === \strlen($sDisplayName) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue(
\MailSo\Base\Enumerations\Encoding::BASE64_SHORT,
$sDisplayName);
$sRemark = 0 === \strlen($sRemark) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue(
\MailSo\Base\Enumerations\Encoding::BASE64_SHORT,
$sRemark);
}
$sDisplayName = 0 === \strlen($sDisplayName) ? '' : '"'.$sDisplayName.'"';
$sRemark = 0 === \strlen($sRemark) ? '' : '('.$sRemark.')';
if (0 < \strlen($this->sEmail))
{
$sReturn = $this->sEmail;
if (0 < \strlen($sDisplayName.$sRemark))
{
$sReturn = $sDisplayName.' <'.$sReturn.'> '.$sRemark;
}
}
return \trim($sReturn);
}
}

View file

@ -0,0 +1,232 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class EmailCollection extends \MailSo\Base\Collection
{
/**
* @access protected
*
* @param string $sEmailAddresses = ''
*/
protected function __construct($sEmailAddresses = '')
{
parent::__construct();
if (0 < \strlen($sEmailAddresses))
{
$this->parseEmailAddresses($sEmailAddresses);
}
}
/**
* @param string $sEmailAddresses = ''
*
* @return \MailSo\Mime\EmailCollection
*/
public static function NewInstance($sEmailAddresses = '')
{
return new self($sEmailAddresses);
}
/**
* @param string $sEmailAddresses
*
* @return \MailSo\Mime\EmailCollection
*/
public static function Parse($sEmailAddresses)
{
return self::NewInstance($sEmailAddresses);
}
/**
* @return array
*/
public function ToArray()
{
$aReturn = $aEmails = array();
$aEmails =& $this->GetAsArray();
foreach ($aEmails as /* @var $oEmail \MailSo\Mime\Email */ $oEmail)
{
$aReturn[] = $oEmail->ToArray();
}
return $aReturn;
}
/**
* @param \MailSo\Mime\EmailCollection $oEmails
*
* @return \MailSo\Mime\EmailCollection
*/
public function MergeWithOtherCollection(\MailSo\Mime\EmailCollection $oEmails)
{
$aEmails =& $oEmails->GetAsArray();
foreach ($aEmails as /* @var $oEmail \MailSo\Mime\Email */ $oEmail)
{
$this->Add($oEmail);
}
return $this;
}
/**
* @return \MailSo\Mime\EmailCollection
*/
public function Unique()
{
$aCache = array();
$aReturn = array();
$aEmails =& $this->GetAsArray();
foreach ($aEmails as /* @var $oEmail \MailSo\Mime\Email */ $oEmail)
{
$sEmail = $oEmail->GetEmail();
if (!isset($aCache[$sEmail]))
{
$aCache[$sEmail] = true;
$aReturn[] = $oEmail;
}
}
$this->SetAsArray($aReturn);
return $this;
}
/**
* @param bool $bConvertSpecialsName = false
*
* @return string
*/
public function ToString($bConvertSpecialsName = false)
{
$aReturn = $aEmails = array();
$aEmails =& $this->GetAsArray();
foreach ($aEmails as /* @var $oEmail \MailSo\Mime\Email */ $oEmail)
{
$aReturn[] = $oEmail->ToString($bConvertSpecialsName);
}
return \implode(', ', $aReturn);
}
/**
* @param string $sRawEmails
*
* @return \MailSo\Mime\EmailCollection
*/
private function parseEmailAddresses($sRawEmails)
{
$this->Clear();
$sWorkingRecipients = \trim($sRawEmails);
if (0 === \strlen($sWorkingRecipients))
{
return $this;
}
$iEmailStartPos = 0;
$iEmailEndPos = 0;
$bIsInQuotes = false;
$sChQuote = '"';
$bIsInAngleBrackets = false;
$bIsInBrackets = false;
$iCurrentPos = 0;
$sWorkingRecipientsLen = \strlen($sWorkingRecipients);
while ($iCurrentPos < $sWorkingRecipientsLen)
{
switch ($sWorkingRecipients{$iCurrentPos})
{
case '\'':
case '"':
if (!$bIsInQuotes)
{
$sChQuote = $sWorkingRecipients{$iCurrentPos};
$bIsInQuotes = true;
}
else if ($sChQuote == $sWorkingRecipients{$iCurrentPos})
{
$bIsInQuotes = false;
}
break;
case '<':
if (!$bIsInAngleBrackets)
{
$bIsInAngleBrackets = true;
if ($bIsInQuotes)
{
$bIsInQuotes = false;
}
}
break;
case '>':
if ($bIsInAngleBrackets)
{
$bIsInAngleBrackets = false;
}
break;
case '(':
if (!$bIsInBrackets)
{
$bIsInBrackets = true;
}
break;
case ')':
if ($bIsInBrackets)
{
$bIsInBrackets = false;
}
break;
case ',':
case ';':
if (!$bIsInAngleBrackets && !$bIsInBrackets && !$bIsInQuotes)
{
$iEmailEndPos = $iCurrentPos;
try
{
$this->Add(
\MailSo\Mime\Email::Parse(\substr($sWorkingRecipients, $iEmailStartPos, $iEmailEndPos - $iEmailStartPos))
);
$iEmailStartPos = $iCurrentPos + 1;
}
catch (\MailSo\Base\Exceptions\InvalidArgumentException $oException)
{
}
}
break;
}
$iCurrentPos++;
}
if ($iEmailStartPos < $iCurrentPos)
{
try
{
$this->Add(
\MailSo\Mime\Email::Parse(\substr($sWorkingRecipients, $iEmailStartPos, $iCurrentPos - $iEmailStartPos))
);
}
catch (\MailSo\Base\Exceptions\InvalidArgumentException $oException) {}
}
return $this;
}
}

View file

@ -0,0 +1,16 @@
<?php
namespace MailSo\Mime\Enumerations;
/**
* @category MailSo
* @package Mime
* @subpackage Enumerations
*/
class Constants
{
const TAB = "\t";
const CRLF = "\r\n";
const LINE_LENGTH = 74;
}

View file

@ -0,0 +1,49 @@
<?php
namespace MailSo\Mime\Enumerations;
/**
* @category MailSo
* @package Mime
* @subpackage Enumerations
*/
class Header
{
const DATE = 'Date';
const RECEIVED = 'Received';
const SUBJECT = 'Subject';
const TO_ = 'To';
const FROM_ = 'From';
const CC = 'Cc';
const BCC = 'Bcc';
const REPLY_TO = 'Reply-To';
const SENDER = 'Sender';
const RETURN_PATH = 'Return-Path';
const MESSAGE_ID = 'Message-ID';
const IN_REPLY_TO = 'In-Reply-To';
const REFERENCES = 'References';
const X_DRAFT_INFO = 'X-Draft-Info';
const X_ORIGINATING_IP = 'X-Originating-IP';
const CONTENT_TYPE = 'Content-Type';
const CONTENT_TRANSFER_ENCODING = 'Content-Transfer-Encoding';
const CONTENT_DISPOSITION = 'Content-Disposition';
const CONTENT_DESCRIPTION = 'Content-Description';
const CONTENT_ID = 'Content-ID';
const CONTENT_LOCATION = 'Content-Location';
const SENSITIVITY = 'Sensitivity';
const DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To';
const X_CONFIRM_READING_TO = 'X-Confirm-Reading-To';
const MIME_VERSION = 'Mime-Version';
const X_MAILER = 'X-Mailer';
const X_MSMAIL_PRIORITY = 'X-MSMail-Priority';
const IMPORTANCE = 'Importance';
const X_PRIORITY = 'X-Priority';
}

View file

@ -0,0 +1,15 @@
<?php
namespace MailSo\Mime\Enumerations;
/**
* @category MailSo
* @package Mime
* @subpackage Enumerations
*/
class MessagePriority
{
const LOW = 5;
const NORMAL = 3;
const HIGH = 1;
}

View file

@ -0,0 +1,27 @@
<?php
namespace MailSo\Mime\Enumerations;
/**
* @category MailSo
* @package Mime
* @subpackage Enumerations
*/
class MimeType
{
const TEXT_PLAIN = 'text/plain';
const TEXT_HTML = 'text/html';
const MULTIPART_ALTERNATIVE = 'multipart/alternative';
const MULTIPART_RELATED = 'multipart/related';
const MULTIPART_MIXED = 'multipart/mixed';
const MULTIPART_SIGNED = 'multipart/signed';
const MESSAGE_RFC822 = 'message/rfc822';
const MESSAGE_PARTIAL = 'message/partial';
const MESSAGE_REPORT = 'message/report';
const APPLICATION_MS_TNEF = 'application/ms-tnef';
const APPLICATION_PKCS7_MIME = 'application/pkcs7-mime';
const APPLICATION_PKCS7_SIGNATURE = 'application/pkcs7-signature';
}

View file

@ -0,0 +1,16 @@
<?php
namespace MailSo\Mime\Enumerations;
/**
* @category MailSo
* @package Mime
* @subpackage Enumerations
*/
class Parameter
{
const CHARSET = 'charset';
const NAME = 'name';
const FILENAME = 'filename';
const BOUNDARY = 'boundary';
}

View file

@ -0,0 +1,16 @@
<?php
namespace MailSo\Mime\Enumerations;
/**
* @category MailSo
* @package Mime
* @subpackage Enumerations
*/
class Sensitivity
{
const NOTHING = 0;
const CONFIDENTIAL = 1;
const PRIVATE_ = 2;
const PERSONAL = 3;
}

View file

@ -0,0 +1,299 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class Header
{
/**
* @var string
*/
private $sName;
/**
* @var string
*/
private $sValue;
/**
* @var string
*/
private $sFullValue;
/**
* @var string
*/
private $sEncodedValueForReparse;
/**
* @var ParameterCollection
*/
private $oParameters;
/**
* @var strign
*/
private $sParentCharset;
/**
* @access private
*
* @param string $sName
* @param string $sValue
* @param string $sEncodedValueForReparse
*/
private function __construct($sName, $sValue, $sEncodedValueForReparse)
{
$this->sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
$this->initInputData($sName, $sValue, $sEncodedValueForReparse);
}
/**
* @param string $sName
* @param string $sValue
* @param string $sEncodedValueForReparse
*
* @return void
*/
private function initInputData($sName, $sValue, $sEncodedValueForReparse)
{
$this->sName = trim($sName);
$this->sFullValue = trim($sValue);
$this->sEncodedValueForReparse = '';
$this->oParameters = null;
if (0 < \strlen($sEncodedValueForReparse) && $this->IsReparsed())
{
$this->sEncodedValueForReparse = \trim($sEncodedValueForReparse);
}
if (0 < \strlen($this->sFullValue) && $this->IsParameterized())
{
$aRawExplode = \explode(';', $this->sFullValue, 2);
if (2 === \count($aRawExplode))
{
$this->sValue = $aRawExplode[0];
$this->oParameters =
\MailSo\Mime\ParameterCollection::NewInstance($aRawExplode[1]);
}
else
{
$this->sValue = $this->sFullValue;
}
}
else
{
$this->sValue = $this->sFullValue;
}
}
/**
* @param string $sName
* @param string $sValue = ''
* @param string $sEncodedValueForReparse = ''
*
* @return \MailSo\Mime\Header
*/
public static function NewInstance($sName, $sValue = '', $sEncodedValueForReparse = '')
{
return new self($sName, $sValue, $sEncodedValueForReparse);
}
/**
* @param string $sEncodedLines
* @param string $sIncomingCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1
*
* @return \MailSo\Mime\Header | false
*/
public static function NewInstanceFromEncodedString($sEncodedLines, $sIncomingCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1)
{
$aParts = \explode(':', \str_replace("\r", '', $sEncodedLines), 2);
if (isset($aParts[0]) && isset($aParts[1]) && 0 < \strlen($aParts[0]) && 0 < \strlen($aParts[1]))
{
return self::NewInstance(
\trim($aParts[0]),
\trim(\MailSo\Base\Utils::DecodeHeaderValue(\trim($aParts[1]), $sIncomingCharset)),
\trim($aParts[1])
);
}
return false;
}
/**
* @return string
*/
public function Name()
{
return $this->sName;
}
/**
* @return string
*/
public function NameWithDelimitrom()
{
return $this->Name().': ';
}
/**
* @return string
*/
public function Value()
{
return $this->sValue;
}
/**
* @return string
*/
public function FullValue()
{
return $this->sFullValue;
}
/**
* @param string $sParentCharset
* @return \MailSo\Mime\Header
*/
public function SetParentCharset($sParentCharset)
{
if ($this->sParentCharset !== $sParentCharset && $this->IsReparsed() && 0 < \strlen($this->sEncodedValueForReparse))
{
$this->initInputData(
$this->sName,
\trim(\MailSo\Base\Utils::DecodeHeaderValue($this->sEncodedValueForReparse, $sParentCharset)),
$this->sEncodedValueForReparse);
}
$this->sParentCharset = $sParentCharset;
return $this;
}
/**
* @return \MailSo\Mime\ParameterCollection | null
*/
public function Parameters()
{
return $this->oParameters;
}
/**
* @param string $sValue
* @return string
*/
private function wordWrapHelper($sValue, $sGlue = "\r\n ")
{
return \trim(substr(wordwrap($this->NameWithDelimitrom().$sValue,
\MailSo\Mime\Enumerations\Constants::LINE_LENGTH, $sGlue
), \strlen($this->NameWithDelimitrom())));
}
/**
* @return string
*/
public function EncodedValue()
{
$sResult = $this->sFullValue;
if ($this->IsSubject())
{
if (!\MailSo\Base\Utils::IsAscii($sResult) && \function_exists('iconv_mime_encode'))
{
$aPreferences = array(
// 'scheme' => \MailSo\Base\Enumerations\Encoding::QUOTED_PRINTABLE_SHORT,
'scheme' => \MailSo\Base\Enumerations\Encoding::BASE64_SHORT,
'input-charset' => \MailSo\Base\Enumerations\Charset::UTF_8,
'output-charset' => \MailSo\Base\Enumerations\Charset::UTF_8,
'line-length' => \MailSo\Mime\Enumerations\Constants::LINE_LENGTH,
'line-break-chars' => \MailSo\Mime\Enumerations\Constants::CRLF
);
return \iconv_mime_encode($this->Name(), $sResult, $aPreferences);
}
}
else if ($this->IsParameterized() && $this->oParameters && 0 < $this->oParameters->Count())
{
$sResult = $this->sValue.'; '.$this->oParameters->ToString(true);
}
else if ($this->IsEmail())
{
$oEmailCollection = \MailSo\Mime\EmailCollection::NewInstance($this->sFullValue);
if ($oEmailCollection && 0 < $oEmailCollection->Count())
{
$sResult = $oEmailCollection->ToString(true);
}
}
return $this->NameWithDelimitrom().$this->wordWrapHelper($sResult);
}
/**
* @return bool
*/
public function IsSubject()
{
return \strtolower(\MailSo\Mime\Enumerations\Header::SUBJECT) === \strtolower($this->Name());
}
/**
* @return bool
*/
public function IsParameterized()
{
return \in_array(\strtolower($this->sName), array(
\strtolower(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE),
\strtolower(\MailSo\Mime\Enumerations\Header::CONTENT_DISPOSITION)
));
}
/**
* @return bool
*/
public function IsEmail()
{
return \in_array(\strtolower($this->sName), array(
\strtolower(\MailSo\Mime\Enumerations\Header::FROM_),
\strtolower(\MailSo\Mime\Enumerations\Header::TO_),
\strtolower(\MailSo\Mime\Enumerations\Header::CC),
\strtolower(\MailSo\Mime\Enumerations\Header::BCC),
\strtolower(\MailSo\Mime\Enumerations\Header::REPLY_TO),
\strtolower(\MailSo\Mime\Enumerations\Header::RETURN_PATH),
\strtolower(\MailSo\Mime\Enumerations\Header::SENDER)
));
}
/**
* @return string
*/
public function ValueWithCharsetAutoDetect()
{
$sValue = $this->Value();
if (!\MailSo\Base\Utils::IsAscii($sValue) &&
0 < \strlen($this->sEncodedValueForReparse) &&
!\MailSo\Base\Utils::IsAscii($this->sEncodedValueForReparse))
{
$sValueCharset = \MailSo\Base\Utils::CharsetDetect($this->sEncodedValueForReparse);
if (0 < \strlen($sValueCharset))
{
$this->SetParentCharset($sValueCharset);
$sValue = $this->Value();
}
}
return $sValue;
}
/**
* @return bool
*/
public function IsReparsed()
{
return $this->IsEmail() || $this->IsSubject() || $this->IsParameterized();
}
}

View file

@ -0,0 +1,362 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class HeaderCollection extends \MailSo\Base\Collection
{
/**
* @return string
*/
protected $sRawHeaders;
/**
* @var strign
*/
protected $sParentCharset;
/**
* @access protected
*
* @param string $sRawHeaders = ''
* @param bool $bStoreRawHeaders = true
*/
protected function __construct($sRawHeaders = '', $bStoreRawHeaders = true)
{
parent::__construct();
$this->sRawHeaders = '';
$this->sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
if (0 < \strlen($sRawHeaders))
{
$this->Parse($sRawHeaders, $bStoreRawHeaders);
}
}
/**
* @param string $sRawHeaders = ''
* @param bool $bStoreRawHeaders = true
*
* @return \MailSo\Mime\HeaderCollection
*/
public static function NewInstance($sRawHeaders = '', $bStoreRawHeaders = true)
{
return new self($sRawHeaders, $bStoreRawHeaders);
}
/**
* @param string $sName
* @param string $sValue
* @param bool $bToTop = false
*
* @return \MailSo\Mime\HeaderCollection
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function AddByName($sName, $sValue, $bToTop = false)
{
return $this->Add(Header::NewInstance($sName, $sValue), $bToTop);
}
/**
* @param string $sName
* @param string $sValue
* @param bool $bToTop = false
*
* @return \MailSo\Mime\HeaderCollection
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function SetByName($sName, $sValue, $bToTop = false)
{
return $this->RemoveByName($sName)->Add(Header::NewInstance($sName, $sValue), $bToTop);
}
/**
* @return \MailSo\Mime\Header | null
*/
public function &GetByIndex($iIndex)
{
$mResult = null;
$mResult =& parent::GetByIndex($iIndex);
return $mResult;
}
/**
* @param string $sHeaderName
* @param bool $bCharsetAutoDetect = false
* @return string
*/
public function ValueByName($sHeaderName, $bCharsetAutoDetect = false)
{
$oHeader = null;
$oHeader =& $this->GetByName($sHeaderName);
return (null !== $oHeader) ? ($bCharsetAutoDetect ? $oHeader->ValueWithCharsetAutoDetect() : $oHeader->Value()) : '';
}
/**
* @param string $sHeaderName
* @param bool $bCharsetAutoDetect = false
* @return array
*/
public function ValuesByName($sHeaderName, $bCharsetAutoDetect = false)
{
$aResult = array();
$oHeader = null;
$sHeaderNameLower = \strtolower($sHeaderName);
$aHeaders =& $this->GetAsArray();
foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader)
{
if ($sHeaderNameLower === \strtolower($oHeader->Name()))
{
$aResult[] = $bCharsetAutoDetect ? $oHeader->ValueWithCharsetAutoDetect() : $oHeader->Value();
}
}
return $aResult;
}
/**
* @param string $sHeaderName
*
* @return \MailSo\Mime\HeaderCollection
*/
public function RemoveByName($sHeaderName)
{
$aResult = $this->FilterList(function ($oHeader) use ($sHeaderName) {
return $oHeader && \strtolower($oHeader->Name()) !== \strtolower($sHeaderName);
});
return $this->SetAsArray($aResult);
}
/**
* @param string $sHeaderName
* @param bool $bCharsetAutoDetect = false
* @return string
*/
public function GetAsEmailCollection($sHeaderName, $bCharsetAutoDetect = false)
{
$oResult = null;
$sValue = $this->ValueByName($sHeaderName, $bCharsetAutoDetect);
if (0 < \strlen($sValue))
{
$oResult = \MailSo\Mime\EmailCollection::NewInstance($sValue);
}
return $oResult && 0 < $oResult->Count() ? $oResult : null;
}
/**
* @param string $sHeaderName
* @return \MailSo\Mime\ParameterCollection | null
*/
public function ParametersByName($sHeaderName)
{
$oParameters = $oHeader = null;
$oHeader =& $this->GetByName($sHeaderName);
if ($oHeader)
{
$oParameters = $oHeader->Parameters();
}
return $oParameters;
}
/**
* @param string $sHeaderName
* @param string $sParamName
* @return string
*/
public function ParameterValue($sHeaderName, $sParamName)
{
$oParameters = $this->ParametersByName($sHeaderName);
return (null !== $oParameters) ? $oParameters->ParameterValueByName($sParamName) : '';
}
/**
* @param string $sHeaderName
* @return \MailSo\Mime\Header | false
*/
public function &GetByName($sHeaderName)
{
$oResult = $oHeader = null;
$sHeaderNameLower = \strtolower($sHeaderName);
$aHeaders =& $this->GetAsArray();
foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader)
{
if ($sHeaderNameLower === \strtolower($oHeader->Name()))
{
$oResult =& $oHeader;
break;
}
}
return $oResult;
}
/**
* @param array $aList
* @return \MailSo\Mime\HeaderCollection
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function SetAsArray($aList)
{
parent::SetAsArray($aList);
return $this;
}
/**
* @param string $sParentCharset
* @return \MailSo\Mime\HeaderCollection
*/
public function SetParentCharset($sParentCharset)
{
if (0 < \strlen($sParentCharset))
{
if ($this->sParentCharset !== $sParentCharset)
{
$oHeader = null;
$aHeaders =& $this->GetAsArray();
foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader)
{
$oHeader->SetParentCharset($sParentCharset);
}
$this->sParentCharset = $sParentCharset;
}
}
return $this;
}
/**
* @return void
*/
public function Clear()
{
parent::Clear();
$this->sRawHeaders = '';
}
/**
* @param string $sRawHeaders
* @param bool $bStoreRawHeaders = false
* @param string $sParentCharset = ''
*
* @return \MailSo\Mime\HeaderCollection
*/
public function Parse($sRawHeaders, $bStoreRawHeaders = false, $sParentCharset = '')
{
$this->Clear();
if ($bStoreRawHeaders)
{
$this->sRawHeaders = $sRawHeaders;
}
if (0 === \strlen($this->sParentCharset))
{
$this->sParentCharset = $sParentCharset;
}
$aHeaders = \explode("\n", \str_replace("\r", '', $sRawHeaders));
$sName = null;
$sValue = null;
foreach ($aHeaders as $sHeadersValue)
{
if (0 === strlen($sHeadersValue))
{
continue;
}
$sFirstChar = \substr($sHeadersValue, 0, 1);
if ($sFirstChar !== ' ' && $sFirstChar !== "\t" && false === \strpos($sHeadersValue, ':'))
{
continue;
}
else if (null !== $sName && ($sFirstChar === ' ' || $sFirstChar === "\t"))
{
$sValue = \is_null($sValue) ? '' : $sValue;
if ('?=' === \substr(\rtrim($sHeadersValue), -2))
{
$sHeadersValue = \rtrim($sHeadersValue);
}
if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2))
{
$sHeadersValue = \ltrim($sHeadersValue);
}
if ('=?' === \substr($sHeadersValue, 0, 2))
{
$sValue .= $sHeadersValue;
}
else
{
$sValue .= "\n".$sHeadersValue;
}
}
else
{
if (null !== $sName)
{
$oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset);
if ($oHeader)
{
$this->Add($oHeader);
}
$sName = null;
$sValue = null;
}
$aHeaderParts = \explode(':', $sHeadersValue, 2);
$sName = $aHeaderParts[0];
$sValue = isset($aHeaderParts[1]) ? $aHeaderParts[1] : '';
if ('?=' === \substr(\rtrim($sValue), -2))
{
$sValue = \rtrim($sValue);
}
}
}
if (null !== $sName)
{
$oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset);
if ($oHeader)
{
$this->Add($oHeader);
}
}
return $this;
}
/**
* @return string
*/
public function ToEncodedString()
{
$aResult = array();
$aHeaders =& $this->GetAsArray();
foreach ($aHeaders as /* @var $oHeader \MailSo\Mime\Header */ &$oHeader)
{
$aResult[] = $oHeader->EncodedValue();
}
return \implode(\MailSo\Mime\Enumerations\Constants::CRLF, $aResult);
}
}

View file

@ -0,0 +1,864 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class Message
{
/**
* @var array
*/
private $aHeadersValue;
/**
* @var array
*/
private $aAlternativeParts;
/**
* @var \MailSo\Mime\AttachmentCollection
*/
private $oAttachmentCollection;
/**
* @var bool
*/
private $bAddEmptyTextPart;
/**
* @var bool
*/
private $bAddDefaultXMailer;
/**
* @access private
*/
private function __construct()
{
$this->aHeadersValue = array();
$this->aAlternativeParts = array();
$this->oAttachmentCollection = AttachmentCollection::NewInstance();
$this->bAddEmptyTextPart = true;
$this->bAddDefaultXMailer = true;
}
/**
* @return \MailSo\Mime\Message
*/
public static function NewInstance()
{
return new self();
}
/**
* @return \MailSo\Mime\Message
*/
public function DoesNotCreateEmptyTextPart()
{
$this->bAddEmptyTextPart = false;
return $this;
}
/**
* @return \MailSo\Mime\Message
*/
public function DoesNotAddDefaultXMailer()
{
$this->bAddDefaultXMailer = false;
return $this;
}
/**
* @return string
*/
public function MessageId()
{
return $this->sMessageId;
}
/**
* @param string $sMessageId
*
* @return void
*/
public function SetMessageId($sMessageId)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::MESSAGE_ID] = $sMessageId;
}
/**
* @param string $sHostName = ''
*
* @return void
*/
public function RegenerateMessageId($sHostName = '')
{
$this->SetMessageId($this->generateNewMessageId($sHostName));
}
/**
* @return \MailSo\Mime\AttachmentCollection
*/
public function Attachments()
{
return $this->oAttachmentCollection;
}
/**
* @return \MailSo\Mime\Email|null
*/
public function GetFrom()
{
$oResult = null;
if (isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::FROM_]) &&
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::FROM_] instanceof \MailSo\Mime\Email)
{
$oResult = $this->aHeadersValue[\MailSo\Mime\Enumerations\Header::FROM_];
}
return $oResult;
}
/**
* @return \MailSo\Mime\EmailCollection
*/
public function GetTo()
{
$oResult = \MailSo\Mime\EmailCollection::NewInstance();
if (isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::TO_]) &&
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::TO_] instanceof \MailSo\Mime\EmailCollection)
{
$oResult->MergeWithOtherCollection($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::TO_]);
}
return $oResult->Unique();
}
/**
* @return \MailSo\Mime\EmailCollection
*/
public function GetRcpt()
{
$oResult = \MailSo\Mime\EmailCollection::NewInstance();
if (isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::TO_]) &&
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::TO_] instanceof \MailSo\Mime\EmailCollection)
{
$oResult->MergeWithOtherCollection($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::TO_]);
}
if (isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::CC]) &&
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::CC] instanceof \MailSo\Mime\EmailCollection)
{
$oResult->MergeWithOtherCollection($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::CC]);
}
if (isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::BCC]) &&
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::BCC] instanceof \MailSo\Mime\EmailCollection)
{
$oResult->MergeWithOtherCollection($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::BCC]);
}
return $oResult->Unique();
}
/**
* @param string $sHeader
* @param string $sValue
*
* @return \MailSo\Mime\Message
*/
public function SetCustomHeader($sHeaderName, $sValue)
{
$sHeaderName = \trim($sHeaderName);
if (0 < \strlen($sHeaderName))
{
$this->aHeadersValue[$sHeaderName] = $sValue;
}
return $this;
}
/**
* @param string $sSubject
*
* @return \MailSo\Mime\Message
*/
public function SetSubject($sSubject)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::SUBJECT] = $sSubject;
return $this;
}
/**
* @param string $sInReplyTo
*
* @return \MailSo\Mime\Message
*/
public function SetInReplyTo($sInReplyTo)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::IN_REPLY_TO] = $sInReplyTo;
return $this;
}
/**
* @param string $sReferences
*
* @return \MailSo\Mime\Message
*/
public function SetReferences($sReferences)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::REFERENCES] = $sReferences;
return $this;
}
/**
* @param string $sEmail
*
* @return \MailSo\Mime\Message
*/
public function SetReadConfirmation($sEmail)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO] = $sEmail;
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO] = $sEmail;
return $this;
}
/**
* @param int $iValue
*
* @return \MailSo\Mime\Message
*/
public function SetPriority($iValue)
{
$sResult = '';
switch ($iValue)
{
case \MailSo\Mime\Enumerations\MessagePriority::HIGH:
$sResult = \MailSo\Mime\Enumerations\MessagePriority::HIGH.' (Highest)';
break;
case \MailSo\Mime\Enumerations\MessagePriority::NORMAL:
$sResult = \MailSo\Mime\Enumerations\MessagePriority::NORMAL.' (Normal)';
break;
case \MailSo\Mime\Enumerations\MessagePriority::LOW:
$sResult = \MailSo\Mime\Enumerations\MessagePriority::LOW.' (Lowest)';
break;
}
if (0 < \strlen($sResult))
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::X_PRIORITY] = $sResult;
}
return $this;
}
/**
* @param int $iValue
*
* @return \MailSo\Mime\Message
*/
public function SetSensitivity($iValue)
{
$sResult = '';
switch ($iValue)
{
case \MailSo\Mime\Enumerations\Sensitivity::CONFIDENTIAL:
$sResult = 'Company-Confidential';
break;
case \MailSo\Mime\Enumerations\Sensitivity::PERSONAL:
$sResult = 'Personal';
break;
case \MailSo\Mime\Enumerations\Sensitivity::PRIVATE_:
$sResult = 'Private';
break;
}
if (0 < \strlen($sResult))
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::SENSITIVITY] = $sResult;
}
return $this;
}
/**
* @param string $sXMailer
*
* @return \MailSo\Mime\Message
*/
public function SetXMailer($sXMailer)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::X_MAILER] = $sXMailer;
return $this;
}
/**
* @param \MailSo\Mime\Email $oEmail
*
* @return \MailSo\Mime\Message
*/
public function SetFrom(\MailSo\Mime\Email $oEmail)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::FROM_] = $oEmail;
return $this;
}
/**
* @param \MailSo\Mime\EmailCollection $oEmails
*
* @return \MailSo\Mime\Message
*/
public function SetTo(\MailSo\Mime\EmailCollection $oEmails)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::TO_] = $oEmails;
return $this;
}
/**
* @param $iDateTime $iDateTime
*
* @return \MailSo\Mime\Message
*/
public function SetDate($iDateTime)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::DATE] = gmdate('r', $iDateTime);
return $this;
}
/**
* @param \MailSo\Mime\EmailCollection $oEmails
*
* @return \MailSo\Mime\Message
*/
public function SetReplyTo(\MailSo\Mime\EmailCollection $oEmails)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::REPLY_TO] = $oEmails;
return $this;
}
/**
* @param \MailSo\Mime\EmailCollection $oEmails
*
* @return \MailSo\Mime\Message
*/
public function SetCc(\MailSo\Mime\EmailCollection $oEmails)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::CC] = $oEmails;
return $this;
}
/**
* @param \MailSo\Mime\EmailCollection $oEmails
*
* @return \MailSo\Mime\Message
*/
public function SetBcc(\MailSo\Mime\EmailCollection $oEmails)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::BCC] = $oEmails;
return $this;
}
/**
* @param \MailSo\Mime\EmailCollection $oEmails
*
* @return \MailSo\Mime\Message
*/
public function SetSender(\MailSo\Mime\EmailCollection $oEmails)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::SENDER] = $oEmails;
return $this;
}
/**
* @param string $sType
* @param string $sUid
* @param string $sFolder
*
* @return \MailSo\Mime\Message
*/
public function SetDraftInfo($sType, $sUid, $sFolder)
{
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO] = \MailSo\Mime\ParameterCollection::NewInstance()
->Add(\MailSo\Mime\Parameter::NewInstance('type', $sType))
->Add(\MailSo\Mime\Parameter::NewInstance('uid', $sUid))
->Add(\MailSo\Mime\Parameter::NewInstance('folder', base64_encode($sFolder)))
;
return $this;
}
/**
* @param string $sPlain
*
* @return \MailSo\Mime\Message
*/
public function AddPlain($sPlain)
{
return $this->AddAlternative(
\MailSo\Mime\Enumerations\MimeType::TEXT_PLAIN, trim($sPlain),
\MailSo\Base\Enumerations\Encoding::QUOTED_PRINTABLE);
}
/**
* @param string $sHtml
*
* @return \MailSo\Mime\Message
*/
public function AddHtml($sHtml)
{
return $this->AddAlternative(
\MailSo\Mime\Enumerations\MimeType::TEXT_HTML, trim($sHtml),
\MailSo\Base\Enumerations\Encoding::QUOTED_PRINTABLE);
}
/**
* @param string $sHtmlOrPlainText
* @param bool $bIsHtml = false
*
* @return \MailSo\Mime\Message
*/
public function AddText($sHtmlOrPlainText, $bIsHtml = false)
{
return $bIsHtml ? $this->AddHtml($sHtmlOrPlainText) : $this->AddPlain($sHtmlOrPlainText);
}
/**
* @param string $sContentType
* @param string|resource $mData
* @param string $sContentTransferEncoding = ''
* @param array $aCustomContentTypeParams = array()
*
* @return \MailSo\Mime\Message
*/
public function AddAlternative($sContentType, $mData, $sContentTransferEncoding = '', $aCustomContentTypeParams = array())
{
$this->aAlternativeParts[] = array($sContentType, $mData, $sContentTransferEncoding, $aCustomContentTypeParams);
return $this;
}
/**
* @return string
*/
private function generateNewBoundary()
{
return '----=_Part_'.rand(100, 999).'_'.rand(100000000, 999999999).'.'.time();
}
/**
* @param string $sHostName = ''
*
* @return string
*/
private function generateNewMessageId($sHostName = '')
{
if (0 === strlen($sHostName))
{
$sHostName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'mailso';
}
return '<'.md5(rand(100000, 999999).time().$sHostName).'@'.$sHostName.'>';
}
/**
* @param \MailSo\Mime\Attachment $oAttachment
*
* @return \MailSo\Mime\Part
*/
private function createNewMessageAttachmentBody($oAttachment)
{
$oAttachmentPart = Part::NewInstance();
$sFileName = $oAttachment->FileName();
$sCID = $oAttachment->CID();
$sContentLocation = $oAttachment->ContentLocation();
$oContentTypeParameters = null;
$oContentDispositionParameters = null;
if (0 < strlen(trim($sFileName)))
{
$oContentTypeParameters =
ParameterCollection::NewInstance()->Add(Parameter::NewInstance(
\MailSo\Mime\Enumerations\Parameter::NAME, $sFileName));
$oContentDispositionParameters =
ParameterCollection::NewInstance()->Add(Parameter::NewInstance(
\MailSo\Mime\Enumerations\Parameter::FILENAME, $sFileName));
}
$oAttachmentPart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
$oAttachment->ContentType().';'.
(($oContentTypeParameters) ? ' '.$oContentTypeParameters->ToString() : '')
)
);
$oAttachmentPart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_DISPOSITION,
($oAttachment->IsInline() ? 'inline' : 'attachment').';'.
(($oContentDispositionParameters) ? ' '.$oContentDispositionParameters->ToString() : '')
)
);
if (0 < strlen($sCID))
{
$oAttachmentPart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_ID, $sCID)
);
}
if (0 < strlen($sContentLocation))
{
$oAttachmentPart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_LOCATION, $sContentLocation)
);
}
$oAttachmentPart->Body = $oAttachment->Resource();
if ('message/rfc822' !== strtolower($oAttachment->ContentType()))
{
$oAttachmentPart->Headers->Add(
Header::NewInstance(
\MailSo\Mime\Enumerations\Header::CONTENT_TRANSFER_ENCODING,
\MailSo\Base\Enumerations\Encoding::BASE64
)
);
if (is_resource($oAttachmentPart->Body))
{
$oAttachmentPart->Body =
\MailSo\Base\StreamWrappers\Binary::CreateStream($oAttachmentPart->Body,
\MailSo\Base\StreamWrappers\Binary::GetInlineDecodeOrEncodeFunctionName(
\MailSo\Base\Enumerations\Encoding::BASE64, false));
}
}
return $oAttachmentPart;
}
/**
* @param array $aAlternativeData
*
* @return \MailSo\Mime\Part
*/
private function createNewMessageAlternativePartBody($aAlternativeData)
{
$oAlternativePart = null;
if (is_array($aAlternativeData) && isset($aAlternativeData[0]))
{
$oAlternativePart = Part::NewInstance();
$oParameters = ParameterCollection::NewInstance();
$oParameters->Add(
Parameter::NewInstance(
\MailSo\Mime\Enumerations\Parameter::CHARSET,
\MailSo\Base\Enumerations\Charset::UTF_8)
);
if (isset($aAlternativeData[3]) && \is_array($aAlternativeData[3]) && 0 < \count($aAlternativeData[3]))
{
foreach ($aAlternativeData[3] as $sName => $sValue)
{
$oParameters->Add(Parameter::NewInstance($sName, $sValue));
}
}
$oAlternativePart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
$aAlternativeData[0].'; '.$oParameters->ToString())
);
$oAlternativePart->Body = null;
if (isset($aAlternativeData[1]))
{
if (is_resource($aAlternativeData[1]))
{
$oAlternativePart->Body = $aAlternativeData[1];
}
else if (is_string($aAlternativeData[1]) && 0 < strlen($aAlternativeData[1]))
{
$oAlternativePart->Body =
\MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString($aAlternativeData[1]);
}
}
if (isset($aAlternativeData[2]) && 0 < strlen($aAlternativeData[2]))
{
$oAlternativePart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_TRANSFER_ENCODING,
$aAlternativeData[2]
)
);
if (is_resource($oAlternativePart->Body))
{
$oAlternativePart->Body =
\MailSo\Base\StreamWrappers\Binary::CreateStream($oAlternativePart->Body,
\MailSo\Base\StreamWrappers\Binary::GetInlineDecodeOrEncodeFunctionName(
$aAlternativeData[2], false));
}
}
if (!is_resource($oAlternativePart->Body))
{
$oAlternativePart->Body =
\MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString('');
}
}
return $oAlternativePart;
}
/**
* @param \MailSo\Mime\Part $oPlainPart
* @param \MailSo\Mime\Part $oHtmlPart
*
* @return \MailSo\Mime\Part
*/
private function createNewMessageSimpleOrAlternativeBody()
{
$oResultPart = null;
if (1 < count($this->aAlternativeParts))
{
$oResultPart = Part::NewInstance();
$oResultPart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
\MailSo\Mime\Enumerations\MimeType::MULTIPART_ALTERNATIVE.'; '.
ParameterCollection::NewInstance()->Add(
Parameter::NewInstance(
\MailSo\Mime\Enumerations\Parameter::BOUNDARY,
$this->generateNewBoundary())
)->ToString()
)
);
foreach ($this->aAlternativeParts as $aAlternativeData)
{
$oAlternativePart = $this->createNewMessageAlternativePartBody($aAlternativeData);
if ($oAlternativePart)
{
$oResultPart->SubParts->Add($oAlternativePart);
}
unset($oAlternativePart);
}
}
else if (1 === count($this->aAlternativeParts))
{
$oAlternativePart = $this->createNewMessageAlternativePartBody($this->aAlternativeParts[0]);
if ($oAlternativePart)
{
$oResultPart = $oAlternativePart;
}
}
if (!$oResultPart)
{
if ($this->bAddEmptyTextPart)
{
$oResultPart = $this->createNewMessageAlternativePartBody(array(
\MailSo\Mime\Enumerations\MimeType::TEXT_PLAIN, null
));
}
else
{
$aAttachments = $this->oAttachmentCollection->CloneAsArray();
if (\is_array($aAttachments) && 1 === count($aAttachments) && isset($aAttachments[0]))
{
$this->oAttachmentCollection->Clear();
$oResultPart = $this->createNewMessageAlternativePartBody(array(
$aAttachments[0]->ContentType(), $aAttachments[0]->Resource(),
'', $aAttachments[0]->CustomContentTypeParams()
));
}
}
}
return $oResultPart;
}
/**
* @param \MailSo\Mime\Part $oIncPart
*
* @return \MailSo\Mime\Part
*/
private function createNewMessageRelatedBody($oIncPart)
{
$oResultPart = null;
$aAttachments = $this->oAttachmentCollection->LinkedAttachments();
if (0 < count($aAttachments))
{
$oResultPart = Part::NewInstance();
$oResultPart->Headers->Add(
Header::NewInstance(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
\MailSo\Mime\Enumerations\MimeType::MULTIPART_RELATED.'; '.
ParameterCollection::NewInstance()->Add(
Parameter::NewInstance(
\MailSo\Mime\Enumerations\Parameter::BOUNDARY,
$this->generateNewBoundary())
)->ToString()
)
);
$oResultPart->SubParts->Add($oIncPart);
foreach ($aAttachments as $oAttachment)
{
$oResultPart->SubParts->Add($this->createNewMessageAttachmentBody($oAttachment));
}
}
else
{
$oResultPart = $oIncPart;
}
return $oResultPart;
}
/**
* @param \MailSo\Mime\Part $oIncPart
*
* @return \MailSo\Mime\Part
*/
private function createNewMessageMixedBody($oIncPart)
{
$oResultPart = null;
$aAttachments = $this->oAttachmentCollection->UnlinkedAttachments();
if (0 < count($aAttachments))
{
$oResultPart = Part::NewInstance();
$oResultPart->Headers->AddByName(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
\MailSo\Mime\Enumerations\MimeType::MULTIPART_MIXED.'; '.
ParameterCollection::NewInstance()->Add(
Parameter::NewInstance(
\MailSo\Mime\Enumerations\Parameter::BOUNDARY,
$this->generateNewBoundary())
)->ToString()
);
$oResultPart->SubParts->Add($oIncPart);
foreach ($aAttachments as $oAttachment)
{
$oResultPart->SubParts->Add($this->createNewMessageAttachmentBody($oAttachment));
}
}
else
{
$oResultPart = $oIncPart;
}
return $oResultPart;
}
/**
* @param \MailSo\Mime\Part $oIncPart
* @param bool $bWithoutBcc = false
*
* @return \MailSo\Mime\Part
*/
private function setDefaultHeaders($oIncPart, $bWithoutBcc = false)
{
if (!isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::DATE]))
{
$oIncPart->Headers->SetByName(\MailSo\Mime\Enumerations\Header::DATE, \gmdate('r'), true);
}
if (!isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::MESSAGE_ID]))
{
$oIncPart->Headers->SetByName(\MailSo\Mime\Enumerations\Header::MESSAGE_ID, $this->generateNewMessageId(), true);
}
if (!isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::X_MAILER]) && $this->bAddDefaultXMailer)
{
$oIncPart->Headers->SetByName(\MailSo\Mime\Enumerations\Header::X_MAILER, \MailSo\Version::XMailer(), true);
}
if (!isset($this->aHeadersValue[\MailSo\Mime\Enumerations\Header::MIME_VERSION]))
{
$oIncPart->Headers->SetByName(\MailSo\Mime\Enumerations\Header::MIME_VERSION, '1.0', true);
}
foreach ($this->aHeadersValue as $sName => $mValue)
{
if (\is_object($mValue))
{
if ($mValue instanceof \MailSo\Mime\EmailCollection || $mValue instanceof \MailSo\Mime\Email ||
$mValue instanceof \MailSo\Mime\ParameterCollection)
{
$mValue = $mValue->ToString();
}
}
if (!($bWithoutBcc && \strtolower(\MailSo\Mime\Enumerations\Header::BCC) === \strtolower($sName)))
{
$oIncPart->Headers->SetByName($sName, (string) $mValue);
}
}
return $oIncPart;
}
/**
* @param bool $bWithoutBcc = false
*
* @return \MailSo\Mime\Part
*/
public function ToPart($bWithoutBcc = false)
{
$oPart = $this->createNewMessageSimpleOrAlternativeBody();
$oPart = $this->createNewMessageRelatedBody($oPart);
$oPart = $this->createNewMessageMixedBody($oPart);
$oPart = $this->setDefaultHeaders($oPart, $bWithoutBcc);
return $oPart;
}
/**
* @param bool $bWithoutBcc = false
*
* @return resource
*/
public function ToStream($bWithoutBcc = false)
{
return $this->ToPart($bWithoutBcc)->ToStream();
}
/**
* @param bool $bWithoutBcc = false
*
* @return string
*/
public function ToString($bWithoutBcc = false)
{
return \stream_get_contents($this->ToStream($bWithoutBcc));
}
}

View file

@ -0,0 +1,132 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class Parameter
{
/**
* @var string
*/
private $sName;
/**
* @var string
*/
private $sValue;
/**
* @access private
*
* @param string $sName
* @param string $sValue
*/
private function __construct($sName, $sValue)
{
$this->sName = $sName;
$this->sValue = $sValue;
}
/**
* @param string $sName
* @param string $sValue = ''
*
* @return \MailSo\Mime\Parameter
*/
public static function NewInstance($sName, $sValue = '')
{
return new self($sName, $sValue);
}
/**
* @param string $sName
* @param string $sValue = ''
*
* @return \MailSo\Mime\Parameter
*/
public static function CreateFromParameterLine($sRawParam)
{
$oParameter = self::NewInstance('');
return $oParameter->Parse($sRawParam);
}
/**
* @return \MailSo\Mime\Parameter
*/
public function Reset()
{
$this->sName = '';
$this->sValue = '';
return $this;
}
/**
* @return string
*/
public function Name()
{
return $this->sName;
}
/**
* @return string
*/
public function Value()
{
return $this->sValue;
}
/**
* @param string $sRawParam
* @param string $sSeparator = '='
*
* @return \MailSo\Mime\Parameter
*/
public function Parse($sRawParam, $sSeparator = '=')
{
$this->Reset();
$aParts = explode($sSeparator, $sRawParam, 2);
$this->sName = trim(trim($aParts[0]), '"\'');
if (2 === count($aParts))
{
$this->sValue = trim(trim($aParts[1]), '"\'');
}
return $this;
}
/**
* @param bool $bConvertSpecialsName = false
*
* @return string
*/
public function ToString($bConvertSpecialsName = false)
{
$sResult = '';
if (0 < strlen($this->sName))
{
$sResult = $this->sName.'=';
if ($bConvertSpecialsName && in_array(strtolower($this->sName), array(
strtolower(\MailSo\Mime\Enumerations\Parameter::NAME),
strtolower(\MailSo\Mime\Enumerations\Parameter::FILENAME)
)))
{
$sResult .= '"'.\MailSo\Base\Utils::EncodeUnencodedValue(
\MailSo\Base\Enumerations\Encoding::BASE64_SHORT,
$this->sValue).'"';
}
else
{
$sResult .= '"'.$this->sValue.'"';
}
}
return $sResult;
}
}

View file

@ -0,0 +1,197 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class ParameterCollection extends \MailSo\Base\Collection
{
/**
* @access protected
*
* @param string $sRawParams = ''
*/
protected function __construct($sRawParams = '')
{
parent::__construct();
if (0 < strlen($sRawParams))
{
$this->Parse($sRawParams);
}
}
/**
* @param string $sRawParams = ''
*
* @return \MailSo\Mime\ParameterCollection
*/
public static function NewInstance($sRawParams = '')
{
return new self($sRawParams);
}
/**
* @return \MailSo\Mime\Parameter|null
*/
public function &GetByIndex($iIndex)
{
$mResult = null;
$mResult =& parent::GetByIndex($iIndex);
return $mResult;
}
/**
* @param array $aList
*
* @return \MailSo\Mime\ParameterCollection
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function SetAsArray($aList)
{
parent::SetAsArray($aList);
return $this;
}
/**
* @param string $sName
*
* @return string
*/
public function ParameterValueByName($sName)
{
$sResult = '';
$sName = trim($sName);
$aParams =& $this->GetAsArray();
foreach ($aParams as /* @var $oParam \MailSo\Mime\ParameterCollection */ $oParam)
{
if (strtolower($sName) === strtolower($oParam->Name()))
{
$sResult = $oParam->Value();
break;
}
}
return $sResult;
}
/**
* @param string $sRawParams
*
* @return \MailSo\Mime\ParameterCollection
*/
public function Parse($sRawParams)
{
$this->Clear();
$aDataToParse = explode(';', $sRawParams);
foreach ($aDataToParse as $sParam)
{
$this->Add(Parameter::CreateFromParameterLine($sParam));
}
$this->reParseParameters();
return $this;
}
/**
* @param bool $bConvertSpecialsName = false
*
* @return string
*/
public function ToString($bConvertSpecialsName = false)
{
$aResult = array();
$aParams =& $this->GetAsArray();
foreach ($aParams as /* @var $oParam \MailSo\Mime\Parameter */ $oParam)
{
$sLine = $oParam->ToString($bConvertSpecialsName);
if (0 < strlen($sLine))
{
$aResult[] = $sLine;
}
}
return 0 < count($aResult) ? implode('; ', $aResult) : '';
}
/**
* @return void
*/
private function reParseParameters()
{
$aDataToReParse = $this->CloneAsArray();
$sCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
$this->Clear();
$aPreParams = array();
foreach ($aDataToReParse as /* @var $oParam \MailSo\Mime\Parameter */ $oParam)
{
$aMatch = array();
$sParamName = $oParam->Name();
if (preg_match('/([^\*]+)\*([\d]{1,2})\*/', $sParamName, $aMatch) && isset($aMatch[1], $aMatch[2])
&& 0 < strlen($aMatch[1]) && is_numeric($aMatch[2]))
{
if (!isset($aPreParams[$aMatch[1]]))
{
$aPreParams[$aMatch[1]] = array();
}
$sValue = $oParam->Value();
$aValueParts = explode('\'\'', $sValue, 2);
if (is_array($aValueParts) && 2 === count($aValueParts) && 0 < strlen($aValueParts[1]))
{
$sCharset = $aValueParts[0];
$sValue = $aValueParts[1];
}
$aPreParams[$aMatch[1]][(int) $aMatch[2]] = $sValue;
}
else if (preg_match('/([^\*]+)\*/', $sParamName, $aMatch) && isset($aMatch[1]))
{
if (!isset($aPreParams[$aMatch[1]]))
{
$aPreParams[$aMatch[1]] = array();
}
$sValue = $oParam->Value();
$aValueParts = explode('\'\'', $sValue, 2);
if (is_array($aValueParts) && 2 === count($aValueParts) && 0 < strlen($aValueParts[1]))
{
$sCharset = $aValueParts[0];
$sValue = $aValueParts[1];
}
$aPreParams[$aMatch[1]][0] = $sValue;
}
else
{
$this->Add($oParam);
}
}
foreach ($aPreParams as $sName => $aValues)
{
ksort($aValues);
$sResult = implode(array_values($aValues));
$sResult = urldecode($sResult);
if (0 < strlen($sCharset))
{
$sResult = \MailSo\Base\Utils::ConvertEncoding($sResult,
$sCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
}
$this->Add(Parameter::NewInstance($sName, $sResult));
}
}
}

View file

@ -0,0 +1,72 @@
<?php
namespace MailSo\Mime\Parser;
/**
* @category MailSo
* @package Mime
* @subpackage Parser
*/
class ParserEmpty implements ParserInterface
{
/**
* @param \MailSo\Mime\Part $oPart
*
* @return void
*/
public function StartParse(\MailSo\Mime\Part &$oPart)
{
}
/**
* @param \MailSo\Mime\Part $oPart
*
* @return void
*/
public function EndParse(\MailSo\Mime\Part &$oPart)
{
}
/**
* @param \MailSo\Mime\Part $oPart
*
* @return void
*/
public function StartParseMimePart(\MailSo\Mime\Part &$oPart)
{
}
/**
* @param \MailSo\Mime\Part $oMimePart
*
* @return void
*/
public function EndParseMimePart(\MailSo\Mime\Part &$oPart)
{
}
/**
* @return void
*/
public function InitMimePartHeader()
{
}
/**
* @param string $sBuffer
*
* @return void
*/
public function ReadBuffer($sBuffer)
{
}
/**
* @param string $sBuffer
*
* @return void
*/
public function WriteBody($sBuffer)
{
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace MailSo\Mime\Parser;
/**
* @category MailSo
* @package Mime
* @subpackage Parser
*/
interface ParserInterface
{
/**
* @param \MailSo\Mime\Part $oPart
*
* @return void
*/
public function StartParse(\MailSo\Mime\Part &$oPart);
/**
* @param \MailSo\Mime\Part $oPart
*
* @return void
*/
public function EndParse(\MailSo\Mime\Part &$oPart);
/**
* @param \MailSo\Mime\Part $oPart
*
* @return void
*/
public function StartParseMimePart(\MailSo\Mime\Part &$oPart);
/**
* @param \MailSo\Mime\Part $oMimePart
*
* @return void
*/
public function EndParseMimePart(\MailSo\Mime\Part &$oPart);
/**
* @return void
*/
public function InitMimePartHeader();
/**
* @param string $sBuffer
*
* @return void
*/
public function ReadBuffer($sBuffer);
/**
* @param string $sBuffer
* @return void
*/
public function WriteBody($sBuffer);
}

View file

@ -0,0 +1,44 @@
<?php
namespace MailSo\Mime\Parser;
/**
* @category MailSo
* @package Mime
* @subpackage Parser
*/
class ParserMemory extends ParserEmpty implements ParserInterface
{
/**
* @var \MailSo\Mime\Part
*/
protected $oCurrentMime = null;
/**
* @param \MailSo\Mime\Part $oMimePart
*
* @return void
*/
public function StartParseMimePart(\MailSo\Mime\Part &$oPart)
{
$this->oCurrentMime = $oPart;
}
/**
* @param string $sBuffer
*
* @return void
*/
public function WriteBody($sBuffer)
{
if (null === $this->oCurrentMime->Body)
{
$this->oCurrentMime->Body = \MailSo\Base\ResourceRegistry::CreateMemoryResource();
}
if (\is_resource($this->oCurrentMime->Body))
{
\fwrite($this->oCurrentMime->Body, $sBuffer);
}
}
}

View file

@ -0,0 +1,618 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class Part
{
const POS_HEADERS = 1;
const POS_BODY = 2;
const POS_SUBPARTS = 3;
const POS_CLOSE_BOUNDARY = 4;
const DEFAUL_BUFFER = 8192;
/**
* @var string
*/
public static $DefaultCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
/**
* @var string
*/
public static $ForceCharset = '';
/**
* @var \MailSo\Mime\HeaderCollection
*/
public $Headers;
/**
* @var resource
*/
public $Body;
/**
* @var \MailSo\Mime\PartCollection
*/
public $SubParts;
/**
* @var array
*/
public $LineParts;
/**
* @var string
*/
private $sBoundary;
/**
* @var string
*/
private $sParentCharset;
/**
* @var int
*/
private $iParseBuffer;
/**
* @access private
*/
private function __construct()
{
$this->iParseBuffer = \MailSo\Mime\Part::DEFAUL_BUFFER;
$this->Reset();
}
/**
* @return \MailSo\Mime\Part
*/
public static function NewInstance()
{
return new self();
}
/**
* @return \MailSo\Mime\Part
*/
public function Reset()
{
\MailSo\Base\ResourceRegistry::CloseMemoryResource($this->Body);
$this->Body = null;
$this->Headers = HeaderCollection::NewInstance();
$this->SubParts = PartCollection::NewInstance();
$this->LineParts = array();
$this->sBoundary = '';
$this->sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
return $this;
}
/**
* @return string
*/
public function Boundary()
{
return $this->sBoundary;
}
/**
* @return string
*/
public function ParentCharset()
{
return (0 < \strlen($this->sCharset)) ? $this->sParentCharset : self::$DefaultCharset;
}
/**
* @param string $sParentCharset
* @return \MailSo\Mime\Part
*/
public function SetParentCharset($sParentCharset)
{
$this->sParentCharset = $sParentCharset;
return $this;
}
/**
* @param string $sBoundary
* @return \MailSo\Mime\Part
*/
public function SetBoundary($sBoundary)
{
$this->sBoundary = $sBoundary;
return $this;
}
/**
* @param int $iParseBuffer
* @return \MailSo\Mime\Part
*/
public function SetParseBuffer($iParseBuffer)
{
$this->iParseBuffer = $iParseBuffer;
return $this;
}
/**
* @return string
*/
public function HeaderCharset()
{
return ($this->Headers) ? trim(strtolower($this->Headers->ParameterValue(
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
\MailSo\Mime\Enumerations\Parameter::CHARSET))) : '';
}
/**
* @return string
*/
public function HeaderBoundary()
{
return ($this->Headers) ? trim($this->Headers->ParameterValue(
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
\MailSo\Mime\Enumerations\Parameter::BOUNDARY)) : '';
}
/**
* @return string
*/
public function ContentType()
{
return ($this->Headers) ?
trim(strtolower($this->Headers->ValueByName(
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE))) : '';
}
/**
* @return string
*/
public function ContentTransferEncoding()
{
return ($this->Headers) ?
trim(strtolower($this->Headers->ValueByName(
\MailSo\Mime\Enumerations\Header::CONTENT_TRANSFER_ENCODING))) : '';
}
/**
* @return string
*/
public function ContentID()
{
return ($this->Headers) ? trim($this->Headers->ValueByName(
\MailSo\Mime\Enumerations\Header::CONTENT_ID)) : '';
}
/**
* @return string
*/
public function ContentLocation()
{
return ($this->Headers) ? trim($this->Headers->ValueByName(
\MailSo\Mime\Enumerations\Header::CONTENT_LOCATION)) : '';
}
/**
* @return string
*/
public function FileName()
{
$sResult = '';
if ($this->Headers)
{
$sResult = trim($this->Headers->ParameterValue(
\MailSo\Mime\Enumerations\Header::CONTENT_DISPOSITION,
\MailSo\Mime\Enumerations\Parameter::FILENAME));
if (0 === strlen($sResult))
{
$sResult = trim($this->Headers->ParameterValue(
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
\MailSo\Mime\Enumerations\Parameter::NAME));
}
}
return $sResult;
}
/**
* @param string $sFileName
* @return \MailSo\Mime\Part
*/
public function ParseFromFile($sFileName)
{
$rStreamHandle = (@file_exists($sFileName)) ? @fopen($sFileName, 'rb') : false;
if (is_resource($rStreamHandle))
{
$this->ParseFromStream($rStreamHandle);
if (is_resource($rStreamHandle))
{
fclose($rStreamHandle);
}
}
return $this;
}
/**
* @param string $sRawMessage
* @return \MailSo\Mime\Part
*/
public function ParseFromString($sRawMessage)
{
$rStreamHandle = (0 < strlen($sRawMessage)) ?
\MailSo\Base\ResourceRegistry::CreateMemoryResource() : false;
if (is_resource($rStreamHandle))
{
fwrite($rStreamHandle, $sRawMessage);
unset($sRawMessage);
fseek($rStreamHandle, 0);
$this->ParseFromStream($rStreamHandle);
\MailSo\Base\ResourceRegistry::CloseMemoryResource($rStreamHandle);
}
return $this;
}
/**
* @param resource $rStreamHandle
* @return \MailSo\Mime\Part
*/
public function ParseFromStream($rStreamHandle)
{
$this->Reset();
$oParserClass = new \MailSo\Mime\Parser\ParserMemory();
$oMimePart = null;
$bIsOef = false;
$iOffset = 0;
$sBuffer = '';
$sPrevBuffer = '';
$aBoundaryStack = array();
$oParserClass->StartParse($this);
$this->LineParts[] =& $this;
$this->ParseFromStreamRecursion($rStreamHandle, $oParserClass, $iOffset,
$sPrevBuffer, $sBuffer, $aBoundaryStack, $bIsOef);
$sFirstNotNullCharset = null;
foreach ($this->LineParts as /* @var $oMimePart \MailSo\Mime\Part */ &$oMimePart)
{
$sCharset = $oMimePart->HeaderCharset();
if (0 < strlen($sCharset))
{
$sFirstNotNullCharset = $sCharset;
break;
}
}
$sForceCharset = self::$ForceCharset;
if (0 < strlen($sForceCharset))
{
foreach ($this->LineParts as /* @var $oMimePart \MailSo\Mime\Part */ &$oMimePart)
{
$oMimePart->SetParentCharset($sForceCharset);
$oMimePart->Headers->SetParentCharset($sForceCharset);
}
}
else
{
$sFirstNotNullCharset = (null !== $sFirstNotNullCharset)
? $sFirstNotNullCharset : self::$DefaultCharset;
foreach ($this->LineParts as /* @var $oMimePart \MailSo\Mime\Part */ &$oMimePart)
{
$sHeaderCharset = $oMimePart->HeaderCharset();
$oMimePart->SetParentCharset((0 < strlen($sHeaderCharset)) ? $sHeaderCharset : $sFirstNotNullCharset);
$oMimePart->Headers->SetParentCharset($sHeaderCharset);
}
}
$oParserClass->EndParse($this);
return $this;
}
/**
* @param resource $rStreamHandle
* @return \MailSo\Mime\Part
*/
public function ParseFromStreamRecursion($rStreamHandle, &$oCallbackClass, &$iOffset,
&$sPrevBuffer, &$sBuffer, &$aBoundaryStack, &$bIsOef, $bNotFirstRead = false)
{
$oCallbackClass->StartParseMimePart($this);
$iPos = 0;
$iParsePosition = self::POS_HEADERS;
$sCurrentBoundary = '';
$bIsBoundaryCheck = false;
$aHeadersLines = array();
while (true)
{
if (!$bNotFirstRead)
{
$sPrevBuffer = $sBuffer;
$sBuffer = '';
}
if (!$bIsOef && !feof($rStreamHandle))
{
if (!$bNotFirstRead)
{
$sBuffer = @fread($rStreamHandle, $this->iParseBuffer);
if (false === $sBuffer)
{
break;
}
$oCallbackClass->ReadBuffer($sBuffer);
}
else
{
$bNotFirstRead = false;
}
}
else if ($bIsOef && 0 === strlen($sBuffer))
{
break;
}
else
{
$bIsOef = true;
}
while (true)
{
$sCurrentLine = $sPrevBuffer.$sBuffer;
if (self::POS_HEADERS === $iParsePosition)
{
$iEndLen = 4;
$iPos = strpos($sCurrentLine, "\r\n\r\n", $iOffset);
if (false === $iPos)
{
$iEndLen = 2;
$iPos = strpos($sCurrentLine, "\n\n", $iOffset);
}
if (false !== $iPos)
{
$aHeadersLines[] = substr($sCurrentLine, $iOffset, $iPos + $iEndLen - $iOffset);
$this->Headers->Parse(implode($aHeadersLines))->SetParentCharset($this->HeaderCharset());
$aHeadersLines = array();
$oCallbackClass->InitMimePartHeader();
$sBoundary = $this->HeaderBoundary();
if (0 < strlen($sBoundary))
{
$sBoundary = '--'.$sBoundary;
$sCurrentBoundary = $sBoundary;
array_unshift($aBoundaryStack, $sBoundary);
}
$iOffset = $iPos + $iEndLen;
$iParsePosition = self::POS_BODY;
continue;
}
else
{
$iBufferLen = strlen($sPrevBuffer);
if ($iBufferLen > $iOffset)
{
$aHeadersLines[] = substr($sPrevBuffer, $iOffset);
$iOffset = 0;
}
else
{
$iOffset -= $iBufferLen;
}
break;
}
}
else if (self::POS_BODY === $iParsePosition)
{
$iPos = false;
$sBoundaryLen = 0;
$bIsBoundaryEnd = false;
$bCurrentPartBody = false;
$bIsBoundaryCheck = 0 < count($aBoundaryStack);
foreach ($aBoundaryStack as $sKey => $sBoundary)
{
if (false !== ($iPos = strpos($sCurrentLine, $sBoundary, $iOffset)))
{
if ($sCurrentBoundary === $sBoundary)
{
$bCurrentPartBody = true;
}
$sBoundaryLen = strlen($sBoundary);
if ('--' === substr($sCurrentLine, $iPos + $sBoundaryLen, 2))
{
$sBoundaryLen += 2;
$bIsBoundaryEnd = true;
unset($aBoundaryStack[$sKey]);
$sCurrentBoundary = (isset($aBoundaryStack[$sKey + 1]))
? $aBoundaryStack[$sKey + 1] : '';
}
break;
}
}
if (false !== $iPos)
{
$oCallbackClass->WriteBody(substr($sCurrentLine, $iOffset, $iPos - $iOffset));
$iOffset = $iPos;
if ($bCurrentPartBody)
{
$iParsePosition = self::POS_SUBPARTS;
continue;
}
$oCallbackClass->EndParseMimePart($this);
return true;
}
else
{
$iBufferLen = strlen($sPrevBuffer);
if ($iBufferLen > $iOffset)
{
$oCallbackClass->WriteBody(substr($sPrevBuffer, $iOffset));
$iOffset = 0;
}
else
{
$iOffset -= $iBufferLen;
}
break;
}
}
else if (self::POS_SUBPARTS === $iParsePosition)
{
$iPos = false;
$sBoundaryLen = 0;
$bIsBoundaryEnd = false;
$bCurrentPartBody = false;
$bIsBoundaryCheck = 0 < count($aBoundaryStack);
foreach ($aBoundaryStack as $sKey => $sBoundary)
{
if (false !== ($iPos = strpos($sCurrentLine, $sBoundary, $iOffset)))
{
if ($sCurrentBoundary === $sBoundary)
{
$bCurrentPartBody = true;
}
$sBoundaryLen = strlen($sBoundary);
if ('--' === substr($sCurrentLine, $iPos + $sBoundaryLen, 2))
{
$sBoundaryLen += 2;
$bIsBoundaryEnd = true;
unset($aBoundaryStack[$sKey]);
$sCurrentBoundary = (isset($aBoundaryStack[$sKey + 1]))
? $aBoundaryStack[$sKey + 1] : '';
}
break;
}
}
if (false !== $iPos && $bCurrentPartBody)
{
$iOffset = $iPos + $sBoundaryLen;
$oSubPart = self::NewInstance();
$oSubPart
->SetParseBuffer($this->iParseBuffer)
->ParseFromStreamRecursion($rStreamHandle, $oCallbackClass,
$iOffset, $sPrevBuffer, $sBuffer, $aBoundaryStack, $bIsOef, true);
$this->SubParts->Add($oSubPart);
$this->LineParts[] =& $oSubPart;
//$iParsePosition = self::POS_HEADERS;
unset($oSubPart);
}
else
{
$oCallbackClass->EndParseMimePart($this);
return true;
}
}
}
}
if (0 < strlen($sPrevBuffer))
{
if (self::POS_HEADERS === $iParsePosition)
{
$aHeadersLines[] = ($iOffset < strlen($sPrevBuffer))
? substr($sPrevBuffer, $iOffset)
: $sPrevBuffer;
$this->Headers->Parse(implode($aHeadersLines))->SetParentCharset($this->HeaderCharset());
$aHeadersLines = array();
$oCallbackClass->InitMimePartHeader();
}
else if (self::POS_BODY === $iParsePosition)
{
if (!$bIsBoundaryCheck)
{
$oCallbackClass->WriteBody(($iOffset < strlen($sPrevBuffer))
? substr($sPrevBuffer, $iOffset) : $sPrevBuffer);
}
}
}
else
{
if (self::POS_HEADERS === $iParsePosition && 0 < count($aHeadersLines))
{
$this->Headers->Parse(implode($aHeadersLines))->SetParentCharset($this->HeaderCharset());
$aHeadersLines = array();
$oCallbackClass->InitMimePartHeader();
}
}
$oCallbackClass->EndParseMimePart($this);
return $this;
}
/**
* @return resorce
*/
public function ToStream()
{
$aSubStreams = array(
$this->Headers->ToEncodedString().
\MailSo\Mime\Enumerations\Constants::CRLF.
\MailSo\Mime\Enumerations\Constants::CRLF,
null === $this->Body ? '' : $this->Body,
\MailSo\Mime\Enumerations\Constants::CRLF
);
if (0 < $this->SubParts->Count())
{
$sBoundary = $this->HeaderBoundary();
if (0 < strlen($sBoundary))
{
$aSubStreams[] = '--'.$sBoundary.\MailSo\Mime\Enumerations\Constants::CRLF;
$rSubPartsStream = $this->SubParts->ToStream($sBoundary);
if (is_resource($rSubPartsStream))
{
$aSubStreams[] = $rSubPartsStream;
}
$aSubStreams[] = \MailSo\Mime\Enumerations\Constants::CRLF.
'--'.$sBoundary.'--'.\MailSo\Mime\Enumerations\Constants::CRLF;
}
}
return \MailSo\Base\StreamWrappers\SubStreams::CreateStream($aSubStreams);
}
}

View file

@ -0,0 +1,56 @@
<?php
namespace MailSo\Mime;
/**
* @category MailSo
* @package Mime
*/
class PartCollection extends \MailSo\Base\Collection
{
/**
* @access protected
*/
protected function __construct()
{
parent::__construct();
}
/**
* @return \MailSo\Mime\PartCollection
*/
public static function NewInstance()
{
return new self();
}
/**
* @param string $sBoundary
*
* @return resorce
*/
public function ToStream($sBoundary)
{
$rResult = null;
if (0 < \strlen($sBoundary))
{
$aResult = array();
$aParts =& $this->GetAsArray();
foreach ($aParts as /* @var $oPart \MailSo\Mime\Part */ &$oPart)
{
if (0 < count($aResult))
{
$aResult[] = \MailSo\Mime\Enumerations\Constants::CRLF.
'--'.$sBoundary.\MailSo\Mime\Enumerations\Constants::CRLF;
}
$aResult[] = $oPart->ToStream();
}
return \MailSo\Base\StreamWrappers\SubStreams::CreateStream($aResult);
}
return $rResult;
}
}