Skip to content

Commit

Permalink
Merging develop to master in preparation for 2.12.0 release.
Browse files Browse the repository at this point in the history
  • Loading branch information
weierophinney committed Jul 30, 2020
2 parents 628c8b4 + 28c2252 commit 036eba8
Show file tree
Hide file tree
Showing 21 changed files with 574 additions and 185 deletions.
12 changes: 0 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,6 @@ env:
matrix:
fast_finish: true
include:
- php: 5.6
env:
- DEPS=lowest
- php: 5.6
env:
- DEPS=latest
- php: 7.0
env:
- DEPS=lowest
- php: 7.0
env:
- DEPS=latest
- php: 7.1
env:
- DEPS=lowest
Expand Down
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,38 @@

All notable changes to this project will be documented in this file, in reverse chronological order by release.

## 2.12.0 - 2020-07-30

### Added

- [#95](https://github.com/laminas/laminas-mail/pull/95) adds a new interface, `Laminas\Mail\Header\HeaderLocatorInterface`. This defines classes that will locate header classes based on an email header name.

- [#95](https://github.com/laminas/laminas-mail/pull/95) adds a new class, `Laminas\Mail\Header\HeaderLocator`, implementing `Laminas\Mail\Header\HeaderLocatorInterface`. This is the default implementation of that new interface.

- [#95](https://github.com/laminas/laminas-mail/pull/95) adds the methods `setHeaderLocator(Laminas\Mail\Header\HeaderLocatorInterface $locator)` and `getHeaderLocator(): Laminas\Mail\Header\HeaderLocatorInterface` to the `Laminas\Mail\Headers` implementation. Users are encouraged to use these when providing custom header implementations in order to prepare for a 3.0 release. **The value of `getHeaderLocator()` will now be used as the default mechanism for resolving header names to header classes.**

- [#94](https://github.com/laminas/laminas-mail/pull/94) and [#99](https://github.com/laminas/laminas-mail/pull/99) add the "novalidatecert" option for each of the POP3, IMAP, and SMTP protocol implementations. When toggled true, you can connect to servers using self-signed certificates.

### Changed

- [#95](https://github.com/laminas/laminas-mail/pull/95) bumps the minimum supported PHP version to 7.1.

### Deprecated

- [#99](https://github.com/laminas/laminas-mail/pull/99) deprecates the `Laminas\Mail\Protocol\AbstractProtocol::_connect()` method, as it is no longer used internally.

- [#95](https://github.com/laminas/laminas-mail/pull/95) deprecates `Laminas\Mail\Header\HeaderLoader` in favor of the new `Laminas\Mail\Header\HeaderLocator` class. The class will be removed in version 3.0.0.

- [#95](https://github.com/laminas/laminas-mail/pull/95) deprecates the `Headers::getPluginClassLoader()` and `Headers::setPluginClassLoader()` methods, in favor of the new `setHeaderLocator()` and `getHeaderLocator()` methods. These methods will be removed in version 3.0.0, and laminas-loader `PluginClassLocator` instances will no longer be supported. Please update your code to use the new `HeaderLocatorInterface` instead.

### Removed

- [#98](https://github.com/laminas/laminas-mail/pull/98) removes `Laminas\Mail\Transport\Null`, as it is unusable with the new minimum supported PHP version (7.1). Users should use `Laminas\Mail\Transport\InMemory` instead. As this has been the default when requesting a "null" transport from `Laminas\Mail\Transport\Factory` for the past several minor releases, end-users should be unaffected. However, **users are encouraged to specify "inmemory" instead of "null" when requiring a no-op transport.**

### Fixed

- Nothing.

## 2.11.1 - 2020-07-28

### Added
Expand Down
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.11.x-dev",
"dev-develop": "2.12.x-dev"
"dev-master": "2.12.x-dev",
"dev-develop": "2.13.x-dev"
},
"laminas": {
"component": "Laminas\\Mail",
"config-provider": "Laminas\\Mail\\ConfigProvider"
}
},
"require": {
"php": "^5.6 || ^7.0",
"php": "^7.1",
"ext-iconv": "*",
"laminas/laminas-loader": "^2.5",
"laminas/laminas-mime": "^2.5",
Expand All @@ -42,8 +42,8 @@
"laminas/laminas-coding-standard": "~1.0.0",
"laminas/laminas-config": "^2.6",
"laminas/laminas-crypt": "^2.6 || ^3.0",
"laminas/laminas-servicemanager": "^2.7.10 || ^3.3.1",
"phpunit/phpunit": "^5.7.25 || ^6.4.4 || ^7.1.4"
"laminas/laminas-servicemanager": "^3.2.1",
"phpunit/phpunit": "^7.5.20"
},
"suggest": {
"laminas/laminas-crypt": "Crammd5 support in SMTP Auth",
Expand Down
4 changes: 4 additions & 0 deletions docs/book/read.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ $mail = new Pop3([
]);
```

If you are connecting to a mail server with a self-signed certificate and want to
skip the SSL verification, you can also pass an additional argument `novalidatecert`
with the value `true`.

Both constructors throw `Laminas\Mail\Exception` or `Laminas\Mail\Protocol\Exception`
(extends `Laminas\Mail\Exception`) for connection errors, depending on the type of
error encountered.
Expand Down
75 changes: 75 additions & 0 deletions src/Header/HeaderLocator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/**
* @see https://github.com/laminas/laminas-mail for the canonical source repository
* @copyright https://github.com/laminas/laminas-mail/blob/master/COPYRIGHT.md
* @license https://github.com/laminas/laminas-mail/blob/master/LICENSE.md New BSD License
*/

declare(strict_types=1);

namespace Laminas\Mail\Header;

/**
* Plugin Class Loader implementation for HTTP headers
*/
final class HeaderLocator implements HeaderLocatorInterface
{
/**
* @var array Pre-aliased Header plugins
*/
private $plugins = [
'bcc' => Bcc::class,
'cc' => Cc::class,
'contentdisposition' => ContentDisposition::class,
'content_disposition' => ContentDisposition::class,
'content-disposition' => ContentDisposition::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,
'in-reply-to' => InReplyTo::class,
'message-id' => MessageId::class,
'mimeversion' => MimeVersion::class,
'mime_version' => MimeVersion::class,
'mime-version' => MimeVersion::class,
'received' => Received::class,
'references' => References::class,
'replyto' => ReplyTo::class,
'reply_to' => ReplyTo::class,
'reply-to' => ReplyTo::class,
'sender' => Sender::class,
'subject' => Subject::class,
'to' => To::class,
];

public function get(string $name, ?string $default = null): ?string
{
$name = $this->normalizeName($name);
return isset($this->plugins[$name]) ? $this->plugins[$name] : $default;
}

public function has(string $name): bool
{
return isset($this->plugins[$this->normalizeName($name)]);
}

public function add(string $name, string $class): void
{
$this->plugins[$this->normalizeName($name)] = $class;
}

public function remove(string $name): void
{
unset($this->plugins[$this->normalizeName($name)]);
}

private function normalizeName(string $name): string
{
return strtolower($name);
}
}
25 changes: 25 additions & 0 deletions src/Header/HeaderLocatorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* @see https://github.com/laminas/laminas-mail for the canonical source repository
* @copyright https://github.com/laminas/laminas-mail/blob/master/COPYRIGHT.md
* @license https://github.com/laminas/laminas-mail/blob/master/LICENSE.md New BSD License
*/

declare(strict_types=1);

namespace Laminas\Mail\Header;

/**
* Interface detailing how to resolve header names to classes.
*/
interface HeaderLocatorInterface
{
public function get(string $name, ?string $default = null): ?string;

public function has(string $name): bool;

public function add(string $name, string $class): void;

public function remove(string $name): void;
}
95 changes: 85 additions & 10 deletions src/Headers.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
* @license https://github.com/laminas/laminas-mail/blob/master/LICENSE.md New BSD License
*/

declare(strict_types=1);

namespace Laminas\Mail;

use ArrayIterator;
use Countable;
use Iterator;
use Laminas\Loader\PluginClassLoader;
use Laminas\Loader\PluginClassLocator;
use Laminas\Mail\Header\GenericHeader;
use Laminas\Mail\Header\HeaderInterface;
Expand All @@ -30,9 +33,15 @@ class Headers implements Countable, Iterator
const FOLDING = "\r\n ";

/**
* @var \Laminas\Loader\PluginClassLoader
* @var null|Header\HeaderLocatorInterface
*/
protected $pluginClassLoader = null;
private $headerLocator;

/**
* @todo Remove for 3.0.0.
* @var null|PluginClassLocator
*/
protected $pluginClassLoader;

/**
* @var array key names for $headers array
Expand Down Expand Up @@ -119,30 +128,73 @@ public static function fromString($string, $EOL = self::EOL)
}

/**
* Set an alternate implementation for the PluginClassLoader
* Set an alternate PluginClassLocator implementation for loading header classes.
*
* @param PluginClassLocator $pluginClassLoader
* @return Headers
* @deprecated since 2.12.0
* @todo Remove for version 3.0.0
* @return $this
*/
public function setPluginClassLoader(PluginClassLocator $pluginClassLoader)
{
// Silenced; can be caught in custom error handlers.
@trigger_error(sprintf(
'Since laminas/laminas-mail 2.12.0: Usage of %s is deprecated; use %s::setHeaderLocator() instead',
__METHOD__,
__CLASS__
), E_USER_DEPRECATED);

$this->pluginClassLoader = $pluginClassLoader;
return $this;
}

/**
* Return an instance of a PluginClassLocator, lazyload and inject map if necessary
* Return a PluginClassLocator instance for customizing headers.
*
* Lazyloads a Header\HeaderLoader if necessary.
*
* @deprecated since 2.12.0
* @todo Remove for version 3.0.0
* @return PluginClassLocator
*/
public function getPluginClassLoader()
{
if ($this->pluginClassLoader === null) {
// Silenced; can be caught in custom error handlers.
@trigger_error(sprintf(
'Since laminas/laminas-mail 2.12.0: Usage of %s is deprecated; use %s::getHeaderLocator() instead',
__METHOD__,
__CLASS__
), E_USER_DEPRECATED);

if (! $this->pluginClassLoader) {
$this->pluginClassLoader = new Header\HeaderLoader();
}

return $this->pluginClassLoader;
}

/**
* Retrieve the header class locator for customizing headers.
*
* Lazyloads a Header\HeaderLocator instance if necessary.
*/
public function getHeaderLocator(): Header\HeaderLocatorInterface
{
if (! $this->headerLocator) {
$this->setHeaderLocator(new Header\HeaderLocator());
}
return $this->headerLocator;
}

/**
* @todo Return self when we update to 7.4 or later as minimum PHP version.
* @return $this
*/
public function setHeaderLocator(Header\HeaderLocatorInterface $headerLocator)
{
$this->headerLocator = $headerLocator;
return $this;
}

/**
* Set the header encoding
*
Expand Down Expand Up @@ -270,9 +322,20 @@ public function addHeader(Header\HeaderInterface $header)
*/
public function removeHeader($instanceOrFieldName)
{
if (! $instanceOrFieldName instanceof Header\HeaderInterface && ! is_string($instanceOrFieldName)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s requires a string or %s instance; received %s',
__METHOD__,
Header\HeaderInterface::class,
is_object($instanceOrFieldName) ? get_class($instanceOrFieldName) : gettype($instanceOrFieldName)
));
}

if ($instanceOrFieldName instanceof Header\HeaderInterface) {
$indexes = array_keys($this->headers, $instanceOrFieldName, true);
} else {
}

if (is_string($instanceOrFieldName)) {
$key = $this->normalizeFieldName($instanceOrFieldName);
$indexes = array_keys($this->headersKeys, $key, true);
}
Expand Down Expand Up @@ -481,7 +544,7 @@ 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);
}

Expand All @@ -496,7 +559,7 @@ protected function lazyLoadHeader($index)
$key = $this->headersKeys[$index];

/** @var GenericHeader $class */
$class = ($this->getPluginClassLoader()->load($key)) ?: Header\GenericHeader::class;
$class = $this->resolveHeaderClass($key);

$encoding = $current->getEncoding();
$headers = $class::fromString($current->toString());
Expand Down Expand Up @@ -528,4 +591,16 @@ protected function normalizeFieldName($fieldName)
{
return str_replace(['-', '_', ' ', '.'], '', strtolower($fieldName));
}

/**
* @param string $key
* @return string
*/
private function resolveHeaderClass($key)
{
if ($this->pluginClassLoader) {
return $this->pluginClassLoader->load($key) ?: Header\GenericHeader::class;
}
return $this->getHeaderLocator()->get($key, Header\GenericHeader::class);
}
}
6 changes: 4 additions & 2 deletions src/Protocol/AbstractProtocol.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ abstract class AbstractProtocol

/**
* Socket connection resource
* @var resource
* @var null|resource
*/
protected $socket;

Expand Down Expand Up @@ -194,13 +194,15 @@ protected function _addLog($value)
*
* An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222'
*
* @deprecated Since 1.12.0. Implementations should use the ProtocolTrait::setupSocket() method instead.
* @todo Remove for 3.0.0.
* @param string $remote Remote
* @throws Exception\RuntimeException
* @return bool
*/
protected function _connect($remote)
{
// @codingStandardsIgnoreEnd
// @codingStandardsIgnoreEnd
$errorNum = 0;
$errorStr = '';

Expand Down
Loading

0 comments on commit 036eba8

Please sign in to comment.