mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-29 20:19:22 +03:00
MailSo class properties to typed properties and clean up
This commit is contained in:
parent
22450e7430
commit
731ac52564
53 changed files with 677 additions and 1944 deletions
|
|
@ -23,8 +23,7 @@ abstract class DateTimeHelper
|
|||
public static function GetUtcTimeZoneObject() : \DateTimeZone
|
||||
{
|
||||
static $oDateTimeZone = null;
|
||||
if (null === $oDateTimeZone)
|
||||
{
|
||||
if (null === $oDateTimeZone) {
|
||||
$oDateTimeZone = new \DateTimeZone('UTC');
|
||||
}
|
||||
return $oDateTimeZone;
|
||||
|
|
@ -37,8 +36,7 @@ abstract class DateTimeHelper
|
|||
public static function ParseRFC2822DateString(string $sDateTime) : int
|
||||
{
|
||||
$sDateTime = \trim($sDateTime);
|
||||
if (empty($sDateTime))
|
||||
{
|
||||
if (empty($sDateTime)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -54,13 +52,12 @@ abstract class DateTimeHelper
|
|||
public static function ParseInternalDateString(string $sDateTime) : int
|
||||
{
|
||||
$sDateTime = \trim($sDateTime);
|
||||
if (empty($sDateTime))
|
||||
{
|
||||
if (empty($sDateTime)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (\preg_match('/^[a-z]{2,4}, /i', $sDateTime)) // RFC2822 ~ "Thu, 10 Jun 2010 08:58:33 -0700 (PDT)"
|
||||
{
|
||||
// RFC2822 ~ "Thu, 10 Jun 2010 08:58:33 -0700 (PDT)"
|
||||
if (\preg_match('/^[a-z]{2,4}, /i', $sDateTime)) {
|
||||
return static::ParseRFC2822DateString($sDateTime);
|
||||
}
|
||||
|
||||
|
|
@ -74,8 +71,7 @@ abstract class DateTimeHelper
|
|||
public static function ParseDateStringType1(string $sDateTime) : int
|
||||
{
|
||||
$sDateTime = \trim($sDateTime);
|
||||
if (empty($sDateTime))
|
||||
{
|
||||
if (empty($sDateTime)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,87 +201,6 @@ abstract class HtmlUtils
|
|||
. $oDoc->saveHTML($oBody) . '</html>';
|
||||
}
|
||||
|
||||
public static function ConvertPlainToHtml(string $sText, bool $bLinksWithTargetBlank = true) : string
|
||||
{
|
||||
$sText = \trim($sText);
|
||||
if (!\strlen($sText))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$sText = (new \MailSo\Base\LinkFinder)
|
||||
->Text($sText)
|
||||
->UseDefaultWrappers($bLinksWithTargetBlank)
|
||||
->CompileText()
|
||||
;
|
||||
|
||||
$sText = \str_replace("\r", '', $sText);
|
||||
|
||||
$aText = \explode("\n", $sText);
|
||||
unset($sText);
|
||||
|
||||
$bIn = false;
|
||||
$bDo = true;
|
||||
do
|
||||
{
|
||||
$bDo = false;
|
||||
$aNextText = array();
|
||||
foreach ($aText as $sTextLine)
|
||||
{
|
||||
$bStart = 0 === \strpos(\ltrim($sTextLine), '>');
|
||||
if ($bStart && !$bIn)
|
||||
{
|
||||
$bDo = true;
|
||||
$bIn = true;
|
||||
$aNextText[] = '<blockquote>';
|
||||
$aNextText[] = \substr(\ltrim($sTextLine), 4);
|
||||
}
|
||||
else if (!$bStart && $bIn)
|
||||
{
|
||||
$bIn = false;
|
||||
$aNextText[] = '</blockquote>';
|
||||
$aNextText[] = $sTextLine;
|
||||
}
|
||||
else if ($bStart && $bIn)
|
||||
{
|
||||
$aNextText[] = \substr(\ltrim($sTextLine), 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aNextText[] = $sTextLine;
|
||||
}
|
||||
}
|
||||
|
||||
if ($bIn)
|
||||
{
|
||||
$bIn = false;
|
||||
$aNextText[] = '</blockquote>';
|
||||
}
|
||||
|
||||
$aText = $aNextText;
|
||||
}
|
||||
while ($bDo);
|
||||
|
||||
$sText = \join("\n", $aText);
|
||||
unset($aText);
|
||||
|
||||
$sText = \preg_replace('/[\n][ ]+/', "\n", $sText);
|
||||
// $sText = \preg_replace('/[\s]+([\s])/', '\\1', $sText);
|
||||
|
||||
$sText = \preg_replace('/<blockquote>[\s]+/i', '<blockquote>', $sText);
|
||||
$sText = \preg_replace('/[\s]+<\/blockquote>/i', '</blockquote>', $sText);
|
||||
|
||||
$sText = \preg_replace('/<\/blockquote>([\n]{0,2})<blockquote>/i', '\\1', $sText);
|
||||
$sText = \preg_replace('/[\n]{3,}/', "\n\n", $sText);
|
||||
|
||||
$sText = \strtr($sText, array(
|
||||
"\t" => "\xC2\xA0\xC2\xA0\xC2\xA0\xC2\xA0",
|
||||
' ' => "\xC2\xA0\xC2\xA0"
|
||||
));
|
||||
|
||||
return \nl2br($sText);
|
||||
}
|
||||
|
||||
public static function ConvertHtmlToPlain(string $sText) : string
|
||||
{
|
||||
$sText = \MailSo\Base\Utils::StripSpaces($sText);
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ class Http
|
|||
public static function SingletonInstance() : self
|
||||
{
|
||||
static $oInstance = null;
|
||||
if (null === $oInstance)
|
||||
{
|
||||
if (null === $oInstance) {
|
||||
$oInstance = new self;
|
||||
}
|
||||
|
||||
|
|
@ -65,8 +64,7 @@ class Http
|
|||
|
||||
public function IsLocalhost(string $sValueToCheck = '') : bool
|
||||
{
|
||||
if (empty($sValueToCheck))
|
||||
{
|
||||
if (empty($sValueToCheck)) {
|
||||
$sValueToCheck = static::GetServer('REMOTE_ADDR', '');
|
||||
}
|
||||
|
||||
|
|
@ -76,8 +74,7 @@ class Http
|
|||
public function GetRawBody() : string
|
||||
{
|
||||
static $sRawBody = null;
|
||||
if (null === $sRawBody)
|
||||
{
|
||||
if (null === $sRawBody) {
|
||||
$sBody = \file_get_contents('php://input');
|
||||
$sRawBody = (false !== $sBody) ? $sBody : '';
|
||||
}
|
||||
|
|
@ -88,7 +85,7 @@ class Http
|
|||
{
|
||||
$sServerKey = 'HTTP_'.\strtoupper(\str_replace('-', '_', $sHeader));
|
||||
$sResultHeader = static::GetServer($sServerKey, '');
|
||||
if (0 === \strlen($sResultHeader) && \MailSo\Base\Utils::FunctionCallable('apache_request_headers')) {
|
||||
if (!\strlen($sResultHeader) && \MailSo\Base\Utils::FunctionCallable('apache_request_headers')) {
|
||||
$sHeaders = \apache_request_headers();
|
||||
if (isset($sHeaders[$sHeader])) {
|
||||
$sResultHeader = $sHeaders[$sHeader];
|
||||
|
|
@ -105,69 +102,44 @@ class Http
|
|||
public function IsSecure(bool $bCheckProxy = true) : bool
|
||||
{
|
||||
$sHttps = \strtolower(static::GetServer('HTTPS', ''));
|
||||
if ('on' === $sHttps || ('' === $sHttps && '443' === (string) static::GetServer('SERVER_PORT', '')))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($bCheckProxy && (
|
||||
return ('on' === $sHttps || ('' === $sHttps && '443' === (string) static::GetServer('SERVER_PORT', '')))
|
||||
|| ($bCheckProxy && (
|
||||
('https' === \strtolower(static::GetServer('HTTP_X_FORWARDED_PROTO', ''))) ||
|
||||
('on' === \strtolower(static::GetServer('HTTP_X_FORWARDED_SSL', '')))
|
||||
))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
));
|
||||
}
|
||||
|
||||
public function GetHost(bool $bWithRemoteUserData = false, bool $bWithoutWWW = true, bool $bWithoutPort = false) : string
|
||||
{
|
||||
$sHost = static::GetServer('HTTP_HOST', '');
|
||||
if (!\strlen($sHost))
|
||||
{
|
||||
if (!\strlen($sHost)) {
|
||||
$sName = static::GetServer('SERVER_NAME');
|
||||
$iPort = (int) static::GetServer('SERVER_PORT', 80);
|
||||
|
||||
$sHost = (\in_array($iPort, array(80, 433))) ? $sName : $sName.':'.$iPort;
|
||||
}
|
||||
|
||||
if ($bWithoutWWW)
|
||||
{
|
||||
if ($bWithoutWWW) {
|
||||
$sHost = 'www.' === \substr(\strtolower($sHost), 0, 4) ? \substr($sHost, 4) : $sHost;
|
||||
}
|
||||
|
||||
if ($bWithRemoteUserData)
|
||||
{
|
||||
if ($bWithRemoteUserData) {
|
||||
$sUser = \trim(static::GetServer('REMOTE_USER', ''));
|
||||
$sHost = (\strlen($sUser) ? $sUser.'@' : '').$sHost;
|
||||
}
|
||||
|
||||
if ($bWithoutPort)
|
||||
{
|
||||
$sHost = \preg_replace('/:\d+$/', '', $sHost);
|
||||
}
|
||||
|
||||
return $sHost;
|
||||
return $bWithoutPort ? \preg_replace('/:\d+$/', '', $sHost) : $sHost;
|
||||
}
|
||||
|
||||
public function GetClientIp(bool $bCheckProxy = false) : string
|
||||
{
|
||||
$sIp = '';
|
||||
if ($bCheckProxy && null !== static::GetServer('HTTP_CLIENT_IP', null))
|
||||
{
|
||||
$sIp = static::GetServer('HTTP_CLIENT_IP', '');
|
||||
if ($bCheckProxy && null !== static::GetServer('HTTP_CLIENT_IP', null)) {
|
||||
return static::GetServer('HTTP_CLIENT_IP', '');
|
||||
}
|
||||
else if ($bCheckProxy && null !== static::GetServer('HTTP_X_FORWARDED_FOR', null))
|
||||
{
|
||||
$sIp = static::GetServer('HTTP_X_FORWARDED_FOR', '');
|
||||
if ($bCheckProxy && null !== static::GetServer('HTTP_X_FORWARDED_FOR', null)) {
|
||||
return static::GetServer('HTTP_X_FORWARDED_FOR', '');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sIp = static::GetServer('REMOTE_ADDR', '');
|
||||
}
|
||||
|
||||
return $sIp;
|
||||
return static::GetServer('REMOTE_ADDR', '');
|
||||
}
|
||||
|
||||
public static function checkETag(string $ETag) : void
|
||||
|
|
@ -236,8 +208,7 @@ class Http
|
|||
|
||||
public static function StatusHeader(int $iStatus, string $sCustomStatusText = '') : void
|
||||
{
|
||||
if (99 < $iStatus)
|
||||
{
|
||||
if (99 < $iStatus) {
|
||||
$aStatus = array(
|
||||
200 => 'OK',
|
||||
206 => 'Partial Content',
|
||||
|
|
@ -253,7 +224,7 @@ class Http
|
|||
500 => 'Internal Server Error'
|
||||
);
|
||||
|
||||
$sHeaderText = (0 === \strlen($sCustomStatusText) && isset($aStatus[$iStatus]) ? $aStatus[$iStatus] : $sCustomStatusText);
|
||||
$sHeaderText = (!\strlen($sCustomStatusText) && isset($aStatus[$iStatus]) ? $aStatus[$iStatus] : $sCustomStatusText);
|
||||
|
||||
\http_response_code($iStatus);
|
||||
if (isset($_SERVER['SERVER_PROTOCOL'])) {
|
||||
|
|
|
|||
|
|
@ -1,259 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Base;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Base
|
||||
*/
|
||||
class LinkFinder
|
||||
{
|
||||
/**
|
||||
* @const
|
||||
*/
|
||||
const OPEN_LINK = '@#@link{';
|
||||
const CLOSE_LINK = '}link@#@';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aPrepearPlainStringUrls;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sText;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $fLinkWrapper;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iHtmlSpecialCharsFlags;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $fMailWrapper;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iOptimizationLimit;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->iHtmlSpecialCharsFlags = (\defined('ENT_QUOTES') && \defined('ENT_SUBSTITUTE') && \defined('ENT_HTML401'))
|
||||
? ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 : ENT_QUOTES;
|
||||
|
||||
if (\defined('ENT_IGNORE'))
|
||||
{
|
||||
$this->iHtmlSpecialCharsFlags |= ENT_IGNORE;
|
||||
}
|
||||
|
||||
$this->iOptimizationLimit = 300000;
|
||||
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
public function Clear() : self
|
||||
{
|
||||
$this->aPrepearPlainStringUrls = array();
|
||||
$this->fLinkWrapper = null;
|
||||
$this->fMailWrapper = null;
|
||||
$this->sText = '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function Text(string $sText) : self
|
||||
{
|
||||
$this->sText = $sText;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fLinkWrapper
|
||||
*/
|
||||
public function LinkWrapper($fLinkWrapper) : self
|
||||
{
|
||||
$this->fLinkWrapper = $fLinkWrapper;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fMailWrapper
|
||||
*/
|
||||
public function MailWrapper($fMailWrapper) : self
|
||||
{
|
||||
$this->fMailWrapper = $fMailWrapper;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function UseDefaultWrappers(bool $bAddTargetBlank = false) : self
|
||||
{
|
||||
$this->fLinkWrapper = function ($sLink) use ($bAddTargetBlank) {
|
||||
|
||||
$sNameLink = $sLink;
|
||||
if (!\preg_match('/^[a-z]{3,5}\:\/\//i', \ltrim($sLink)))
|
||||
{
|
||||
$sLink = 'https://'.\ltrim($sLink);
|
||||
}
|
||||
|
||||
return '<a '.($bAddTargetBlank ? 'target="_blank" ': '').'href="'.$sLink.'">'.$sNameLink.'</a>';
|
||||
};
|
||||
|
||||
$this->fMailWrapper = function ($sEmail) use ($bAddTargetBlank) {
|
||||
return '<a '.($bAddTargetBlank ? 'target="_blank" ': '').'href="mailto:'.$sEmail.'">'.$sEmail.'</a>';
|
||||
};
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function CompileText(bool $bUseHtmlSpecialChars = true) : string
|
||||
{
|
||||
$sText = \substr($this->sText, 0, $this->iOptimizationLimit);
|
||||
$sSubText = \substr($this->sText, $this->iOptimizationLimit);
|
||||
|
||||
$this->aPrepearPlainStringUrls = array();
|
||||
if (null !== $this->fLinkWrapper && \is_callable($this->fLinkWrapper))
|
||||
{
|
||||
$sText = $this->findLinks($sText, $this->fLinkWrapper);
|
||||
}
|
||||
|
||||
if (null !== $this->fMailWrapper && \is_callable($this->fMailWrapper))
|
||||
{
|
||||
$sText = $this->findMails($sText, $this->fMailWrapper);
|
||||
}
|
||||
|
||||
$sResult = '';
|
||||
if ($bUseHtmlSpecialChars)
|
||||
{
|
||||
$sResult = \htmlentities($sText.$sSubText, $this->iHtmlSpecialCharsFlags, 'UTF-8');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = $sText.$sSubText;
|
||||
}
|
||||
|
||||
unset($sText, $sSubText);
|
||||
|
||||
if (\count($this->aPrepearPlainStringUrls))
|
||||
{
|
||||
$aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
|
||||
$sResult = \preg_replace_callback('/'.\preg_quote(static::OPEN_LINK, '/').
|
||||
'([\d]+)'.\preg_quote(static::CLOSE_LINK, '/').'/',
|
||||
function ($aMatches) use ($aPrepearPlainStringUrls) {
|
||||
$iIndex = (int) $aMatches[1];
|
||||
return isset($aPrepearPlainStringUrls[$iIndex]) ? $aPrepearPlainStringUrls[$iIndex] : '';
|
||||
}, $sResult);
|
||||
|
||||
$this->aPrepearPlainStringUrls = array();
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fWrapper
|
||||
*/
|
||||
private function findLinks(string $sText, $fWrapper) : string
|
||||
{
|
||||
$sPattern = '/([\W]|^)((?:https?:\/\/)|(?:svn:\/\/)|(?:git:\/\/)|(?:s?ftps?:\/\/)|(?:www\.))'.
|
||||
'((\S+?)(\\/)?)((?:>)?|[^\w\=\\/;\(\)\[\]]*?)(?=<|\s|$)/imu';
|
||||
|
||||
$aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
|
||||
$sText = \preg_replace_callback($sPattern, function ($aMatch) use ($fWrapper, &$aPrepearPlainStringUrls) {
|
||||
|
||||
if (\is_array($aMatch) && 6 < \count($aMatch))
|
||||
{
|
||||
while (\in_array($sChar = \substr($aMatch[3], -1), array(']', ')')))
|
||||
{
|
||||
if (\substr_count($aMatch[3], ']' === $sChar ? '[': '(') - \substr_count($aMatch[3], $sChar) < 0)
|
||||
{
|
||||
$aMatch[3] = \substr($aMatch[3], 0, -1);
|
||||
$aMatch[6] = (']' === $sChar ? ']': ')').$aMatch[6];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$sLinkWithWrap = $fWrapper($aMatch[2].$aMatch[3]);
|
||||
if (\is_string($sLinkWithWrap) && \strlen($sLinkWithWrap))
|
||||
{
|
||||
$aPrepearPlainStringUrls[] = \stripslashes($sLinkWithWrap);
|
||||
return $aMatch[1].
|
||||
static::OPEN_LINK.
|
||||
(\count($aPrepearPlainStringUrls) - 1).
|
||||
static::CLOSE_LINK.
|
||||
$aMatch[6];
|
||||
}
|
||||
|
||||
return $aMatch[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}, $sText);
|
||||
|
||||
if (\count($aPrepearPlainStringUrls))
|
||||
{
|
||||
$this->aPrepearPlainStringUrls = $aPrepearPlainStringUrls;
|
||||
}
|
||||
|
||||
return $sText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fWrapper
|
||||
*/
|
||||
private function findMails(string $sText, $fWrapper) : string
|
||||
{
|
||||
$sPattern = '/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/';
|
||||
|
||||
$aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
|
||||
$sText = \preg_replace_callback($sPattern, function ($aMatch) use ($fWrapper, &$aPrepearPlainStringUrls) {
|
||||
|
||||
if (\is_array($aMatch) && isset($aMatch[1]))
|
||||
{
|
||||
$sMailWithWrap = $fWrapper($aMatch[1]);
|
||||
if (\is_string($sMailWithWrap) && \strlen($sMailWithWrap))
|
||||
{
|
||||
$aPrepearPlainStringUrls[] = \stripslashes($sMailWithWrap);
|
||||
return static::OPEN_LINK.
|
||||
(\count($aPrepearPlainStringUrls) - 1).
|
||||
static::CLOSE_LINK;
|
||||
}
|
||||
|
||||
return $aMatch[1];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}, $sText);
|
||||
|
||||
if (\count($aPrepearPlainStringUrls))
|
||||
{
|
||||
$this->aPrepearPlainStringUrls = $aPrepearPlainStringUrls;
|
||||
}
|
||||
|
||||
return $sText;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,10 +17,7 @@ namespace MailSo\Base;
|
|||
*/
|
||||
abstract class ResourceRegistry
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $Resources = array();
|
||||
public static array $Resources = array();
|
||||
|
||||
/**
|
||||
* @staticvar bool $bInited
|
||||
|
|
@ -28,16 +25,12 @@ abstract class ResourceRegistry
|
|||
private static function regResourcesShutdownFunc() : void
|
||||
{
|
||||
static $bInited = false;
|
||||
if (!$bInited)
|
||||
{
|
||||
if (!$bInited) {
|
||||
$bInited = true;
|
||||
\register_shutdown_function(function () {
|
||||
if (\is_array(static::$Resources))
|
||||
{
|
||||
foreach (\array_keys(static::$Resources) as $sKey)
|
||||
{
|
||||
if (\is_resource(static::$Resources[$sKey]))
|
||||
{
|
||||
if (\is_array(static::$Resources)) {
|
||||
foreach (\array_keys(static::$Resources) as $sKey) {
|
||||
if (\is_resource(static::$Resources[$sKey])) {
|
||||
\fclose(static::$Resources[$sKey]);
|
||||
}
|
||||
static::$Resources[$sKey] = null;
|
||||
|
|
@ -57,8 +50,7 @@ abstract class ResourceRegistry
|
|||
self::regResourcesShutdownFunc();
|
||||
|
||||
$oResult = \fopen('php://temp/maxmemory:'.($iMemoryMaxInMb * 1024 * 1024), 'r+b');
|
||||
if (\is_resource($oResult))
|
||||
{
|
||||
if (\is_resource($oResult)) {
|
||||
static::$Resources[(string) $oResult] = $oResult;
|
||||
return $oResult;
|
||||
}
|
||||
|
|
@ -72,8 +64,7 @@ abstract class ResourceRegistry
|
|||
public static function CreateMemoryResourceFromString(string $sString)
|
||||
{
|
||||
$oResult = self::CreateMemoryResource();
|
||||
if (\is_resource($oResult))
|
||||
{
|
||||
if (\is_resource($oResult)) {
|
||||
\fwrite($oResult, $sString);
|
||||
\rewind($oResult);
|
||||
}
|
||||
|
|
@ -86,18 +77,15 @@ abstract class ResourceRegistry
|
|||
*/
|
||||
public static function CloseMemoryResource(&$rResource) : void
|
||||
{
|
||||
if (\is_resource($rResource))
|
||||
{
|
||||
if (\is_resource($rResource)) {
|
||||
$sKey = (string) $rResource;
|
||||
if (isset(static::$Resources[$sKey]))
|
||||
{
|
||||
if (isset(static::$Resources[$sKey])) {
|
||||
\fclose(static::$Resources[$sKey]);
|
||||
static::$Resources[$sKey] = null;
|
||||
unset(static::$Resources[$sKey]);
|
||||
}
|
||||
|
||||
if (\is_resource($rResource))
|
||||
{
|
||||
if (\is_resource($rResource)) {
|
||||
\fclose($rResource);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,50 +27,26 @@ class Binary
|
|||
*/
|
||||
const STREAM_NAME = 'mailsobinary';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
private static array $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aRememberStreams = array();
|
||||
private static array $aRememberStreams = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $rStream;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFromEncoding;
|
||||
private string $sFromEncoding;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sToEncoding;
|
||||
private string $sToEncoding;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFunctionName;
|
||||
private string $sFunctionName;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPos;
|
||||
private int $iPos;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBuffer;
|
||||
private string $sBuffer;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sReadEndBuffer;
|
||||
private string $sReadEndBuffer;
|
||||
|
||||
public static function GetInlineDecodeOrEncodeFunctionName(string $sContentTransferEncoding, bool $bDecode = true) : string
|
||||
{
|
||||
|
|
@ -96,8 +72,7 @@ class Binary
|
|||
$sEndBuffer = '';
|
||||
$iQuotedPrintableLen = \strlen($sEncodedString);
|
||||
$iLastSpace = \strrpos($sEncodedString, ' ');
|
||||
if (false !== $iLastSpace && $iLastSpace + 1 < $iQuotedPrintableLen)
|
||||
{
|
||||
if (false !== $iLastSpace && $iLastSpace + 1 < $iQuotedPrintableLen) {
|
||||
$sEndBuffer = \substr($sEncodedString, $iLastSpace + 1);
|
||||
$sEncodedString = \substr($sEncodedString, 0, $iLastSpace + 1);
|
||||
}
|
||||
|
|
@ -109,10 +84,8 @@ class Binary
|
|||
*/
|
||||
public static function IsStreamRemembed($rStream) : bool
|
||||
{
|
||||
foreach (self::$aRememberStreams as $rRem)
|
||||
{
|
||||
if ($rStream === $rRem)
|
||||
{
|
||||
foreach (self::$aRememberStreams as $rRem) {
|
||||
if ($rStream === $rRem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -125,8 +98,7 @@ class Binary
|
|||
*/
|
||||
public static function RememberStream($rStream)
|
||||
{
|
||||
if (!self::IsStreamRemembed($rStream))
|
||||
{
|
||||
if (!self::IsStreamRemembed($rStream)) {
|
||||
self::$aRememberStreams[] = $rStream;
|
||||
}
|
||||
}
|
||||
|
|
@ -139,15 +111,13 @@ class Binary
|
|||
public static function CreateStream($rStream,
|
||||
string $sUtilsDecodeOrEncodeFunctionName = null, string $sFromEncoding = null, string $sToEncoding = null)
|
||||
{
|
||||
if (null === $sUtilsDecodeOrEncodeFunctionName || !\strlen($sUtilsDecodeOrEncodeFunctionName))
|
||||
{
|
||||
if (null === $sUtilsDecodeOrEncodeFunctionName || !\strlen($sUtilsDecodeOrEncodeFunctionName)) {
|
||||
$sUtilsDecodeOrEncodeFunctionName = 'InlineNullDecode';
|
||||
}
|
||||
|
||||
$sHashName = \md5(\microtime(true).\rand(1000, 9999));
|
||||
|
||||
if (null !== $sFromEncoding && null !== $sToEncoding && $sFromEncoding !== $sToEncoding)
|
||||
{
|
||||
if (null !== $sFromEncoding && null !== $sToEncoding && $sFromEncoding !== $sToEncoding) {
|
||||
$rStream = self::CreateStream($rStream, $sUtilsDecodeOrEncodeFunctionName);
|
||||
$sUtilsDecodeOrEncodeFunctionName = 'InlineConvertDecode';
|
||||
}
|
||||
|
|
@ -216,27 +186,19 @@ class Binary
|
|||
$sReturn = '';
|
||||
$sFunctionName = $this->sFunctionName;
|
||||
|
||||
if ($iCount > 0)
|
||||
{
|
||||
if ($iCount < \strlen($this->sBuffer))
|
||||
{
|
||||
if ($iCount > 0) {
|
||||
if ($iCount < \strlen($this->sBuffer)) {
|
||||
$sReturn = \substr($this->sBuffer, 0, $iCount);
|
||||
$this->sBuffer = \substr($this->sBuffer, $iCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sReturn = $this->sBuffer;
|
||||
while ($iCount > 0)
|
||||
{
|
||||
if (\feof($this->rStream))
|
||||
{
|
||||
if (!\strlen($this->sBuffer.$sReturn))
|
||||
{
|
||||
while ($iCount > 0) {
|
||||
if (\feof($this->rStream)) {
|
||||
if (!\strlen($this->sBuffer.$sReturn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (\strlen($this->sReadEndBuffer))
|
||||
{
|
||||
if (\strlen($this->sReadEndBuffer)) {
|
||||
$sReturn .= self::$sFunctionName($this->sReadEndBuffer,
|
||||
$this->sReadEndBuffer, $this->sFromEncoding, $this->sToEncoding);
|
||||
|
||||
|
|
@ -245,12 +207,9 @@ class Binary
|
|||
|
||||
$iCount = 0;
|
||||
$this->sBuffer = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sReadResult = \fread($this->rStream, 8192);
|
||||
if (false === $sReadResult)
|
||||
{
|
||||
if (false === $sReadResult) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -258,14 +217,11 @@ class Binary
|
|||
$this->sReadEndBuffer, $this->sFromEncoding, $this->sToEncoding);
|
||||
|
||||
$iDecodeLen = \strlen($sReadResult);
|
||||
if ($iCount < $iDecodeLen)
|
||||
{
|
||||
if ($iCount < $iDecodeLen) {
|
||||
$this->sBuffer = \substr($sReturn, $iCount);
|
||||
$sReturn = \substr($sReturn, 0, $iCount);
|
||||
$iCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iCount -= $iDecodeLen;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,25 +26,16 @@ class Literal
|
|||
*/
|
||||
const STREAM_NAME = 'mailsoliteral';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
private static array $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $rStream;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSize;
|
||||
private int $iSize;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPos;
|
||||
private int $iPos;
|
||||
|
||||
/**
|
||||
* @param resource $rStream
|
||||
|
|
@ -95,20 +86,16 @@ class Literal
|
|||
public function stream_read(int $iCount) : string
|
||||
{
|
||||
$sResult = false;
|
||||
if ($this->iSize < $this->iPos + $iCount)
|
||||
{
|
||||
if ($this->iSize < $this->iPos + $iCount) {
|
||||
$iCount = $this->iSize - $this->iPos;
|
||||
}
|
||||
|
||||
if ($iCount > 0)
|
||||
{
|
||||
if ($iCount > 0) {
|
||||
$sReadResult = '';
|
||||
$iRead = $iCount;
|
||||
while (0 < $iRead)
|
||||
{
|
||||
while (0 < $iRead) {
|
||||
$sAddRead = \fread($this->rStream, $iRead);
|
||||
if (false === $sAddRead)
|
||||
{
|
||||
if (false === $sAddRead) {
|
||||
$sReadResult = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -118,8 +105,7 @@ class Literal
|
|||
$this->iPos += \strlen($sAddRead);
|
||||
}
|
||||
|
||||
if (false !== $sReadResult)
|
||||
{
|
||||
if (false !== $sReadResult) {
|
||||
$sResult = $sReadResult;
|
||||
}
|
||||
}
|
||||
|
|
@ -163,6 +149,8 @@ class Literal
|
|||
|
||||
public function stream_seek() : bool
|
||||
{
|
||||
// $this->iPos = $offset;
|
||||
// \fseek($this->rStream, $offset, $whence);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,35 +27,17 @@ class SubStreams
|
|||
*/
|
||||
const STREAM_NAME = 'mailsosubstreams';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $aStreams = array();
|
||||
private static array $aStreams = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aSubStreams;
|
||||
private array $aSubStreams;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iIndex;
|
||||
private int $iIndex;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBuffer;
|
||||
private string $sBuffer;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bIsEnd;
|
||||
private bool $bIsEnd;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPos;
|
||||
private int $iPos;
|
||||
|
||||
/**
|
||||
* @return resource|bool
|
||||
|
|
@ -72,20 +54,6 @@ class SubStreams
|
|||
return \fopen(self::STREAM_NAME.'://'.$sHashName, 'rb');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource|null
|
||||
*/
|
||||
protected function &getPart()
|
||||
{
|
||||
$nNull = null;
|
||||
if (isset($this->aSubStreams[$this->iIndex]))
|
||||
{
|
||||
return $this->aSubStreams[$this->iIndex];
|
||||
}
|
||||
|
||||
return $nNull;
|
||||
}
|
||||
|
||||
public function stream_open(string $sPath) : bool
|
||||
{
|
||||
$this->aSubStreams = array();
|
||||
|
|
@ -119,53 +87,41 @@ class SubStreams
|
|||
{
|
||||
$sReturn = '';
|
||||
$mCurrentPart = null;
|
||||
if ($iCount > 0)
|
||||
{
|
||||
if ($iCount < \strlen($this->sBuffer))
|
||||
{
|
||||
if ($iCount > 0) {
|
||||
if ($iCount < \strlen($this->sBuffer)) {
|
||||
$sReturn = \substr($this->sBuffer, 0, $iCount);
|
||||
$this->sBuffer = \substr($this->sBuffer, $iCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sReturn = $this->sBuffer;
|
||||
while ($iCount > 0)
|
||||
{
|
||||
$mCurrentPart =& $this->getPart();
|
||||
if (null === $mCurrentPart)
|
||||
{
|
||||
while ($iCount > 0) {
|
||||
$mCurrentPart = isset($this->aSubStreams[$this->iIndex])
|
||||
? $this->aSubStreams[$this->iIndex]
|
||||
: null;
|
||||
if (null === $mCurrentPart) {
|
||||
$this->bIsEnd = true;
|
||||
$this->sBuffer = '';
|
||||
$iCount = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (\is_resource($mCurrentPart))
|
||||
{
|
||||
if (!\feof($mCurrentPart))
|
||||
{
|
||||
if (\is_resource($mCurrentPart)) {
|
||||
if (!\feof($mCurrentPart)) {
|
||||
$sReadResult = \fread($mCurrentPart, 8192);
|
||||
if (false === $sReadResult)
|
||||
{
|
||||
if (false === $sReadResult) {
|
||||
return false;
|
||||
}
|
||||
$sReturn .= $sReadResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->iIndex++;
|
||||
} else {
|
||||
++$this->iIndex;
|
||||
}
|
||||
}
|
||||
|
||||
$iLen = \strlen($sReturn);
|
||||
if ($iCount < $iLen)
|
||||
{
|
||||
if ($iCount < $iLen) {
|
||||
$this->sBuffer = \substr($sReturn, $iCount);
|
||||
$sReturn = \substr($sReturn, 0, $iCount);
|
||||
$iCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iCount -= $iLen;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,6 +170,8 @@ class SubStreams
|
|||
|
||||
public function stream_seek() : bool
|
||||
{
|
||||
// $this->iPos = $offset;
|
||||
// foreach ($this->aSubStreams as $rStream) \fseek($rStream, $offset, $whence);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,15 +59,11 @@ class TempFile
|
|||
self::STREAM_NAME === $aPath['scheme'])
|
||||
{
|
||||
$sHashName = $aPath['host'];
|
||||
if (isset(self::$aStreams[$sHashName]) &&
|
||||
\is_resource(self::$aStreams[$sHashName]))
|
||||
{
|
||||
if (isset(self::$aStreams[$sHashName]) && \is_resource(self::$aStreams[$sHashName])) {
|
||||
$this->rStream = self::$aStreams[$sHashName];
|
||||
\fseek($this->rStream, 0);
|
||||
$bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->rStream = \fopen('php://temp', 'r+b');
|
||||
self::$aStreams[$sHashName] = $this->rStream;
|
||||
|
||||
|
|
|
|||
|
|
@ -190,8 +190,7 @@ abstract class Utils
|
|||
public static function FormatFileSize(int $iSize, int $iRound = 0) : string
|
||||
{
|
||||
$aSizes = array('B', 'KB', 'MB');
|
||||
for ($iIndex = 0; $iSize > 1024 && isset($aSizes[$iIndex + 1]); $iIndex++)
|
||||
{
|
||||
for ($iIndex = 0; $iSize > 1024 && isset($aSizes[$iIndex + 1]); ++$iIndex) {
|
||||
$iSize /= 1024;
|
||||
}
|
||||
return \round($iSize, $iRound).$aSizes[$iIndex];
|
||||
|
|
@ -223,12 +222,10 @@ abstract class Utils
|
|||
public static function DecodeHeaderValue(string $sEncodedValue, string $sIncomingCharset = '', string $sForcedIncomingCharset = '') : string
|
||||
{
|
||||
$sValue = $sEncodedValue;
|
||||
if (\strlen($sIncomingCharset))
|
||||
{
|
||||
if (\strlen($sIncomingCharset)) {
|
||||
$sIncomingCharset = static::NormalizeCharsetByValue($sIncomingCharset, $sValue);
|
||||
|
||||
$sValue = static::ConvertEncoding($sValue, $sIncomingCharset,
|
||||
Enumerations\Charset::UTF_8);
|
||||
$sValue = static::ConvertEncoding($sValue, $sIncomingCharset, Enumerations\Charset::UTF_8);
|
||||
}
|
||||
|
||||
$sValue = \preg_replace('/\?=[\n\r\t\s]{1,5}=\?/m', '?==?', $sValue);
|
||||
|
|
@ -239,15 +236,11 @@ abstract class Utils
|
|||
// \preg_match_all('/=\?[^\?]+\?[q|b|Q|B]\?[^\?]*?\?=/', $sValue, $aMatch);
|
||||
\preg_match_all('/=\?[^\?]+\?[q|b|Q|B]\?.*?\?=/', $sValue, $aMatch);
|
||||
|
||||
if (isset($aMatch[0]) && \is_array($aMatch[0]))
|
||||
{
|
||||
for ($iIndex = 0, $iLen = \count($aMatch[0]); $iIndex < $iLen; $iIndex++)
|
||||
{
|
||||
if (isset($aMatch[0][$iIndex]))
|
||||
{
|
||||
if (isset($aMatch[0]) && \is_array($aMatch[0])) {
|
||||
for ($iIndex = 0, $iLen = \count($aMatch[0]); $iIndex < $iLen; ++$iIndex) {
|
||||
if (isset($aMatch[0][$iIndex])) {
|
||||
$iPos = \strpos($aMatch[0][$iIndex], '*');
|
||||
if (false !== $iPos)
|
||||
{
|
||||
if (false !== $iPos) {
|
||||
$aMatch[0][$iIndex][0] = \substr($aMatch[0][$iIndex][0], 0, $iPos);
|
||||
}
|
||||
}
|
||||
|
|
@ -261,11 +254,9 @@ abstract class Utils
|
|||
$sMainCharset = '';
|
||||
$bOneCharset = true;
|
||||
|
||||
for ($iIndex = 0, $iLen = \count($aEncodeArray); $iIndex < $iLen; $iIndex++)
|
||||
{
|
||||
for ($iIndex = 0, $iLen = \count($aEncodeArray); $iIndex < $iLen; ++$iIndex) {
|
||||
$aTempArr = array('', $aEncodeArray[$iIndex]);
|
||||
if ('=?' === \substr(\trim($aTempArr[1]), 0, 2))
|
||||
{
|
||||
if ('=?' === \substr(\trim($aTempArr[1]), 0, 2)) {
|
||||
$iPos = \strpos($aTempArr[1], '?', 2);
|
||||
$aTempArr[0] = \substr($aTempArr[1], 2, $iPos - 2);
|
||||
$sEncType = \strtoupper($aTempArr[1][$iPos + 1]);
|
||||
|
|
@ -284,17 +275,13 @@ abstract class Utils
|
|||
}
|
||||
}
|
||||
|
||||
if (\strlen($aTempArr[0]))
|
||||
{
|
||||
if (\strlen($aTempArr[0])) {
|
||||
$sCharset = \strlen($sForcedIncomingCharset) ? $sForcedIncomingCharset : $aTempArr[0];
|
||||
$sCharset = static::NormalizeCharset($sCharset, true);
|
||||
|
||||
if ('' === $sMainCharset)
|
||||
{
|
||||
if ('' === $sMainCharset) {
|
||||
$sMainCharset = $sCharset;
|
||||
}
|
||||
else if ($sMainCharset !== $sCharset)
|
||||
{
|
||||
} else if ($sMainCharset !== $sCharset) {
|
||||
$bOneCharset = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -308,14 +295,10 @@ abstract class Utils
|
|||
unset($aTempArr);
|
||||
}
|
||||
|
||||
for ($iIndex = 0, $iLen = \count($aParts); $iIndex < $iLen; $iIndex++)
|
||||
{
|
||||
if ($bOneCharset)
|
||||
{
|
||||
for ($iIndex = 0, $iLen = \count($aParts); $iIndex < $iLen; ++$iIndex) {
|
||||
if ($bOneCharset) {
|
||||
$sValue = \str_replace($aParts[$iIndex][0], $aParts[$iIndex][1], $sValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aParts[$iIndex][2] = static::NormalizeCharsetByValue($aParts[$iIndex][2], $aParts[$iIndex][1]);
|
||||
|
||||
$sValue = \str_replace($aParts[$iIndex][0],
|
||||
|
|
@ -324,8 +307,7 @@ abstract class Utils
|
|||
}
|
||||
}
|
||||
|
||||
if ($bOneCharset && \strlen($sMainCharset))
|
||||
{
|
||||
if ($bOneCharset && \strlen($sMainCharset)) {
|
||||
$sMainCharset = static::NormalizeCharsetByValue($sMainCharset, $sValue);
|
||||
$sValue = static::ConvertEncoding($sValue, $sMainCharset, Enumerations\Charset::UTF_8);
|
||||
}
|
||||
|
|
@ -337,8 +319,7 @@ abstract class Utils
|
|||
{
|
||||
$sResultHeaders = $sIncHeaders;
|
||||
|
||||
if ($aHeadersToRemove)
|
||||
{
|
||||
if ($aHeadersToRemove) {
|
||||
$aHeadersToRemove = \array_map('strtolower', $aHeadersToRemove);
|
||||
|
||||
$sIncHeaders = \preg_replace('/[\r\n]+/', "\n", $sIncHeaders);
|
||||
|
|
@ -347,31 +328,21 @@ abstract class Utils
|
|||
$bSkip = false;
|
||||
$aResult = array();
|
||||
|
||||
foreach ($aHeaders as $sLine)
|
||||
{
|
||||
if (\strlen($sLine))
|
||||
{
|
||||
foreach ($aHeaders as $sLine) {
|
||||
if (\strlen($sLine)) {
|
||||
$sFirst = \substr($sLine,0,1);
|
||||
if (' ' === $sFirst || "\t" === $sFirst)
|
||||
{
|
||||
if (!$bSkip)
|
||||
{
|
||||
if (' ' === $sFirst || "\t" === $sFirst) {
|
||||
if (!$bSkip) {
|
||||
$aResult[] = $sLine;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$bSkip = false;
|
||||
$aParts = \explode(':', $sLine, 2);
|
||||
|
||||
if (!empty($aParts) && !empty($aParts[0]))
|
||||
{
|
||||
if (\in_array(\strtolower(\trim($aParts[0])), $aHeadersToRemove))
|
||||
{
|
||||
if (!empty($aParts) && !empty($aParts[0])) {
|
||||
if (\in_array(\strtolower(\trim($aParts[0])), $aHeadersToRemove)) {
|
||||
$bSkip = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aResult[] = $sLine;
|
||||
}
|
||||
}
|
||||
|
|
@ -388,20 +359,17 @@ abstract class Utils
|
|||
public static function EncodeUnencodedValue(string $sEncodeType, string $sValue) : string
|
||||
{
|
||||
$sValue = \trim($sValue);
|
||||
if (\strlen($sValue) && !static::IsAscii($sValue))
|
||||
{
|
||||
if (\strlen($sValue) && !static::IsAscii($sValue)) {
|
||||
switch (\strtoupper($sEncodeType))
|
||||
{
|
||||
case 'B':
|
||||
$sValue = '=?'.\strtolower(Enumerations\Charset::UTF_8).
|
||||
return '=?'.\strtolower(Enumerations\Charset::UTF_8).
|
||||
'?B?'.\base64_encode($sValue).'?=';
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
$sValue = '=?'.\strtolower(Enumerations\Charset::UTF_8).
|
||||
return '=?'.\strtolower(Enumerations\Charset::UTF_8).
|
||||
'?Q?'.\str_replace(array('?', ' ', '_'), array('=3F', '_', '=5F'),
|
||||
\quoted_printable_encode($sValue)).'?=';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -418,28 +386,22 @@ abstract class Utils
|
|||
$iNlen = \strlen($sAttrName);
|
||||
$iVlen = \strlen($sValue);
|
||||
|
||||
if (\strlen($sAttrName) + $iVlen > $iLen - 3)
|
||||
{
|
||||
if (\strlen($sAttrName) + $iVlen > $iLen - 3) {
|
||||
$sections = array();
|
||||
$section = 0;
|
||||
|
||||
for ($i = 0, $j = 0; $i < $iVlen; $i += $j)
|
||||
{
|
||||
for ($i = 0, $j = 0; $i < $iVlen; $i += $j) {
|
||||
$j = $iLen - $iNlen - \strlen($section) - 4;
|
||||
$sections[$section++] = \substr($sValue, $i, $j);
|
||||
}
|
||||
|
||||
for ($i = 0, $n = $section; $i < $n; $i++)
|
||||
{
|
||||
for ($i = 0, $n = $section; $i < $n; ++$i) {
|
||||
$sections[$i] = ' '.$sAttrName.'*'.$i.'*='.$sections[$i];
|
||||
}
|
||||
|
||||
return \implode(";\r\n", $sections);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sAttrName.'*='.$sValue;
|
||||
}
|
||||
return $sAttrName.'*='.$sValue;
|
||||
}
|
||||
|
||||
public static function EncodeHeaderUtf8AttributeValue(string $sAttrName, string $sValue) : string
|
||||
|
|
@ -447,12 +409,9 @@ abstract class Utils
|
|||
$sAttrName = \trim($sAttrName);
|
||||
$sValue = \trim($sValue);
|
||||
|
||||
if (\strlen($sValue) && !static::IsAscii($sValue))
|
||||
{
|
||||
if (\strlen($sValue) && !static::IsAscii($sValue)) {
|
||||
$sValue = static::AttributeRfc2231Encode($sAttrName, $sValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sValue = $sAttrName.'="'.\str_replace('"', '\\"', $sValue).'"';
|
||||
}
|
||||
|
||||
|
|
@ -462,8 +421,7 @@ abstract class Utils
|
|||
public static function GetAccountNameFromEmail(string $sEmail) : string
|
||||
{
|
||||
$sResult = '';
|
||||
if (\strlen($sEmail))
|
||||
{
|
||||
if (\strlen($sEmail)) {
|
||||
$iPos = \strrpos($sEmail, '@');
|
||||
$sResult = (false === $iPos) ? $sEmail : \substr($sEmail, 0, $iPos);
|
||||
}
|
||||
|
|
@ -474,11 +432,9 @@ abstract class Utils
|
|||
public static function GetDomainFromEmail(string $sEmail) : string
|
||||
{
|
||||
$sResult = '';
|
||||
if (\strlen($sEmail))
|
||||
{
|
||||
if (\strlen($sEmail)) {
|
||||
$iPos = \strrpos($sEmail, '@');
|
||||
if (false !== $iPos && 0 < $iPos)
|
||||
{
|
||||
if (false !== $iPos && 0 < $iPos) {
|
||||
$sResult = \substr($sEmail, $iPos + 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -563,8 +519,7 @@ abstract class Utils
|
|||
public static function ResetTimeLimit(int $iTimeToReset = 15, int $iTimeToAdd = 120) : bool
|
||||
{
|
||||
$iTime = \time();
|
||||
if ($iTime < $_SERVER['REQUEST_TIME_FLOAT'] + 5)
|
||||
{
|
||||
if ($iTime < $_SERVER['REQUEST_TIME_FLOAT'] + 5) {
|
||||
// do nothing first 5s
|
||||
return true;
|
||||
}
|
||||
|
|
@ -572,18 +527,15 @@ abstract class Utils
|
|||
static $bValidateAction = null;
|
||||
static $iResetTimer = null;
|
||||
|
||||
if (null === $bValidateAction)
|
||||
{
|
||||
if (null === $bValidateAction) {
|
||||
$iResetTimer = 0;
|
||||
|
||||
$bValidateAction = static::FunctionCallable('set_time_limit');
|
||||
}
|
||||
|
||||
if ($bValidateAction && $iTimeToReset < $iTime - $iResetTimer)
|
||||
{
|
||||
if ($bValidateAction && $iTimeToReset < $iTime - $iResetTimer) {
|
||||
$iResetTimer = $iTime;
|
||||
if (!\set_time_limit($iTimeToAdd))
|
||||
{
|
||||
if (!\set_time_limit($iTimeToAdd)) {
|
||||
$bValidateAction = false;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -675,24 +627,19 @@ abstract class Utils
|
|||
public static function Base64Decode(string $sString) : string
|
||||
{
|
||||
$sResultString = \base64_decode($sString, true);
|
||||
if (false === $sResultString)
|
||||
{
|
||||
if (false === $sResultString) {
|
||||
$sString = \str_replace(array(' ', "\r", "\n", "\t"), '', $sString);
|
||||
$sString = \preg_replace('/[^a-zA-Z0-9=+\/](.*)$/', '', $sString);
|
||||
|
||||
if (false !== \strpos(\trim(\trim($sString), '='), '='))
|
||||
{
|
||||
if (false !== \strpos(\trim(\trim($sString), '='), '=')) {
|
||||
$sString = \preg_replace('/=([^=])/', '= $1', $sString);
|
||||
$aStrings = \explode(' ', $sString);
|
||||
foreach ($aStrings as $iIndex => $sParts)
|
||||
{
|
||||
foreach ($aStrings as $iIndex => $sParts) {
|
||||
$aStrings[$iIndex] = \base64_decode($sParts);
|
||||
}
|
||||
|
||||
$sResultString = \implode('', $aStrings);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sResultString = \base64_decode($sString);
|
||||
}
|
||||
}
|
||||
|
|
@ -715,23 +662,16 @@ abstract class Utils
|
|||
*/
|
||||
public static function FpassthruWithTimeLimitReset($fResource, int $iBufferLen = 8192) : bool
|
||||
{
|
||||
$bResult = false;
|
||||
if (\is_resource($fResource))
|
||||
{
|
||||
while (!\feof($fResource))
|
||||
{
|
||||
$bResult = \is_resource($fResource);
|
||||
if ($bResult) {
|
||||
while (!\feof($fResource)) {
|
||||
$sBuffer = \fread($fResource, $iBufferLen);
|
||||
if (false !== $sBuffer)
|
||||
{
|
||||
echo $sBuffer;
|
||||
static::ResetTimeLimit();
|
||||
continue;
|
||||
if (false === $sBuffer) {
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
echo $sBuffer;
|
||||
static::ResetTimeLimit();
|
||||
}
|
||||
|
||||
$bResult = true;
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
|
|
@ -743,53 +683,42 @@ abstract class Utils
|
|||
public static function MultipleStreamWriter($rRead, array $aWrite, int $iBufferLen = 8192, bool $bResetTimeLimit = true, bool $bFixCrLf = false, bool $bRewindOnComplete = false) : int
|
||||
{
|
||||
$mResult = false;
|
||||
if (\is_resource($rRead) && \count($aWrite))
|
||||
{
|
||||
if (\is_resource($rRead) && \count($aWrite)) {
|
||||
$mResult = 0;
|
||||
while (!\feof($rRead))
|
||||
{
|
||||
while (!\feof($rRead)) {
|
||||
$sBuffer = \fread($rRead, $iBufferLen);
|
||||
if (false === $sBuffer)
|
||||
{
|
||||
if (false === $sBuffer) {
|
||||
$mResult = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ('' === $sBuffer)
|
||||
{
|
||||
if ('' === $sBuffer) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($bFixCrLf)
|
||||
{
|
||||
if ($bFixCrLf) {
|
||||
$sBuffer = \str_replace("\n", "\r\n", \str_replace("\r", '', $sBuffer));
|
||||
}
|
||||
|
||||
$mResult += \strlen($sBuffer);
|
||||
|
||||
foreach ($aWrite as $rWriteStream)
|
||||
{
|
||||
foreach ($aWrite as $rWriteStream) {
|
||||
$mWriteResult = \fwrite($rWriteStream, $sBuffer);
|
||||
if (false === $mWriteResult)
|
||||
{
|
||||
if (false === $mWriteResult) {
|
||||
$mResult = false;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ($bResetTimeLimit)
|
||||
{
|
||||
if ($bResetTimeLimit) {
|
||||
static::ResetTimeLimit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($mResult && $bRewindOnComplete)
|
||||
{
|
||||
foreach ($aWrite as $rWriteStream)
|
||||
{
|
||||
if (\is_resource($rWriteStream))
|
||||
{
|
||||
if ($mResult && $bRewindOnComplete) {
|
||||
foreach ($aWrite as $rWriteStream) {
|
||||
if (\is_resource($rWriteStream)) {
|
||||
\rewind($rWriteStream);
|
||||
}
|
||||
}
|
||||
|
|
@ -843,8 +772,7 @@ abstract class Utils
|
|||
public static function ValidateDomain(string $sDomain, bool $bSimple = false) : bool
|
||||
{
|
||||
$aMatch = array();
|
||||
if ($bSimple)
|
||||
{
|
||||
if ($bSimple) {
|
||||
return \preg_match('/.+(\.[a-zA-Z]+)$/', $sDomain, $aMatch) && !empty($aMatch[1]);
|
||||
}
|
||||
|
||||
|
|
@ -861,8 +789,7 @@ abstract class Utils
|
|||
|
||||
public static function IdnToUtf8(string $sStr, bool $bLowerIfAscii = false) : string
|
||||
{
|
||||
if (\strlen($sStr) && \preg_match('/(^|\.|@)xn--/i', $sStr))
|
||||
{
|
||||
if (\strlen($sStr) && \preg_match('/(^|\.|@)xn--/i', $sStr)) {
|
||||
try
|
||||
{
|
||||
$sStr = \SnappyMail\IDN::anyToUtf8($sStr);
|
||||
|
|
@ -879,14 +806,12 @@ abstract class Utils
|
|||
|
||||
$sUser = '';
|
||||
$sDomain = $sStr;
|
||||
if (false !== \strpos($sStr, '@'))
|
||||
{
|
||||
if (false !== \strpos($sStr, '@')) {
|
||||
$sUser = static::GetAccountNameFromEmail($sStr);
|
||||
$sDomain = static::GetDomainFromEmail($sStr);
|
||||
}
|
||||
|
||||
if (\strlen($sDomain) && \preg_match('/[^\x20-\x7E]/', $sDomain))
|
||||
{
|
||||
if (\strlen($sDomain) && \preg_match('/[^\x20-\x7E]/', $sDomain)) {
|
||||
try
|
||||
{
|
||||
$sDomain = \SnappyMail\IDN::anyToAscii($sDomain);
|
||||
|
|
|
|||
|
|
@ -22,10 +22,8 @@ class Xxtea
|
|||
{
|
||||
$aV = self::str2long($sString, true);
|
||||
$aK = self::str2long($sKey, false);
|
||||
if (\count($aK) < 4)
|
||||
{
|
||||
for ($iIndex = \count($aK); $iIndex < 4; $iIndex++)
|
||||
{
|
||||
if (\count($aK) < 4) {
|
||||
for ($iIndex = \count($aK); $iIndex < 4; $iIndex++) {
|
||||
$aK[$iIndex] = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -36,12 +34,10 @@ class Xxtea
|
|||
$iDelta = 0x9E3779B9;
|
||||
$iQ = \floor(6 + 52 / ($iN + 1));
|
||||
$iSum = 0;
|
||||
while (0 < $iQ--)
|
||||
{
|
||||
while (0 < $iQ--) {
|
||||
$iSum = self::int32($iSum + $iDelta);
|
||||
$iE = $iSum >> 2 & 3;
|
||||
for ($iPIndex = 0; $iPIndex < $iN; $iPIndex++)
|
||||
{
|
||||
for ($iPIndex = 0; $iPIndex < $iN; ++$iPIndex) {
|
||||
$iY = $aV[$iPIndex + 1];
|
||||
$iMx = self::int32((($iZ >> 5 & 0x07ffffff) ^ $iY << 2) +
|
||||
(($iY >> 3 & 0x1fffffff) ^ $iZ << 4)) ^ self::int32(($iSum ^ $iY) + ($aK[$iPIndex & 3 ^ $iE] ^ $iZ));
|
||||
|
|
@ -61,10 +57,8 @@ class Xxtea
|
|||
$aV = self::str2long($sEncryptedString, false);
|
||||
$aK = self::str2long($sKey, false);
|
||||
|
||||
if (\count($aK) < 4)
|
||||
{
|
||||
for ($iIndex = \count($aK); $iIndex < 4; $iIndex++)
|
||||
{
|
||||
if (\count($aK) < 4) {
|
||||
for ($iIndex = \count($aK); $iIndex < 4; ++$iIndex) {
|
||||
$aK[$iIndex] = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -76,11 +70,9 @@ class Xxtea
|
|||
$iDelta = 0x9E3779B9;
|
||||
$iQ = \floor(6 + 52 / ($iN + 1));
|
||||
$iSum = self::int32($iQ * $iDelta);
|
||||
while ($iSum != 0)
|
||||
{
|
||||
while ($iSum != 0) {
|
||||
$iE = $iSum >> 2 & 3;
|
||||
for ($iPIndex = $iN; $iPIndex > 0; $iPIndex--)
|
||||
{
|
||||
for ($iPIndex = $iN; $iPIndex > 0; --$iPIndex) {
|
||||
$iZ = $aV[$iPIndex - 1];
|
||||
$iMx = self::int32((($iZ >> 5 & 0x07ffffff) ^ $iY << 2) +
|
||||
(($iY >> 3 & 0x1fffffff) ^ $iZ << 4)) ^ self::int32(($iSum ^ $iY) + ($aK[$iPIndex & 3 ^ $iE] ^ $iZ));
|
||||
|
|
@ -100,33 +92,25 @@ class Xxtea
|
|||
{
|
||||
$iLen = \count($aV);
|
||||
$iN = ($iLen - 1) << 2;
|
||||
if ($aW)
|
||||
{
|
||||
if ($aW) {
|
||||
$iM = $aV[$iLen - 1];
|
||||
if (($iM < $iN - 3) || ($iM > $iN))
|
||||
{
|
||||
if (($iM < $iN - 3) || ($iM > $iN)) {
|
||||
return false;
|
||||
}
|
||||
$iN = $iM;
|
||||
}
|
||||
$aS = array();
|
||||
for ($iIndex = 0; $iIndex < $iLen; $iIndex++)
|
||||
{
|
||||
for ($iIndex = 0; $iIndex < $iLen; ++$iIndex) {
|
||||
$aS[$iIndex] = \pack('V', $aV[$iIndex]);
|
||||
}
|
||||
if ($aW)
|
||||
{
|
||||
return \substr(\join('', $aS), 0, $iN);
|
||||
}
|
||||
return \join('', $aS);
|
||||
return $aW ? \substr(\join('', $aS), 0, $iN) : \join('', $aS);
|
||||
}
|
||||
|
||||
private static function str2long(string $sS, string $sW) : array
|
||||
{
|
||||
$aV = \unpack('V*', $sS . \str_repeat("\0", (4 - \strlen($sS) % 4) & 3));
|
||||
$aV = \array_values($aV);
|
||||
if ($sW)
|
||||
{
|
||||
if ($sW) {
|
||||
$aV[\count($aV)] = \strlen($sS);
|
||||
}
|
||||
return $aV;
|
||||
|
|
|
|||
|
|
@ -22,10 +22,7 @@ class CacheClient
|
|||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCacheIndex = '';
|
||||
private string $sCacheIndex = '';
|
||||
|
||||
public function Set(string $sKey, string $sValue) : bool
|
||||
{
|
||||
|
|
@ -56,13 +53,11 @@ class CacheClient
|
|||
{
|
||||
$sValue = '';
|
||||
|
||||
if ($this->oDriver)
|
||||
{
|
||||
if ($this->oDriver) {
|
||||
$sValue = $this->oDriver->Get($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
if ($bClearAfterGet)
|
||||
{
|
||||
if ($bClearAfterGet) {
|
||||
$this->Delete($sKey);
|
||||
}
|
||||
|
||||
|
|
@ -73,8 +68,7 @@ class CacheClient
|
|||
{
|
||||
$iTimer = 0;
|
||||
$sValue = $this->Get($sKey.'/TIMER');
|
||||
if (\strlen($sValue) && is_numeric($sValue))
|
||||
{
|
||||
if (\strlen($sValue) && \is_numeric($sValue)) {
|
||||
$iTimer = (int) $sValue;
|
||||
}
|
||||
|
||||
|
|
@ -83,8 +77,7 @@ class CacheClient
|
|||
|
||||
public function Delete(string $sKey) : self
|
||||
{
|
||||
if ($this->oDriver)
|
||||
{
|
||||
if ($this->oDriver) {
|
||||
$this->oDriver->Delete($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
|
|
@ -117,11 +110,9 @@ class CacheClient
|
|||
|
||||
public function Verify(bool $bCache = false) : bool
|
||||
{
|
||||
if ($this->oDriver)
|
||||
{
|
||||
if ($this->oDriver) {
|
||||
$sCacheData = \gmdate('Y-m-d-H');
|
||||
if ($bCache && $sCacheData === $this->Get('__verify_key__'))
|
||||
{
|
||||
if ($bCache && $sCacheData === $this->Get('__verify_key__')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,19 +18,13 @@ namespace MailSo\Cache\Drivers;
|
|||
*/
|
||||
class APCU implements \MailSo\Cache\DriverInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sKeyPrefix;
|
||||
private string $sKeyPrefix;
|
||||
|
||||
function __construct(string $sKeyPrefix = '')
|
||||
{
|
||||
$this->sKeyPrefix = $sKeyPrefix;
|
||||
if (!empty($this->sKeyPrefix))
|
||||
{
|
||||
$this->sKeyPrefix =
|
||||
\preg_replace('/[^a-zA-Z0-9_]/', '_', rtrim(trim($this->sKeyPrefix), '\\/')).'/';
|
||||
}
|
||||
$this->sKeyPrefix = empty($sKeyPrefix)
|
||||
? $sKeyPrefix
|
||||
: \preg_replace('/[^a-zA-Z0-9_]/', '_', \rtrim(\trim($sKeyPrefix), '\\/')).'/';
|
||||
}
|
||||
|
||||
public function Set(string $sKey, string $sValue) : bool
|
||||
|
|
@ -51,12 +45,7 @@ class APCU implements \MailSo\Cache\DriverInterface
|
|||
|
||||
public function GC(int $iTimeToClearInHours = 24) : bool
|
||||
{
|
||||
if (0 === $iTimeToClearInHours)
|
||||
{
|
||||
return \apcu_clear_cache('user');
|
||||
}
|
||||
|
||||
return false;
|
||||
return (0 === $iTimeToClearInHours) ? \apcu_clear_cache('user') : false;
|
||||
}
|
||||
|
||||
private function generateCachedKey(string $sKey) : string
|
||||
|
|
|
|||
|
|
@ -18,37 +18,27 @@ namespace MailSo\Cache\Drivers;
|
|||
*/
|
||||
class Memcache implements \MailSo\Cache\DriverInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iExpire;
|
||||
private int $iExpire;
|
||||
|
||||
/**
|
||||
* @var \Memcache|null
|
||||
* @var \Memcache|\Memcached|null
|
||||
*/
|
||||
private $oMem;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sKeyPrefix;
|
||||
private string $sKeyPrefix;
|
||||
|
||||
function __construct(string $sHost = '127.0.0.1', int $iPort = 11211, int $iExpire = 43200, string $sKeyPrefix = '')
|
||||
{
|
||||
$this->iExpire = 0 < $iExpire ? $iExpire : 43200;
|
||||
|
||||
$this->oMem = \class_exists('Memcache',false) ? new \Memcache : new \Memcached;
|
||||
if (!$this->oMem->addServer($sHost, \strpos($sHost, ':/') ? 0 : $this->iPort))
|
||||
{
|
||||
if (!$this->oMem->addServer($sHost, \strpos($sHost, ':/') ? 0 : $iPort)) {
|
||||
$this->oMem = null;
|
||||
}
|
||||
|
||||
$this->sKeyPrefix = $sKeyPrefix;
|
||||
if (!empty($this->sKeyPrefix))
|
||||
{
|
||||
$this->sKeyPrefix =
|
||||
\preg_replace('/[^a-zA-Z0-9_]/', '_', rtrim(trim($this->sKeyPrefix), '\\/')).'/';
|
||||
}
|
||||
$this->sKeyPrefix = empty($sKeyPrefix)
|
||||
? $sKeyPrefix
|
||||
: \preg_replace('/[^a-zA-Z0-9_]/', '_', \rtrim(\trim($this->sKeyPrefix), '\\/')) . '/';
|
||||
}
|
||||
|
||||
public function Set(string $sKey, string $sValue) : bool
|
||||
|
|
@ -64,19 +54,14 @@ class Memcache implements \MailSo\Cache\DriverInterface
|
|||
|
||||
public function Delete(string $sKey) : void
|
||||
{
|
||||
if ($this->oMem)
|
||||
{
|
||||
$this->oMem->delete($this->generateCachedKey($sKey));
|
||||
}
|
||||
$this->oMem && $this->oMem->delete($this->generateCachedKey($sKey));
|
||||
}
|
||||
|
||||
public function GC(int $iTimeToClearInHours = 24) : bool
|
||||
{
|
||||
if (0 === $iTimeToClearInHours && $this->oMem)
|
||||
{
|
||||
if (0 === $iTimeToClearInHours && $this->oMem) {
|
||||
return $this->oMem->flush();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,21 +18,14 @@ namespace MailSo\Cache\Drivers;
|
|||
*/
|
||||
class Redis implements \MailSo\Cache\DriverInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iExpire;
|
||||
private int $iExpire;
|
||||
|
||||
/**
|
||||
* @var \Memcache|null
|
||||
* @var \Predis\Client|null
|
||||
*/
|
||||
private $oRedis;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sKeyPrefix;
|
||||
|
||||
private string $sKeyPrefix;
|
||||
|
||||
function __construct(string $sHost = '127.0.0.1', int $iPort = 6379, int $iExpire = 43200, string $sKeyPrefix = '')
|
||||
{
|
||||
|
|
@ -49,8 +42,7 @@ class Redis implements \MailSo\Cache\DriverInterface
|
|||
|
||||
$this->oRedis->connect();
|
||||
|
||||
if (!$this->oRedis->isConnected())
|
||||
{
|
||||
if (!$this->oRedis->isConnected()) {
|
||||
$this->oRedis = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -60,18 +52,14 @@ class Redis implements \MailSo\Cache\DriverInterface
|
|||
unset($oExc);
|
||||
}
|
||||
|
||||
$this->sKeyPrefix = $sKeyPrefix;
|
||||
if (!empty($this->sKeyPrefix))
|
||||
{
|
||||
$this->sKeyPrefix =
|
||||
\preg_replace('/[^a-zA-Z0-9_]/', '_', rtrim(trim($this->sKeyPrefix), '\\/')).'/';
|
||||
}
|
||||
$this->sKeyPrefix = empty($sKeyPrefix)
|
||||
? $sKeyPrefix
|
||||
: \preg_replace('/[^a-zA-Z0-9_]/', '_', rtrim(trim($this->sKeyPrefix), '\\/')) . '/';
|
||||
}
|
||||
|
||||
public function Set(string $sKey, string $sValue) : bool
|
||||
{
|
||||
if (!$this->oRedis)
|
||||
{
|
||||
if (!$this->oRedis) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -88,16 +76,14 @@ class Redis implements \MailSo\Cache\DriverInterface
|
|||
|
||||
public function Delete(string $sKey) : void
|
||||
{
|
||||
if ($this->oRedis)
|
||||
{
|
||||
if ($this->oRedis) {
|
||||
$this->oRedis->del($this->generateCachedKey($sKey));
|
||||
}
|
||||
}
|
||||
|
||||
public function GC(int $iTimeToClearInHours = 24) : bool
|
||||
{
|
||||
if (0 === $iTimeToClearInHours && $this->oRedis)
|
||||
{
|
||||
if (0 === $iTimeToClearInHours && $this->oRedis) {
|
||||
return $this->oRedis->flushdb();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
*/
|
||||
class Hooks
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
static $aCallbacks = array();
|
||||
|
||||
static public function Run(string $sName, array $aArg = array()) : void
|
||||
{
|
||||
if (isset(static::$aCallbacks[$sName]))
|
||||
{
|
||||
foreach (static::$aCallbacks[$sName] as $mCallback)
|
||||
{
|
||||
$mCallback(...$aArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $mCallback
|
||||
*/
|
||||
static public function Add(string $sName, $mCallback) : void
|
||||
{
|
||||
if (\is_callable($mCallback))
|
||||
{
|
||||
if (!isset(static::$aCallbacks[$sName]))
|
||||
{
|
||||
static::$aCallbacks[$sName] = array();
|
||||
}
|
||||
|
||||
static::$aCallbacks[$sName][] = $mCallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,70 +17,31 @@ namespace MailSo\Imap;
|
|||
*/
|
||||
class BodyStructure
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sContentType;
|
||||
private string $sContentType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCharset;
|
||||
private string $sCharset;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aBodyParams;
|
||||
private array $aBodyParams;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sContentID;
|
||||
private string $sContentID;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDescription;
|
||||
private string $sDescription;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sMailEncodingName;
|
||||
private string $sMailEncodingName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDisposition;
|
||||
private string $sDisposition;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFileName;
|
||||
private string $sFileName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLanguage = '';
|
||||
private string $sLanguage = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLocation = '';
|
||||
private string $sLocation = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSize;
|
||||
private int $iSize;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPartID;
|
||||
private string $sPartID;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aSubParts;
|
||||
private array $aSubParts;
|
||||
|
||||
public function MailEncodingName() : string
|
||||
{
|
||||
|
|
@ -385,8 +346,7 @@ class BodyStructure
|
|||
|
||||
public static function NewInstance(array $aBodyStructure, string $sPartID = '') : ?self
|
||||
{
|
||||
if (2 > \count($aBodyStructure))
|
||||
{
|
||||
if (2 > \count($aBodyStructure)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -587,20 +547,15 @@ class BodyStructure
|
|||
$oStructure->sPartID = $sPartID;
|
||||
$oStructure->aSubParts = $aSubParts;
|
||||
|
||||
if ($iExtraItemPos < \count($aBodyStructure))
|
||||
{
|
||||
if (\is_array($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
if ($iExtraItemPos < \count($aBodyStructure)) {
|
||||
if (\is_array($aBodyStructure[$iExtraItemPos])) {
|
||||
$oStructure->sLanguage = \implode(',', $aBodyStructure[$iExtraItemPos]);
|
||||
}
|
||||
else if (\is_string($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
} else if (\is_string($aBodyStructure[$iExtraItemPos])) {
|
||||
$oStructure->sLanguage = $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
++$iExtraItemPos;
|
||||
|
||||
if ($iExtraItemPos < \count($aBodyStructure) && \is_string($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
if ($iExtraItemPos < \count($aBodyStructure) && \is_string($aBodyStructure[$iExtraItemPos])) {
|
||||
$oStructure->sLocation = $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ namespace MailSo\Imap\Exceptions;
|
|||
*/
|
||||
class ResponseException extends \MailSo\RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $oResponses;
|
||||
|
||||
public function __construct(?\MailSo\Imap\ResponseCollection $oResponses = null, string $sMessage = '', int $iCode = 0, ?\Throwable $oPrevious = null)
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class FetchResponse
|
|||
|
||||
if (\is_string($mItem) && (
|
||||
$mItem === 'BODY[HEADER]' ||
|
||||
0 === \strpos($mItem, 'BODY[HEADER.FIELDS') ||
|
||||
\str_starts_with($mItem, 'BODY[HEADER.FIELDS') ||
|
||||
$mItem === 'BODY[MIME]'))
|
||||
{
|
||||
$bNextIsValue = true;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ class ImapClient extends \MailSo\Net\NetClient
|
|||
|
||||
try
|
||||
{
|
||||
if (0 === \strpos($type, 'SCRAM-'))
|
||||
if (\str_starts_with($type, 'SCRAM-'))
|
||||
{
|
||||
$sAuthzid = $this->getResponseValue($this->SendRequestGetResponse('AUTHENTICATE', array($type)), Enumerations\ResponseType::CONTINUATION);
|
||||
$this->sendRaw($SASL->authenticate($sLogin, $sPassword/*, $sAuthzid*/), true);
|
||||
|
|
@ -377,9 +377,7 @@ class ImapClient extends \MailSo\Net\NetClient
|
|||
if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
|
||||
&& 'NAMESPACE' === $oResponse->StatusOrIndex)
|
||||
{
|
||||
$oReturn = new NamespaceResult;
|
||||
$oReturn->InitByImapResponse($oResponse);
|
||||
return $oReturn;
|
||||
return new NamespaceResult($oResponse);
|
||||
}
|
||||
}
|
||||
throw new Exceptions\ResponseException;
|
||||
|
|
|
|||
|
|
@ -17,75 +17,38 @@ namespace MailSo\Imap;
|
|||
*/
|
||||
class NamespaceResult
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPersonal = '';
|
||||
private string $sPersonal = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPersonalDelimiter = '';
|
||||
private string $sPersonalDelimiter = '';
|
||||
/*
|
||||
private string $sOtherUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sOtherUser = '';
|
||||
private string $sOtherUserDelimiter = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sOtherUserDelimiter = '';
|
||||
private string $sShared = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sShared = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSharedDelimiter = '';
|
||||
|
||||
public function InitByImapResponse(\MailSo\Imap\Response $oImapResponse) : self
|
||||
private string $sSharedDelimiter = '';
|
||||
*/
|
||||
function __construct(Response $oImapResponse)
|
||||
{
|
||||
if ($oImapResponse)
|
||||
{
|
||||
if (isset($oImapResponse->ResponseList[2][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[2][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[2][0]))
|
||||
{
|
||||
$this->sPersonal = $oImapResponse->ResponseList[2][0][0];
|
||||
$this->sPersonalDelimiter = $oImapResponse->ResponseList[2][0][1];
|
||||
|
||||
$this->sPersonal = 'INBOX'.$this->sPersonalDelimiter === \substr(\strtoupper($this->sPersonal), 0, 6) ?
|
||||
'INBOX'.$this->sPersonalDelimiter.\substr($this->sPersonal, 6) : $this->sPersonal;
|
||||
}
|
||||
|
||||
if (isset($oImapResponse->ResponseList[3][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[3][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[3][0]))
|
||||
{
|
||||
$this->sOtherUser = $oImapResponse->ResponseList[3][0][0];
|
||||
$this->sOtherUserDelimiter = $oImapResponse->ResponseList[3][0][1];
|
||||
|
||||
$this->sOtherUser = 'INBOX'.$this->sOtherUserDelimiter === \substr(\strtoupper($this->sOtherUser), 0, 6) ?
|
||||
'INBOX'.$this->sOtherUserDelimiter.\substr($this->sOtherUser, 6) : $this->sOtherUser;
|
||||
}
|
||||
|
||||
if (isset($oImapResponse->ResponseList[4][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[4][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[4][0]))
|
||||
{
|
||||
$this->sShared = $oImapResponse->ResponseList[4][0][0];
|
||||
$this->sSharedDelimiter = $oImapResponse->ResponseList[4][0][1];
|
||||
|
||||
$this->sShared = 'INBOX'.$this->sSharedDelimiter === \substr(\strtoupper($this->sShared), 0, 6) ?
|
||||
'INBOX'.$this->sSharedDelimiter.\substr($this->sShared, 6) : $this->sShared;
|
||||
}
|
||||
$space = static::getNamespace($oImapResponse, 2);
|
||||
if ($space) {
|
||||
$this->sPersonal = $space[0];
|
||||
$this->sPersonalDelimiter = $space[1];
|
||||
}
|
||||
/*
|
||||
$space = static::getNamespace($oImapResponse, 3);
|
||||
if ($space) {
|
||||
$this->sOtherUser = $space[0];
|
||||
$this->sOtherUserDelimiter = $space[1];
|
||||
}
|
||||
|
||||
return $this;
|
||||
$space = static::getNamespace($oImapResponse, 4);
|
||||
if ($space) {
|
||||
$this->sShared = $space[0];
|
||||
$this->sSharedDelimiter = $space[1];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public function GetPersonalNamespace() : string
|
||||
|
|
@ -93,4 +56,20 @@ class NamespaceResult
|
|||
return $this->sPersonal;
|
||||
}
|
||||
|
||||
private static function getNamespace(Response $oImapResponse, int $section) : ?array
|
||||
{
|
||||
if (isset($oImapResponse->ResponseList[$section][0])
|
||||
&& \is_array($oImapResponse->ResponseList[$section][0])
|
||||
&& 2 <= \count($oImapResponse->ResponseList[$section][0]))
|
||||
{
|
||||
$sName = $oImapResponse->ResponseList[$section][0][0];
|
||||
$sDelimiter = $oImapResponse->ResponseList[$section][0][1];
|
||||
$sName = 'INBOX'.$sDelimiter === \substr(\strtoupper($sName), 0, 6)
|
||||
? 'INBOX'.$sDelimiter.\substr($sName, 6)
|
||||
: $sName;
|
||||
return [$sName, $sDelimiter];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ namespace MailSo\Imap\Requests;
|
|||
*/
|
||||
class ESEARCH extends Request
|
||||
{
|
||||
public
|
||||
$sCriterias = 'ALL',
|
||||
$aReturn = [
|
||||
public string $sCriterias = 'ALL';
|
||||
|
||||
public array $aReturn = [
|
||||
/**
|
||||
ALL
|
||||
Return all message numbers/UIDs which match the search criteria,
|
||||
|
|
@ -41,14 +41,18 @@ class ESEARCH extends Request
|
|||
Return all message numbers/UIDs which match the search criteria,
|
||||
in the requested sort order, using a sequence-set.
|
||||
*/
|
||||
],
|
||||
$bUid = true,
|
||||
$sLimit = '',
|
||||
$sCharset = '',
|
||||
// https://datatracker.ietf.org/doc/html/rfc7377
|
||||
$aMailboxes = [],
|
||||
$aSubtrees = [],
|
||||
$aSubtreesOne = [];
|
||||
];
|
||||
|
||||
public bool $bUid = true;
|
||||
|
||||
public string $sLimit = '';
|
||||
|
||||
public string $sCharset = '';
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc7377
|
||||
public array $aMailboxes = [];
|
||||
public array $aSubtrees = [];
|
||||
public array $aSubtreesOne = [];
|
||||
|
||||
function __construct(\MailSo\Imap\ImapClient $oImapClient)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ namespace MailSo\Imap\Requests;
|
|||
|
||||
abstract class Request
|
||||
{
|
||||
protected
|
||||
$oImapClient;
|
||||
protected \MailSo\Imap\ImapClient $oImapClient;
|
||||
|
||||
function __construct(\MailSo\Imap\ImapClient $oImapClient)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,14 +21,18 @@ namespace MailSo\Imap\Requests;
|
|||
*/
|
||||
class SORT extends Request
|
||||
{
|
||||
public
|
||||
$sCriterias = 'ALL',
|
||||
$sCharset = '',
|
||||
$bUid = true,
|
||||
$aSortTypes = [],
|
||||
$sLimit = '',
|
||||
// RFC 5267
|
||||
$aReturn = [
|
||||
public string $sCriterias = 'ALL';
|
||||
|
||||
public string $sCharset = '';
|
||||
|
||||
public bool $bUid = true;
|
||||
|
||||
public array $aSortTypes = [];
|
||||
|
||||
public string $sLimit = '';
|
||||
|
||||
// RFC 5267
|
||||
public array $aReturn = [
|
||||
/**
|
||||
ALL
|
||||
Return all message numbers/UIDs which match the search criteria,
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ namespace MailSo\Imap\Requests;
|
|||
*/
|
||||
class THREAD extends Request
|
||||
{
|
||||
public
|
||||
$sAlgorithm = '', // ORDEREDSUBJECT or REFERENCES or REFS
|
||||
$sCriterias = 'ALL',
|
||||
$bUid = true;
|
||||
// ORDEREDSUBJECT or REFERENCES or REFS
|
||||
public string $sAlgorithm = '';
|
||||
|
||||
public string $sCriterias = 'ALL';
|
||||
|
||||
public bool $bUid = true;
|
||||
|
||||
function __construct(\MailSo\Imap\ImapClient $oImapClient)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,46 +19,24 @@ use MailSo\Imap\Enumerations\ResponseType;
|
|||
*/
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $ResponseList = array();
|
||||
public array $ResponseList = array();
|
||||
|
||||
/**
|
||||
* @var array | null
|
||||
*/
|
||||
public $OptionalResponse = null;
|
||||
public ?array $OptionalResponse = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $StatusOrIndex;
|
||||
public ?string $StatusOrIndex = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $HumanReadable = '';
|
||||
public string $HumanReadable = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $IsStatusResponse = false;
|
||||
public bool $IsStatusResponse = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $ResponseType = 0;
|
||||
public int $ResponseType = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Tag;
|
||||
public ?string $Tag = null;
|
||||
|
||||
private function recToLine(array $aList) : string
|
||||
{
|
||||
$aResult = array();
|
||||
foreach ($aList as $mItem)
|
||||
{
|
||||
foreach ($aList as $mItem) {
|
||||
$aResult[] = \is_array($mItem) ? '('.$this->recToLine($mItem).')' : (string) $mItem;
|
||||
}
|
||||
return \implode(' ', $aResult);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace MailSo\Imap\Responses;
|
|||
*/
|
||||
class ACL implements \JsonSerializable
|
||||
{
|
||||
private $rights;
|
||||
private array $rights;
|
||||
|
||||
function __construct(array $rights)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ class SequenceSet /*extends \SplFixedArray*/ implements \Countable
|
|||
/**
|
||||
* By default the numbers are unique identifiers as this is more reliable.
|
||||
*/
|
||||
public $UID = true;
|
||||
public bool $UID = true;
|
||||
|
||||
private $data = [];
|
||||
private array $data = [];
|
||||
|
||||
public function __construct($mItems, bool $uid = true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,15 +21,9 @@ use MailSo\Imap\Exceptions\ResponseNotFoundException;
|
|||
*/
|
||||
trait ResponseParser
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iResponseBufParsedPos;
|
||||
private int $iResponseBufParsedPos;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bNeedNext = true;
|
||||
private bool $bNeedNext = true;
|
||||
|
||||
protected function partialParseResponse() : Response
|
||||
{
|
||||
|
|
@ -365,9 +359,9 @@ trait ResponseParser
|
|||
}
|
||||
|
||||
$sLiteralAtomUpperCasePeek = '';
|
||||
if (0 === \strpos($sLiteralAtomUpperCase, 'BODY')) {
|
||||
if (\str_starts_with($sLiteralAtomUpperCase, 'BODY')) {
|
||||
$sLiteralAtomUpperCasePeek = \str_replace('BODY', 'BODY.PEEK', $sLiteralAtomUpperCase);
|
||||
} else if (0 === \strpos($sLiteralAtomUpperCase, 'BINARY')) {
|
||||
} else if (\str_starts_with($sLiteralAtomUpperCase, 'BINARY')) {
|
||||
$sLiteralAtomUpperCasePeek = \str_replace('BINARY', 'BINARY.PEEK', $sLiteralAtomUpperCase);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,9 @@ namespace MailSo\Log;
|
|||
*/
|
||||
abstract class Driver
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sDatePattern = 'H:i:s';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sName = '';
|
||||
protected string
|
||||
$sDatePattern = 'H:i:s',
|
||||
$sName = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
|
|
@ -41,25 +35,13 @@ abstract class Driver
|
|||
\LOG_DEBUG => '[DEBUG]'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bGuidPrefix = true;
|
||||
protected bool $bGuidPrefix = true;
|
||||
|
||||
/**
|
||||
* @var DateTimeZone
|
||||
*/
|
||||
protected $oTimeZone;
|
||||
protected \DateTimeZone $oTimeZone;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bTimePrefix = true;
|
||||
protected bool $bTimePrefix = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bTypedPrefix = true;
|
||||
protected bool $bTypedPrefix = true;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ namespace MailSo\Log\Drivers;
|
|||
*/
|
||||
class File extends \MailSo\Log\Driver
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLoggerFileName;
|
||||
private string $sLoggerFileName;
|
||||
|
||||
function __construct(string $sLoggerFileName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace MailSo\Log\Drivers;
|
|||
*/
|
||||
class Syslog extends \MailSo\Log\Driver
|
||||
{
|
||||
private $iLogLevel;
|
||||
private int $iLogLevel = 0;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,20 +17,19 @@ namespace MailSo\Log;
|
|||
*/
|
||||
class Logger extends \SplFixedArray
|
||||
{
|
||||
private $bUsed = false;
|
||||
private bool $bUsed = false;
|
||||
|
||||
private $iLevel = \LOG_WARNING;
|
||||
private int $iLevel = \LOG_WARNING;
|
||||
|
||||
private $aSecretWords = [];
|
||||
private array $aSecretWords = [];
|
||||
|
||||
private $bShowSecrets = false;
|
||||
private bool $bShowSecrets = false;
|
||||
|
||||
function __construct(bool $bMainLogger = false)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if ($bMainLogger)
|
||||
{
|
||||
if ($bMainLogger) {
|
||||
\set_error_handler(array($this, '__phpErrorHandler'));
|
||||
\set_exception_handler(array($this, '__phpExceptionHandler'));
|
||||
\register_shutdown_function(array($this, '__loggerShutDown'));
|
||||
|
|
@ -43,8 +42,7 @@ class Logger extends \SplFixedArray
|
|||
public static function Guid() : string
|
||||
{
|
||||
static $sCache = null;
|
||||
if (null === $sCache)
|
||||
{
|
||||
if (null === $sCache) {
|
||||
$sCache = \substr(\MailSo\Base\Utils::Sha1Rand(), -8);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,15 +25,9 @@ use MailSo\Mime\Enumerations\Parameter as MimeParameter;
|
|||
*/
|
||||
class MailClient
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
private ?\MailSo\Log\Logger $oLogger = null;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Imap\ImapClient
|
||||
*/
|
||||
private $oImapClient;
|
||||
private \MailSo\Imap\ImapClient $oImapClient;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
|
|
@ -759,7 +753,7 @@ class MailClient
|
|||
|
||||
if ($aAllThreads && !$oParams->iThreadUid) {
|
||||
foreach ($oMessageCollection as $oMessage) {
|
||||
$iUid = $oMessage->Uid();
|
||||
$iUid = $oMessage->Uid;
|
||||
// Find thread and set it.
|
||||
// Used by GUI to delete/move the whole thread or other features
|
||||
foreach ($aAllThreads as $aMap) {
|
||||
|
|
|
|||
|
|
@ -20,80 +20,74 @@ use \MailSo\Imap\Enumerations\FetchType;
|
|||
*/
|
||||
class Message implements \JsonSerializable
|
||||
{
|
||||
private
|
||||
private string
|
||||
$sFolder = '',
|
||||
$iUid = 0,
|
||||
$sSubject = '',
|
||||
$sMessageId = '',
|
||||
$sContentType = '',
|
||||
$iSize = 0,
|
||||
$iSpamScore = 0,
|
||||
$sSpamResult = '',
|
||||
$bIsSpam = false,
|
||||
$bHasVirus = null,
|
||||
$sVirusScanned = '',
|
||||
$iInternalTimeStampInUTC = 0,
|
||||
$iHeaderTimeStampInUTC = 0,
|
||||
$sHeaderDate = '',
|
||||
// $aFlags = [],
|
||||
$aFlagsLowerCase = [],
|
||||
$InReplyTo = '',
|
||||
$sPlain = '',
|
||||
$sHtml = '',
|
||||
$References = '',
|
||||
$sDeliveryReceipt = '',
|
||||
$ReadReceipt = '';
|
||||
|
||||
private ?string
|
||||
/**
|
||||
* https://www.rfc-editor.org/rfc/rfc8474#section-5
|
||||
*/
|
||||
$sEmailId = '',
|
||||
$sThreadId = '',
|
||||
$sEmailId = null,
|
||||
$sThreadId = null,
|
||||
// https://autocrypt.org/level1.html#the-autocrypt-header
|
||||
$sAutocrypt = '';
|
||||
|
||||
private int
|
||||
$Uid = 0,
|
||||
$iSize = 0,
|
||||
$SpamScore = 0,
|
||||
$iInternalTimeStampInUTC = 0,
|
||||
$HeaderTimeStampInUTC = 0,
|
||||
$iPriority = \MailSo\Mime\Enumerations\MessagePriority::NORMAL;
|
||||
|
||||
private bool
|
||||
$bIsSpam = false;
|
||||
|
||||
private ?bool
|
||||
/**
|
||||
* @var \MailSo\Mime\EmailCollection
|
||||
* null = not scanned
|
||||
* true = scanned and infected
|
||||
* false = scanned and no infection found
|
||||
*/
|
||||
$bHasVirus = null;
|
||||
|
||||
private array
|
||||
// $aFlags = [],
|
||||
$aFlagsLowerCase = [],
|
||||
$UnsubsribeLinks = [],
|
||||
$aThreads = [];
|
||||
|
||||
private ?array
|
||||
$DraftInfo = null,
|
||||
$pgpSigned = null,
|
||||
$pgpEncrypted = null;
|
||||
|
||||
private ?\MailSo\Mime\EmailCollection
|
||||
$oFrom = null,
|
||||
$oSender = null,
|
||||
$oReplyTo = null,
|
||||
$oDeliveredTo = null,
|
||||
$oTo = null,
|
||||
$oCc = null,
|
||||
$oBcc = null,
|
||||
$oBcc = null;
|
||||
|
||||
$sInReplyTo = '',
|
||||
private ?AttachmentCollection
|
||||
$Attachments = null;
|
||||
|
||||
$sPlain = '',
|
||||
$sHtml = '',
|
||||
|
||||
/**
|
||||
* @var AttachmentCollection
|
||||
*/
|
||||
$oAttachments = null,
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
$aDraftInfo = null,
|
||||
|
||||
$sReferences = '',
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
$iPriority,
|
||||
|
||||
$sDeliveryReceipt = '',
|
||||
|
||||
$sReadReceipt = '',
|
||||
|
||||
// https://autocrypt.org/level1.html#the-autocrypt-header
|
||||
$sAutocrypt = '',
|
||||
|
||||
$aUnsubsribeLinks = array(),
|
||||
|
||||
$aThreads = array(),
|
||||
|
||||
$aPgpSigned = null,
|
||||
$aPgpEncrypted = null;
|
||||
|
||||
function __construct()
|
||||
function __get($k)
|
||||
{
|
||||
$this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::NORMAL;
|
||||
return \property_exists($this, $k) ? $this->$k : null;
|
||||
}
|
||||
|
||||
public function Plain() : string
|
||||
|
|
@ -106,174 +100,9 @@ class Message implements \JsonSerializable
|
|||
return $this->sHtml;
|
||||
}
|
||||
|
||||
public function PgpSigned() : ?array
|
||||
{
|
||||
return $this->aPgpSigned;
|
||||
}
|
||||
|
||||
public function PgpEncrypted() : ?array
|
||||
{
|
||||
return $this->aPgpEncrypted;
|
||||
}
|
||||
|
||||
public function Folder() : string
|
||||
{
|
||||
return $this->sFolder;
|
||||
}
|
||||
|
||||
public function Uid() : int
|
||||
{
|
||||
return $this->iUid;
|
||||
}
|
||||
|
||||
public function MessageId() : string
|
||||
{
|
||||
return $this->sMessageId;
|
||||
}
|
||||
|
||||
public function Subject() : string
|
||||
{
|
||||
return $this->sSubject;
|
||||
}
|
||||
|
||||
public function ContentType() : string
|
||||
{
|
||||
return $this->sContentType;
|
||||
}
|
||||
|
||||
public function Size() : int
|
||||
{
|
||||
return $this->iSize;
|
||||
}
|
||||
|
||||
public function SpamScore() : int
|
||||
{
|
||||
return $this->iSpamScore;
|
||||
}
|
||||
|
||||
private function setSpamScore($value) : void
|
||||
{
|
||||
$this->iSpamScore = \intval(\max(0, \min(100, $value)));
|
||||
}
|
||||
|
||||
public function SpamResult() : string
|
||||
{
|
||||
return $this->sSpamResult;
|
||||
}
|
||||
|
||||
public function IsSpam() : bool
|
||||
{
|
||||
return $this->bIsSpam;
|
||||
}
|
||||
|
||||
/**
|
||||
* null = not scanned
|
||||
* true = scanned and infected
|
||||
* false = scanned and no infection found
|
||||
*/
|
||||
public function HasVirus() : ?bool
|
||||
{
|
||||
return $this->bHasVirus;
|
||||
}
|
||||
|
||||
public function InternalTimeStampInUTC() : int
|
||||
{
|
||||
return $this->iInternalTimeStampInUTC;
|
||||
}
|
||||
|
||||
public function HeaderTimeStampInUTC() : int
|
||||
{
|
||||
return $this->iHeaderTimeStampInUTC;
|
||||
}
|
||||
|
||||
public function HeaderDate() : string
|
||||
{
|
||||
return $this->sHeaderDate;
|
||||
}
|
||||
|
||||
public function From() : ?\MailSo\Mime\EmailCollection
|
||||
{
|
||||
return $this->oFrom;
|
||||
}
|
||||
|
||||
public function Priority() : int
|
||||
{
|
||||
return $this->iPriority;
|
||||
}
|
||||
|
||||
public function Sender() : ?\MailSo\Mime\EmailCollection
|
||||
{
|
||||
return $this->oSender;
|
||||
}
|
||||
|
||||
public function ReplyTo() : ?\MailSo\Mime\EmailCollection
|
||||
{
|
||||
return $this->oReplyTo;
|
||||
}
|
||||
|
||||
public function DeliveredTo() : ?\MailSo\Mime\EmailCollection
|
||||
{
|
||||
return $this->oDeliveredTo;
|
||||
}
|
||||
|
||||
public function To() : ?\MailSo\Mime\EmailCollection
|
||||
{
|
||||
return $this->oTo;
|
||||
}
|
||||
|
||||
public function Cc() : ?\MailSo\Mime\EmailCollection
|
||||
{
|
||||
return $this->oCc;
|
||||
}
|
||||
|
||||
public function Bcc() : ?\MailSo\Mime\EmailCollection
|
||||
{
|
||||
return $this->oBcc;
|
||||
}
|
||||
|
||||
public function Attachments() : ?AttachmentCollection
|
||||
{
|
||||
return $this->oAttachments;
|
||||
}
|
||||
|
||||
public function InReplyTo() : string
|
||||
{
|
||||
return $this->sInReplyTo;
|
||||
}
|
||||
|
||||
public function References() : string
|
||||
{
|
||||
return $this->sReferences;
|
||||
}
|
||||
|
||||
public function DeliveryReceipt() : string
|
||||
{
|
||||
return $this->sDeliveryReceipt;
|
||||
}
|
||||
|
||||
public function ReadReceipt() : string
|
||||
{
|
||||
return $this->sReadReceipt;
|
||||
}
|
||||
|
||||
public function UnsubsribeLinks() : array
|
||||
{
|
||||
return $this->aUnsubsribeLinks;
|
||||
}
|
||||
|
||||
public function ReadingConfirmation() : string
|
||||
{
|
||||
return $this->ReadReceipt();
|
||||
}
|
||||
|
||||
public function DraftInfo() : ?array
|
||||
{
|
||||
return $this->aDraftInfo;
|
||||
}
|
||||
|
||||
public function Threads() : array
|
||||
{
|
||||
return $this->aThreads;
|
||||
$this->SpamScore = \intval(\max(0, \min(100, $value)));
|
||||
}
|
||||
|
||||
public function SetThreads(array $aThreads)
|
||||
|
|
@ -285,15 +114,14 @@ class Message implements \JsonSerializable
|
|||
{
|
||||
$oMessage = new self;
|
||||
|
||||
if (!$oBodyStructure)
|
||||
{
|
||||
if (!$oBodyStructure) {
|
||||
$oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
|
||||
}
|
||||
|
||||
$aFlags = $oFetchResponse->GetFetchValue(FetchType::FLAGS) ?: [];
|
||||
|
||||
$oMessage->sFolder = $sFolder;
|
||||
$oMessage->iUid = (int) $oFetchResponse->GetFetchValue(FetchType::UID);
|
||||
$oMessage->Uid = (int) $oFetchResponse->GetFetchValue(FetchType::UID);
|
||||
$oMessage->iSize = (int) $oFetchResponse->GetFetchValue(FetchType::RFC822_SIZE);
|
||||
// $oMessage->aFlags = $aFlags;
|
||||
$oMessage->aFlagsLowerCase = \array_map('mb_strtolower', \array_map('\\MailSo\\Base\\Utils::Utf7ModifiedToUtf8', $aFlags));
|
||||
|
|
@ -310,8 +138,7 @@ class Message implements \JsonSerializable
|
|||
$sCharset = $oBodyStructure ? Utils::NormalizeCharset($oBodyStructure->SearchCharset()) : '';
|
||||
|
||||
$sHeaders = $oFetchResponse->GetHeaderFieldsValue();
|
||||
if (\strlen($sHeaders))
|
||||
{
|
||||
if (\strlen($sHeaders)) {
|
||||
$oHeaders = new \MailSo\Mime\HeaderCollection($sHeaders, false, $sCharset);
|
||||
|
||||
$sContentTypeCharset = $oHeaders->ParameterValue(
|
||||
|
|
@ -319,13 +146,11 @@ class Message implements \JsonSerializable
|
|||
\MailSo\Mime\Enumerations\Parameter::CHARSET
|
||||
);
|
||||
|
||||
if (\strlen($sContentTypeCharset))
|
||||
{
|
||||
if (\strlen($sContentTypeCharset)) {
|
||||
$sCharset = Utils::NormalizeCharset($sContentTypeCharset);
|
||||
}
|
||||
|
||||
if (\strlen($sCharset))
|
||||
{
|
||||
if (\strlen($sCharset)) {
|
||||
$oHeaders->SetParentCharset($sCharset);
|
||||
}
|
||||
|
||||
|
|
@ -348,40 +173,28 @@ class Message implements \JsonSerializable
|
|||
$oMessage->oReplyTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::REPLY_TO, $bCharsetAutoDetect);
|
||||
$oMessage->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect);
|
||||
|
||||
$oMessage->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
|
||||
$oMessage->sReferences = Utils::StripSpaces(
|
||||
$oMessage->InReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
|
||||
$oMessage->References = Utils::StripSpaces(
|
||||
$oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES));
|
||||
|
||||
$sHeaderDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE);
|
||||
$oMessage->sHeaderDate = $sHeaderDate;
|
||||
$oMessage->iHeaderTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseRFC2822DateString($sHeaderDate);
|
||||
$oMessage->HeaderTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseRFC2822DateString(
|
||||
$oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE)
|
||||
);
|
||||
|
||||
// Priority
|
||||
$oMessage->iPriority = \MailSo\Mime\Enumerations\MessagePriority::NORMAL;
|
||||
$sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY);
|
||||
if (!\strlen($sPriority))
|
||||
{
|
||||
$sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IMPORTANCE);
|
||||
}
|
||||
if (!\strlen($sPriority))
|
||||
{
|
||||
$sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_PRIORITY);
|
||||
}
|
||||
if (\strlen($sPriority))
|
||||
{
|
||||
switch (\str_replace(' ', '', \strtolower($sPriority)))
|
||||
$sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY)
|
||||
?: $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IMPORTANCE)
|
||||
?: $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_PRIORITY);
|
||||
if (\strlen($sPriority)) {
|
||||
switch (\substr(\trim($sPriority), 0, 1))
|
||||
{
|
||||
case 'high':
|
||||
case '1(highest)':
|
||||
case '2(high)':
|
||||
case 'h':
|
||||
case '1':
|
||||
case '2':
|
||||
$oMessage->iPriority = \MailSo\Mime\Enumerations\MessagePriority::HIGH;
|
||||
break;
|
||||
|
||||
case 'low':
|
||||
case '4(low)':
|
||||
case '5(lowest)':
|
||||
case 'l':
|
||||
case '4':
|
||||
case '5':
|
||||
$oMessage->iPriority = \MailSo\Mime\Enumerations\MessagePriority::LOW;
|
||||
|
|
@ -393,26 +206,19 @@ class Message implements \JsonSerializable
|
|||
$oMessage->sDeliveryReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::RETURN_RECEIPT_TO));
|
||||
|
||||
// Read Receipt
|
||||
$oMessage->sReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO));
|
||||
if (empty($oMessage->sReadReceipt))
|
||||
{
|
||||
$oMessage->sReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO));
|
||||
$oMessage->ReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO));
|
||||
if (empty($oMessage->ReadReceipt)) {
|
||||
$oMessage->ReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO));
|
||||
}
|
||||
|
||||
// Unsubscribe links
|
||||
$oMessage->aUnsubsribeLinks = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE);
|
||||
if (empty($oMessage->aUnsubsribeLinks))
|
||||
{
|
||||
$oMessage->aUnsubsribeLinks = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$oMessage->aUnsubsribeLinks = explode(',', $oMessage->aUnsubsribeLinks);
|
||||
$oMessage->aUnsubsribeLinks = array_map(
|
||||
$UnsubsribeLinks = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE);
|
||||
if ($UnsubsribeLinks) {
|
||||
$UnsubsribeLinks = \array_map(
|
||||
function ($link) {
|
||||
return trim($link, ' <>');
|
||||
},
|
||||
$oMessage->aUnsubsribeLinks
|
||||
\explode(',', $UnsubsribeLinks)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -481,7 +287,7 @@ class Message implements \JsonSerializable
|
|||
}
|
||||
|
||||
if (\strlen($sType) && \strlen($sFolder) && $iUid) {
|
||||
$oMessage->aDraftInfo = array($sType, $iUid, $sFolder);
|
||||
$oMessage->DraftInfo = array($sType, $iUid, $sFolder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -501,15 +307,14 @@ class Message implements \JsonSerializable
|
|||
$oMessage->oTo = $oFetchResponse->GetFetchEnvelopeEmailCollection(5, $sCharset);
|
||||
$oMessage->oCc = $oFetchResponse->GetFetchEnvelopeEmailCollection(6, $sCharset);
|
||||
$oMessage->oBcc = $oFetchResponse->GetFetchEnvelopeEmailCollection(7, $sCharset);
|
||||
$oMessage->sInReplyTo = $oFetchResponse->GetFetchEnvelopeValue(8, '');
|
||||
$oMessage->InReplyTo = $oFetchResponse->GetFetchEnvelopeValue(8, '');
|
||||
}
|
||||
|
||||
if ($oBodyStructure)
|
||||
{
|
||||
if ($oBodyStructure) {
|
||||
$gEncryptedParts = $oBodyStructure->SearchByContentType('multipart/encrypted');
|
||||
foreach ($gEncryptedParts as $oPart) {
|
||||
if ($oPart->IsPgpEncrypted()) {
|
||||
$oMessage->aPgpEncrypted = [
|
||||
$oMessage->pgpEncrypted = [
|
||||
'PartId' => $oPart->SubParts()[1]->PartID()
|
||||
];
|
||||
}
|
||||
|
|
@ -521,7 +326,7 @@ class Message implements \JsonSerializable
|
|||
continue;
|
||||
}
|
||||
$oPgpSignaturePart = $oPart->SubParts()[1];
|
||||
$oMessage->aPgpSigned = [
|
||||
$oMessage->pgpSigned = [
|
||||
// /?/Raw/&q[]=/0/Download/&q[]=/...
|
||||
// /?/Raw/&q[]=/0/View/&q[]=/...
|
||||
'BodyPartId' => $oPart->SubParts()[0]->PartID(),
|
||||
|
|
@ -532,40 +337,36 @@ class Message implements \JsonSerializable
|
|||
// An empty section specification refers to the entire message, including the header.
|
||||
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
|
||||
$sPgpText = \trim(
|
||||
\trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->aPgpSigned['BodyPartId'].'.MIME]'))
|
||||
\trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['BodyPartId'].'.MIME]'))
|
||||
. "\r\n\r\n"
|
||||
. \trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->aPgpSigned['BodyPartId'].']'))
|
||||
. \trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['BodyPartId'].']'))
|
||||
);
|
||||
if ($sPgpText) {
|
||||
$oMessage->aPgpSigned['Body'] = $sPgpText;
|
||||
$oMessage->pgpSigned['Body'] = $sPgpText;
|
||||
}
|
||||
$sPgpSignatureText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->aPgpSigned['SigPartId'].']');
|
||||
$sPgpSignatureText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['SigPartId'].']');
|
||||
if ($sPgpSignatureText && 0 < \strpos($sPgpSignatureText, 'BEGIN PGP SIGNATURE')) {
|
||||
$oMessage->aPgpSigned['Signature'] = $oPart->SubParts()[0]->PartID();
|
||||
$oMessage->pgpSigned['Signature'] = $oPart->SubParts()[0]->PartID();
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
$aTextParts = $oBodyStructure->GetHtmlAndPlainParts();
|
||||
if ($aTextParts)
|
||||
{
|
||||
if ($aTextParts) {
|
||||
$sCharset = $sCharset ?: \MailSo\Base\Enumerations\Charset::UTF_8;
|
||||
|
||||
$aHtmlParts = array();
|
||||
$aPlainParts = array();
|
||||
|
||||
foreach ($aTextParts as $oPart)
|
||||
{
|
||||
foreach ($aTextParts as $oPart) {
|
||||
$sText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oPart->PartID().']');
|
||||
if (null === $sText)
|
||||
{
|
||||
if (null === $sText) {
|
||||
// TextPartIsTrimmed ?
|
||||
$sText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oPart->PartID().']<0>');
|
||||
}
|
||||
|
||||
if (\is_string($sText) && \strlen($sText))
|
||||
{
|
||||
if (\is_string($sText) && \strlen($sText)) {
|
||||
$sText = Utils::DecodeEncodingValue($sText, $oPart->MailEncodingName());
|
||||
$sText = Utils::ConvertEncoding($sText,
|
||||
Utils::NormalizeCharset($oPart->Charset() ?: $sCharset, true),
|
||||
|
|
@ -575,34 +376,28 @@ class Message implements \JsonSerializable
|
|||
|
||||
// https://datatracker.ietf.org/doc/html/rfc4880#section-7
|
||||
// Cleartext Signature
|
||||
if (!$oMessage->aPgpSigned && \str_contains($sText, '-----BEGIN PGP SIGNED MESSAGE-----'))
|
||||
{
|
||||
$oMessage->aPgpSigned = [
|
||||
if (!$oMessage->pgpSigned && \str_contains($sText, '-----BEGIN PGP SIGNED MESSAGE-----')) {
|
||||
$oMessage->pgpSigned = [
|
||||
'BodyPartId' => $oPart->PartID()
|
||||
];
|
||||
}
|
||||
|
||||
if (\str_contains($sText, '-----BEGIN PGP MESSAGE-----'))
|
||||
{
|
||||
if (\str_contains($sText, '-----BEGIN PGP MESSAGE-----')) {
|
||||
$keyIds = [];
|
||||
if (\SnappyMail\PGP\GPG::isSupported()) {
|
||||
$GPG = new \SnappyMail\PGP\GPG('');
|
||||
$keyIds = $GPG->getEncryptedMessageKeys($sText);
|
||||
}
|
||||
$oMessage->aPgpEncrypted = [
|
||||
$oMessage->pgpEncrypted = [
|
||||
'PartId' => $oPart->PartID(),
|
||||
'KeyIds' => $keyIds
|
||||
];
|
||||
}
|
||||
|
||||
if ('text/html' === $oPart->ContentType())
|
||||
{
|
||||
if ('text/html' === $oPart->ContentType()) {
|
||||
$aHtmlParts[] = $sText;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($oPart->IsFlowedFormat())
|
||||
{
|
||||
} else {
|
||||
if ($oPart->IsFlowedFormat()) {
|
||||
$sText = Utils::DecodeFlowedFormat($sText);
|
||||
}
|
||||
|
||||
|
|
@ -618,14 +413,12 @@ class Message implements \JsonSerializable
|
|||
}
|
||||
|
||||
$gAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();
|
||||
if ($gAttachmentsParts->valid())
|
||||
{
|
||||
$oMessage->oAttachments = new AttachmentCollection;
|
||||
foreach ($gAttachmentsParts as /* @var $oAttachmentItem \MailSo\Imap\BodyStructure */ $oAttachmentItem)
|
||||
{
|
||||
if ($gAttachmentsParts->valid()) {
|
||||
$oMessage->Attachments = new AttachmentCollection;
|
||||
foreach ($gAttachmentsParts as /* @var $oAttachmentItem \MailSo\Imap\BodyStructure */ $oAttachmentItem) {
|
||||
// if ('application/pgp-keys' === $oAttachmentItem->ContentType()) import ???
|
||||
$oMessage->oAttachments->append(
|
||||
new Attachment($oMessage->sFolder, $oMessage->iUid, $oAttachmentItem)
|
||||
$oMessage->Attachments->append(
|
||||
new Attachment($oMessage->sFolder, $oMessage->Uid, $oAttachmentItem)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -657,11 +450,11 @@ class Message implements \JsonSerializable
|
|||
return array(
|
||||
'@Object' => 'Object/Message',
|
||||
'Folder' => $this->sFolder,
|
||||
'Uid' => $this->iUid,
|
||||
'Uid' => $this->Uid,
|
||||
'subject' => \trim(Utils::Utf8Clear($this->sSubject)),
|
||||
'encrypted' => 'multipart/encrypted' == $this->sContentType || $this->PgpEncrypted(),
|
||||
'encrypted' => 'multipart/encrypted' == $this->sContentType || $this->pgpEncrypted,
|
||||
'MessageId' => $this->sMessageId,
|
||||
'SpamScore' => $this->bIsSpam ? 100 : $this->iSpamScore,
|
||||
'SpamScore' => $this->bIsSpam ? 100 : $this->SpamScore,
|
||||
'SpamResult' => $this->sSpamResult,
|
||||
'IsSpam' => $this->bIsSpam,
|
||||
'HasVirus' => $this->bHasVirus,
|
||||
|
|
@ -679,11 +472,11 @@ class Message implements \JsonSerializable
|
|||
|
||||
'Priority' => $this->iPriority,
|
||||
'Threads' => $this->aThreads,
|
||||
'UnsubsribeLinks' => $this->aUnsubsribeLinks,
|
||||
'UnsubsribeLinks' => $this->UnsubsribeLinks,
|
||||
'ReadReceipt' => '',
|
||||
'Autocrypt' => $this->sAutocrypt,
|
||||
|
||||
'Attachments' => $this->oAttachments,
|
||||
'Attachments' => $this->Attachments,
|
||||
|
||||
'Flags' => $aFlags,
|
||||
|
||||
|
|
|
|||
|
|
@ -13,18 +13,22 @@ namespace MailSo\Mail;
|
|||
|
||||
class MessageListParams
|
||||
{
|
||||
public
|
||||
$sFolderName, // string
|
||||
$sSearch = '', // string
|
||||
$oCacher = null, // ?\MailSo\Cache\CacheClient
|
||||
$bUseSortIfSupported = false, // bool
|
||||
$bUseThreads = false, // bool
|
||||
$bHideDeleted = true, // bool
|
||||
$sSort = ''; // string
|
||||
public string
|
||||
$sFolderName,
|
||||
$sSearch,
|
||||
$sSort;
|
||||
|
||||
protected
|
||||
$iOffset = 0,
|
||||
$iLimit = 10,
|
||||
public ?\MailSo\Cache\CacheClient
|
||||
$oCacher = null;
|
||||
|
||||
public bool
|
||||
$bUseSortIfSupported = false,
|
||||
$bUseThreads,
|
||||
$bHideDeleted = true;
|
||||
|
||||
protected int
|
||||
$iOffset,
|
||||
$iLimit,
|
||||
$iPrevUidNext = 0, // used to check for new messages
|
||||
$iThreadUid = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,33 +17,20 @@ namespace MailSo\Mime;
|
|||
*/
|
||||
class Email implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDisplayName;
|
||||
private string $sDisplayName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEmail;
|
||||
private string $sEmail;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDkimStatus;
|
||||
private string $sDkimStatus = Enumerations\DkimStatus::NONE;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDkimValue;
|
||||
private string $sDkimValue = '';
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
function __construct(string $sEmail, string $sDisplayName = '')
|
||||
{
|
||||
if (!\strlen(\trim($sEmail)))
|
||||
{
|
||||
if (!\strlen(\trim($sEmail))) {
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
|
|
@ -51,9 +38,6 @@ class Email implements \JsonSerializable
|
|||
\MailSo\Base\Utils::Trim($sEmail), true);
|
||||
|
||||
$this->sDisplayName = \MailSo\Base\Utils::Trim($sDisplayName);
|
||||
|
||||
$this->sDkimStatus = Enumerations\DkimStatus::NONE;
|
||||
$this->sDkimValue = '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -62,8 +46,7 @@ class Email implements \JsonSerializable
|
|||
public static function Parse(string $sEmailAddress) : self
|
||||
{
|
||||
$sEmailAddress = \MailSo\Base\Utils::Trim($sEmailAddress);
|
||||
if (!\strlen(\trim($sEmailAddress)))
|
||||
{
|
||||
if (!\strlen(\trim($sEmailAddress))) {
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
|
|
@ -79,20 +62,16 @@ class Email implements \JsonSerializable
|
|||
$iEndIndex = 0;
|
||||
$iCurrentIndex = 0;
|
||||
|
||||
while ($iCurrentIndex < \strlen($sEmailAddress))
|
||||
{
|
||||
while ($iCurrentIndex < \strlen($sEmailAddress)) {
|
||||
switch ($sEmailAddress[$iCurrentIndex])
|
||||
{
|
||||
// case '\'':
|
||||
case '"':
|
||||
// $sQuoteChar = $sEmailAddress[$iCurrentIndex];
|
||||
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
|
||||
{
|
||||
if (!$bInName && !$bInAddress && !$bInComment) {
|
||||
$bInName = true;
|
||||
$iStartIndex = $iCurrentIndex;
|
||||
}
|
||||
else if ((!$bInAddress) && (!$bInComment))
|
||||
{
|
||||
} else if (!$bInAddress && !$bInComment) {
|
||||
$iEndIndex = $iCurrentIndex;
|
||||
$sName = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
|
||||
$sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
|
||||
|
|
@ -103,10 +82,8 @@ class Email implements \JsonSerializable
|
|||
}
|
||||
break;
|
||||
case '<':
|
||||
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
|
||||
{
|
||||
if ($iCurrentIndex > 0 && \strlen($sName) === 0)
|
||||
{
|
||||
if (!$bInName && !$bInAddress && !$bInComment) {
|
||||
if ($iCurrentIndex > 0 && !\strlen($sName)) {
|
||||
$sName = \substr($sEmailAddress, 0, $iCurrentIndex);
|
||||
}
|
||||
|
||||
|
|
@ -115,8 +92,7 @@ class Email implements \JsonSerializable
|
|||
}
|
||||
break;
|
||||
case '>':
|
||||
if ($bInAddress)
|
||||
{
|
||||
if ($bInAddress) {
|
||||
$iEndIndex = $iCurrentIndex;
|
||||
$sEmail = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
|
||||
$sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
|
||||
|
|
@ -127,15 +103,13 @@ class Email implements \JsonSerializable
|
|||
}
|
||||
break;
|
||||
case '(':
|
||||
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
|
||||
{
|
||||
if (!$bInName && !$bInAddress && !$bInComment) {
|
||||
$bInComment = true;
|
||||
$iStartIndex = $iCurrentIndex;
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
if ($bInComment)
|
||||
{
|
||||
if ($bInComment) {
|
||||
$iEndIndex = $iCurrentIndex;
|
||||
$sComment = \substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
|
||||
$sEmailAddress = \substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
|
||||
|
|
@ -146,28 +120,23 @@ class Email implements \JsonSerializable
|
|||
}
|
||||
break;
|
||||
case '\\':
|
||||
$iCurrentIndex++;
|
||||
++$iCurrentIndex;
|
||||
break;
|
||||
}
|
||||
|
||||
$iCurrentIndex++;
|
||||
++$iCurrentIndex;
|
||||
}
|
||||
|
||||
if (\strlen($sEmail) === 0)
|
||||
{
|
||||
if (!\strlen($sEmail)) {
|
||||
$aRegs = array('');
|
||||
if (\preg_match('/[^@\s]+@\S+/i', $sEmailAddress, $aRegs) && isset($aRegs[0]))
|
||||
{
|
||||
if (\preg_match('/[^@\s]+@\S+/i', $sEmailAddress, $aRegs) && isset($aRegs[0])) {
|
||||
$sEmail = $aRegs[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sName = $sEmailAddress;
|
||||
}
|
||||
}
|
||||
|
||||
if ((\strlen($sEmail) > 0) && (\strlen($sName) == 0) && (\strlen($sComment) == 0))
|
||||
{
|
||||
if (\strlen($sEmail) && !\strlen($sName) && !\strlen($sComment)) {
|
||||
$sName = \str_replace($sEmail, '', $sEmailAddress);
|
||||
}
|
||||
|
||||
|
|
@ -234,19 +203,16 @@ class Email implements \JsonSerializable
|
|||
$sReturn = '';
|
||||
|
||||
$sDisplayName = \str_replace('"', '\"', $this->sDisplayName);
|
||||
if ($bConvertSpecialsName)
|
||||
{
|
||||
$sDisplayName = 0 === \strlen($sDisplayName) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue(
|
||||
\MailSo\Base\Enumerations\Encoding::BASE64_SHORT,
|
||||
$sDisplayName);
|
||||
if ($bConvertSpecialsName) {
|
||||
$sDisplayName = \strlen($sDisplayName)
|
||||
? \MailSo\Base\Utils::EncodeUnencodedValue(\MailSo\Base\Enumerations\Encoding::BASE64_SHORT, $sDisplayName)
|
||||
: '';
|
||||
}
|
||||
|
||||
$sDisplayName = 0 === \strlen($sDisplayName) ? '' : '"'.$sDisplayName.'"';
|
||||
if (\strlen($this->sEmail))
|
||||
{
|
||||
$sDisplayName = \strlen($sDisplayName) ? '"'.$sDisplayName.'"' : '';
|
||||
if (\strlen($this->sEmail)) {
|
||||
$sReturn = $this->GetEmail($bIdn);
|
||||
if (\strlen($sDisplayName))
|
||||
{
|
||||
if (\strlen($sDisplayName)) {
|
||||
$sReturn = $sDisplayName.' <'.$sReturn.'>';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ class EmailCollection extends \MailSo\Base\Collection
|
|||
public function ToArray() : array
|
||||
{
|
||||
$aReturn = array();
|
||||
foreach ($this as $oEmail)
|
||||
{
|
||||
foreach ($this as $oEmail) {
|
||||
$aReturn[] = $oEmail->ToArray();
|
||||
}
|
||||
|
||||
|
|
@ -46,8 +45,7 @@ class EmailCollection extends \MailSo\Base\Collection
|
|||
|
||||
public function MergeWithOtherCollection(EmailCollection $oEmails) : self
|
||||
{
|
||||
foreach ($oEmails as $oEmail)
|
||||
{
|
||||
foreach ($oEmails as $oEmail) {
|
||||
$this->append($oEmail);
|
||||
}
|
||||
|
||||
|
|
@ -58,11 +56,9 @@ class EmailCollection extends \MailSo\Base\Collection
|
|||
{
|
||||
$aReturn = array();
|
||||
|
||||
foreach ($this as $oEmail)
|
||||
{
|
||||
foreach ($this as $oEmail) {
|
||||
$sEmail = $oEmail->GetEmail();
|
||||
if (!isset($aReturn[$sEmail]))
|
||||
{
|
||||
if (!isset($aReturn[$sEmail])) {
|
||||
$aReturn[$sEmail] = $oEmail;
|
||||
}
|
||||
}
|
||||
|
|
@ -73,8 +69,7 @@ class EmailCollection extends \MailSo\Base\Collection
|
|||
public function ToString(bool $bConvertSpecialsName = false, bool $bIdn = false) : string
|
||||
{
|
||||
$aReturn = array();
|
||||
foreach ($this as $oEmail)
|
||||
{
|
||||
foreach ($this as $oEmail) {
|
||||
$aReturn[] = $oEmail->ToString($bConvertSpecialsName, $bIdn);
|
||||
}
|
||||
|
||||
|
|
@ -87,8 +82,7 @@ class EmailCollection extends \MailSo\Base\Collection
|
|||
$sRawEmails = \trim($sRawEmails);
|
||||
|
||||
$sWorkingRecipientsLen = \strlen($sRawEmails);
|
||||
if (!$sWorkingRecipientsLen)
|
||||
{
|
||||
if (!$sWorkingRecipientsLen) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -102,59 +96,49 @@ class EmailCollection extends \MailSo\Base\Collection
|
|||
|
||||
$iCurrentPos = 0;
|
||||
|
||||
while ($iCurrentPos < $sWorkingRecipientsLen)
|
||||
{
|
||||
while ($iCurrentPos < $sWorkingRecipientsLen) {
|
||||
switch ($sRawEmails[$iCurrentPos])
|
||||
{
|
||||
case '\'':
|
||||
case '"':
|
||||
if (!$bIsInQuotes)
|
||||
{
|
||||
if (!$bIsInQuotes) {
|
||||
$sChQuote = $sRawEmails[$iCurrentPos];
|
||||
$bIsInQuotes = true;
|
||||
}
|
||||
else if ($sChQuote == $sRawEmails[$iCurrentPos])
|
||||
{
|
||||
} else if ($sChQuote == $sRawEmails[$iCurrentPos]) {
|
||||
$bIsInQuotes = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if (!$bIsInAngleBrackets)
|
||||
{
|
||||
if (!$bIsInAngleBrackets) {
|
||||
$bIsInAngleBrackets = true;
|
||||
if ($bIsInQuotes)
|
||||
{
|
||||
if ($bIsInQuotes) {
|
||||
$bIsInQuotes = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if ($bIsInAngleBrackets)
|
||||
{
|
||||
if ($bIsInAngleBrackets) {
|
||||
$bIsInAngleBrackets = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
if (!$bIsInBrackets)
|
||||
{
|
||||
if (!$bIsInBrackets) {
|
||||
$bIsInBrackets = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ')':
|
||||
if ($bIsInBrackets)
|
||||
{
|
||||
if ($bIsInBrackets) {
|
||||
$bIsInBrackets = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
case ';':
|
||||
if (!$bIsInAngleBrackets && !$bIsInBrackets && !$bIsInQuotes)
|
||||
{
|
||||
if (!$bIsInAngleBrackets && !$bIsInBrackets && !$bIsInQuotes) {
|
||||
$iEmailEndPos = $iCurrentPos;
|
||||
|
||||
try
|
||||
|
|
@ -175,8 +159,7 @@ class EmailCollection extends \MailSo\Base\Collection
|
|||
++$iCurrentPos;
|
||||
}
|
||||
|
||||
if ($iEmailStartPos < $iCurrentPos)
|
||||
{
|
||||
if ($iEmailStartPos < $iCurrentPos) {
|
||||
try
|
||||
{
|
||||
$this->append(
|
||||
|
|
|
|||
|
|
@ -17,35 +17,17 @@ namespace MailSo\Mime;
|
|||
*/
|
||||
class Header
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
private string $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sValue;
|
||||
private string $sValue;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFullValue;
|
||||
private string $sFullValue;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEncodedValueForReparse;
|
||||
private string $sEncodedValueForReparse;
|
||||
|
||||
/**
|
||||
* @var ParameterCollection
|
||||
*/
|
||||
private $oParameters;
|
||||
private ?ParameterCollection $oParameters = null;
|
||||
|
||||
/**
|
||||
* @var strign
|
||||
*/
|
||||
private $sParentCharset;
|
||||
private string $sParentCharset;
|
||||
|
||||
function __construct(string $sName, string $sValue = '', string $sEncodedValueForReparse = '', string $sParentCharset = '')
|
||||
{
|
||||
|
|
@ -59,26 +41,19 @@ class Header
|
|||
$this->sFullValue = \trim($sValue);
|
||||
$this->sEncodedValueForReparse = '';
|
||||
|
||||
if (\strlen($sEncodedValueForReparse) && $this->IsReparsed())
|
||||
{
|
||||
if (\strlen($sEncodedValueForReparse) && $this->IsReparsed()) {
|
||||
$this->sEncodedValueForReparse = \trim($sEncodedValueForReparse);
|
||||
}
|
||||
|
||||
if (\strlen($this->sFullValue) && $this->IsParameterized())
|
||||
{
|
||||
if (\strlen($this->sFullValue) && $this->IsParameterized()) {
|
||||
$aRawExplode = \explode(';', $this->sFullValue, 2);
|
||||
if (2 === \count($aRawExplode))
|
||||
{
|
||||
if (2 === \count($aRawExplode)) {
|
||||
$this->sValue = $aRawExplode[0];
|
||||
$this->oParameters = new ParameterCollection($aRawExplode[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->sValue = $this->sFullValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->sValue = $this->sFullValue;
|
||||
}
|
||||
|
||||
|
|
@ -89,14 +64,12 @@ class Header
|
|||
|
||||
public static function NewInstanceFromEncodedString(string $sEncodedLines, string $sIncomingCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1) : Header
|
||||
{
|
||||
if (empty($sIncomingCharset))
|
||||
{
|
||||
if (empty($sIncomingCharset)) {
|
||||
$sIncomingCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
|
||||
}
|
||||
|
||||
$aParts = \explode(':', \str_replace("\r", '', $sEncodedLines), 2);
|
||||
if (isset($aParts[0]) && isset($aParts[1]) && \strlen($aParts[0]) && \strlen($aParts[1]))
|
||||
{
|
||||
if (isset($aParts[0]) && isset($aParts[1]) && \strlen($aParts[0]) && \strlen($aParts[1])) {
|
||||
return new self(
|
||||
\trim($aParts[0]),
|
||||
\trim(\MailSo\Base\Utils::DecodeHeaderValue(\trim($aParts[1]), $sIncomingCharset)),
|
||||
|
|
@ -130,8 +103,7 @@ class Header
|
|||
|
||||
public function SetParentCharset(string $sParentCharset) : Header
|
||||
{
|
||||
if ($this->sParentCharset !== $sParentCharset && $this->IsReparsed() && \strlen($this->sEncodedValueForReparse))
|
||||
{
|
||||
if ($this->sParentCharset !== $sParentCharset && $this->IsReparsed() && \strlen($this->sEncodedValueForReparse)) {
|
||||
$this->initInputData(
|
||||
$this->sName,
|
||||
\trim(\MailSo\Base\Utils::DecodeHeaderValue($this->sEncodedValueForReparse, $sParentCharset)),
|
||||
|
|
@ -165,11 +137,8 @@ class Header
|
|||
{
|
||||
$sResult = $this->sFullValue;
|
||||
|
||||
if ($this->IsSubject())
|
||||
{
|
||||
if (!\MailSo\Base\Utils::IsAscii($sResult) &&
|
||||
\function_exists('iconv_mime_encode'))
|
||||
{
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -18,12 +18,9 @@ namespace MailSo\Mime;
|
|||
class HeaderCollection extends \MailSo\Base\Collection
|
||||
{
|
||||
|
||||
protected $sRawHeaders = '';
|
||||
protected string $sRawHeaders = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sParentCharset = '';
|
||||
protected string $sParentCharset = '';
|
||||
|
||||
function __construct(string $sRawHeaders = '', bool $bStoreRawHeaders = true, string $sParentCharset = '')
|
||||
{
|
||||
|
|
@ -149,40 +146,29 @@ class HeaderCollection extends \MailSo\Base\Collection
|
|||
}
|
||||
|
||||
$sFirstChar = \substr($sHeadersValue, 0, 1);
|
||||
if ($sFirstChar !== ' ' && $sFirstChar !== "\t" && false === \strpos($sHeadersValue, ':'))
|
||||
{
|
||||
if ($sFirstChar !== ' ' && $sFirstChar !== "\t" && false === \strpos($sHeadersValue, ':')) {
|
||||
continue;
|
||||
}
|
||||
else if (null !== $sName && ($sFirstChar === ' ' || $sFirstChar === "\t"))
|
||||
{
|
||||
if (null !== $sName && ($sFirstChar === ' ' || $sFirstChar === "\t")) {
|
||||
$sValue = \is_null($sValue) ? '' : $sValue;
|
||||
|
||||
if ('?=' === \substr(\rtrim($sHeadersValue), -2))
|
||||
{
|
||||
if ('?=' === \substr(\rtrim($sHeadersValue), -2)) {
|
||||
$sHeadersValue = \rtrim($sHeadersValue);
|
||||
}
|
||||
|
||||
if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2))
|
||||
{
|
||||
if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2)) {
|
||||
$sHeadersValue = \ltrim($sHeadersValue);
|
||||
}
|
||||
|
||||
if ('=?' === \substr($sHeadersValue, 0, 2))
|
||||
{
|
||||
if ('=?' === \substr($sHeadersValue, 0, 2)) {
|
||||
$sValue .= $sHeadersValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sValue .= "\n".$sHeadersValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (null !== $sName)
|
||||
{
|
||||
} else {
|
||||
if (null !== $sName) {
|
||||
$oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset);
|
||||
if ($oHeader)
|
||||
{
|
||||
if ($oHeader) {
|
||||
$this->append($oHeader);
|
||||
}
|
||||
|
||||
|
|
@ -194,18 +180,15 @@ class HeaderCollection extends \MailSo\Base\Collection
|
|||
$sName = $aHeaderParts[0];
|
||||
$sValue = isset($aHeaderParts[1]) ? $aHeaderParts[1] : '';
|
||||
|
||||
if ('?=' === \substr(\rtrim($sValue), -2))
|
||||
{
|
||||
if ('?=' === \substr(\rtrim($sValue), -2)) {
|
||||
$sValue = \rtrim($sValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $sName)
|
||||
{
|
||||
if (null !== $sName) {
|
||||
$oHeader = Header::NewInstanceFromEncodedString($sName.': '.$sValue, $this->sParentCharset);
|
||||
if ($oHeader)
|
||||
{
|
||||
if ($oHeader) {
|
||||
$this->append($oHeader);
|
||||
}
|
||||
}
|
||||
|
|
@ -218,10 +201,8 @@ class HeaderCollection extends \MailSo\Base\Collection
|
|||
$aResult = array();
|
||||
|
||||
$aHeaders = $this->ValuesByName(Enumerations\Header::AUTHENTICATION_RESULTS);
|
||||
if (\count($aHeaders))
|
||||
{
|
||||
foreach ($aHeaders as $sHeaderValue)
|
||||
{
|
||||
if (\count($aHeaders)) {
|
||||
foreach ($aHeaders as $sHeaderValue) {
|
||||
$sStatus = '';
|
||||
$sHeader = '';
|
||||
$sDkimLine = '';
|
||||
|
|
@ -230,35 +211,28 @@ class HeaderCollection extends \MailSo\Base\Collection
|
|||
|
||||
$sHeaderValue = \preg_replace('/[\r\n\t\s]+/', ' ', $sHeaderValue);
|
||||
|
||||
if (\preg_match('/dkim=.+/i', $sHeaderValue, $aMatch) && !empty($aMatch[0]))
|
||||
{
|
||||
if (\preg_match('/dkim=.+/i', $sHeaderValue, $aMatch) && !empty($aMatch[0])) {
|
||||
$sDkimLine = $aMatch[0];
|
||||
|
||||
$aMatch = array();
|
||||
if (\preg_match('/dkim=([a-zA-Z0-9]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[1]))
|
||||
{
|
||||
if (\preg_match('/dkim=([a-zA-Z0-9]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[1])) {
|
||||
$sStatus = $aMatch[1];
|
||||
}
|
||||
|
||||
$aMatch = array();
|
||||
if (\preg_match('/header\.(d|i|from)=([^\s;]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[2]))
|
||||
{
|
||||
if (\preg_match('/header\.(d|i|from)=([^\s;]+)/i', $sDkimLine, $aMatch) && !empty($aMatch[2])) {
|
||||
$sHeader = \trim($aMatch[2]);
|
||||
}
|
||||
|
||||
if (!empty($sStatus) && !empty($sHeader))
|
||||
{
|
||||
if (!empty($sStatus) && !empty($sHeader)) {
|
||||
$aResult[] = array($sStatus, $sHeader, $sDkimLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// X-DKIM-Authentication-Results: signer="hostinger.com" status="pass"
|
||||
$aHeaders = $this->ValuesByName(Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS);
|
||||
foreach ($aHeaders as $sHeaderValue)
|
||||
{
|
||||
foreach ($aHeaders as $sHeaderValue) {
|
||||
$sStatus = '';
|
||||
$sHeader = '';
|
||||
|
||||
|
|
@ -266,18 +240,15 @@ class HeaderCollection extends \MailSo\Base\Collection
|
|||
|
||||
$sHeaderValue = \preg_replace('/[\r\n\t\s]+/', ' ', $sHeaderValue);
|
||||
|
||||
if (\preg_match('/status[\s]?=[\s]?"([a-zA-Z0-9]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1]))
|
||||
{
|
||||
if (\preg_match('/status[\s]?=[\s]?"([a-zA-Z0-9]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1])) {
|
||||
$sStatus = $aMatch[1];
|
||||
}
|
||||
|
||||
if (\preg_match('/signer[\s]?=[\s]?"([^";]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1]))
|
||||
{
|
||||
if (\preg_match('/signer[\s]?=[\s]?"([^";]+)"/i', $sHeaderValue, $aMatch) && !empty($aMatch[1])) {
|
||||
$sHeader = \trim($aMatch[1]);
|
||||
}
|
||||
|
||||
if (!empty($sStatus) && !empty($sHeader))
|
||||
{
|
||||
if (!empty($sStatus) && !empty($sHeader)) {
|
||||
$aResult[] = array($sStatus, $sHeader, $sHeaderValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -292,9 +263,7 @@ class HeaderCollection extends \MailSo\Base\Collection
|
|||
foreach ($oEmails as $oEmail) {
|
||||
$sEmail = $oEmail->GetEmail();
|
||||
foreach ($aDkimStatuses as $aDkimData) {
|
||||
if (isset($aDkimData[0], $aDkimData[1]) &&
|
||||
$aDkimData[1] === \strstr($sEmail, $aDkimData[1]))
|
||||
{
|
||||
if (isset($aDkimData[0], $aDkimData[1]) && $aDkimData[1] === \strstr($sEmail, $aDkimData[1])) {
|
||||
$oEmail->SetDkimStatusAndValue($aDkimData[0], empty($aDkimData[2]) ? '' : $aDkimData[2]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ namespace MailSo\Mime;
|
|||
*/
|
||||
class Message extends Part
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aHeadersValue = array(
|
||||
private array $aHeadersValue = array(
|
||||
/*
|
||||
Enumerations\Header::BCC => '',
|
||||
Enumerations\Header::CC => '',
|
||||
|
|
@ -42,22 +39,11 @@ class Message extends Part
|
|||
*/
|
||||
);
|
||||
|
||||
/**
|
||||
* @var AttachmentCollection
|
||||
*/
|
||||
private $oAttachmentCollection;
|
||||
private AttachmentCollection $oAttachmentCollection;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bAddEmptyTextPart = true;
|
||||
private bool $bAddEmptyTextPart = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bAddDefaultXMailer = true;
|
||||
|
||||
public $messageIdRequired = true;
|
||||
private bool $bAddDefaultXMailer = true;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
|
|
@ -177,8 +163,7 @@ class Message extends Part
|
|||
public function SetCustomHeader(string $sHeaderName, string $sValue) : self
|
||||
{
|
||||
$sHeaderName = \trim($sHeaderName);
|
||||
if (\strlen($sHeaderName))
|
||||
{
|
||||
if (\strlen($sHeaderName)) {
|
||||
$this->aHeadersValue[$sHeaderName] = $sValue;
|
||||
}
|
||||
|
||||
|
|
@ -236,8 +221,7 @@ class Message extends Part
|
|||
break;
|
||||
}
|
||||
|
||||
if (\strlen($sResult))
|
||||
{
|
||||
if (\strlen($sResult)) {
|
||||
$this->aHeadersValue[Enumerations\Header::X_PRIORITY] = $sResult;
|
||||
}
|
||||
|
||||
|
|
@ -313,18 +297,15 @@ class Message extends Part
|
|||
|
||||
private function generateNewMessageId(string $sHostName = '') : string
|
||||
{
|
||||
if (0 === \strlen($sHostName))
|
||||
{
|
||||
if (!\strlen($sHostName)) {
|
||||
$sHostName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
|
||||
}
|
||||
|
||||
if (empty($sHostName) && \MailSo\Base\Utils::FunctionCallable('php_uname'))
|
||||
{
|
||||
if (empty($sHostName) && \MailSo\Base\Utils::FunctionCallable('php_uname')) {
|
||||
$sHostName = \php_uname('n');
|
||||
}
|
||||
|
||||
if (empty($sHostName))
|
||||
{
|
||||
if (empty($sHostName)) {
|
||||
$sHostName = 'localhost';
|
||||
}
|
||||
|
||||
|
|
@ -432,7 +413,7 @@ class Message extends Part
|
|||
$oRootPart->Headers->SetByName(Enumerations\Header::DATE, \gmdate('r'), true);
|
||||
}
|
||||
|
||||
if ($this->messageIdRequired && !isset($this->aHeadersValue[Enumerations\Header::MESSAGE_ID])) {
|
||||
if (!isset($this->aHeadersValue[Enumerations\Header::MESSAGE_ID])) {
|
||||
$oRootPart->Headers->SetByName(Enumerations\Header::MESSAGE_ID, $this->generateNewMessageId(), true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,9 @@ namespace MailSo\Mime;
|
|||
*/
|
||||
class Parameter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
private string $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sValue;
|
||||
private string $sValue;
|
||||
|
||||
function __construct(string $sName, string $sValue)
|
||||
{
|
||||
|
|
@ -66,12 +60,11 @@ class Parameter
|
|||
{
|
||||
$this->Reset();
|
||||
|
||||
$aParts = explode($sSeparator, $sRawParam, 2);
|
||||
$aParts = \explode($sSeparator, $sRawParam, 2);
|
||||
|
||||
$this->sName = trim(trim($aParts[0]), '"\'');
|
||||
if (2 === count($aParts))
|
||||
{
|
||||
$this->sValue = trim(trim($aParts[1]), '"\'');
|
||||
$this->sName = \trim(\trim($aParts[0]), '"\'');
|
||||
if (2 === \count($aParts)) {
|
||||
$this->sValue = \trim(\trim($aParts[1]), '"\'');
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
@ -79,25 +72,20 @@ class Parameter
|
|||
|
||||
public function ToString(bool $bConvertSpecialsName = false) : string
|
||||
{
|
||||
$sResult = '';
|
||||
if (\strlen($this->sName))
|
||||
{
|
||||
$sResult = $this->sName.'=';
|
||||
if ($bConvertSpecialsName && in_array(strtolower($this->sName), array(
|
||||
strtolower(Enumerations\Parameter::NAME),
|
||||
strtolower(Enumerations\Parameter::FILENAME)
|
||||
)))
|
||||
{
|
||||
$sResult .= '"'.\MailSo\Base\Utils::EncodeUnencodedValue(
|
||||
\MailSo\Base\Enumerations\Encoding::BASE64_SHORT,
|
||||
$this->sValue).'"';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult .= '"'.$this->sValue.'"';
|
||||
}
|
||||
if (!\strlen($this->sName)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
if ($bConvertSpecialsName && \in_array(\strtolower($this->sName), array(
|
||||
\strtolower(Enumerations\Parameter::NAME),
|
||||
\strtolower(Enumerations\Parameter::FILENAME)
|
||||
)))
|
||||
{
|
||||
return $this->sName . '="' . \MailSo\Base\Utils::EncodeUnencodedValue(
|
||||
\MailSo\Base\Enumerations\Encoding::BASE64_SHORT,
|
||||
$this->sValue) . '"';
|
||||
}
|
||||
|
||||
return $this->sName . '="' . $this->sValue . '"';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
{
|
||||
parent::__construct();
|
||||
|
||||
if (\strlen($sRawParams))
|
||||
{
|
||||
$this->Parse($sRawParams);
|
||||
}
|
||||
\strlen($sRawParams) && $this->Parse($sRawParams);
|
||||
}
|
||||
|
||||
public function append($oParameter, bool $bToTop = false) : void
|
||||
|
|
@ -66,8 +63,7 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
|
||||
$aDataToParse = \explode(';', $sRawParams);
|
||||
|
||||
foreach ($aDataToParse as $sParam)
|
||||
{
|
||||
foreach ($aDataToParse as $sParam) {
|
||||
$this->append(Parameter::CreateFromParameterLine($sParam));
|
||||
}
|
||||
|
||||
|
|
@ -79,11 +75,9 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
public function ToString(bool $bConvertSpecialsName = false) : string
|
||||
{
|
||||
$aResult = array();
|
||||
foreach ($this as $oParam)
|
||||
{
|
||||
foreach ($this as $oParam) {
|
||||
$sLine = $oParam->ToString($bConvertSpecialsName);
|
||||
if (\strlen($sLine))
|
||||
{
|
||||
if (\strlen($sLine)) {
|
||||
$aResult[] = $sLine;
|
||||
}
|
||||
}
|
||||
|
|
@ -99,26 +93,22 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
$this->Clear();
|
||||
|
||||
$aPreParams = array();
|
||||
foreach ($aDataToReParse as $oParam)
|
||||
{
|
||||
foreach ($aDataToReParse as $oParam) {
|
||||
$aMatch = array();
|
||||
$sParamName = $oParam->Name();
|
||||
|
||||
if (\preg_match('/([^\*]+)\*([\d]{1,2})\*/', $sParamName, $aMatch) && isset($aMatch[1], $aMatch[2])
|
||||
&& \strlen($aMatch[1]) && \is_numeric($aMatch[2]))
|
||||
{
|
||||
if (!isset($aPreParams[$aMatch[1]]))
|
||||
{
|
||||
if (!isset($aPreParams[$aMatch[1]])) {
|
||||
$aPreParams[$aMatch[1]] = array();
|
||||
}
|
||||
|
||||
$sValue = $oParam->Value();
|
||||
|
||||
if (false !== \strpos($sValue, "''"))
|
||||
{
|
||||
if (false !== \strpos($sValue, "''")) {
|
||||
$aValueParts = \explode("''", $sValue, 2);
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts) && \strlen($aValueParts[1]))
|
||||
{
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts) && \strlen($aValueParts[1])) {
|
||||
$sCharset = $aValueParts[0];
|
||||
$sValue = $aValueParts[1];
|
||||
}
|
||||
|
|
@ -128,17 +118,14 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
}
|
||||
else if (\preg_match('/([^\*]+)\*/', $sParamName, $aMatch) && isset($aMatch[1]))
|
||||
{
|
||||
if (!isset($aPreParams[$aMatch[1]]))
|
||||
{
|
||||
if (!isset($aPreParams[$aMatch[1]])) {
|
||||
$aPreParams[$aMatch[1]] = array();
|
||||
}
|
||||
|
||||
$sValue = $oParam->Value();
|
||||
if (false !== \strpos($sValue, "''"))
|
||||
{
|
||||
if (false !== \strpos($sValue, "''")) {
|
||||
$aValueParts = \explode("''", $sValue, 2);
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts) && \strlen($aValueParts[1]))
|
||||
{
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts) && \strlen($aValueParts[1])) {
|
||||
$sCharset = $aValueParts[0];
|
||||
$sValue = $aValueParts[1];
|
||||
}
|
||||
|
|
@ -152,14 +139,12 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
}
|
||||
}
|
||||
|
||||
foreach ($aPreParams as $sName => $aValues)
|
||||
{
|
||||
ksort($aValues);
|
||||
foreach ($aPreParams as $sName => $aValues) {
|
||||
\ksort($aValues);
|
||||
$sResult = \implode(\array_values($aValues));
|
||||
$sResult = \urldecode($sResult);
|
||||
|
||||
if (\strlen($sCharset))
|
||||
{
|
||||
if (\strlen($sCharset)) {
|
||||
$sResult = \MailSo\Base\Utils::ConvertEncoding($sResult,
|
||||
$sCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ abstract class Parser
|
|||
POS_SUBPARTS = 3,
|
||||
POS_CLOSE_BOUNDARY = 4;
|
||||
|
||||
private static $LineParts = [];
|
||||
private static array $LineParts = [];
|
||||
|
||||
protected static function writeBody(Part $oPart, string $sBuffer) : void
|
||||
{
|
||||
|
|
@ -59,21 +59,18 @@ abstract class Parser
|
|||
|
||||
$oMimePart = null;
|
||||
$sFirstNotNullCharset = null;
|
||||
foreach (static::$LineParts as /* @var $oMimePart Part */ $oMimePart)
|
||||
{
|
||||
foreach (static::$LineParts as /* @var $oMimePart Part */ $oMimePart) {
|
||||
$sCharset = $oMimePart->HeaderCharset();
|
||||
if (\strlen($sCharset))
|
||||
{
|
||||
if (\strlen($sCharset)) {
|
||||
$sFirstNotNullCharset = $sCharset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$sFirstNotNullCharset = (null !== $sFirstNotNullCharset)
|
||||
? $sFirstNotNullCharset : Part::$DefaultCharset;
|
||||
? $sFirstNotNullCharset : \MailSo\Base\Enumerations\Charset::ISO_8859_1;
|
||||
|
||||
foreach (static::$LineParts as /* @var $oMimePart Part */ $oMimePart)
|
||||
{
|
||||
foreach (static::$LineParts as /* @var $oMimePart Part */ $oMimePart) {
|
||||
$sHeaderCharset = $oMimePart->HeaderCharset();
|
||||
$oMimePart->Headers->SetParentCharset($sHeaderCharset);
|
||||
}
|
||||
|
|
@ -93,53 +90,38 @@ abstract class Parser
|
|||
$sCurrentBoundary = '';
|
||||
$bIsBoundaryCheck = false;
|
||||
$aHeadersLines = array();
|
||||
while (true)
|
||||
{
|
||||
if (!$bNotFirstRead)
|
||||
{
|
||||
while (true) {
|
||||
if (!$bNotFirstRead) {
|
||||
$sPrevBuffer = $sBuffer;
|
||||
$sBuffer = '';
|
||||
}
|
||||
|
||||
if (!$bIsOef && !\feof($rStreamHandle))
|
||||
{
|
||||
if (!$bNotFirstRead)
|
||||
{
|
||||
if (!$bIsOef && !\feof($rStreamHandle)) {
|
||||
if (!$bNotFirstRead) {
|
||||
$sBuffer = \fread($rStreamHandle, 8192);
|
||||
if (false === $sBuffer)
|
||||
{
|
||||
if (false === $sBuffer) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$bNotFirstRead = false;
|
||||
}
|
||||
}
|
||||
else if ($bIsOef && !\strlen($sBuffer))
|
||||
{
|
||||
} else if ($bIsOef && !\strlen($sBuffer)) {
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$bIsOef = true;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
$sCurrentLine = $sPrevBuffer.$sBuffer;
|
||||
if (self::POS_HEADERS === $iParsePosition)
|
||||
{
|
||||
if (self::POS_HEADERS === $iParsePosition) {
|
||||
$iEndLen = 4;
|
||||
$iPos = \strpos($sCurrentLine, "\r\n\r\n", $iOffset);
|
||||
if (false === $iPos)
|
||||
{
|
||||
if (false === $iPos) {
|
||||
$iEndLen = 2;
|
||||
$iPos = \strpos($sCurrentLine, "\n\n", $iOffset);
|
||||
}
|
||||
|
||||
if (false !== $iPos)
|
||||
{
|
||||
if (false !== $iPos) {
|
||||
$aHeadersLines[] = \substr($sCurrentLine, $iOffset, $iPos + $iEndLen - $iOffset);
|
||||
|
||||
$oPart->Headers->Parse(\implode($aHeadersLines))->SetParentCharset($oPart->HeaderCharset());
|
||||
|
|
@ -156,42 +138,31 @@ abstract class Parser
|
|||
$iOffset = $iPos + $iEndLen;
|
||||
$iParsePosition = self::POS_BODY;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iBufferLen = \strlen($sPrevBuffer);
|
||||
if ($iBufferLen > $iOffset)
|
||||
{
|
||||
if ($iBufferLen > $iOffset) {
|
||||
$aHeadersLines[] = \substr($sPrevBuffer, $iOffset);
|
||||
$iOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iOffset -= $iBufferLen;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (self::POS_BODY === $iParsePosition)
|
||||
{
|
||||
} else if (self::POS_BODY === $iParsePosition) {
|
||||
$iPos = false;
|
||||
$sBoundaryLen = 0;
|
||||
$bIsBoundaryEnd = false;
|
||||
$bCurrentPartBody = false;
|
||||
$bIsBoundaryCheck = \count($aBoundaryStack);
|
||||
|
||||
foreach ($aBoundaryStack as $sKey => $sBoundary)
|
||||
{
|
||||
if (false !== ($iPos = \strpos($sCurrentLine, $sBoundary, $iOffset)))
|
||||
{
|
||||
if ($sCurrentBoundary === $sBoundary)
|
||||
{
|
||||
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))
|
||||
{
|
||||
if ('--' === \substr($sCurrentLine, $iPos + $sBoundaryLen, 2)) {
|
||||
$sBoundaryLen += 2;
|
||||
$bIsBoundaryEnd = true;
|
||||
unset($aBoundaryStack[$sKey]);
|
||||
|
|
@ -203,54 +174,42 @@ abstract class Parser
|
|||
}
|
||||
}
|
||||
|
||||
if (false !== $iPos)
|
||||
{
|
||||
if (false !== $iPos) {
|
||||
static::writeBody($oPart, \substr($sCurrentLine, $iOffset, $iPos - $iOffset));
|
||||
$iOffset = $iPos;
|
||||
|
||||
if ($bCurrentPartBody)
|
||||
{
|
||||
if ($bCurrentPartBody) {
|
||||
$iParsePosition = self::POS_SUBPARTS;
|
||||
continue;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iBufferLen = \strlen($sPrevBuffer);
|
||||
if ($iBufferLen > $iOffset)
|
||||
{
|
||||
if ($iBufferLen > $iOffset) {
|
||||
static::writeBody($oPart, \substr($sPrevBuffer, $iOffset));
|
||||
$iOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iOffset -= $iBufferLen;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (self::POS_SUBPARTS === $iParsePosition)
|
||||
{
|
||||
} else if (self::POS_SUBPARTS === $iParsePosition) {
|
||||
$iPos = false;
|
||||
$iBoundaryLen = 0;
|
||||
$bIsBoundaryEnd = false;
|
||||
$bCurrentPartBody = false;
|
||||
$bIsBoundaryCheck = \count($aBoundaryStack);
|
||||
|
||||
foreach ($aBoundaryStack as $sKey => $sBoundary)
|
||||
{
|
||||
if (false !== ($iPos = \strpos($sCurrentLine, $sBoundary, $iOffset)))
|
||||
{
|
||||
if ($sCurrentBoundary === $sBoundary)
|
||||
{
|
||||
foreach ($aBoundaryStack as $sKey => $sBoundary) {
|
||||
$iPos = \strpos($sCurrentLine, $sBoundary, $iOffset);
|
||||
if (false !== $iPos) {
|
||||
if ($sCurrentBoundary === $sBoundary) {
|
||||
$bCurrentPartBody = true;
|
||||
}
|
||||
|
||||
$iBoundaryLen = \strlen($sBoundary);
|
||||
if ('--' === \substr($sCurrentLine, $iPos + $iBoundaryLen, 2))
|
||||
{
|
||||
if ('--' === \substr($sCurrentLine, $iPos + $iBoundaryLen, 2)) {
|
||||
$iBoundaryLen += 2;
|
||||
$bIsBoundaryEnd = true;
|
||||
unset($aBoundaryStack[$sKey]);
|
||||
|
|
@ -261,8 +220,7 @@ abstract class Parser
|
|||
}
|
||||
}
|
||||
|
||||
if (false !== $iPos && $bCurrentPartBody)
|
||||
{
|
||||
if (false !== $iPos && $bCurrentPartBody) {
|
||||
$iOffset = $iPos + $iBoundaryLen;
|
||||
|
||||
$oSubPart = new Part;
|
||||
|
|
@ -274,39 +232,27 @@ abstract class Parser
|
|||
static::$LineParts[] = $oSubPart;
|
||||
//$iParsePosition = self::POS_HEADERS;
|
||||
unset($oSubPart);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (\strlen($sPrevBuffer))
|
||||
{
|
||||
if (self::POS_HEADERS === $iParsePosition)
|
||||
{
|
||||
if (\strlen($sPrevBuffer)) {
|
||||
if (self::POS_HEADERS === $iParsePosition) {
|
||||
$aHeadersLines[] = ($iOffset < \strlen($sPrevBuffer))
|
||||
? \substr($sPrevBuffer, $iOffset)
|
||||
: $sPrevBuffer;
|
||||
|
||||
$oPart->Headers->Parse(\implode($aHeadersLines))->SetParentCharset($oPart->HeaderCharset());
|
||||
$aHeadersLines = array();
|
||||
} else if (!$bIsBoundaryCheck && self::POS_BODY === $iParsePosition) {
|
||||
static::writeBody($oPart, ($iOffset < \strlen($sPrevBuffer))
|
||||
? \substr($sPrevBuffer, $iOffset) : $sPrevBuffer);
|
||||
}
|
||||
else if (self::POS_BODY === $iParsePosition)
|
||||
{
|
||||
if (!$bIsBoundaryCheck)
|
||||
{
|
||||
static::writeBody($oPart, ($iOffset < \strlen($sPrevBuffer))
|
||||
? \substr($sPrevBuffer, $iOffset) : $sPrevBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self::POS_HEADERS === $iParsePosition && \count($aHeadersLines))
|
||||
{
|
||||
} else {
|
||||
if (self::POS_HEADERS === $iParsePosition && \count($aHeadersLines)) {
|
||||
$oPart->Headers->Parse(\implode($aHeadersLines))->SetParentCharset($oPart->HeaderCharset());
|
||||
$aHeadersLines = array();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,15 +17,7 @@ namespace MailSo\Mime;
|
|||
*/
|
||||
class Part
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public static $DefaultCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
|
||||
|
||||
/**
|
||||
* @var HeaderCollection
|
||||
*/
|
||||
public $Headers;
|
||||
public HeaderCollection $Headers;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
|
|
@ -37,10 +29,7 @@ class Part
|
|||
*/
|
||||
public $Raw = null;
|
||||
|
||||
/**
|
||||
* @var PartCollection
|
||||
*/
|
||||
public $SubParts;
|
||||
public PartCollection $SubParts;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
|
|
@ -75,17 +64,12 @@ class Part
|
|||
|
||||
public function IsFlowedFormat() : bool
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->Headers)
|
||||
{
|
||||
$bResult = 'flowed' === \trim(\strtolower($this->Headers->ParameterValue(
|
||||
Enumerations\Header::CONTENT_TYPE,
|
||||
Enumerations\Parameter::FORMAT)));
|
||||
$bResult = 'flowed' === \trim(\strtolower($this->Headers->ParameterValue(
|
||||
Enumerations\Header::CONTENT_TYPE,
|
||||
Enumerations\Parameter::FORMAT)));
|
||||
|
||||
if ($bResult && \in_array($this->MailEncodingName(), array('base64', 'quoted-printable')))
|
||||
{
|
||||
$bResult = false;
|
||||
}
|
||||
if ($bResult && \in_array($this->MailEncodingName(), array('base64', 'quoted-printable'))) {
|
||||
$bResult = false;
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
|
|
@ -93,19 +77,14 @@ class Part
|
|||
|
||||
public function FileName() : string
|
||||
{
|
||||
$sResult = '';
|
||||
if ($this->Headers)
|
||||
{
|
||||
$sResult = \trim($this->Headers->ParameterValue(
|
||||
Enumerations\Header::CONTENT_DISPOSITION,
|
||||
Enumerations\Parameter::FILENAME));
|
||||
$sResult = \trim($this->Headers->ParameterValue(
|
||||
Enumerations\Header::CONTENT_DISPOSITION,
|
||||
Enumerations\Parameter::FILENAME));
|
||||
|
||||
if (!\strlen($sResult))
|
||||
{
|
||||
$sResult = \trim($this->Headers->ParameterValue(
|
||||
Enumerations\Header::CONTENT_TYPE,
|
||||
Enumerations\Parameter::NAME));
|
||||
}
|
||||
if (!\strlen($sResult)) {
|
||||
$sResult = \trim($this->Headers->ParameterValue(
|
||||
Enumerations\Header::CONTENT_TYPE,
|
||||
Enumerations\Parameter::NAME));
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace MailSo\Mime;
|
|||
*/
|
||||
class PartCollection extends \MailSo\Base\Collection
|
||||
{
|
||||
protected $sBoundary;
|
||||
protected string $sBoundary = '';
|
||||
|
||||
public function append($oPart, bool $bToTop = false) : void
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,15 +18,9 @@ namespace MailSo\Net\Exceptions;
|
|||
*/
|
||||
class SocketCanNotConnectToHostException extends ConnectionException
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSocketMessage;
|
||||
private string $sSocketMessage;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSocketCode;
|
||||
private int $iSocketCode;
|
||||
|
||||
public function __construct(string $sSocketMessage = '', int $iSocketCode = 0, string $sMessage = '', int $iCode = 0, ?\Throwable $oPrevious = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ namespace MailSo\Sieve\Exceptions;
|
|||
*/
|
||||
class ResponseException extends \MailSo\RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aResponses;
|
||||
private array $aResponses;
|
||||
|
||||
public function __construct(array $aResponses = array(), string $sMessage = '', int $iCode = 0, ?\Throwable $oPrevious = null)
|
||||
{
|
||||
|
|
@ -37,7 +34,7 @@ class ResponseException extends \MailSo\RuntimeException
|
|||
|
||||
public function GetLastResponse() : ?\MailSo\Sieve\Response
|
||||
{
|
||||
$iCnt = count($this->aResponses);
|
||||
$iCnt = \count($this->aResponses);
|
||||
return $iCnt ? $this->aResponses[$iCnt - 1] : null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class SieveClient extends \MailSo\Net\NetClient
|
|||
$bAuth = false;
|
||||
try
|
||||
{
|
||||
if (0 === \strpos($type, 'SCRAM-'))
|
||||
if (\str_starts_with($type, 'SCRAM-'))
|
||||
{
|
||||
/*
|
||||
$sAuthzid = $this->getResponseValue($this->SendRequestGetResponse('AUTHENTICATE', array($type)), \MailSo\Imap\Enumerations\ResponseType::CONTINUATION);
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ namespace MailSo\Smtp\Exceptions;
|
|||
*/
|
||||
class ResponseException extends \MailSo\RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aResponses;
|
||||
private array $aResponses;
|
||||
|
||||
public function __construct(array $aResponses = array(), string $sMessage = '', int $iCode = 0, ?\Throwable $oPrevious = null)
|
||||
{
|
||||
|
|
@ -37,7 +34,7 @@ class ResponseException extends \MailSo\RuntimeException
|
|||
|
||||
public function GetLastResponse() : ?\MailSo\Smtp\Response
|
||||
{
|
||||
$iCnt = count($this->aResponses);
|
||||
$iCnt = \count($this->aResponses);
|
||||
return $iCnt ? $this->aResponses[$iCnt - 1] : null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ class SmtpClient extends \MailSo\Net\NetClient
|
|||
|
||||
try
|
||||
{
|
||||
if (0 === \strpos($type, 'SCRAM-')) {
|
||||
if (\str_starts_with($type, 'SCRAM-')) {
|
||||
// RFC 5802
|
||||
$sResult = $this->sendRequestWithCheck($SASL->authenticate($sLogin, $sPassword, $sResult), 234, '');
|
||||
$sChallenge = $SASL->challenge($sResult);
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ class Actions
|
|||
{
|
||||
$time = \microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
|
||||
if ($iDelay > $time) {
|
||||
\usleep(($iDelay - $time) * 1000000);
|
||||
\usleep(\intval(($iDelay - $time) * 1000000));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,7 @@ trait Response
|
|||
;
|
||||
|
||||
$aAdditionalParams = array();
|
||||
if (null !== $iErrorCode)
|
||||
{
|
||||
if (null !== $iErrorCode) {
|
||||
$aAdditionalParams['ErrorCode'] = (int) $iErrorCode;
|
||||
$aAdditionalParams['ErrorMessage'] = null === $sErrorMessage ? '' : (string) $sErrorMessage;
|
||||
$aAdditionalParams['ErrorMessageAdditional'] = null === $sAdditionalErrorMessage ? '' : (string) $sAdditionalErrorMessage;
|
||||
|
|
@ -56,35 +55,27 @@ trait Response
|
|||
$sErrorMessage = null;
|
||||
$sErrorMessageAdditional = null;
|
||||
|
||||
if ($oException instanceof \RainLoop\Exceptions\ClientException)
|
||||
{
|
||||
if ($oException instanceof \RainLoop\Exceptions\ClientException) {
|
||||
$iErrorCode = $oException->getCode();
|
||||
$sErrorMessage = null;
|
||||
|
||||
if ($iErrorCode === Notifications::ClientViewError)
|
||||
{
|
||||
if ($iErrorCode === Notifications::ClientViewError) {
|
||||
$sErrorMessage = $oException->getMessage();
|
||||
}
|
||||
|
||||
$sErrorMessageAdditional = $oException->getAdditionalMessage();
|
||||
if (empty($sErrorMessageAdditional))
|
||||
{
|
||||
if (empty($sErrorMessageAdditional)) {
|
||||
$sErrorMessageAdditional = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iErrorCode = Notifications::UnknownError;
|
||||
$sErrorMessage = $oException->getCode().' - '.$oException->getMessage();
|
||||
}
|
||||
|
||||
$oPrevious = $oException->getPrevious();
|
||||
if ($oPrevious)
|
||||
{
|
||||
if ($oPrevious) {
|
||||
$this->Logger()->WriteException($oPrevious);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->Logger()->WriteException($oException);
|
||||
}
|
||||
|
||||
|
|
@ -105,8 +96,7 @@ trait Response
|
|||
'Result' => $this->responseObject($mResult, $sActionName)
|
||||
);
|
||||
|
||||
foreach ($aAdditionalParams as $sKey => $mValue)
|
||||
{
|
||||
foreach ($aAdditionalParams as $sKey => $mValue) {
|
||||
$aResult[$sKey] = $mValue;
|
||||
}
|
||||
|
||||
|
|
@ -141,17 +131,13 @@ trait Response
|
|||
private $aCheckableFolder = null;
|
||||
private function responseObject($mResponse, string $sParent = '')
|
||||
{
|
||||
if (!($mResponse instanceof \JsonSerializable))
|
||||
{
|
||||
if (\is_object($mResponse))
|
||||
{
|
||||
if (!($mResponse instanceof \JsonSerializable)) {
|
||||
if (\is_object($mResponse)) {
|
||||
return '["'.\get_class($mResponse).'"]';
|
||||
}
|
||||
|
||||
if (\is_array($mResponse))
|
||||
{
|
||||
foreach ($mResponse as $iKey => $oItem)
|
||||
{
|
||||
if (\is_array($mResponse)) {
|
||||
foreach ($mResponse as $iKey => $oItem) {
|
||||
$mResponse[$iKey] = $this->responseObject($oItem, $sParent);
|
||||
}
|
||||
}
|
||||
|
|
@ -159,14 +145,13 @@ trait Response
|
|||
return $mResponse;
|
||||
}
|
||||
|
||||
if ($mResponse instanceof \MailSo\Mail\Message)
|
||||
{
|
||||
if ($mResponse instanceof \MailSo\Mail\Message) {
|
||||
$mResult = $mResponse->jsonSerialize();
|
||||
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$mResult['DateTimeStampInUTC'] || $this->Config()->Get('labs', 'date_from_headers', false)) {
|
||||
$iDateTimeStampInUTC = $mResponse->HeaderTimeStampInUTC();
|
||||
$iDateTimeStampInUTC = $mResponse->HeaderTimeStampInUTC;
|
||||
if ($iDateTimeStampInUTC) {
|
||||
$mResult['DateTimeStampInUTC'] = $iDateTimeStampInUTC;
|
||||
}
|
||||
|
|
@ -187,34 +172,30 @@ trait Response
|
|||
'FileName' => (\strlen($sSubject) ? \MailSo\Base\Utils::SecureFileName($sSubject) : 'message-'.$mResult['Uid']) . '.eml'
|
||||
));
|
||||
|
||||
$mResult['Attachments'] = $this->responseObject($mResponse->Attachments(), $sParent);
|
||||
$mResult['Attachments'] = $this->responseObject($mResponse->Attachments, $sParent);
|
||||
|
||||
if ('Message' === $sParent)
|
||||
{
|
||||
$mResult['DraftInfo'] = $mResponse->DraftInfo();
|
||||
$mResult['InReplyTo'] = $mResponse->InReplyTo();
|
||||
$mResult['UnsubsribeLinks'] = $mResponse->UnsubsribeLinks();
|
||||
$mResult['References'] = $mResponse->References();
|
||||
if ('Message' === $sParent) {
|
||||
$mResult['DraftInfo'] = $mResponse->DraftInfo;
|
||||
$mResult['InReplyTo'] = $mResponse->InReplyTo;
|
||||
$mResult['UnsubsribeLinks'] = $mResponse->UnsubsribeLinks;
|
||||
$mResult['References'] = $mResponse->References;
|
||||
|
||||
$mResult['Html'] = $mResponse->Html();
|
||||
$mResult['Plain'] = $mResponse->Plain();
|
||||
|
||||
// $this->GetCapa(Capa::OPEN_PGP) || $this->GetCapa(Capa::GNUPG)
|
||||
$mResult['PgpSigned'] = $mResponse->PgpSigned();
|
||||
$mResult['PgpEncrypted'] = $mResponse->PgpEncrypted();
|
||||
$mResult['PgpSigned'] = $mResponse->pgpSigned;
|
||||
$mResult['PgpEncrypted'] = $mResponse->pgpEncrypted;
|
||||
|
||||
$mResult['ReadReceipt'] = $mResponse->ReadReceipt();
|
||||
$mResult['ReadReceipt'] = $mResponse->ReadReceipt;
|
||||
|
||||
if (\strlen($mResult['ReadReceipt']) && !\in_array('$forwarded', $mResult['Flags']))
|
||||
{
|
||||
if (\strlen($mResult['ReadReceipt']) && !\in_array('$forwarded', $mResult['Flags'])) {
|
||||
// \in_array('$mdnsent', $mResult['Flags'])
|
||||
if (\strlen($mResult['ReadReceipt']))
|
||||
{
|
||||
if (\strlen($mResult['ReadReceipt'])) {
|
||||
try
|
||||
{
|
||||
$oReadReceipt = \MailSo\Mime\Email::Parse($mResult['ReadReceipt']);
|
||||
if (!$oReadReceipt)
|
||||
{
|
||||
if (!$oReadReceipt) {
|
||||
$mResult['ReadReceipt'] = '';
|
||||
}
|
||||
}
|
||||
|
|
@ -231,8 +212,7 @@ trait Response
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
if ($mResponse instanceof \MailSo\Mail\Attachment)
|
||||
{
|
||||
if ($mResponse instanceof \MailSo\Mail\Attachment) {
|
||||
$mResult = $mResponse->jsonSerialize();
|
||||
$mResult['IsThumbnail'] = $this->GetCapa(Capa::ATTACHMENT_THUMBNAILS) && $this->isFileHasThumbnail($mResult['FileName']);
|
||||
$mResult['Download'] = Utils::EncodeKeyValuesQ(array(
|
||||
|
|
@ -246,8 +226,7 @@ trait Response
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
if ($mResponse instanceof \MailSo\Imap\Folder)
|
||||
{
|
||||
if ($mResponse instanceof \MailSo\Imap\Folder) {
|
||||
$aResult = $mResponse->jsonSerialize();
|
||||
|
||||
$sHash = $mResponse->Hash($this->MailClient()->ImapClient()->Hash());
|
||||
|
|
@ -268,8 +247,7 @@ trait Response
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
if ($mResponse instanceof \MailSo\Base\Collection)
|
||||
{
|
||||
if ($mResponse instanceof \MailSo\Base\Collection) {
|
||||
$mResult = $mResponse->jsonSerialize();
|
||||
$mResult['@Collection'] = $this->responseObject($mResult['@Collection'], $sParent);
|
||||
if ($mResponse instanceof \MailSo\Mail\EmailCollection) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue