mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-06-25 07:44:17 +00:00
Updated php-mime-mail-parser library to 5.0 to fix webui html preview
Preview versions of php-mime-mail-parser uses iconv for the most cases and iconv isn't properly supported in alpine php
This commit is contained in:
+90
-1
@@ -50,6 +50,11 @@ class Attachment
|
||||
*/
|
||||
protected $mimePartStr;
|
||||
|
||||
/**
|
||||
* @var integer $maxDuplicateNumber
|
||||
*/
|
||||
public $maxDuplicateNumber = 100;
|
||||
|
||||
/**
|
||||
* Attachment constructor.
|
||||
*
|
||||
@@ -133,13 +138,44 @@ class Attachment
|
||||
/**
|
||||
* Get a handle to the stream
|
||||
*
|
||||
* @return stream
|
||||
* @return resource
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a file if it already exists at its destination.
|
||||
* Renaming is done by adding a duplicate number to the file name. E.g. existingFileName_1.ext.
|
||||
* After a max duplicate number, renaming the file will switch over to generating a random suffix.
|
||||
*
|
||||
* @param string $fileName Complete path to the file.
|
||||
* @return string The suffixed file name.
|
||||
*/
|
||||
protected function suffixFileName(string $fileName): string
|
||||
{
|
||||
$pathInfo = pathinfo($fileName);
|
||||
$dirname = $pathInfo['dirname'].DIRECTORY_SEPARATOR;
|
||||
$filename = $pathInfo['filename'];
|
||||
$extension = empty($pathInfo['extension']) ? '' : '.'.$pathInfo['extension'];
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
$i++;
|
||||
|
||||
if ($i > $this->maxDuplicateNumber) {
|
||||
$duplicateExtension = uniqid();
|
||||
} else {
|
||||
$duplicateExtension = $i;
|
||||
}
|
||||
|
||||
$resultName = $dirname.$filename."_$duplicateExtension".$extension;
|
||||
} while (file_exists($resultName));
|
||||
|
||||
return $resultName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the contents a few bytes at a time until completed
|
||||
* Once read to completion, it always returns false
|
||||
@@ -180,4 +216,57 @@ class Attachment
|
||||
{
|
||||
return $this->mimePartStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the attachment individually
|
||||
*
|
||||
* @param string $attach_dir
|
||||
* @param string $filenameStrategy
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function save(
|
||||
$attach_dir,
|
||||
$filenameStrategy = Parser::ATTACHMENT_DUPLICATE_SUFFIX
|
||||
) {
|
||||
$attach_dir = rtrim($attach_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($attach_dir)) {
|
||||
mkdir($attach_dir);
|
||||
}
|
||||
|
||||
// Determine filename
|
||||
switch ($filenameStrategy) {
|
||||
case Parser::ATTACHMENT_RANDOM_FILENAME:
|
||||
$attachment_path = tempnam($attach_dir, '');
|
||||
break;
|
||||
case Parser::ATTACHMENT_DUPLICATE_THROW:
|
||||
case Parser::ATTACHMENT_DUPLICATE_SUFFIX:
|
||||
$attachment_path = $attach_dir.$this->getFilename();
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid filename strategy argument provided.');
|
||||
}
|
||||
|
||||
// Handle duplicate filename
|
||||
if (file_exists($attachment_path)) {
|
||||
switch ($filenameStrategy) {
|
||||
case Parser::ATTACHMENT_DUPLICATE_THROW:
|
||||
throw new Exception('Could not create file for attachment: duplicate filename.');
|
||||
case Parser::ATTACHMENT_DUPLICATE_SUFFIX:
|
||||
$attachment_path = $this->suffixFileName($attachment_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var resource $fp */
|
||||
if ($fp = fopen($attachment_path, 'w')) {
|
||||
while ($bytes = $this->read()) {
|
||||
fwrite($fp, $bytes);
|
||||
}
|
||||
fclose($fp);
|
||||
return realpath($attachment_path);
|
||||
} else {
|
||||
throw new Exception('Could not write attachments. Your directory may be unwritable by PHP.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-19
@@ -78,20 +78,20 @@ class Charset implements CharsetManager
|
||||
'cns11643' => 'x-euc-tw',
|
||||
'x-imap4-modified-utf7' => 'x-imap4-modified-utf7',
|
||||
'x-euc-tw' => 'x-euc-tw',
|
||||
'x-mac-ce' => 'x-mac-ce',
|
||||
'x-mac-turkish' => 'x-mac-turkish',
|
||||
'x-mac-greek' => 'x-mac-greek',
|
||||
'x-mac-icelandic' => 'x-mac-icelandic',
|
||||
'x-mac-croatian' => 'x-mac-croatian',
|
||||
'x-mac-romanian' => 'x-mac-romanian',
|
||||
'x-mac-cyrillic' => 'x-mac-cyrillic',
|
||||
'x-mac-ukrainian' => 'x-mac-cyrillic',
|
||||
'x-mac-hebrew' => 'x-mac-hebrew',
|
||||
'x-mac-arabic' => 'x-mac-arabic',
|
||||
'x-mac-farsi' => 'x-mac-farsi',
|
||||
'x-mac-devanagari' => 'x-mac-devanagari',
|
||||
'x-mac-gujarati' => 'x-mac-gujarati',
|
||||
'x-mac-gurmukhi' => 'x-mac-gurmukhi',
|
||||
'x-mac-ce' => 'MACCE',
|
||||
'x-mac-turkish' => 'MACTURKISH',
|
||||
'x-mac-greek' => 'MACGREEK',
|
||||
'x-mac-icelandic' => 'MACICELANDIC',
|
||||
'x-mac-croatian' => 'MACCROATIAN',
|
||||
'x-mac-romanian' => 'MACROMANIAN',
|
||||
'x-mac-cyrillic' => 'MACCYRILLIC',
|
||||
'x-mac-ukrainian' => 'MACUKRAINIAN',
|
||||
'x-mac-hebrew' => 'MACHEBREW',
|
||||
'x-mac-arabic' => 'MACARABIC',
|
||||
'x-mac-farsi' => 'MACFARSI',
|
||||
'x-mac-devanagari' => 'MACDEVANAGARI',
|
||||
'x-mac-gujarati' => 'MACGUJARATI',
|
||||
'x-mac-gurmukhi' => 'MACGURMUKHI',
|
||||
'armscii-8' => 'armscii-8',
|
||||
'x-viet-tcvn5712' => 'x-viet-tcvn5712',
|
||||
'x-viet-vps' => 'x-viet-vps',
|
||||
@@ -315,11 +315,23 @@ class Charset implements CharsetManager
|
||||
*/
|
||||
public function decodeCharset($encodedString, $charset)
|
||||
{
|
||||
if (strtolower($charset) == 'utf-8' || strtolower($charset) == 'us-ascii') {
|
||||
$charset = $this->getCharsetAlias($charset);
|
||||
|
||||
if ($charset == 'utf-8' || $charset == 'us-ascii') {
|
||||
return $encodedString;
|
||||
} else {
|
||||
return iconv($this->getCharsetAlias($charset), 'UTF-8//TRANSLIT//IGNORE', $encodedString);
|
||||
}
|
||||
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
if ($charset == 'ISO-2022-JP') {
|
||||
return mb_convert_encoding($encodedString, 'UTF-8', 'ISO-2022-JP-MS');
|
||||
}
|
||||
|
||||
if (array_search($charset, array_map('strtolower', mb_list_encodings()))) {
|
||||
return mb_convert_encoding($encodedString, 'UTF-8', $charset);
|
||||
}
|
||||
}
|
||||
|
||||
return iconv($charset, 'UTF-8//TRANSLIT//IGNORE', $encodedString);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,8 +343,8 @@ class Charset implements CharsetManager
|
||||
|
||||
if (array_key_exists($charset, $this->charsetAlias)) {
|
||||
return $this->charsetAlias[$charset];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return 'us-ascii';
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -7,6 +7,8 @@ namespace PhpMimeMailParser;
|
||||
*/
|
||||
class Middleware implements Contracts\Middleware
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* Create a middleware using a callable $fn
|
||||
*
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace PhpMimeMailParser;
|
||||
|
||||
use PhpMimeMailParser\Contracts\MiddleWare;
|
||||
use PhpMimeMailParser\Contracts\MiddleWare as MiddleWareContracts;
|
||||
|
||||
/**
|
||||
* A stack of middleware chained together by (MiddlewareStack $next)
|
||||
@@ -29,7 +29,7 @@ class MiddlewareStack
|
||||
*
|
||||
* @param Middleware $middleware
|
||||
*/
|
||||
public function __construct(Middleware $middleware = null)
|
||||
public function __construct(MiddleWareContracts $middleware = null)
|
||||
{
|
||||
$this->middleware = $middleware;
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class MiddlewareStack
|
||||
* @param Middleware $middleware
|
||||
* @return MiddlewareStack Immutable MiddlewareStack
|
||||
*/
|
||||
public function add(Middleware $middleware)
|
||||
public function add(MiddleWareContracts $middleware)
|
||||
{
|
||||
$stack = new static($middleware);
|
||||
$stack->next = $this;
|
||||
|
||||
+24
-45
@@ -110,6 +110,15 @@ class Parser
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
if (is_writable($path)) {
|
||||
$file = fopen($path, 'a+');
|
||||
fseek($file, -1, SEEK_END);
|
||||
if (fread($file, 1) != "\n") {
|
||||
fwrite($file, PHP_EOL);
|
||||
}
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
// should parse message incrementally from file
|
||||
$this->resource = mailparse_msg_parse_file($path);
|
||||
$this->stream = fopen($path, 'r');
|
||||
@@ -142,6 +151,11 @@ class Parser
|
||||
while (!feof($stream)) {
|
||||
fwrite($tmp_fp, fread($stream, 2028));
|
||||
}
|
||||
|
||||
if (fread($tmp_fp, 1) != "\n") {
|
||||
fwrite($tmp_fp, PHP_EOL);
|
||||
}
|
||||
|
||||
fseek($tmp_fp, 0);
|
||||
$this->stream = &$tmp_fp;
|
||||
} else {
|
||||
@@ -170,9 +184,14 @@ class Parser
|
||||
*/
|
||||
public function setText($data)
|
||||
{
|
||||
if (!$data) {
|
||||
if (empty($data)) {
|
||||
throw new Exception('You must not call MimeMailParser::setText with an empty string parameter');
|
||||
}
|
||||
|
||||
if (substr($data, -1) != "\n") {
|
||||
$data = $data.PHP_EOL;
|
||||
}
|
||||
|
||||
$this->resource = mailparse_msg_create();
|
||||
// does not parse incrementally, fast memory hog might explode
|
||||
mailparse_msg_parse($this->resource, $data);
|
||||
@@ -205,7 +224,7 @@ class Parser
|
||||
*
|
||||
* @param string $name Header name (case-insensitive)
|
||||
*
|
||||
* @return string
|
||||
* @return string|bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRawHeader($name)
|
||||
@@ -214,7 +233,7 @@ class Parser
|
||||
if (isset($this->parts[1])) {
|
||||
$headers = $this->getPart('headers', $this->parts[1]);
|
||||
|
||||
return (isset($headers[$name])) ? $headers[$name] : false;
|
||||
return isset($headers[$name]) ? $headers[$name] : false;
|
||||
} else {
|
||||
throw new Exception(
|
||||
'setPath() or setText() or setStream() must be called before retrieving email headers.'
|
||||
@@ -227,7 +246,7 @@ class Parser
|
||||
*
|
||||
* @param string $name Header name (case-insensitive)
|
||||
*
|
||||
* @return string
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getHeader($name)
|
||||
{
|
||||
@@ -559,50 +578,10 @@ class Parser
|
||||
$filenameStrategy = self::ATTACHMENT_DUPLICATE_SUFFIX
|
||||
) {
|
||||
$attachments = $this->getAttachments($include_inline);
|
||||
if (empty($attachments)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_dir($attach_dir)) {
|
||||
mkdir($attach_dir);
|
||||
}
|
||||
|
||||
$attachments_paths = [];
|
||||
foreach ($attachments as $attachment) {
|
||||
// Determine filename
|
||||
switch ($filenameStrategy) {
|
||||
case self::ATTACHMENT_RANDOM_FILENAME:
|
||||
$attachment_path = tempnam($attach_dir, '');
|
||||
break;
|
||||
case self::ATTACHMENT_DUPLICATE_THROW:
|
||||
case self::ATTACHMENT_DUPLICATE_SUFFIX:
|
||||
$attachment_path = $attach_dir.$attachment->getFilename();
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid filename strategy argument provided.');
|
||||
}
|
||||
|
||||
// Handle duplicate filename
|
||||
if (file_exists($attachment_path)) {
|
||||
switch ($filenameStrategy) {
|
||||
case self::ATTACHMENT_DUPLICATE_THROW:
|
||||
throw new Exception('Could not create file for attachment: duplicate filename.');
|
||||
case self::ATTACHMENT_DUPLICATE_SUFFIX:
|
||||
$attachment_path = tempnam($attach_dir, $attachment->getFilename());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var resource $fp */
|
||||
if ($fp = fopen($attachment_path, 'w')) {
|
||||
while ($bytes = $attachment->read()) {
|
||||
fwrite($fp, $bytes);
|
||||
}
|
||||
fclose($fp);
|
||||
$attachments_paths[] = realpath($attachment_path);
|
||||
} else {
|
||||
throw new Exception('Could not write attachments. Your directory may be unwritable by PHP.');
|
||||
}
|
||||
$attachments_paths[] = $attachment->save($attach_dir, $filenameStrategy);
|
||||
}
|
||||
|
||||
return $attachments_paths;
|
||||
|
||||
Reference in New Issue
Block a user