MailSo class properties to typed properties and clean up

This commit is contained in:
the-djmaze 2022-12-20 20:17:11 +01:00
parent 22450e7430
commit 731ac52564
53 changed files with 677 additions and 1944 deletions

View file

@ -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;
}

View file

@ -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), '&gt;');
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);

View file

@ -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'])) {

View file

@ -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+?)(\\/)?)((?:&gt;)?|[^\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;
}
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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;
}
}
}

View file

@ -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];
}
}

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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)
{

View file

@ -13,8 +13,7 @@ namespace MailSo\Imap\Requests;
abstract class Request
{
protected
$oImapClient;
protected \MailSo\Imap\ImapClient $oImapClient;
function __construct(\MailSo\Imap\ImapClient $oImapClient)
{

View file

@ -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,

View file

@ -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)
{

View file

@ -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);

View file

@ -17,7 +17,7 @@ namespace MailSo\Imap\Responses;
*/
class ACL implements \JsonSerializable
{
private $rights;
private array $rights;
function __construct(array $rights)
{

View file

@ -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)
{

View file

@ -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);
}

View file

@ -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()
{

View file

@ -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)
{

View file

@ -18,7 +18,7 @@ namespace MailSo\Log\Drivers;
*/
class Syslog extends \MailSo\Log\Driver
{
private $iLogLevel;
private int $iLogLevel = 0;
function __construct()
{

View file

@ -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);
}

View file

@ -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) {

View file

@ -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,

View file

@ -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;

View file

@ -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.'>';
}
}

View file

@ -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(

View file

@ -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,

View file

@ -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]);
}
}

View file

@ -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);
}

View file

@ -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 . '"';
}
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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;

View file

@ -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
{

View file

@ -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)
{

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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));
}
}

View file

@ -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) {