mirror of
https://github.com/itflow-org/itflow
synced 2026-06-16 14:51:04 +00:00
Rewrite email parser using ImapEngine, harden processing loop
Replace webklex/php-imap with directorytree/imapengine in the ticket email parser. ImapEngine is pure PHP over sockets. Parser improvements: - Wrap per-message processing in try/catch so one malformed email can't abort the run; failures are flagged and logged with UID - Query unseen + unflagged so previously-failed (flagged) messages are no longer re-processed on every cron run - Skip vacation/auto-responder emails (RFC 3834) to prevent mail loops with the ticket auto-reply - Cap messages per run (50) and attachment size (15MB); inline images over 2MB are stored as attachments instead of base64-embedded in ticket details - Atomic lock file creation - preg_quote() the ticket prefix in subject matching - Dedupe CC watchers and exclude the sender - Map webklex 'tls' encryption setting to STARTTLS for compatibility NDR/DSN parsing now walks MIME parts via the underlying zbateson parser instead of relying on attachment extraction.
This commit is contained in:
75
plugins/vendor/zbateson/mail-mime-parser/src/Parser/AbstractParserService.php
vendored
Normal file
75
plugins/vendor/zbateson/mail-mime-parser/src/Parser/AbstractParserService.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxyFactory;
|
||||
|
||||
/**
|
||||
* Provides basic implementations for:
|
||||
* - IParser::setParserManager
|
||||
* - IParser::getParserMessageProxyFactory (returns $this->parserMessageProxyFactory
|
||||
* which can be set via the default constructor)
|
||||
* - IParser::getParserPartProxyFactory (returns $this->parserPartProxyFactory
|
||||
* which can be set via the default constructor)
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
abstract class AbstractParserService implements IParserService
|
||||
{
|
||||
/**
|
||||
* @var ParserPartProxyFactory the parser's message proxy factory service
|
||||
* responsible for creating an IMessage part wrapped in a
|
||||
* ParserPartProxy.
|
||||
*/
|
||||
protected ParserPartProxyFactory $parserMessageProxyFactory;
|
||||
|
||||
/**
|
||||
* @var ParserPartProxyFactory the parser's part proxy factory service
|
||||
* responsible for creating IMessagePart parts wrapped in a
|
||||
* ParserPartProxy.
|
||||
*/
|
||||
protected ParserPartProxyFactory $parserPartProxyFactory;
|
||||
|
||||
/**
|
||||
* @var PartBuilderFactory Service for creating PartBuilder objects for new
|
||||
* children.
|
||||
*/
|
||||
protected PartBuilderFactory $partBuilderFactory;
|
||||
|
||||
/**
|
||||
* @var ParserManagerService the ParserManager, which should call setParserManager
|
||||
* when the parser is added.
|
||||
*/
|
||||
protected ParserManagerService $parserManager;
|
||||
|
||||
public function __construct(
|
||||
ParserPartProxyFactory $parserMessageProxyFactory,
|
||||
ParserPartProxyFactory $parserPartProxyFactory,
|
||||
PartBuilderFactory $partBuilderFactory
|
||||
) {
|
||||
$this->parserMessageProxyFactory = $parserMessageProxyFactory;
|
||||
$this->parserPartProxyFactory = $parserPartProxyFactory;
|
||||
$this->partBuilderFactory = $partBuilderFactory;
|
||||
}
|
||||
|
||||
public function setParserManager(ParserManagerService $pm) : static
|
||||
{
|
||||
$this->parserManager = $pm;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParserMessageProxyFactory() : ParserPartProxyFactory
|
||||
{
|
||||
return $this->parserMessageProxyFactory;
|
||||
}
|
||||
|
||||
public function getParserPartProxyFactory() : ParserPartProxyFactory
|
||||
{
|
||||
return $this->parserPartProxyFactory;
|
||||
}
|
||||
}
|
||||
22
plugins/vendor/zbateson/mail-mime-parser/src/Parser/CompatibleParserNotFoundException.php
vendored
Normal file
22
plugins/vendor/zbateson/mail-mime-parser/src/Parser/CompatibleParserNotFoundException.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Exception thrown if the ParserManagerService doesn't contain a parser that
|
||||
* can handle a given type of part. The default configuration of MailMimeParser
|
||||
* uses NonMimeParserService that is a 'catch-all', so this would indicate a
|
||||
* configuration error.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class CompatibleParserNotFoundException extends RuntimeException
|
||||
{
|
||||
}
|
||||
67
plugins/vendor/zbateson/mail-mime-parser/src/Parser/HeaderParserService.php
vendored
Normal file
67
plugins/vendor/zbateson/mail-mime-parser/src/Parser/HeaderParserService.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use Psr\Log\LogLevel;
|
||||
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
|
||||
|
||||
/**
|
||||
* Reads headers from an input stream, adding them to a PartHeaderContainer.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class HeaderParserService
|
||||
{
|
||||
/**
|
||||
* Ensures the header isn't empty and contains a colon separator character,
|
||||
* then splits it and adds it to the passed PartHeaderContainer.
|
||||
*
|
||||
* @param int $offset read offset for error reporting
|
||||
* @param string $header the header line
|
||||
* @param PartHeaderContainer $headerContainer the container
|
||||
*/
|
||||
private function addRawHeaderToPart(int $offset, string $header, PartHeaderContainer $headerContainer) : static
|
||||
{
|
||||
if ($header !== '') {
|
||||
if (\strpos($header, ':') !== false) {
|
||||
$a = \explode(':', $header, 2);
|
||||
$headerContainer->add($a[0], \trim($a[1]));
|
||||
} else {
|
||||
$headerContainer->addError(
|
||||
"Invalid header found at offset: $offset",
|
||||
LogLevel::ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads header lines up to an empty line, adding them to the passed
|
||||
* PartHeaderContainer.
|
||||
*
|
||||
* @param resource $handle The resource handle to read from.
|
||||
* @param PartHeaderContainer $container the container to add headers to.
|
||||
*/
|
||||
public function parse($handle, PartHeaderContainer $container) : static
|
||||
{
|
||||
$header = '';
|
||||
do {
|
||||
$offset = \ftell($handle);
|
||||
$line = MessageParserService::readLine($handle);
|
||||
if ($line === false || $line === '' || $line[0] !== "\t" && $line[0] !== ' ') {
|
||||
$this->addRawHeaderToPart($offset, $header, $container);
|
||||
$header = '';
|
||||
} else {
|
||||
$line = "\r\n" . $line;
|
||||
}
|
||||
$header .= \rtrim($line, "\r\n");
|
||||
} while ($header !== '');
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
91
plugins/vendor/zbateson/mail-mime-parser/src/Parser/IParserService.php
vendored
Normal file
91
plugins/vendor/zbateson/mail-mime-parser/src/Parser/IParserService.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMimePartProxy;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxy;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxyFactory;
|
||||
|
||||
/**
|
||||
* Interface defining a message part parser.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
interface IParserService
|
||||
{
|
||||
/**
|
||||
* Sets up the passed ParserManager as the ParserManager for this part,
|
||||
* which should be used when a new part is created (after its headers are
|
||||
* read and a PartBuilder is created from it.)
|
||||
*
|
||||
* @param ParserManagerService $pm The ParserManager to set.
|
||||
*/
|
||||
public function setParserManager(ParserManagerService $pm) : static;
|
||||
|
||||
/**
|
||||
* Called by the ParserManager to determine if the passed PartBuilder is a
|
||||
* part handled by this IParser.
|
||||
*/
|
||||
public function canParse(PartBuilder $part) : bool;
|
||||
|
||||
/**
|
||||
* Returns the ParserPartProxyFactory responsible for creating IMessage
|
||||
* parts for this parser.
|
||||
*
|
||||
* This is called by ParserManager after 'canParse' if it returns true so
|
||||
* a ParserPartProxy can be created out of the PartBuilder.
|
||||
*/
|
||||
public function getParserMessageProxyFactory() : ParserPartProxyFactory;
|
||||
|
||||
/**
|
||||
* Returns the ParserPartProxyFactory responsible for creating IMessagePart
|
||||
* parts for this parser.
|
||||
*
|
||||
* This is called by ParserManager after 'canParse' if it returns true so
|
||||
* a ParserPartProxy can be created out of the PartBuilder.
|
||||
*/
|
||||
public function getParserPartProxyFactory() : ParserPartProxyFactory;
|
||||
|
||||
/**
|
||||
* Performs read operations for content from the stream of the passed
|
||||
* ParserPartProxy, and setting content bounds for the part in the passed
|
||||
* ParserPartProxy.
|
||||
*
|
||||
* The implementation should call $proxy->setStreamContentStartPos() and
|
||||
* $proxy->setStreamContentAndPartEndPos() so an IMessagePart can return
|
||||
* content from the raw message.
|
||||
*
|
||||
* Reading should stop once the end of the current part's content has been
|
||||
* reached or the end of the message has been reached. If the end of the
|
||||
* message has been reached $proxy->setEof() should be called in addition to
|
||||
* setStreamContentAndPartEndPos().
|
||||
*/
|
||||
public function parseContent(ParserPartProxy $proxy) : static;
|
||||
|
||||
/**
|
||||
* Performs read operations to read children from the passed $proxy, using
|
||||
* its stream, and reading up to (and not including) the beginning of the
|
||||
* child's content if another child exists.
|
||||
*
|
||||
* The implementation should:
|
||||
* 1. Return null if there are no more children.
|
||||
* 2. Read headers
|
||||
* 3. Create a PartBuilder (adding the passed $proxy as its parent)
|
||||
* 4. Call ParserManager::createParserProxyFor() on the ParserManager
|
||||
* previously set by a call to setParserManager(), which may determine
|
||||
* that a different parser is responsible for parts represented by
|
||||
* the headers and PartBuilder passed to it.
|
||||
*
|
||||
* The method should then return the ParserPartProxy returned by the
|
||||
* ParserManager, or null if there are no more children to read.
|
||||
*
|
||||
* @return ParserPartProxy|null The child ParserPartProxy or null if there
|
||||
* are no more children under $proxy.
|
||||
*/
|
||||
public function parseNextChild(ParserMimePartProxy $proxy) : ?ParserPartProxy;
|
||||
}
|
||||
95
plugins/vendor/zbateson/mail-mime-parser/src/Parser/MessageParserService.php
vendored
Normal file
95
plugins/vendor/zbateson/mail-mime-parser/src/Parser/MessageParserService.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use ZBateson\MailMimeParser\IMessage;
|
||||
use ZBateson\MailMimeParser\Message\Factory\PartHeaderContainerFactory;
|
||||
|
||||
/**
|
||||
* Parses a mail mime message into its component parts. To invoke, call
|
||||
* {@see MailMimeParser::parse()}.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class MessageParserService
|
||||
{
|
||||
/**
|
||||
* @var PartHeaderContainerFactory To create a container to read the
|
||||
* message's headers into.
|
||||
*/
|
||||
protected PartHeaderContainerFactory $partHeaderContainerFactory;
|
||||
|
||||
/**
|
||||
* @var ParserManagerService To figure out what parser is responsible for parsing a
|
||||
* message.
|
||||
*/
|
||||
protected ParserManagerService $parserManager;
|
||||
|
||||
/**
|
||||
* @var PartBuilderFactory To create a PartBuilder representing this
|
||||
* message, and to pass it to ParserManager.
|
||||
*/
|
||||
protected PartBuilderFactory $partBuilderFactory;
|
||||
|
||||
/**
|
||||
* @var HeaderParserService To parse the headers into a PartHeaderContainer.
|
||||
*/
|
||||
protected HeaderParserService $headerParser;
|
||||
|
||||
public function __construct(
|
||||
PartBuilderFactory $pbf,
|
||||
PartHeaderContainerFactory $phcf,
|
||||
ParserManagerService $pm,
|
||||
HeaderParserService $hp
|
||||
) {
|
||||
$this->partBuilderFactory = $pbf;
|
||||
$this->partHeaderContainerFactory = $phcf;
|
||||
$this->parserManager = $pm;
|
||||
$this->headerParser = $hp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to read a line of up to 4096 characters from the
|
||||
* passed resource handle.
|
||||
*
|
||||
* If the line is larger than 4096 characters, the remaining characters in
|
||||
* the line are read and discarded, and only the first 4096 characters are
|
||||
* returned.
|
||||
*
|
||||
* @param resource $handle
|
||||
* @return string|false the read line or false on EOF or on error.
|
||||
*/
|
||||
public static function readLine($handle) : string|false
|
||||
{
|
||||
$size = 4096;
|
||||
$ret = $line = \fgets($handle, $size);
|
||||
while (\strlen($line) === $size - 1 && \substr($line, -1) !== "\n") {
|
||||
$line = \fgets($handle, $size);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the passed stream into an {@see ZBateson\MailMimeParser\IMessage}
|
||||
* object and returns it.
|
||||
*
|
||||
* @param StreamInterface $stream the stream to parse the message from
|
||||
*/
|
||||
public function parse(StreamInterface $stream) : IMessage
|
||||
{
|
||||
$headerContainer = $this->partHeaderContainerFactory->newInstance();
|
||||
$partBuilder = $this->partBuilderFactory->newPartBuilder($headerContainer, $stream);
|
||||
$this->headerParser->parse(
|
||||
$partBuilder->getMessageResourceHandle(),
|
||||
$headerContainer
|
||||
);
|
||||
$proxy = $this->parserManager->createParserProxyFor($partBuilder);
|
||||
return $proxy->getPart();
|
||||
}
|
||||
}
|
||||
167
plugins/vendor/zbateson/mail-mime-parser/src/Parser/MimeParserService.php
vendored
Normal file
167
plugins/vendor/zbateson/mail-mime-parser/src/Parser/MimeParserService.php
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use ZBateson\MailMimeParser\Message\Factory\PartHeaderContainerFactory;
|
||||
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMessageProxyFactory;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMimePartProxy;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMimePartProxyFactory;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxy;
|
||||
|
||||
/**
|
||||
* Parses content and children of MIME parts.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class MimeParserService extends AbstractParserService
|
||||
{
|
||||
/**
|
||||
* @var PartHeaderContainerFactory Factory service for creating
|
||||
* PartHeaderContainers for headers.
|
||||
*/
|
||||
protected PartHeaderContainerFactory $partHeaderContainerFactory;
|
||||
|
||||
/**
|
||||
* @var HeaderParserService The HeaderParser service.
|
||||
*/
|
||||
protected HeaderParserService $headerParser;
|
||||
|
||||
public function __construct(
|
||||
ParserMessageProxyFactory $parserMessageProxyFactory,
|
||||
ParserMimePartProxyFactory $parserMimePartProxyFactory,
|
||||
PartBuilderFactory $partBuilderFactory,
|
||||
PartHeaderContainerFactory $partHeaderContainerFactory,
|
||||
HeaderParserService $headerParser
|
||||
) {
|
||||
parent::__construct($parserMessageProxyFactory, $parserMimePartProxyFactory, $partBuilderFactory);
|
||||
$this->partHeaderContainerFactory = $partHeaderContainerFactory;
|
||||
$this->headerParser = $headerParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the passed PartBuilder::isMime() method returns true.
|
||||
*
|
||||
*/
|
||||
public function canParse(PartBuilder $part) : bool
|
||||
{
|
||||
return $part->isMime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to 2048 bytes of input from the passed resource handle,
|
||||
* discarding portions of a line that are longer than that, and returning
|
||||
* the read portions of the line.
|
||||
*
|
||||
* The method also calls $proxy->setLastLineEndingLength which is used in
|
||||
* findContentBoundary() to set the exact end byte of a part.
|
||||
*
|
||||
* @param resource $handle
|
||||
*/
|
||||
private function readBoundaryLine($handle, ParserMimePartProxy $proxy) : string
|
||||
{
|
||||
$size = 2048;
|
||||
$isCut = false;
|
||||
$line = \fgets($handle, $size);
|
||||
while (\strlen($line) === $size - 1 && \substr($line, -1) !== "\n") {
|
||||
$line = \fgets($handle, $size);
|
||||
$isCut = true;
|
||||
}
|
||||
$ret = \rtrim($line, "\r\n");
|
||||
$proxy->setLastLineEndingLength(\strlen($line) - \strlen($ret));
|
||||
return ($isCut) ? '' : $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads 2048-byte lines from the passed $handle, calling
|
||||
* $partBuilder->setEndBoundaryFound with the passed line until it returns
|
||||
* true or the stream is at EOF.
|
||||
*
|
||||
* setEndBoundaryFound returns true if the passed line matches a boundary
|
||||
* for the $partBuilder itself or any of its parents.
|
||||
*
|
||||
* Lines longer than 2048 bytes are returned as single lines of 2048 bytes,
|
||||
* the longer line is not returned separately but is simply discarded.
|
||||
*
|
||||
* Once a boundary is found, setStreamPartAndContentEndPos is called with
|
||||
* the passed $handle's read pos before the boundary and its line separator
|
||||
* were read.
|
||||
*/
|
||||
private function findContentBoundary(ParserMimePartProxy $proxy) : static
|
||||
{
|
||||
$handle = $proxy->getMessageResourceHandle();
|
||||
// last separator before a boundary belongs to the boundary, and is not
|
||||
// part of the current part, if a part is immediately followed by a
|
||||
// boundary, this could result in a '-1' or '-2' content length
|
||||
while (!\feof($handle)) {
|
||||
$endPos = \ftell($handle) - $proxy->getLastLineEndingLength();
|
||||
$line = $this->readBoundaryLine($handle, $proxy);
|
||||
if (\substr($line, 0, 2) === '--' && $proxy->setEndBoundaryFound($line)) {
|
||||
$proxy->setStreamPartAndContentEndPos($endPos);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
$proxy->setStreamPartAndContentEndPos(\ftell($handle));
|
||||
$proxy->setEof();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function parseContent(ParserPartProxy $proxy) : static
|
||||
{
|
||||
$proxy->setStreamContentStartPos($proxy->getMessageResourceHandlePos());
|
||||
$this->findContentBoundary($proxy);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the header parser to fill the passed $headerContainer, then calls
|
||||
* $this->parserManager->createParserProxyFor($child);
|
||||
*
|
||||
* The method first checks though if the 'part' represents hidden content
|
||||
* past a MIME end boundary, which some messages like to include, for
|
||||
* instance:
|
||||
*
|
||||
* ```
|
||||
* --outer-boundary--
|
||||
* --boundary
|
||||
* content
|
||||
* --boundary--
|
||||
* some hidden information
|
||||
* --outer-boundary--
|
||||
* ```
|
||||
*
|
||||
* In this case, $this->parserPartProxyFactory is called directly to create
|
||||
* a part, $this->parseContent is called immediately to parse it and discard
|
||||
* it, and null is returned.
|
||||
*/
|
||||
private function createPart(ParserMimePartProxy $parent, PartHeaderContainer $headerContainer, PartBuilder $child) : ?ParserPartProxy
|
||||
{
|
||||
if (!$parent->isEndBoundaryFound()) {
|
||||
$this->headerParser->parse(
|
||||
$child->getMessageResourceHandle(),
|
||||
$headerContainer
|
||||
);
|
||||
$parserProxy = $this->parserManager->createParserProxyFor($child);
|
||||
return $parserProxy;
|
||||
}
|
||||
// reads content past an end boundary if there is any
|
||||
$parserProxy = $this->parserPartProxyFactory->newInstance($child, $this);
|
||||
$this->parseContent($parserProxy);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function parseNextChild(ParserMimePartProxy $proxy) : ?ParserPartProxy
|
||||
{
|
||||
if ($proxy->isParentBoundaryFound()) {
|
||||
return null;
|
||||
}
|
||||
$headerContainer = $this->partHeaderContainerFactory->newInstance();
|
||||
$child = $this->partBuilderFactory->newChildPartBuilder($headerContainer, $proxy);
|
||||
return $this->createPart($proxy, $headerContainer, $child);
|
||||
}
|
||||
}
|
||||
111
plugins/vendor/zbateson/mail-mime-parser/src/Parser/NonMimeParserService.php
vendored
Normal file
111
plugins/vendor/zbateson/mail-mime-parser/src/Parser/NonMimeParserService.php
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use ZBateson\MailMimeParser\Parser\Part\UUEncodedPartHeaderContainerFactory;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMimePartProxy;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserNonMimeMessageProxy;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserNonMimeMessageProxyFactory;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxy;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserUUEncodedPartProxy;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserUUEncodedPartProxyFactory;
|
||||
|
||||
/**
|
||||
* Parses content for non-mime messages and uu-encoded child parts.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class NonMimeParserService extends AbstractParserService
|
||||
{
|
||||
protected UUEncodedPartHeaderContainerFactory $partHeaderContainerFactory;
|
||||
|
||||
public function __construct(
|
||||
ParserNonMimeMessageProxyFactory $parserNonMimeMessageProxyFactory,
|
||||
ParserUUEncodedPartProxyFactory $parserUuEncodedPartProxyFactory,
|
||||
PartBuilderFactory $partBuilderFactory,
|
||||
UUEncodedPartHeaderContainerFactory $uuEncodedPartHeaderContainerFactory
|
||||
) {
|
||||
parent::__construct($parserNonMimeMessageProxyFactory, $parserUuEncodedPartProxyFactory, $partBuilderFactory);
|
||||
$this->partHeaderContainerFactory = $uuEncodedPartHeaderContainerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns true, and should therefore be the last parser reached by
|
||||
* a ParserManager.
|
||||
*/
|
||||
public function canParse(PartBuilder $part) : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a UUEncodedPartHeaderContainer attached to a PartBuilder, and
|
||||
* calls $this->parserManager->createParserProxyFor().
|
||||
*
|
||||
* It also sets the PartBuilder's stream part start pos and content start
|
||||
* pos to that of $parent->getNextParStart() (since a 'begin' line is read
|
||||
* prior to another child being created, see parseNextPart()).
|
||||
*/
|
||||
private function createPart(ParserNonMimeMessageProxy $parent) : ParserPartProxy
|
||||
{
|
||||
$hc = $this->partHeaderContainerFactory->newInstance($parent->getNextPartMode(), $parent->getNextPartFilename());
|
||||
$pb = $this->partBuilderFactory->newChildPartBuilder($hc, $parent);
|
||||
$proxy = $this->parserManager->createParserProxyFor($pb);
|
||||
$pb->setStreamPartStartPos($parent->getNextPartStart());
|
||||
$pb->setStreamContentStartPos($parent->getNextPartStart());
|
||||
return $proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads content from the passed ParserPartProxy's stream till a uu-encoded
|
||||
* 'begin' line is found, setting $proxy->setStreamPartContentAndEndPos() to
|
||||
* the last byte read before the begin line.
|
||||
*
|
||||
* @param ParserNonMimeMessageProxy|ParserUUEncodedPartProxy $proxy
|
||||
*/
|
||||
private function parseNextPart(ParserPartProxy $proxy) : static
|
||||
{
|
||||
$handle = $proxy->getMessageResourceHandle();
|
||||
while (!\feof($handle)) {
|
||||
$start = \ftell($handle);
|
||||
$line = \trim(MessageParserService::readLine($handle));
|
||||
if (\preg_match('/^begin ([0-7]{3}) (.*)$/', $line, $matches)) {
|
||||
$proxy->setNextPartStart($start);
|
||||
$proxy->setNextPartMode((int) $matches[1]);
|
||||
$proxy->setNextPartFilename($matches[2]);
|
||||
return $this;
|
||||
}
|
||||
$proxy->setStreamPartAndContentEndPos(\ftell($handle));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function parseContent(ParserPartProxy $proxy) : static
|
||||
{
|
||||
$handle = $proxy->getMessageResourceHandle();
|
||||
if ($proxy->getNextPartStart() !== null || \feof($handle)) {
|
||||
return $this;
|
||||
}
|
||||
if ($proxy->getStreamContentStartPos() === null) {
|
||||
$proxy->setStreamContentStartPos(\ftell($handle));
|
||||
}
|
||||
$this->parseNextPart($proxy);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function parseNextChild(ParserMimePartProxy $proxy) : ?ParserPartProxy
|
||||
{
|
||||
$handle = $proxy->getMessageResourceHandle();
|
||||
if ($proxy->getNextPartStart() === null || \feof($handle)) {
|
||||
return null;
|
||||
}
|
||||
$child = $this->createPart($proxy);
|
||||
$proxy->clearNextPart();
|
||||
return $child;
|
||||
}
|
||||
}
|
||||
92
plugins/vendor/zbateson/mail-mime-parser/src/Parser/ParserManagerService.php
vendored
Normal file
92
plugins/vendor/zbateson/mail-mime-parser/src/Parser/ParserManagerService.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxy;
|
||||
|
||||
/**
|
||||
* Manages a prioritized list of IParser objects for parsing messages and parts
|
||||
* and creating proxied parts.
|
||||
*
|
||||
* The default ParserManager sets up a MimeParser in priority 0, and a
|
||||
* NonMimeParser in priority 1.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserManagerService
|
||||
{
|
||||
/**
|
||||
* @var IParserService[] List of parsers in order of priority (0 is highest
|
||||
* priority).
|
||||
*/
|
||||
protected array $parsers = [];
|
||||
|
||||
public function __construct(MimeParserService $mimeParser, NonMimeParserService $nonMimeParser)
|
||||
{
|
||||
$this->setParsers([$mimeParser, $nonMimeParser]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the internal prioritized list of parses with the passed list,
|
||||
* calling $parser->setParserManager($this) on each one.
|
||||
*
|
||||
* @param IParserService[] $parsers
|
||||
*/
|
||||
public function setParsers(array $parsers) : static
|
||||
{
|
||||
foreach ($parsers as $parser) {
|
||||
$parser->setParserManager($this);
|
||||
}
|
||||
$this->parsers = $parsers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an IParser at the highest priority (up front), calling
|
||||
* $parser->setParserManager($this) on it.
|
||||
*
|
||||
* @param IParserService $parser The parser to add.
|
||||
*/
|
||||
public function prependParser(IParserService $parser) : static
|
||||
{
|
||||
$parser->setParserManager($this);
|
||||
\array_unshift($this->parsers, $parser);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ParserPartProxy for the passed $partBuilder using a compatible
|
||||
* IParser.
|
||||
*
|
||||
* Loops through registered IParsers calling 'canParse()' on each with the
|
||||
* passed PartBuilder, then calling either 'getParserMessageProxyFactory()'
|
||||
* or 'getParserPartProxyFactory()' depending on if the PartBuilder has a
|
||||
* parent, and finally calling 'newInstance' on the returned
|
||||
* ParserPartProxyFactory passing it the IParser, and returning the new
|
||||
* ParserPartProxy instance that was created.
|
||||
*
|
||||
* @param PartBuilder $partBuilder The PartBuilder to wrap in a proxy with
|
||||
* an IParser
|
||||
* @throws CompatibleParserNotFoundException if a compatible parser for the
|
||||
* type is not configured.
|
||||
* @return ParserPartProxy The created ParserPartProxy tied to a new
|
||||
* IMessagePart and associated IParser.
|
||||
*/
|
||||
public function createParserProxyFor(PartBuilder $partBuilder) : ParserPartProxy
|
||||
{
|
||||
foreach ($this->parsers as $parser) {
|
||||
if ($parser->canParse($partBuilder)) {
|
||||
$factory = ($partBuilder->getParent() === null) ?
|
||||
$parser->getParserMessageProxyFactory() :
|
||||
$parser->getParserPartProxyFactory();
|
||||
return $factory->newInstance($partBuilder, $parser);
|
||||
}
|
||||
}
|
||||
throw new CompatibleParserNotFoundException('Compatible parser for a part cannot be found with content-type: ' . $partBuilder->getHeaderContainer()->get('Content-Type'));
|
||||
}
|
||||
}
|
||||
53
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartChildrenContainer.php
vendored
Normal file
53
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartChildrenContainer.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Part;
|
||||
|
||||
use ZBateson\MailMimeParser\Message\PartChildrenContainer;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMimePartProxy;
|
||||
|
||||
/**
|
||||
* A child container that proxies calls to a parser when attempting to access
|
||||
* child parts.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserPartChildrenContainer extends PartChildrenContainer
|
||||
{
|
||||
/**
|
||||
* @var ParserMimePartProxy The parser to proxy requests to when trying to
|
||||
* get child parts.
|
||||
*/
|
||||
protected ParserMimePartProxy $parserProxy;
|
||||
|
||||
/**
|
||||
* @var bool Set to true once all parts have been parsed, and requests to
|
||||
* the proxy won't result in any more child parts.
|
||||
*/
|
||||
private bool $allParsed = false;
|
||||
|
||||
public function __construct(ParserMimePartProxy $parserProxy)
|
||||
{
|
||||
parent::__construct([]);
|
||||
$this->parserProxy = $parserProxy;
|
||||
}
|
||||
|
||||
public function offsetExists($offset) : bool
|
||||
{
|
||||
$exists = parent::offsetExists($offset);
|
||||
while (!$exists && !$this->allParsed) {
|
||||
$child = $this->parserProxy->popNextChild();
|
||||
if ($child === null) {
|
||||
$this->allParsed = true;
|
||||
} else {
|
||||
$this->add($child);
|
||||
}
|
||||
$exists = parent::offsetExists($offset);
|
||||
}
|
||||
return $exists;
|
||||
}
|
||||
}
|
||||
23
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartChildrenContainerFactory.php
vendored
Normal file
23
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartChildrenContainerFactory.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Part;
|
||||
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMimePartProxy;
|
||||
|
||||
/**
|
||||
* Creates ParserPartChildrenContainer instances.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserPartChildrenContainerFactory
|
||||
{
|
||||
public function newInstance(ParserMimePartProxy $parserProxy) : ParserPartChildrenContainer
|
||||
{
|
||||
return new ParserPartChildrenContainer($parserProxy);
|
||||
}
|
||||
}
|
||||
161
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartStreamContainer.php
vendored
Normal file
161
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartStreamContainer.php
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Part;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use SplObserver;
|
||||
use SplSubject;
|
||||
use ZBateson\MailMimeParser\Message\IMessagePart;
|
||||
use ZBateson\MailMimeParser\Message\PartStreamContainer;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxy;
|
||||
use ZBateson\MailMimeParser\Stream\MessagePartStreamDecorator;
|
||||
use ZBateson\MailMimeParser\Stream\StreamFactory;
|
||||
use ZBateson\MbWrapper\MbWrapper;
|
||||
|
||||
/**
|
||||
* A part stream container that proxies requests for content streams to a parser
|
||||
* to read the content.
|
||||
*
|
||||
* Keeps reference to the original stream a part was parsed from, using that
|
||||
* stream as the part's stream instead of the PartStreamContainer's
|
||||
* MessagePartStream (which dynamically creates a stream from an IMessagePart)
|
||||
* unless the part changed.
|
||||
*
|
||||
* The ParserPartStreamContainer must also be attached to its underlying part
|
||||
* with SplSubject::attach() so the ParserPartStreamContainer gets notified of
|
||||
* any changes.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserPartStreamContainer extends PartStreamContainer implements SplObserver
|
||||
{
|
||||
/**
|
||||
* @var ParserPartProxy The parser proxy to ferry requests to on-demand.
|
||||
*/
|
||||
protected ParserPartProxy $parserProxy;
|
||||
|
||||
/**
|
||||
* @var MessagePartStreamDecorator the original stream for a parsed message,
|
||||
* wrapped in a MessagePartStreamDecorator, and used when the message
|
||||
* hasn't changed
|
||||
*/
|
||||
protected ?MessagePartStreamDecorator $parsedStream = null;
|
||||
|
||||
/**
|
||||
* @var bool set to true if the part's been updated since it was created.
|
||||
*/
|
||||
protected bool $partUpdated = false;
|
||||
|
||||
/**
|
||||
* @var bool false if the content for the part represented by this container
|
||||
* has not yet been requested from the parser.
|
||||
*/
|
||||
protected bool $contentParseRequested = false;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
StreamFactory $streamFactory,
|
||||
MbWrapper $mbWrapper,
|
||||
bool $throwExceptionReadingPartContentFromUnsupportedCharsets,
|
||||
ParserPartProxy $parserProxy
|
||||
) {
|
||||
parent::__construct($logger, $streamFactory, $mbWrapper, $throwExceptionReadingPartContentFromUnsupportedCharsets);
|
||||
$this->parserProxy = $parserProxy;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->detachParsedStream && $this->parsedStream !== null) {
|
||||
$this->parsedStream->detach();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests content from the parser if not previously requested, and calls
|
||||
* PartStreamContainer::setContentStream().
|
||||
*/
|
||||
protected function requestParsedContentStream() : static
|
||||
{
|
||||
if (!$this->contentParseRequested) {
|
||||
$this->contentParseRequested = true;
|
||||
$this->parserProxy->parseContent();
|
||||
parent::setContentStream($this->streamFactory->getLimitedContentStream(
|
||||
$this->parserProxy
|
||||
));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the parser has parsed the entire part, and sets
|
||||
* $this->parsedStream to the original parsed stream (or a limited part of
|
||||
* it corresponding to the current part this stream container belongs to).
|
||||
*/
|
||||
protected function requestParsedStream() : static
|
||||
{
|
||||
if ($this->parsedStream === null) {
|
||||
$this->parserProxy->parseAll();
|
||||
$this->parsedStream = $this->streamFactory->newDecoratedMessagePartStream(
|
||||
$this->parserProxy->getPart(),
|
||||
$this->streamFactory->getLimitedPartStream(
|
||||
$this->parserProxy
|
||||
)
|
||||
);
|
||||
if ($this->parsedStream !== null) {
|
||||
$this->detachParsedStream = ($this->parsedStream->getMetadata('mmp-detached-stream') === true);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasContent() : bool
|
||||
{
|
||||
$this->requestParsedContentStream();
|
||||
return parent::hasContent();
|
||||
}
|
||||
|
||||
public function getContentStream(IMessagePart $part, ?string $transferEncoding, ?string $fromCharset, ?string $toCharset) : ?MessagePartStreamDecorator
|
||||
{
|
||||
$this->requestParsedContentStream();
|
||||
return parent::getContentStream($part, $transferEncoding, $fromCharset, $toCharset);
|
||||
}
|
||||
|
||||
public function getBinaryContentStream(IMessagePart $part, ?string $transferEncoding = null) : ?MessagePartStreamDecorator
|
||||
{
|
||||
$this->requestParsedContentStream();
|
||||
return parent::getBinaryContentStream($part, $transferEncoding);
|
||||
}
|
||||
|
||||
public function setContentStream(?StreamInterface $contentStream = null) : static
|
||||
{
|
||||
// has to be overridden because requestParsedContentStream calls
|
||||
// parent::setContentStream as well, so needs to be parsed before
|
||||
// overriding the contentStream with a manual 'set'.
|
||||
$this->requestParsedContentStream();
|
||||
parent::setContentStream($contentStream);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStream() : MessagePartStreamDecorator
|
||||
{
|
||||
$this->requestParsedStream();
|
||||
if (!$this->partUpdated) {
|
||||
if ($this->parsedStream !== null) {
|
||||
$this->parsedStream->rewind();
|
||||
return $this->parsedStream;
|
||||
}
|
||||
}
|
||||
return parent::getStream();
|
||||
}
|
||||
|
||||
public function update(SplSubject $subject) : void
|
||||
{
|
||||
$this->partUpdated = true;
|
||||
}
|
||||
}
|
||||
52
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartStreamContainerFactory.php
vendored
Normal file
52
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/ParserPartStreamContainerFactory.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Part;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxy;
|
||||
use ZBateson\MailMimeParser\Stream\StreamFactory;
|
||||
use ZBateson\MbWrapper\MbWrapper;
|
||||
|
||||
/**
|
||||
* Creates ParserPartStreamContainer instances.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserPartStreamContainerFactory
|
||||
{
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
protected StreamFactory $streamFactory;
|
||||
|
||||
protected MbWrapper $mbWrapper;
|
||||
|
||||
protected bool $throwExceptionReadingPartContentFromUnsupportedCharsets;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
StreamFactory $streamFactory,
|
||||
MbWrapper $mbWrapper,
|
||||
bool $throwExceptionReadingPartContentFromUnsupportedCharsets
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->streamFactory = $streamFactory;
|
||||
$this->mbWrapper = $mbWrapper;
|
||||
$this->throwExceptionReadingPartContentFromUnsupportedCharsets = $throwExceptionReadingPartContentFromUnsupportedCharsets;
|
||||
}
|
||||
|
||||
public function newInstance(ParserPartProxy $parserProxy) : ParserPartStreamContainer
|
||||
{
|
||||
return new ParserPartStreamContainer(
|
||||
$this->logger,
|
||||
$this->streamFactory,
|
||||
$this->mbWrapper,
|
||||
$this->throwExceptionReadingPartContentFromUnsupportedCharsets,
|
||||
$parserProxy
|
||||
);
|
||||
}
|
||||
}
|
||||
66
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/UUEncodedPartHeaderContainer.php
vendored
Normal file
66
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/UUEncodedPartHeaderContainer.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Part;
|
||||
|
||||
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
|
||||
|
||||
/**
|
||||
* Header container representing the start line of a uu-encoded part.
|
||||
*
|
||||
* The line may contain a unix file mode and a filename.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class UUEncodedPartHeaderContainer extends PartHeaderContainer
|
||||
{
|
||||
/**
|
||||
* @var ?int the unix file permission
|
||||
*/
|
||||
protected ?int $mode = null;
|
||||
|
||||
/**
|
||||
* @var ?string the name of the file in the uuencoding 'header'.
|
||||
*/
|
||||
protected ?string $filename = null;
|
||||
|
||||
/**
|
||||
* Returns the file mode included in the uuencoded 'begin' line for this
|
||||
* part.
|
||||
*/
|
||||
public function getUnixFileMode() : ?int
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the unix file mode for the uuencoded 'begin' line.
|
||||
*/
|
||||
public function setUnixFileMode(int $mode) : static
|
||||
{
|
||||
$this->mode = $mode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename included in the uuencoded 'begin' line for this
|
||||
* part.
|
||||
*/
|
||||
public function getFilename() : ?string
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filename included in the uuencoded 'begin' line.
|
||||
*/
|
||||
public function setFilename(string $filename) : static
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
48
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/UUEncodedPartHeaderContainerFactory.php
vendored
Normal file
48
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Part/UUEncodedPartHeaderContainerFactory.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Part;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ZBateson\MailMimeParser\Header\HeaderFactory;
|
||||
|
||||
/**
|
||||
* Creates UUEncodedPartHeaderContainer instances.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class UUEncodedPartHeaderContainerFactory
|
||||
{
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @var HeaderFactory the HeaderFactory passed to
|
||||
* UUEncodedPartHeaderContainer instances.
|
||||
*/
|
||||
protected HeaderFactory $headerFactory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger, HeaderFactory $headerFactory)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->headerFactory = $headerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a UUEncodedPartHeaderContainer.
|
||||
*/
|
||||
public function newInstance(int $mode, string $filename) : UUEncodedPartHeaderContainer
|
||||
{
|
||||
$container = new UUEncodedPartHeaderContainer($this->logger, $this->headerFactory);
|
||||
$container->setUnixFileMode($mode);
|
||||
$container->setFilename($filename);
|
||||
return $container;
|
||||
}
|
||||
}
|
||||
262
plugins/vendor/zbateson/mail-mime-parser/src/Parser/PartBuilder.php
vendored
Normal file
262
plugins/vendor/zbateson/mail-mime-parser/src/Parser/PartBuilder.php
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use GuzzleHttp\Psr7\StreamWrapper;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use ZBateson\MailMimeParser\Header\HeaderConsts;
|
||||
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserMimePartProxy;
|
||||
|
||||
/**
|
||||
* Holds generic/all purpose information about a part while it's being parsed.
|
||||
*
|
||||
* The class holds:
|
||||
* - a HeaderContainer to hold headers
|
||||
* - stream positions (part start/end positions, content start/end)
|
||||
* - the message's psr7 stream and a resource handle created from it (held
|
||||
* only for a top-level PartBuilder representing the message, child
|
||||
* PartBuilders do not duplicate/hold a separate stream).
|
||||
*
|
||||
* More specific information a parser needs to keep about a message as it's
|
||||
* parsing it should be stored in its ParserPartProxy.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class PartBuilder
|
||||
{
|
||||
/**
|
||||
* @var int The offset read start position for this part (beginning of
|
||||
* headers) in the message's stream.
|
||||
*/
|
||||
private int $streamPartStartPos;
|
||||
|
||||
/**
|
||||
* @var int The offset read end position for this part. If the part is a
|
||||
* multipart mime part, the end position is after all of this parts
|
||||
* children.
|
||||
*/
|
||||
private int $streamPartEndPos;
|
||||
|
||||
/**
|
||||
* @var ?int The offset read start position in the message's stream for the
|
||||
* beginning of this part's content (body).
|
||||
*/
|
||||
private ?int $streamContentStartPos = null;
|
||||
|
||||
/**
|
||||
* @var ?int The offset read end position in the message's stream for the
|
||||
* end of this part's content (body).
|
||||
*/
|
||||
private ?int $streamContentEndPos = null;
|
||||
|
||||
/**
|
||||
* @var PartHeaderContainer The parsed part's headers.
|
||||
*/
|
||||
private PartHeaderContainer $headerContainer;
|
||||
|
||||
/**
|
||||
* @var StreamInterface the raw message input stream for a message, or null
|
||||
* for a child part.
|
||||
*/
|
||||
private ?StreamInterface $messageStream = null;
|
||||
|
||||
/**
|
||||
* @var resource the raw message input stream handle constructed from
|
||||
* $messageStream or null for a child part
|
||||
*/
|
||||
private mixed $messageHandle = null;
|
||||
|
||||
/**
|
||||
* @var ParserMimePartProxy The parent proxy part if one is set, or null if
|
||||
* the part being built doesn't have a parent.
|
||||
*/
|
||||
private ?ParserMimePartProxy $parent = null;
|
||||
|
||||
public function __construct(PartHeaderContainer $headerContainer, ?StreamInterface $messageStream = null, ?ParserMimePartProxy $parent = null)
|
||||
{
|
||||
$this->headerContainer = $headerContainer;
|
||||
$this->messageStream = $messageStream;
|
||||
$this->parent = $parent;
|
||||
if ($messageStream !== null) {
|
||||
$this->messageHandle = StreamWrapper::getResource($messageStream);
|
||||
}
|
||||
$this->setStreamPartStartPos($this->getMessageResourceHandlePos());
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->messageHandle) {
|
||||
\fclose($this->messageHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The ParserPartProxy parent of this PartBuilder.
|
||||
*/
|
||||
public function getParent() : ?ParserMimePartProxy
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this part's PartHeaderContainer.
|
||||
*/
|
||||
public function getHeaderContainer() : PartHeaderContainer
|
||||
{
|
||||
return $this->headerContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw message StreamInterface for a message, getting it from
|
||||
* the parent part if this is a child part.
|
||||
*/
|
||||
public function getStream() : StreamInterface
|
||||
{
|
||||
return ($this->messageStream === null && $this->parent !== null) ?
|
||||
$this->parent->getStream() :
|
||||
$this->messageStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource handle for a the message's stream, getting it from
|
||||
* the parent part if this is a child part.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getMessageResourceHandle() : mixed
|
||||
{
|
||||
return ($this->messageHandle === null && $this->parent !== null) ?
|
||||
$this->parent->getMessageResourceHandle() :
|
||||
$this->messageHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for calling ftell($partBuilder->getMessageResourceHandle()).
|
||||
*/
|
||||
public function getMessageResourceHandlePos() : int
|
||||
{
|
||||
return \ftell($this->getMessageResourceHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the byte offset start position for this part within the message
|
||||
* stream.
|
||||
*/
|
||||
public function getStreamPartStartPos() : int
|
||||
{
|
||||
return $this->streamPartStartPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of raw bytes this part has.
|
||||
*
|
||||
* This method does not perform checks on whether the start pos and end pos
|
||||
* of this part have been set, and so could cause errors if called before
|
||||
* being set and are still null.
|
||||
*
|
||||
*/
|
||||
public function getStreamPartLength() : int
|
||||
{
|
||||
return $this->streamPartEndPos - $this->streamPartStartPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the byte offset start position of the content of this part within
|
||||
* the main raw message stream, or null if not set.
|
||||
*
|
||||
*/
|
||||
public function getStreamContentStartPos() : ?int
|
||||
{
|
||||
return $this->streamContentStartPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of this part's content stream.
|
||||
*
|
||||
* This method does not perform checks on whether the start pos and end pos
|
||||
* of this part's content have been set, and so could cause errors if called
|
||||
* before being set and are still null.
|
||||
*
|
||||
*/
|
||||
public function getStreamContentLength() : int
|
||||
{
|
||||
return $this->streamContentEndPos - $this->streamContentStartPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the byte offset start position of the part in the raw message
|
||||
* stream.
|
||||
*/
|
||||
public function setStreamPartStartPos(int $streamPartStartPos) : static
|
||||
{
|
||||
$this->streamPartStartPos = $streamPartStartPos;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the byte offset end position of the part in the raw message stream,
|
||||
* and also calls its parent's setParentStreamPartEndPos to expand to parent
|
||||
* PartBuilders.
|
||||
*/
|
||||
public function setStreamPartEndPos(int $streamPartEndPos) : static
|
||||
{
|
||||
$this->streamPartEndPos = $streamPartEndPos;
|
||||
if ($this->parent !== null) {
|
||||
$this->parent->setStreamPartEndPos($streamPartEndPos);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the byte offset start position of the content in the raw message
|
||||
* stream.
|
||||
*/
|
||||
public function setStreamContentStartPos(int $streamContentStartPos) : static
|
||||
{
|
||||
$this->streamContentStartPos = $streamContentStartPos;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the byte offset end position of the content and part in the raw
|
||||
* message stream.
|
||||
*/
|
||||
public function setStreamPartAndContentEndPos(int $streamContentEndPos) : static
|
||||
{
|
||||
$this->streamContentEndPos = $streamContentEndPos;
|
||||
$this->setStreamPartEndPos($streamContentEndPos);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the byte offset positions for this part's content have
|
||||
* been set.
|
||||
*
|
||||
* @return bool true if set.
|
||||
*/
|
||||
public function isContentParsed() : bool
|
||||
{
|
||||
return ($this->streamContentEndPos !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this part, or any parent, have a Content-Type or
|
||||
* MIME-Version header set.
|
||||
*
|
||||
* @return bool true if it's a mime message or child of a mime message.
|
||||
*/
|
||||
public function isMime() : bool
|
||||
{
|
||||
if ($this->getParent() !== null) {
|
||||
return $this->getParent()->isMime();
|
||||
}
|
||||
return ($this->headerContainer->exists(HeaderConsts::CONTENT_TYPE) ||
|
||||
$this->headerContainer->exists(HeaderConsts::MIME_VERSION));
|
||||
}
|
||||
}
|
||||
41
plugins/vendor/zbateson/mail-mime-parser/src/Parser/PartBuilderFactory.php
vendored
Normal file
41
plugins/vendor/zbateson/mail-mime-parser/src/Parser/PartBuilderFactory.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
|
||||
use ZBateson\MailMimeParser\Parser\Proxy\ParserPartProxy;
|
||||
|
||||
/**
|
||||
* Responsible for creating PartBuilder instances.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class PartBuilderFactory
|
||||
{
|
||||
/**
|
||||
* Constructs a top-level (message) PartBuilder object and returns it.
|
||||
*/
|
||||
public function newPartBuilder(PartHeaderContainer $headerContainer, StreamInterface $messageStream) : PartBuilder
|
||||
{
|
||||
return new PartBuilder($headerContainer, $messageStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a child PartBuilder object with the passed $parent as its
|
||||
* parent, and returns it.
|
||||
*/
|
||||
public function newChildPartBuilder(PartHeaderContainer $headerContainer, ParserPartProxy $parent) : PartBuilder
|
||||
{
|
||||
return new PartBuilder(
|
||||
$headerContainer,
|
||||
null,
|
||||
$parent
|
||||
);
|
||||
}
|
||||
}
|
||||
36
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMessageProxy.php
vendored
Normal file
36
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMessageProxy.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
/**
|
||||
* A bi-directional parser-to-part proxy for IMessage objects created by
|
||||
* MimeParser.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserMessageProxy extends ParserMimePartProxy
|
||||
{
|
||||
/**
|
||||
* @var int maintains the character length of the last line separator,
|
||||
* typically 2 for CRLF, to keep track of the correct 'end' position
|
||||
* for a part because the CRLF before a boundary is considered part of
|
||||
* the boundary.
|
||||
*/
|
||||
protected int $lastLineEndingLength = 0;
|
||||
|
||||
public function getLastLineEndingLength() : int
|
||||
{
|
||||
return $this->lastLineEndingLength;
|
||||
}
|
||||
|
||||
public function setLastLineEndingLength(int $lastLineEndingLength) : static
|
||||
{
|
||||
$this->lastLineEndingLength = $lastLineEndingLength;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
74
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMessageProxyFactory.php
vendored
Normal file
74
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMessageProxyFactory.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ZBateson\MailMimeParser\Message;
|
||||
use ZBateson\MailMimeParser\Message\Factory\PartHeaderContainerFactory;
|
||||
use ZBateson\MailMimeParser\Message\Helper\MultipartHelper;
|
||||
use ZBateson\MailMimeParser\Message\Helper\PrivacyHelper;
|
||||
use ZBateson\MailMimeParser\Parser\IParserService;
|
||||
use ZBateson\MailMimeParser\Parser\Part\ParserPartChildrenContainerFactory;
|
||||
use ZBateson\MailMimeParser\Parser\Part\ParserPartStreamContainerFactory;
|
||||
use ZBateson\MailMimeParser\Parser\PartBuilder;
|
||||
use ZBateson\MailMimeParser\Stream\StreamFactory;
|
||||
|
||||
/**
|
||||
* Responsible for creating proxied IMessage instances wrapped in a
|
||||
* ParserMessageProxy.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserMessageProxyFactory extends ParserMimePartProxyFactory
|
||||
{
|
||||
protected MultipartHelper $multipartHelper;
|
||||
|
||||
protected PrivacyHelper $privacyHelper;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
StreamFactory $sdf,
|
||||
PartHeaderContainerFactory $phcf,
|
||||
ParserPartStreamContainerFactory $pscf,
|
||||
ParserPartChildrenContainerFactory $ppccf,
|
||||
MultipartHelper $multipartHelper,
|
||||
PrivacyHelper $privacyHelper
|
||||
) {
|
||||
parent::__construct($logger, $sdf, $phcf, $pscf, $ppccf);
|
||||
$this->multipartHelper = $multipartHelper;
|
||||
$this->privacyHelper = $privacyHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ParserMessageProxy wrapping an IMessage object that will
|
||||
* dynamically parse a message's content and parts as they're requested.
|
||||
*/
|
||||
public function newInstance(PartBuilder $partBuilder, IParserService $parser) : ParserMessageProxy
|
||||
{
|
||||
$parserProxy = new ParserMessageProxy($partBuilder, $parser);
|
||||
|
||||
$streamContainer = $this->parserPartStreamContainerFactory->newInstance($parserProxy);
|
||||
$headerContainer = $this->partHeaderContainerFactory->newInstance($parserProxy->getHeaderContainer());
|
||||
$childrenContainer = $this->parserPartChildrenContainerFactory->newInstance($parserProxy);
|
||||
|
||||
$message = new Message(
|
||||
$this->logger,
|
||||
$streamContainer,
|
||||
$headerContainer,
|
||||
$childrenContainer,
|
||||
$this->multipartHelper,
|
||||
$this->privacyHelper
|
||||
);
|
||||
$parserProxy->setPart($message);
|
||||
|
||||
$streamContainer->setStream($this->streamFactory->newMessagePartStream($message));
|
||||
$message->attach($streamContainer);
|
||||
return $parserProxy;
|
||||
}
|
||||
}
|
||||
286
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMimePartProxy.php
vendored
Normal file
286
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMimePartProxy.php
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
use Psr\Log\LogLevel;
|
||||
use ZBateson\MailMimeParser\Header\HeaderConsts;
|
||||
use ZBateson\MailMimeParser\Header\ParameterHeader;
|
||||
use ZBateson\MailMimeParser\Message\IMessagePart;
|
||||
|
||||
/**
|
||||
* A bi-directional parser-to-part proxy for MimeParser and IMimeParts.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserMimePartProxy extends ParserPartProxy
|
||||
{
|
||||
/**
|
||||
* @var bool set to true once the end boundary of the currently-parsed
|
||||
* part is found.
|
||||
*/
|
||||
protected bool $endBoundaryFound = false;
|
||||
|
||||
/**
|
||||
* @var bool set to true once a boundary belonging to this parent's part
|
||||
* is found.
|
||||
*/
|
||||
protected bool $parentBoundaryFound = false;
|
||||
|
||||
/**
|
||||
* @var bool true once all children of this part have been parsed.
|
||||
*/
|
||||
protected bool $allChildrenParsed = false;
|
||||
|
||||
/**
|
||||
* @var ParserPartProxy[] Array of all parsed children.
|
||||
*/
|
||||
protected array $children = [];
|
||||
|
||||
/**
|
||||
* @var ParserPartProxy[] Parsed children used as a 'first-in-first-out'
|
||||
* stack as children are parsed.
|
||||
*/
|
||||
protected array $childrenStack = [];
|
||||
|
||||
/**
|
||||
* @var ParserPartProxy Reference to the last child added to this part.
|
||||
*/
|
||||
protected ?ParserPartProxy $lastAddedChild = null;
|
||||
|
||||
/**
|
||||
* @var ?string NULL if the current part does not have a boundary, and
|
||||
* otherwise contains the value of the boundary parameter of the
|
||||
* content-type header if the part contains one.
|
||||
*/
|
||||
private ?string $mimeBoundary = null;
|
||||
|
||||
/**
|
||||
* @var bool FALSE if not queried for in the content-type header of this
|
||||
* part and set in $mimeBoundary.
|
||||
*/
|
||||
private bool $mimeBoundaryQueried = false;
|
||||
|
||||
/**
|
||||
* Ensures that the last child added to this part is fully parsed (content
|
||||
* and children).
|
||||
*/
|
||||
protected function ensureLastChildParsed() : static
|
||||
{
|
||||
if ($this->lastAddedChild !== null) {
|
||||
$this->lastAddedChild->parseAll();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the next child of this part and adds it to the 'stack' of
|
||||
* children.
|
||||
*/
|
||||
protected function parseNextChild() : static
|
||||
{
|
||||
if ($this->allChildrenParsed) {
|
||||
return $this;
|
||||
}
|
||||
$this->parseContent();
|
||||
$this->ensureLastChildParsed();
|
||||
$next = $this->parser->parseNextChild($this);
|
||||
if ($next !== null) {
|
||||
$this->children[] = $next;
|
||||
$this->childrenStack[] = $next;
|
||||
$this->lastAddedChild = $next;
|
||||
} else {
|
||||
$this->allChildrenParsed = true;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next child part if one exists, popping it from the internal
|
||||
* 'stack' of children, attempting to parse a new one if the stack is empty,
|
||||
* and returning null if there are no more children.
|
||||
*
|
||||
* @return ?IMessagePart the child part.
|
||||
*/
|
||||
public function popNextChild() : ?IMessagePart
|
||||
{
|
||||
if (empty($this->childrenStack)) {
|
||||
$this->parseNextChild();
|
||||
}
|
||||
$proxy = \array_shift($this->childrenStack);
|
||||
return ($proxy !== null) ? $proxy->getPart() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses all content and children for this part.
|
||||
*/
|
||||
public function parseAll() : static
|
||||
{
|
||||
$this->parseContent();
|
||||
while (!$this->allChildrenParsed) {
|
||||
$this->parseNextChild();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ParameterHeader representing the parsed Content-Type header for
|
||||
* this part.
|
||||
*/
|
||||
public function getContentType() : ?ParameterHeader
|
||||
{
|
||||
return $this->getHeaderContainer()->get(HeaderConsts::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parsed boundary parameter of the Content-Type header if set
|
||||
* for a multipart message part.
|
||||
*
|
||||
*/
|
||||
public function getMimeBoundary() : ?string
|
||||
{
|
||||
if ($this->mimeBoundaryQueried === false) {
|
||||
$this->mimeBoundaryQueried = true;
|
||||
$contentType = $this->getContentType();
|
||||
if ($contentType !== null) {
|
||||
$this->mimeBoundary = $contentType->getValueFor('boundary');
|
||||
}
|
||||
}
|
||||
return $this->mimeBoundary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the passed $line of read input matches this part's mime
|
||||
* boundary, or any of its parent's mime boundaries for a multipart message.
|
||||
*
|
||||
* If the passed $line is the ending boundary for the current part,
|
||||
* $this->isEndBoundaryFound will return true after.
|
||||
*/
|
||||
public function setEndBoundaryFound(string $line) : bool
|
||||
{
|
||||
$boundary = $this->getMimeBoundary();
|
||||
if ($this->getParent() !== null && $this->getParent()->setEndBoundaryFound($line)) {
|
||||
$this->parentBoundaryFound = true;
|
||||
return true;
|
||||
} elseif ($boundary !== null) {
|
||||
if ($line === "--$boundary--") {
|
||||
$this->endBoundaryFound = true;
|
||||
return true;
|
||||
} elseif ($line === "--$boundary") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the parser passed an input line to setEndBoundary that
|
||||
* matches a parent's mime boundary, and the following input belongs to a
|
||||
* new part under its parent.
|
||||
*
|
||||
*/
|
||||
public function isParentBoundaryFound() : bool
|
||||
{
|
||||
return ($this->parentBoundaryFound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an end boundary was found for this part.
|
||||
*
|
||||
*/
|
||||
public function isEndBoundaryFound() : bool
|
||||
{
|
||||
return ($this->endBoundaryFound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called once EOF is reached while reading content. The method sets the
|
||||
* flag used by isParentBoundaryFound() to true on this part and all parent
|
||||
* parts.
|
||||
*
|
||||
*/
|
||||
public function setEof() : static
|
||||
{
|
||||
$this->parentBoundaryFound = true;
|
||||
if ($this->getParent() !== null) {
|
||||
$this->getParent()->setEof();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to set a 0-length content length, and a stream end pos of -2
|
||||
* if the passed end pos is before the start pos (can happen if a mime
|
||||
* end boundary doesn't have an empty line before the next parent start
|
||||
* boundary).
|
||||
*/
|
||||
public function setStreamPartAndContentEndPos(int $streamContentEndPos) : static
|
||||
{
|
||||
// check if we're expecting a boundary and didn't find one
|
||||
if (!$this->endBoundaryFound && !$this->parentBoundaryFound) {
|
||||
if (!empty($this->mimeBoundary) || ($this->getParent() !== null && !empty($this->getParent()->mimeBoundary))) {
|
||||
$this->addError('End boundary for part not found', LogLevel::WARNING);
|
||||
}
|
||||
}
|
||||
$start = $this->getStreamContentStartPos();
|
||||
if ($streamContentEndPos - $start < 0) {
|
||||
parent::setStreamPartAndContentEndPos($start);
|
||||
$this->setStreamPartEndPos($streamContentEndPos);
|
||||
} else {
|
||||
parent::setStreamPartAndContentEndPos($streamContentEndPos);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of the last line ending read by MimeParser (e.g. 2 for
|
||||
* '\r\n', or 1 for '\n').
|
||||
*
|
||||
* The line ending may not belong specifically to this part, so
|
||||
* ParserMimePartProxy simply calls setLastLineEndingLength on its parent,
|
||||
* which must eventually reach a ParserMessageProxy which actually stores
|
||||
* the length.
|
||||
*/
|
||||
public function setLastLineEndingLength(int $length) : static
|
||||
{
|
||||
$this->getParent()->setLastLineEndingLength($length);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the last line ending read by MimeParser (e.g. 2 for
|
||||
* '\r\n', or 1 for '\n').
|
||||
*
|
||||
* The line ending may not belong specifically to this part, so
|
||||
* ParserMimePartProxy simply calls getLastLineEndingLength on its parent,
|
||||
* which must eventually reach a ParserMessageProxy which actually keeps
|
||||
* the length and returns it.
|
||||
*
|
||||
* @return int the length of the last line ending read
|
||||
*/
|
||||
public function getLastLineEndingLength() : int
|
||||
{
|
||||
return $this->getParent()->getLastLineEndingLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last part that was added.
|
||||
*/
|
||||
public function getLastAddedChild() : ?ParserPartProxy
|
||||
{
|
||||
return $this->lastAddedChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the added child at the provided index, useful for looking at
|
||||
* previously parsed children.
|
||||
*/
|
||||
public function getAddedChildAt(int $index) : ?ParserPartProxy
|
||||
{
|
||||
return $this->children[$index] ?? null;
|
||||
}
|
||||
}
|
||||
77
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMimePartProxyFactory.php
vendored
Normal file
77
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserMimePartProxyFactory.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ZBateson\MailMimeParser\Message\Factory\PartHeaderContainerFactory;
|
||||
use ZBateson\MailMimeParser\Message\MimePart;
|
||||
use ZBateson\MailMimeParser\Parser\IParserService;
|
||||
use ZBateson\MailMimeParser\Parser\Part\ParserPartChildrenContainerFactory;
|
||||
use ZBateson\MailMimeParser\Parser\Part\ParserPartStreamContainerFactory;
|
||||
use ZBateson\MailMimeParser\Parser\PartBuilder;
|
||||
use ZBateson\MailMimeParser\Stream\StreamFactory;
|
||||
|
||||
/**
|
||||
* Responsible for creating proxied IMimePart instances wrapped in a
|
||||
* ParserMimePartProxy with a MimeParser.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserMimePartProxyFactory extends ParserPartProxyFactory
|
||||
{
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
protected StreamFactory $streamFactory;
|
||||
|
||||
protected ParserPartStreamContainerFactory $parserPartStreamContainerFactory;
|
||||
|
||||
protected PartHeaderContainerFactory $partHeaderContainerFactory;
|
||||
|
||||
protected ParserPartChildrenContainerFactory $parserPartChildrenContainerFactory;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
StreamFactory $sdf,
|
||||
PartHeaderContainerFactory $phcf,
|
||||
ParserPartStreamContainerFactory $pscf,
|
||||
ParserPartChildrenContainerFactory $ppccf
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->streamFactory = $sdf;
|
||||
$this->partHeaderContainerFactory = $phcf;
|
||||
$this->parserPartStreamContainerFactory = $pscf;
|
||||
$this->parserPartChildrenContainerFactory = $ppccf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ParserMimePartProxy wrapping an IMimePart object that
|
||||
* will dynamically parse a message's content and parts as they're
|
||||
* requested.
|
||||
*/
|
||||
public function newInstance(PartBuilder $partBuilder, IParserService $parser) : ParserMimePartProxy
|
||||
{
|
||||
$parserProxy = new ParserMimePartProxy($partBuilder, $parser);
|
||||
|
||||
$streamContainer = $this->parserPartStreamContainerFactory->newInstance($parserProxy);
|
||||
$headerContainer = $this->partHeaderContainerFactory->newInstance($parserProxy->getHeaderContainer());
|
||||
$childrenContainer = $this->parserPartChildrenContainerFactory->newInstance($parserProxy);
|
||||
|
||||
$part = new MimePart(
|
||||
$partBuilder->getParent()->getPart(),
|
||||
$this->logger,
|
||||
$streamContainer,
|
||||
$headerContainer,
|
||||
$childrenContainer
|
||||
);
|
||||
$parserProxy->setPart($part);
|
||||
|
||||
$streamContainer->setStream($this->streamFactory->newMessagePartStream($part));
|
||||
$part->attach($streamContainer);
|
||||
return $parserProxy;
|
||||
}
|
||||
}
|
||||
108
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserNonMimeMessageProxy.php
vendored
Normal file
108
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserNonMimeMessageProxy.php
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
/**
|
||||
* A bi-directional parser-to-part proxy for IMessage objects created by
|
||||
* NonMimeParser.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserNonMimeMessageProxy extends ParserMessageProxy
|
||||
{
|
||||
/**
|
||||
* @var ?int The next part's start position within the message's raw stream
|
||||
* or null if not set, not discovered, or there are no more parts.
|
||||
*/
|
||||
protected ?int $nextPartStart = null;
|
||||
|
||||
/**
|
||||
* @var ?int The next part's unix file mode in a uu-encoded 'begin' line if
|
||||
* exists, or null otherwise.
|
||||
*/
|
||||
protected ?int $nextPartMode = null;
|
||||
|
||||
/**
|
||||
* @var ?string The next part's file name in a uu-encoded 'begin' line if
|
||||
* exists, or null otherwise.
|
||||
*/
|
||||
protected ?string $nextPartFilename = null;
|
||||
|
||||
/**
|
||||
* Returns the next part's start position within the message's raw stream,
|
||||
* or null if not set, not discovered, or there are no more parts under this
|
||||
* message.
|
||||
*
|
||||
* @return int|null The start position or null
|
||||
*/
|
||||
public function getNextPartStart() : ?int
|
||||
{
|
||||
return $this->nextPartStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next part's unix file mode in a uu-encoded 'begin' line if
|
||||
* one exists, or null otherwise.
|
||||
*
|
||||
* @return int|null The file mode or null
|
||||
*/
|
||||
public function getNextPartMode() : ?int
|
||||
{
|
||||
return $this->nextPartMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next part's filename in a uu-encoded 'begin' line if one
|
||||
* exists, or null otherwise.
|
||||
*
|
||||
* @return string|null The file name or null
|
||||
*/
|
||||
public function getNextPartFilename() : ?string
|
||||
{
|
||||
return $this->nextPartFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next part's start position within the message's raw stream.
|
||||
*/
|
||||
public function setNextPartStart(int $nextPartStart) : static
|
||||
{
|
||||
$this->nextPartStart = $nextPartStart;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next part's unix file mode from its 'begin' line.
|
||||
*/
|
||||
public function setNextPartMode(int $nextPartMode) : static
|
||||
{
|
||||
$this->nextPartMode = $nextPartMode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next part's filename from its 'begin' line.
|
||||
*
|
||||
*/
|
||||
public function setNextPartFilename(string $nextPartFilename) : static
|
||||
{
|
||||
$this->nextPartFilename = $nextPartFilename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next part start position, file mode, and filename to null
|
||||
*/
|
||||
public function clearNextPart() : static
|
||||
{
|
||||
$this->nextPartStart = null;
|
||||
$this->nextPartMode = null;
|
||||
$this->nextPartFilename = null;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
47
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserNonMimeMessageProxyFactory.php
vendored
Normal file
47
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserNonMimeMessageProxyFactory.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
use ZBateson\MailMimeParser\Message;
|
||||
use ZBateson\MailMimeParser\Parser\IParserService;
|
||||
use ZBateson\MailMimeParser\Parser\PartBuilder;
|
||||
|
||||
/**
|
||||
* Responsible for creating proxied IMessage instances wrapped in a
|
||||
* ParserNonMimeMessageProxy for NonMimeParser.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserNonMimeMessageProxyFactory extends ParserMessageProxyFactory
|
||||
{
|
||||
/**
|
||||
* Constructs a new ParserNonMimeMessageProxy wrapping an IMessage object.
|
||||
*/
|
||||
public function newInstance(PartBuilder $partBuilder, IParserService $parser) : ParserNonMimeMessageProxy
|
||||
{
|
||||
$parserProxy = new ParserNonMimeMessageProxy($partBuilder, $parser);
|
||||
|
||||
$streamContainer = $this->parserPartStreamContainerFactory->newInstance($parserProxy);
|
||||
$headerContainer = $this->partHeaderContainerFactory->newInstance($parserProxy->getHeaderContainer());
|
||||
$childrenContainer = $this->parserPartChildrenContainerFactory->newInstance($parserProxy);
|
||||
|
||||
$message = new Message(
|
||||
$this->logger,
|
||||
$streamContainer,
|
||||
$headerContainer,
|
||||
$childrenContainer,
|
||||
$this->multipartHelper,
|
||||
$this->privacyHelper
|
||||
);
|
||||
$parserProxy->setPart($message);
|
||||
|
||||
$streamContainer->setStream($this->streamFactory->newMessagePartStream($message));
|
||||
$message->attach($streamContainer);
|
||||
return $parserProxy;
|
||||
}
|
||||
}
|
||||
184
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserPartProxy.php
vendored
Normal file
184
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserPartProxy.php
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use ZBateson\MailMimeParser\Message\IMessagePart;
|
||||
use ZBateson\MailMimeParser\Message\PartHeaderContainer;
|
||||
use ZBateson\MailMimeParser\Parser\IParserService;
|
||||
use ZBateson\MailMimeParser\Parser\PartBuilder;
|
||||
|
||||
/**
|
||||
* Proxy between a MessagePart and a Parser.
|
||||
*
|
||||
* ParserPartProxy objects are responsible for ferrying requests from message
|
||||
* parts to a proxy as they're requested, and for maintaining state information
|
||||
* for a parser as necessary.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
abstract class ParserPartProxy extends PartBuilder
|
||||
{
|
||||
/**
|
||||
* @var IParserService The parser.
|
||||
*/
|
||||
protected IParserService $parser;
|
||||
|
||||
/**
|
||||
* @var PartBuilder The part's PartBuilder.
|
||||
*/
|
||||
protected PartBuilder $partBuilder;
|
||||
|
||||
/**
|
||||
* @var IMessagePart The part.
|
||||
*/
|
||||
private IMessagePart $part;
|
||||
|
||||
public function __construct(PartBuilder $partBuilder, IParserService $parser)
|
||||
{
|
||||
$this->partBuilder = $partBuilder;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the associated part.
|
||||
*
|
||||
* @param IMessagePart $part The part
|
||||
*/
|
||||
public function setPart(IMessagePart $part) : static
|
||||
{
|
||||
$this->part = $part;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IMessagePart associated with this proxy.
|
||||
*
|
||||
* @return IMessagePart the part.
|
||||
*/
|
||||
public function getPart() : IMessagePart
|
||||
{
|
||||
return $this->part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the parser to parse this part's content, and call
|
||||
* setStreamContentStartPos/EndPos to setup this part's boundaries within
|
||||
* the main message's raw stream.
|
||||
*
|
||||
* The method first checks to see if the content has already been parsed,
|
||||
* and is safe to call multiple times.
|
||||
*/
|
||||
public function parseContent() : static
|
||||
{
|
||||
if (!$this->isContentParsed()) {
|
||||
$this->parser->parseContent($this);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses everything under this part.
|
||||
*
|
||||
* For ParserPartProxy, this is just content, but sub-classes may override
|
||||
* this to parse all children as well for example.
|
||||
*/
|
||||
public function parseAll() : static
|
||||
{
|
||||
$this->parseContent();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParent() : ?ParserMimePartProxy
|
||||
{
|
||||
return $this->partBuilder->getParent();
|
||||
}
|
||||
|
||||
public function getHeaderContainer() : PartHeaderContainer
|
||||
{
|
||||
return $this->partBuilder->getHeaderContainer();
|
||||
}
|
||||
|
||||
public function getStream() : StreamInterface
|
||||
{
|
||||
return $this->partBuilder->getStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
public function getMessageResourceHandle() : mixed
|
||||
{
|
||||
return $this->partBuilder->getMessageResourceHandle();
|
||||
}
|
||||
|
||||
public function getMessageResourceHandlePos() : int
|
||||
{
|
||||
return $this->partBuilder->getMessageResourceHandlePos();
|
||||
}
|
||||
|
||||
public function getStreamPartStartPos() : int
|
||||
{
|
||||
return $this->partBuilder->getStreamPartStartPos();
|
||||
}
|
||||
|
||||
public function getStreamPartLength() : int
|
||||
{
|
||||
return $this->partBuilder->getStreamPartLength();
|
||||
}
|
||||
|
||||
public function getStreamContentStartPos() : ?int
|
||||
{
|
||||
return $this->partBuilder->getStreamContentStartPos();
|
||||
}
|
||||
|
||||
public function getStreamContentLength() : int
|
||||
{
|
||||
return $this->partBuilder->getStreamContentLength();
|
||||
}
|
||||
|
||||
public function setStreamPartStartPos(int $streamPartStartPos) : static
|
||||
{
|
||||
$this->partBuilder->setStreamPartStartPos($streamPartStartPos);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStreamPartEndPos(int $streamPartEndPos) : static
|
||||
{
|
||||
$this->partBuilder->setStreamPartEndPos($streamPartEndPos);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStreamContentStartPos(int $streamContentStartPos) : static
|
||||
{
|
||||
$this->partBuilder->setStreamContentStartPos($streamContentStartPos);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStreamPartAndContentEndPos(int $streamContentEndPos) : static
|
||||
{
|
||||
$this->partBuilder->setStreamPartAndContentEndPos($streamContentEndPos);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isContentParsed() : bool
|
||||
{
|
||||
return $this->partBuilder->isContentParsed();
|
||||
}
|
||||
|
||||
public function isMime() : bool
|
||||
{
|
||||
return $this->partBuilder->isMime();
|
||||
}
|
||||
|
||||
public function addError(string $message, string $level) : ParserPartProxy
|
||||
{
|
||||
$this->part->addError($message, $level);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
25
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserPartProxyFactory.php
vendored
Normal file
25
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserPartProxyFactory.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
use ZBateson\MailMimeParser\Parser\IParserService;
|
||||
use ZBateson\MailMimeParser\Parser\PartBuilder;
|
||||
|
||||
/**
|
||||
* Base class for factories creating ParserPartProxy classes.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
abstract class ParserPartProxyFactory
|
||||
{
|
||||
/**
|
||||
* Constructs a new ParserPartProxy wrapping an IMessagePart object.
|
||||
*
|
||||
*/
|
||||
abstract public function newInstance(PartBuilder $partBuilder, IParserService $parser) : ParserPartProxy;
|
||||
}
|
||||
128
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserUUEncodedPartProxy.php
vendored
Normal file
128
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserUUEncodedPartProxy.php
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
/**
|
||||
* A bi-directional parser-to-part proxy for NonMimeParser and IUUEncodedParts.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserUUEncodedPartProxy extends ParserPartProxy
|
||||
{
|
||||
/**
|
||||
* Only has a single parent of type ParserNonMimeMessageProxy, overridden to
|
||||
* specify ParserNonMimeMessageProxy as the return type.
|
||||
*/
|
||||
public function getParent() : ParserNonMimeMessageProxy
|
||||
{
|
||||
return parent::getParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next part's start position within the message's raw stream,
|
||||
* or null if not set, not discovered, or there are no more parts under this
|
||||
* message.
|
||||
*
|
||||
* As this is a message-wide setting, ParserUUEncodedPartProxy calls
|
||||
* getNextPartStart() on its parent (a ParserNonMimeMessageProxy, which
|
||||
* stores/returns this information).
|
||||
*
|
||||
* @return int|null The start position or null
|
||||
*/
|
||||
public function getNextPartStart() : ?int
|
||||
{
|
||||
return $this->getParent()->getNextPartStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next part's unix file mode in a uu-encoded 'begin' line if
|
||||
* one exists, or null otherwise.
|
||||
*
|
||||
* As this is a message-wide setting, ParserUUEncodedPartProxy calls
|
||||
* getNextPartMode() on its parent (a ParserNonMimeMessageProxy, which
|
||||
* stores/returns this information).
|
||||
*
|
||||
* @return int|null The file mode or null
|
||||
*/
|
||||
public function getNextPartMode() : ?int
|
||||
{
|
||||
return $this->getParent()->getNextPartMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next part's filename in a uu-encoded 'begin' line if one
|
||||
* exists, or null otherwise.
|
||||
*
|
||||
* As this is a message-wide setting, ParserUUEncodedPartProxy calls
|
||||
* getNextPartFilename() on its parent (a ParserNonMimeMessageProxy, which
|
||||
* stores/returns this information).
|
||||
*
|
||||
* @return ?string The file name or null
|
||||
*/
|
||||
public function getNextPartFilename() : ?string
|
||||
{
|
||||
return $this->getParent()->getNextPartFilename();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next part's start position within the message's raw stream.
|
||||
*
|
||||
* As this is a message-wide setting, ParserUUEncodedPartProxy calls
|
||||
* setNextPartStart() on its parent (a ParserNonMimeMessageProxy, which
|
||||
* stores/returns this information).
|
||||
*/
|
||||
public function setNextPartStart(int $nextPartStart) : static
|
||||
{
|
||||
$this->getParent()->setNextPartStart($nextPartStart);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next part's unix file mode from its 'begin' line.
|
||||
*
|
||||
* As this is a message-wide setting, ParserUUEncodedPartProxy calls
|
||||
* setNextPartMode() on its parent (a ParserNonMimeMessageProxy, which
|
||||
* stores/returns this information).
|
||||
*/
|
||||
public function setNextPartMode(int $nextPartMode) : static
|
||||
{
|
||||
$this->getParent()->setNextPartMode($nextPartMode);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next part's filename from its 'begin' line.
|
||||
*
|
||||
* As this is a message-wide setting, ParserUUEncodedPartProxy calls
|
||||
* setNextPartFilename() on its parent (a ParserNonMimeMessageProxy, which
|
||||
* stores/returns this information).
|
||||
*/
|
||||
public function setNextPartFilename(string $nextPartFilename) : static
|
||||
{
|
||||
$this->getParent()->setNextPartFilename($nextPartFilename);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file mode included in the uuencoded 'begin' line for this
|
||||
* part.
|
||||
*/
|
||||
public function getUnixFileMode() : ?int
|
||||
{
|
||||
return $this->getHeaderContainer()->getUnixFileMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename included in the uuencoded 'begin' line for this
|
||||
* part.
|
||||
*/
|
||||
public function getFilename() : ?string
|
||||
{
|
||||
return $this->getHeaderContainer()->getFilename();
|
||||
}
|
||||
}
|
||||
62
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserUUEncodedPartProxyFactory.php
vendored
Normal file
62
plugins/vendor/zbateson/mail-mime-parser/src/Parser/Proxy/ParserUUEncodedPartProxyFactory.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of the ZBateson\MailMimeParser project.
|
||||
*
|
||||
* @license http://opensource.org/licenses/bsd-license.php BSD
|
||||
*/
|
||||
|
||||
namespace ZBateson\MailMimeParser\Parser\Proxy;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ZBateson\MailMimeParser\Message\UUEncodedPart;
|
||||
use ZBateson\MailMimeParser\Parser\IParserService;
|
||||
use ZBateson\MailMimeParser\Parser\Part\ParserPartStreamContainerFactory;
|
||||
use ZBateson\MailMimeParser\Parser\PartBuilder;
|
||||
use ZBateson\MailMimeParser\Stream\StreamFactory;
|
||||
|
||||
/**
|
||||
* Responsible for creating proxied IUUEncodedPart instances wrapped in a
|
||||
* ParserUUEncodedPartProxy and used by NonMimeParser.
|
||||
*
|
||||
* @author Zaahid Bateson
|
||||
*/
|
||||
class ParserUUEncodedPartProxyFactory extends ParserPartProxyFactory
|
||||
{
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
protected StreamFactory $streamFactory;
|
||||
|
||||
protected ParserPartStreamContainerFactory $parserPartStreamContainerFactory;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
StreamFactory $sdf,
|
||||
ParserPartStreamContainerFactory $parserPartStreamContainerFactory
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->streamFactory = $sdf;
|
||||
$this->parserPartStreamContainerFactory = $parserPartStreamContainerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ParserUUEncodedPartProxy wrapping an IUUEncoded object.
|
||||
*/
|
||||
public function newInstance(PartBuilder $partBuilder, IParserService $parser) : ParserUUEncodedPartProxy
|
||||
{
|
||||
$parserProxy = new ParserUUEncodedPartProxy($partBuilder, $parser);
|
||||
$streamContainer = $this->parserPartStreamContainerFactory->newInstance($parserProxy);
|
||||
|
||||
$part = new UUEncodedPart(
|
||||
$parserProxy->getUnixFileMode(),
|
||||
$parserProxy->getFileName(),
|
||||
$partBuilder->getParent()->getPart(),
|
||||
$this->logger,
|
||||
$streamContainer
|
||||
);
|
||||
$parserProxy->setPart($part);
|
||||
|
||||
$streamContainer->setStream($this->streamFactory->newMessagePartStream($part));
|
||||
$part->attach($streamContainer);
|
||||
return $parserProxy;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user