From 2eb04e89210e703136962eac62f7dee0e761fb6e Mon Sep 17 00:00:00 2001 From: Eugene Kazakov Date: Wed, 20 Nov 2019 15:48:39 +0100 Subject: [PATCH] Drop dependency on zendframework/zend-loader https://github.com/zendframework/zend-mail/pull/186 --- composer.json | 1 - src/Header/HeaderLoader.php | 90 +++++++++++++++++++----------- src/Headers.php | 55 ++++++------------- test/Header/HeaderLoaderTest.php | 94 ++++++++++++++++++++++++++++++++ test/HeadersTest.php | 39 +------------ 5 files changed, 170 insertions(+), 109 deletions(-) create mode 100644 test/Header/HeaderLoaderTest.php diff --git a/composer.json b/composer.json index f33e42e7..b42d7073 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,6 @@ "require": { "php": "^5.6 || ^7.0", "ext-iconv": "*", - "zendframework/zend-loader": "^2.5", "zendframework/zend-mime": "^2.5", "zendframework/zend-stdlib": "^2.7 || ^3.0", "zendframework/zend-validator": "^2.10.2", diff --git a/src/Header/HeaderLoader.php b/src/Header/HeaderLoader.php index 490b6f0c..3ac2c4f9 100644 --- a/src/Header/HeaderLoader.php +++ b/src/Header/HeaderLoader.php @@ -7,39 +7,67 @@ namespace Zend\Mail\Header; -use Zend\Loader\PluginClassLoader; - -/** - * Plugin Class Loader implementation for HTTP headers - */ -class HeaderLoader extends PluginClassLoader +class HeaderLoader { /** - * @var array Pre-aliased Header plugins + * @var array Pre-aliased Header classes */ - protected $plugins = [ - 'bcc' => 'Zend\Mail\Header\Bcc', - 'cc' => 'Zend\Mail\Header\Cc', - 'contenttype' => 'Zend\Mail\Header\ContentType', - 'content_type' => 'Zend\Mail\Header\ContentType', - 'content-type' => 'Zend\Mail\Header\ContentType', - 'contenttransferencoding' => 'Zend\Mail\Header\ContentTransferEncoding', - 'content_transfer_encoding' => 'Zend\Mail\Header\ContentTransferEncoding', - 'content-transfer-encoding' => 'Zend\Mail\Header\ContentTransferEncoding', - 'date' => 'Zend\Mail\Header\Date', - 'from' => 'Zend\Mail\Header\From', - 'in-reply-to' => 'Zend\Mail\Header\InReplyTo', - 'message-id' => 'Zend\Mail\Header\MessageId', - 'mimeversion' => 'Zend\Mail\Header\MimeVersion', - 'mime_version' => 'Zend\Mail\Header\MimeVersion', - 'mime-version' => 'Zend\Mail\Header\MimeVersion', - 'received' => 'Zend\Mail\Header\Received', - 'references' => 'Zend\Mail\Header\References', - 'replyto' => 'Zend\Mail\Header\ReplyTo', - 'reply_to' => 'Zend\Mail\Header\ReplyTo', - 'reply-to' => 'Zend\Mail\Header\ReplyTo', - 'sender' => 'Zend\Mail\Header\Sender', - 'subject' => 'Zend\Mail\Header\Subject', - 'to' => 'Zend\Mail\Header\To', + private $headerClassMap = [ + 'bcc' => Bcc::class, + 'cc' => Cc::class, + 'contenttype' => ContentType::class, + 'content_type' => ContentType::class, + 'content-type' => ContentType::class, + 'contenttransferencoding' => ContentTransferEncoding::class, + 'content_transfer_encoding' => ContentTransferEncoding::class, + 'content-transfer-encoding' => ContentTransferEncoding::class, + 'date' => Date::class, + 'from' => From::class, + 'message-id' => MessageId::class, + 'mimeversion' => MimeVersion::class, + 'mime_version' => MimeVersion::class, + 'mime-version' => MimeVersion::class, + 'received' => Received::class, + 'replyto' => ReplyTo::class, + 'reply_to' => ReplyTo::class, + 'reply-to' => ReplyTo::class, + 'sender' => Sender::class, + 'subject' => Subject::class, + 'to' => To::class, ]; + + /** + * @param string $name + * @param string|null $default + * @return string|null + */ + public function get($name, $default = null) + { + $name = $this->normalizeName($name); + return isset($this->headerClassMap[$name]) ? $this->headerClassMap[$name] : $default; + } + + /** + * @param string $name + * @return bool + */ + public function has($name) + { + return isset($this->headerClassMap[$this->normalizeName($name)]); + } + + public function add($name, $class) + { + $this->headerClassMap[$this->normalizeName($name)] = $class; + } + + public function remove($name) + { + unset($this->headerClassMap[$this->normalizeName($name)]); + } + + private function normalizeName($name) + { + return strtolower($name); + } } diff --git a/src/Headers.php b/src/Headers.php index b8058b97..fa1ebb6b 100644 --- a/src/Headers.php +++ b/src/Headers.php @@ -11,9 +11,6 @@ use Countable; use Iterator; use Traversable; -use Zend\Loader\PluginClassLocator; -use Zend\Mail\Header\GenericHeader; -use Zend\Mail\Header\HeaderInterface; /** * Basic mail headers collection functionality @@ -29,9 +26,9 @@ class Headers implements Countable, Iterator const FOLDING = "\r\n "; /** - * @var \Zend\Loader\PluginClassLoader + * @var Header\HeaderLoader */ - protected $pluginClassLoader = null; + protected $headerLoader; /** * @var array key names for $headers array @@ -117,31 +114,6 @@ public static function fromString($string, $EOL = self::EOL) return $headers; } - /** - * Set an alternate implementation for the PluginClassLoader - * - * @param PluginClassLocator $pluginClassLoader - * @return Headers - */ - public function setPluginClassLoader(PluginClassLocator $pluginClassLoader) - { - $this->pluginClassLoader = $pluginClassLoader; - return $this; - } - - /** - * Return an instance of a PluginClassLocator, lazyload and inject map if necessary - * - * @return PluginClassLocator - */ - public function getPluginClassLoader() - { - if ($this->pluginClassLoader === null) { - $this->pluginClassLoader = new Header\HeaderLoader(); - } - return $this->pluginClassLoader; - } - /** * Set the header encoding * @@ -356,7 +328,6 @@ public function next() { next($this->headers); } - /** * Return the current key for this object as an iterator * @@ -385,7 +356,6 @@ public function rewind() { reset($this->headers); } - /** * Return the current value for this iterator, lazy loading it if need be * @@ -478,9 +448,7 @@ public function forceLoading() public function loadHeader($headerLine) { list($name, ) = Header\GenericHeader::splitHeaderLine($headerLine); - - /** @var HeaderInterface $class */ - $class = $this->getPluginClassLoader()->load($name) ?: Header\GenericHeader::class; + $class = $this->resolveHeaderClass($name); return $class::fromString($headerLine); } @@ -493,10 +461,7 @@ protected function lazyLoadHeader($index) $current = $this->headers[$index]; $key = $this->headersKeys[$index]; - - /** @var GenericHeader $class */ - $class = ($this->getPluginClassLoader()->load($key)) ?: 'Zend\Mail\Header\GenericHeader'; - + $class = $this->resolveHeaderClass($key); $encoding = $current->getEncoding(); $headers = $class::fromString($current->toString()); if (is_array($headers)) { @@ -527,4 +492,16 @@ protected function normalizeFieldName($fieldName) { return str_replace(['-', '_', ' ', '.'], '', strtolower($fieldName)); } + + /** + * @param string $key + * @return string + */ + private function resolveHeaderClass($key) + { + if ($this->headerLoader === null) { + $this->headerLoader = new Header\HeaderLoader(); + } + return $this->headerLoader->get($key, Header\GenericHeader::class); + } } diff --git a/test/Header/HeaderLoaderTest.php b/test/Header/HeaderLoaderTest.php new file mode 100644 index 00000000..c72ce0b0 --- /dev/null +++ b/test/Header/HeaderLoaderTest.php @@ -0,0 +1,94 @@ +headerLoader = new Header\HeaderLoader(); + } + public function provideHeaderNames() + { + return [ + 'with existing name' => ['to', Header\To::class], + 'with non-existent name' => ['foo', null], + 'with default value' => ['foo', Header\GenericHeader::class, Header\GenericHeader::class], + ]; + } + /** + * @param $name + * @param $expected + * @param $default + * @dataProvider provideHeaderNames + */ + public function testHeaderIsProperlyLoaded($name, $expected, $default = null) + { + $this->assertEquals($expected, $this->headerLoader->get($name, $default)); + } + public function testHeaderExistenceIsProperlyChecked() + { + $this->assertTrue($this->headerLoader->has('to')); + $this->assertTrue($this->headerLoader->has('To')); + $this->assertTrue($this->headerLoader->has('Reply_to')); + $this->assertTrue($this->headerLoader->has('SUBJECT')); + $this->assertFalse($this->headerLoader->has('foo')); + $this->assertFalse($this->headerLoader->has('bar')); + } + public function testHeaderCanBeAdded() + { + $this->assertFalse($this->headerLoader->has('foo')); + $this->headerLoader->add('foo', Header\GenericHeader::class); + $this->assertTrue($this->headerLoader->has('foo')); + } + public function testHeaderCanBeRemoved() + { + $this->assertTrue($this->headerLoader->has('to')); + $this->headerLoader->remove('to'); + $this->assertFalse($this->headerLoader->has('to')); + } + public static function expectedHeaders() + { + return [ + ['bcc', Header\Bcc::class], + ['cc', Header\Cc::class], + ['contenttype', Header\ContentType::class], + ['content_type', Header\ContentType::class], + ['content-type', Header\ContentType::class], + ['date', Header\Date::class], + ['from', Header\From::class], + ['mimeversion', Header\MimeVersion::class], + ['mime_version', Header\MimeVersion::class], + ['mime-version', Header\MimeVersion::class], + ['received', Header\Received::class], + ['replyto', Header\ReplyTo::class], + ['reply_to', Header\ReplyTo::class], + ['reply-to', Header\ReplyTo::class], + ['sender', Header\Sender::class], + ['subject', Header\Subject::class], + ['to', Header\To::class], + ]; + } + /** + * @dataProvider expectedHeaders + * @param $name + * @param $class + */ + public function testDefaultHeadersMapResolvesProperHeader($name, $class) + { + $this->assertEquals($class, $this->headerLoader->get($name)); + } +} diff --git a/test/HeadersTest.php b/test/HeadersTest.php index 33afd9c6..e2c39cae 100644 --- a/test/HeadersTest.php +++ b/test/HeadersTest.php @@ -97,10 +97,7 @@ public function testHeadersFromStringFactoryCreatesMultipleObjects() public function testHeadersFromStringMultiHeaderWillAggregateLazyLoadedHeaders() { $headers = new Mail\Headers(); - /* @var $pcl \Zend\Loader\PluginClassLoader */ - $pcl = $headers->getPluginClassLoader(); - $pcl->registerPlugin('foo', 'Zend\Mail\Header\GenericMultiHeader'); - $headers->addHeaderLine('foo: bar1,bar2,bar3'); + $headers->addHeaderLine('foo', ['bar1@domain.com', 'bar2@domain.com', 'bar3@domain.com']); $headers->forceLoading(); $this->assertEquals(3, $headers->count()); } @@ -354,40 +351,6 @@ public function testToArrayFormatEncoded() $this->assertEquals($expected, $array); } - public static function expectedHeaders() - { - return [ - ['bcc', 'Zend\Mail\Header\Bcc'], - ['cc', 'Zend\Mail\Header\Cc'], - ['contenttype', 'Zend\Mail\Header\ContentType'], - ['content_type', 'Zend\Mail\Header\ContentType'], - ['content-type', 'Zend\Mail\Header\ContentType'], - ['date', 'Zend\Mail\Header\Date'], - ['from', 'Zend\Mail\Header\From'], - ['mimeversion', 'Zend\Mail\Header\MimeVersion'], - ['mime_version', 'Zend\Mail\Header\MimeVersion'], - ['mime-version', 'Zend\Mail\Header\MimeVersion'], - ['received', 'Zend\Mail\Header\Received'], - ['replyto', 'Zend\Mail\Header\ReplyTo'], - ['reply_to', 'Zend\Mail\Header\ReplyTo'], - ['reply-to', 'Zend\Mail\Header\ReplyTo'], - ['sender', 'Zend\Mail\Header\Sender'], - ['subject', 'Zend\Mail\Header\Subject'], - ['to', 'Zend\Mail\Header\To'], - ]; - } - - /** - * @dataProvider expectedHeaders - */ - public function testDefaultPluginLoaderIsSeededWithHeaders($plugin, $class) - { - $headers = new Mail\Headers(); - $loader = $headers->getPluginClassLoader(); - $test = $loader->load($plugin); - $this->assertEquals($class, $test); - } - public function testClone() { $headers = new Mail\Headers();