Skip to content

Commit

Permalink
Add HeaderContainer class #58 #74
Browse files Browse the repository at this point in the history
Maintains headers properly -- keeping them in their original order
and allowing access to multiple headers with the same name.
  • Loading branch information
zbateson committed Jul 27, 2018
1 parent ad3faa4 commit 5c49187
Show file tree
Hide file tree
Showing 21 changed files with 795 additions and 549 deletions.
158 changes: 158 additions & 0 deletions src/Header/HeaderContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php
/**
* This file is part of the ZBateson\MailMimeParser project.
*
* @license http://opensource.org/licenses/bsd-license.php BSD
*/
namespace ZBateson\MailMimeParser\Header;

use ArrayIterator;
use IteratorAggregate;
use ZBateson\MailMimeParser\Header\HeaderFactory;

/**
* Maintains a collection of headers for a part.
*
* @author Zaahid Bateson
*/
class HeaderContainer implements IteratorAggregate
{
/**
* @var HeaderFactory the HeaderFactory object used for created headers
*/
protected $headerFactory;

private $headerObjects = [];
private $headers = [];
private $headerMap = [];

private $nextIndex = 0;

public function __construct(HeaderFactory $headerFactory)
{
$this->headerFactory = $headerFactory;
}

/**
* Returns the string in lower-case, and with non-alphanumeric characters
* stripped out.
*
* @param string $header
* @return string
*/
private function getNormalizedHeaderName($header)
{
return preg_replace('/[^a-z0-9]/', '', strtolower($header));
}

public function exists($name, $offset = 0)
{
$s = $this->getNormalizedHeaderName($name);
return isset($this->headerMap[$s][$offset]);
}

/**
* Returns the AbstractHeader object for the header with the given $name
*
* Note that mime headers aren't case sensitive.
*
* @param string $name
* @param int $offset
* @return \ZBateson\MailMimeParser\Header\AbstractHeader
*/
public function get($name, $offset = 0)
{
$s = $this->getNormalizedHeaderName($name);
if (isset($this->headerMap[$s][$offset])) {
return $this->getByIndex($this->headerMap[$s][$offset]);
}
return null;
}

public function getAll($name)
{
$s = $this->getNormalizedHeaderName($name);
$ret = [];
if (!empty($this->headerMap[$s])) {
foreach ($this->headerMap[$s] as $index) {
$ret[] = $this->getByIndex($index);
}
}
return $ret;
}

private function getByIndex($index)
{
if (!isset($this->headers[$index])) {
return null;
}
if ($this->headerObjects[$index] === null) {
$this->headerObjects[$index] = $this->headerFactory->newInstance(
$this->headers[$index][0],
$this->headers[$index][1]
);
}
return $this->headerObjects[$index];
}

public function remove($name, $offset = 0)
{
$s = $this->getNormalizedHeaderName($name);
if (isset($this->headerMap[$s][$offset])) {
$index = $this->headerMap[$s][$offset];
array_splice($this->headerMap[$s], $offset, 1);
unset($this->headers[$index]);
unset($this->headerObjects[$index]);
return true;
}
return false;
}

public function removeAll($name)
{
$s = $this->getNormalizedHeaderName($name);
if (!empty($this->headerMap[$s])) {
foreach ($this->headerMap[$s] as $i) {
unset($this->headers[$i]);
unset($this->headerObjects[$i]);
}
$this->headerMap[$s] = [];
return true;
}
return false;
}

public function add($name, $value)
{
$s = $this->getNormalizedHeaderName($name);
$this->headers[$this->nextIndex] = [ $name, $value ];
$this->headerObjects[$this->nextIndex] = null;
if (!isset($this->headerMap[$s])) {
$this->headerMap[$s] = [];
}
array_push($this->headerMap[$s], $this->nextIndex);
$this->nextIndex++;
}

public function set($name, $value, $offset = 0)
{
$s = $this->getNormalizedHeaderName($name);
if (!isset($this->headerMap[$s][$offset])) {
$this->add($name, $value);
return;
}
$i = $this->headerMap[$s][$offset];
$this->headers[$i] = [ $name, $value ];
$this->headerObjects[$i] = null;
}

public function getHeaders()
{
return array_values(array_filter($this->headers));
}

public function getIterator()
{
return new ArrayIterator($this->getHeaders());
}
}
10 changes: 10 additions & 0 deletions src/Header/HeaderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,14 @@ public function newInstance($name, $value)
$class = $this->getClassFor($name);
return new $class($this->consumerService, $name, $value);
}

/**
* Creates and returns a HeaderContainer.
*
* @return HeaderContainer;
*/
public function newHeaderContainer()
{
return new HeaderContainer($this);
}
}
4 changes: 0 additions & 4 deletions src/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

use GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
use ZBateson\MailMimeParser\Header\HeaderFactory;
use ZBateson\MailMimeParser\Message\Helper\MessageHelperService;
use ZBateson\MailMimeParser\Message\Part\MimePart;
use ZBateson\MailMimeParser\Message\Part\PartBuilder;
Expand Down Expand Up @@ -37,7 +36,6 @@ class Message extends MimePart
* @param PartStreamFilterManager $partStreamFilterManager
* @param StreamFactory $streamFactory
* @param PartFilterFactory $partFilterFactory
* @param HeaderFactory $headerFactory
* @param PartBuilder $partBuilder
* @param MessageHelperService $messageHelperService
* @param StreamInterface $stream
Expand All @@ -47,7 +45,6 @@ public function __construct(
PartStreamFilterManager $partStreamFilterManager,
StreamFactory $streamFactory,
PartFilterFactory $partFilterFactory,
HeaderFactory $headerFactory,
PartBuilder $partBuilder,
MessageHelperService $messageHelperService,
StreamInterface $stream = null,
Expand All @@ -57,7 +54,6 @@ public function __construct(
$partStreamFilterManager,
$streamFactory,
$partFilterFactory,
$headerFactory,
$partBuilder,
$stream,
$contentStream
Expand Down
6 changes: 1 addition & 5 deletions src/Message/MessageFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
namespace ZBateson\MailMimeParser\Message;

use Psr\Http\Message\StreamInterface;
use ZBateson\MailMimeParser\Header\HeaderFactory;
use ZBateson\MailMimeParser\Message;
use ZBateson\MailMimeParser\Message\Helper\MessageHelperService;
use ZBateson\MailMimeParser\Message\Part\PartBuilder;
Expand All @@ -31,18 +30,16 @@ class MessageFactory extends MimePartFactory
/**
* @param StreamFactory $sdf
* @param PartStreamFilterManagerFactory $psf
* @param HeaderFactory $hf
* @param PartFilterFactory $pf
* @param MessageHelperService $mhs
*/
public function __construct(
StreamFactory $sdf,
PartStreamFilterManagerFactory $psf,
HeaderFactory $hf,
PartFilterFactory $pf,
MessageHelperService $mhs
) {
parent::__construct($sdf, $psf, $hf, $pf);
parent::__construct($sdf, $psf, $pf);
$this->messageHelperService = $mhs;
}

Expand All @@ -63,7 +60,6 @@ public function newInstance(PartBuilder $partBuilder, StreamInterface $stream =
$this->partStreamFilterManagerFactory->newInstance(),
$this->streamFactory,
$this->partFilterFactory,
$this->headerFactory,
$partBuilder,
$this->messageHelperService,
$stream,
Expand Down
3 changes: 0 additions & 3 deletions src/Message/Part/Factory/MessagePartFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

use ReflectionClass;
use Psr\Http\Message\StreamInterface;
use ZBateson\MailMimeParser\Header\HeaderFactory;
use ZBateson\MailMimeParser\Message\Helper\MessageHelperService;
use ZBateson\MailMimeParser\Message\PartFilterFactory;
use ZBateson\MailMimeParser\Message\Part\PartBuilder;
Expand Down Expand Up @@ -86,15 +85,13 @@ protected static function getCachedInstance()
*
* @param StreamFactory $sdf
* @param PartStreamFilterManagerFactory $psf
* @param HeaderFactory $hf
* @param PartFilterFactory $pf
* @param MessageHelperService $mhs
* @return MessagePartFactory
*/
public static function getInstance(
StreamFactory $sdf,
PartStreamFilterManagerFactory $psf,
HeaderFactory $hf = null,
PartFilterFactory $pf = null,
MessageHelperService $mhs = null
) {
Expand Down
10 changes: 0 additions & 10 deletions src/Message/Part/Factory/MimePartFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

use Psr\Http\Message\StreamInterface;
use ZBateson\MailMimeParser\Stream\StreamFactory;
use ZBateson\MailMimeParser\Header\HeaderFactory;
use ZBateson\MailMimeParser\Message\PartFilterFactory;
use ZBateson\MailMimeParser\Message\Part\MimePart;
use ZBateson\MailMimeParser\Message\Part\PartBuilder;
Expand All @@ -20,11 +19,6 @@
*/
class MimePartFactory extends MessagePartFactory
{
/**
* @var HeaderFactory an instance used for creating MimePart objects
*/
protected $headerFactory;

/**
* @var PartFilterFactory an instance used for creating MimePart objects
*/
Expand All @@ -35,17 +29,14 @@ class MimePartFactory extends MessagePartFactory
*
* @param StreamFactory $sdf
* @param PartStreamFilterManagerFactory $psf
* @param HeaderFactory $hf
* @param PartFilterFactory $pf
*/
public function __construct(
StreamFactory $sdf,
PartStreamFilterManagerFactory $psf,
HeaderFactory $hf,
PartFilterFactory $pf
) {
parent::__construct($sdf, $psf);
$this->headerFactory = $hf;
$this->partFilterFactory = $pf;
}

Expand All @@ -68,7 +59,6 @@ public function newInstance(PartBuilder $partBuilder, StreamInterface $messageSt
$this->partStreamFilterManagerFactory->newInstance(),
$this->streamFactory,
$this->partFilterFactory,
$this->headerFactory,
$partBuilder,
$partStream,
$contentStream
Expand Down
4 changes: 2 additions & 2 deletions src/Message/Part/Factory/PartBuilderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public function __construct(HeaderFactory $headerFactory)
public function newPartBuilder(MessagePartFactory $messagePartFactory)
{
return new PartBuilder(
$this->headerFactory,
$messagePartFactory
$messagePartFactory,
$this->headerFactory->newHeaderContainer()
);
}
}
13 changes: 1 addition & 12 deletions src/Message/Part/Factory/PartFactoryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
namespace ZBateson\MailMimeParser\Message\Part\Factory;

use ZBateson\MailMimeParser\Stream\StreamFactory;
use ZBateson\MailMimeParser\Header\HeaderFactory;
use ZBateson\MailMimeParser\Message\Helper\MessageHelperService;
use ZBateson\MailMimeParser\Message\MessageFactory;
use ZBateson\MailMimeParser\Message\PartFilterFactory;
Expand All @@ -20,16 +19,11 @@
*/
class PartFactoryService
{
/**
* @var HeaderFactory the HeaderFactory object used for created headers
*/
protected $headerFactory;

/**
* @var PartFilterFactory the PartFilterFactory instance
*/
protected $partFilterFactory;

/**
* @var PartStreamFilterManagerFactory the PartStreamFilterManagerFactory
* instance
Expand All @@ -47,20 +41,17 @@ class PartFactoryService
protected $messageHelperService;

/**
* @param HeaderFactory $headerFactory
* @param PartFilterFactory $partFilterFactory
* @param StreamFactory $streamFactory
* @param PartStreamFilterManagerFactory $partStreamFilterManagerFactory
* @param MessageHelperService $messageHelperService
*/
public function __construct(
HeaderFactory $headerFactory,
PartFilterFactory $partFilterFactory,
StreamFactory $streamFactory,
PartStreamFilterManagerFactory $partStreamFilterManagerFactory,
MessageHelperService $messageHelperService
) {
$this->headerFactory = $headerFactory;
$this->partFilterFactory = $partFilterFactory;
$this->streamFactory = $streamFactory;
$this->partStreamFilterManagerFactory = $partStreamFilterManagerFactory;
Expand All @@ -77,7 +68,6 @@ public function getMessageFactory()
return MessageFactory::getInstance(
$this->streamFactory,
$this->partStreamFilterManagerFactory,
$this->headerFactory,
$this->partFilterFactory,
$this->messageHelperService
);
Expand All @@ -93,7 +83,6 @@ public function getMimePartFactory()
return MimePartFactory::getInstance(
$this->streamFactory,
$this->partStreamFilterManagerFactory,
$this->headerFactory,
$this->partFilterFactory
);
}
Expand Down
Loading

0 comments on commit 5c49187

Please sign in to comment.