<?php
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;
class ParserPartStreamContainer extends PartStreamContainer implements SplObserver
{
protected ParserPartProxy $parserProxy;
protected ?MessagePartStreamDecorator $parsedStream = null;
protected bool $partUpdated = false;
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();
}
}
protected function requestParsedContentStream() : static
{
if (!$this->contentParseRequested) {
$this->contentParseRequested = true;
$this->parserProxy->parseContent();
parent::setContentStream($this->streamFactory->getLimitedContentStream(
$this->parserProxy
));
}
return $this;
}
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
{
$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;
}
}