[Web] Fix mailbox editing when password is unchanged, fix adding new administrator (fixes #4054, fixes #4053); [Web] Update libs, add LDAP for future admin/domain admin authentication
This commit is contained in:
@@ -1,5 +1,27 @@
|
||||
# Changelog
|
||||
|
||||
## [1.12.0](https://github.com/ddeboer/imap/tree/1.12.0) (2021-04-02)
|
||||
|
||||
[Full Changelog](https://github.com/ddeboer/imap/compare/1.11.0...1.12.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Require PHP 7.4 for types attributes [\#496](https://github.com/ddeboer/imap/pull/496) ([Slamdunk](https://github.com/Slamdunk))
|
||||
- Add x-mac-ce charset as alias for windows-1250 [\#488](https://github.com/ddeboer/imap/pull/488) ([aixkalur](https://github.com/aixkalur))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Cannot decode a content with an uknown encoding [\#491](https://github.com/ddeboer/imap/issues/491)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Implement copyMove\(\) function [\#494](https://github.com/ddeboer/imap/issues/494)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Implement move with imap\_mail\_copy+CP\_MOVE [\#495](https://github.com/ddeboer/imap/pull/495) ([Slamdunk](https://github.com/Slamdunk))
|
||||
- Dev tools refactor [\#486](https://github.com/ddeboer/imap/pull/486) ([Slamdunk](https://github.com/Slamdunk))
|
||||
|
||||
## [1.11.0](https://github.com/ddeboer/imap/tree/1.11.0) (2020-11-30)
|
||||
|
||||
[Full Changelog](https://github.com/ddeboer/imap/compare/1.10.1...1.11.0)
|
||||
|
65
data/web/inc/lib/vendor/ddeboer/imap/README.md
vendored
65
data/web/inc/lib/vendor/ddeboer/imap/README.md
vendored
@@ -1,37 +1,15 @@
|
||||
# IMAP library
|
||||
# PHP IMAP library
|
||||
|
||||
[](https://packagist.org/packages/ddeboer/imap)
|
||||
[](https://packagist.org/packages/ddeboer/imap)
|
||||
[](https://github.com/ddeboer/imap/actions)
|
||||
[](https://codecov.io/gh/ddeboer/imap?branch=master)
|
||||
|
||||
A PHP 7.3+ library to read and process e-mails over IMAP.
|
||||
A PHP IMAP library to read and process e-mails over IMAP protocol, built with robust Object-Oriented architecture.
|
||||
|
||||
This library requires [IMAP](https://secure.php.net/manual/en/book.imap.php),
|
||||
[iconv](https://secure.php.net/manual/en/book.iconv.php) and
|
||||
[Multibyte String](https://secure.php.net/manual/en/book.mbstring.php) extensions installed.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Feature Requests](#feature-requests)
|
||||
1. [Installation](#installation)
|
||||
1. [Usage](#usage)
|
||||
1. [Connect and Authenticate](#connect-and-authenticate)
|
||||
1. [Mailboxes](#mailboxes)
|
||||
1. [Messages](#messages)
|
||||
1. [Searching for Messages](#searching-for-messages)
|
||||
1. [Unknown search criterion: OR](#unknown-search-criterion-or)
|
||||
1. [Message Properties and Operations](#message-properties-and-operations)
|
||||
1. [Message Attachments](#message-attachments)
|
||||
1. [Embedded Messages](#embedded-messages)
|
||||
1. [Timeouts](#timeouts)
|
||||
1. [Mock the library](#mock-the-library)
|
||||
1. [Running the Tests](#running-the-tests)
|
||||
1. [Running Tests using Docker](#running-tests-using-docker)
|
||||
|
||||
## Feature Requests
|
||||
|
||||
[](https://feathub.com/ddeboer/imap)
|
||||
This library requires PHP >= 7.4 with [IMAP](https://www.php.net/manual/en/book.imap.php),
|
||||
[iconv](https://www.php.net/manual/en/book.iconv.php) and
|
||||
[Multibyte String](https://www.php.net/manual/en/book.mbstring.php) extensions installed.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -236,7 +214,6 @@ Move a message to another mailbox:
|
||||
```php
|
||||
$mailbox = $connection->getMailbox('another-mailbox');
|
||||
$message->move($mailbox);
|
||||
$connection->expunge();
|
||||
```
|
||||
|
||||
Deleting messages:
|
||||
@@ -321,40 +298,10 @@ $ IMAP_SERVER_NAME="my.imap.server.com" IMAP_SERVER_PORT="60993" IMAP_USERNAME="
|
||||
```
|
||||
|
||||
You can also copy `phpunit.xml.dist` file to a custom `phpunit.xml` and put
|
||||
these environment variables in it:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
bootstrap="./vendor/autoload.php"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="ddeboer/imap">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<php>
|
||||
<env name="IMAP_SERVER_NAME" value="my.imap.server.com" />
|
||||
<env name="IMAP_SERVER_PORT" value="60993" />
|
||||
<env name="IMAP_USERNAME" value="johndoe" />
|
||||
<env name="IMAP_PASSWORD" value="p4ssword" />
|
||||
</php>
|
||||
</phpunit>
|
||||
```
|
||||
these environment variables in it.
|
||||
|
||||
**WARNING** Tests create new mailboxes without removing them.
|
||||
|
||||
### Running Tests using Docker
|
||||
|
||||
If you have Docker installed you can run the tests locally with the following command:
|
||||
|
||||
```
|
||||
$ docker-compose run tests
|
||||
```
|
||||
|
@@ -22,23 +22,18 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-iconv": "*",
|
||||
"ext-imap": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.16.7",
|
||||
"laminas/laminas-mail": "^2.12.3",
|
||||
"phpstan/phpstan": "^0.12.57",
|
||||
"phpstan/phpstan-phpunit": "^0.12.16",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.5",
|
||||
"phpunit/phpunit": "^9.4.3"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.3"
|
||||
}
|
||||
"friendsofphp/php-cs-fixer": "^2.18.4",
|
||||
"laminas/laminas-mail": "^2.14.0",
|
||||
"phpstan/phpstan": "^0.12.80",
|
||||
"phpstan/phpstan-phpunit": "^0.12.18",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.9",
|
||||
"phpunit/phpunit": "^9.5.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
@@ -9,7 +9,6 @@ use Ddeboer\Imap\Exception\DeleteMailboxException;
|
||||
use Ddeboer\Imap\Exception\ImapGetmailboxesException;
|
||||
use Ddeboer\Imap\Exception\ImapNumMsgException;
|
||||
use Ddeboer\Imap\Exception\ImapQuotaException;
|
||||
use Ddeboer\Imap\Exception\InvalidResourceException;
|
||||
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
|
||||
|
||||
/**
|
||||
@@ -17,25 +16,16 @@ use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
|
||||
*/
|
||||
final class Connection implements ConnectionInterface
|
||||
{
|
||||
private ImapResourceInterface $resource;
|
||||
private string $server;
|
||||
/**
|
||||
* @var ImapResourceInterface
|
||||
* @var null|MailboxInterface[]
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
private ?array $mailboxes = null;
|
||||
/**
|
||||
* @var string
|
||||
* @var null|array<int|string, \stdClass>
|
||||
*/
|
||||
private $server;
|
||||
|
||||
/**
|
||||
* @var null|array
|
||||
*/
|
||||
private $mailboxes;
|
||||
|
||||
/**
|
||||
* @var null|array
|
||||
*/
|
||||
private $mailboxNames;
|
||||
private ?array $mailboxNames = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -48,25 +38,16 @@ final class Connection implements ConnectionInterface
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IMAP resource.
|
||||
*/
|
||||
public function getResource(): ImapResourceInterface
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all messages marked for deletion.
|
||||
*/
|
||||
public function expunge(): bool
|
||||
{
|
||||
return \imap_expunge($this->resource->getStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Close connection.
|
||||
*/
|
||||
public function close(int $flag = 0): bool
|
||||
{
|
||||
$this->resource->clearLastMailboxUsedCache();
|
||||
@@ -74,9 +55,6 @@ final class Connection implements ConnectionInterface
|
||||
return \imap_close($this->resource->getStream(), $flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mailbox quota.
|
||||
*/
|
||||
public function getQuota(string $root = 'INBOX'): array
|
||||
{
|
||||
$errorMessage = null;
|
||||
@@ -106,14 +84,10 @@ final class Connection implements ConnectionInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of mailboxes (also known as folders).
|
||||
*
|
||||
* @return MailboxInterface[]
|
||||
*/
|
||||
public function getMailboxes(): array
|
||||
{
|
||||
$this->initMailboxNames();
|
||||
\assert(null !== $this->mailboxNames);
|
||||
|
||||
if (null === $this->mailboxes) {
|
||||
$this->mailboxes = [];
|
||||
@@ -125,39 +99,24 @@ final class Connection implements ConnectionInterface
|
||||
return $this->mailboxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a mailbox with the given name exists.
|
||||
*
|
||||
* @param string $name Mailbox name
|
||||
*/
|
||||
public function hasMailbox(string $name): bool
|
||||
{
|
||||
$this->initMailboxNames();
|
||||
\assert(null !== $this->mailboxNames);
|
||||
|
||||
return isset($this->mailboxNames[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mailbox by its name.
|
||||
*
|
||||
* @param string $name Mailbox name
|
||||
*
|
||||
* @throws MailboxDoesNotExistException If mailbox does not exist
|
||||
*/
|
||||
public function getMailbox(string $name): MailboxInterface
|
||||
{
|
||||
if (false === $this->hasMailbox($name)) {
|
||||
throw new MailboxDoesNotExistException(\sprintf('Mailbox name "%s" does not exist', $name));
|
||||
}
|
||||
\assert(isset($this->mailboxNames[$name]));
|
||||
|
||||
return new Mailbox($this->resource, $name, $this->mailboxNames[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count number of messages not in any mailbox.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$return = \imap_num_msg($this->resource->getStream());
|
||||
@@ -169,21 +128,11 @@ final class Connection implements ConnectionInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the connection is still active.
|
||||
*
|
||||
* @throws InvalidResourceException If connection was closed
|
||||
*/
|
||||
public function ping(): bool
|
||||
{
|
||||
return \imap_ping($this->resource->getStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create mailbox.
|
||||
*
|
||||
* @throws CreateMailboxException
|
||||
*/
|
||||
public function createMailbox(string $name): MailboxInterface
|
||||
{
|
||||
if (false === \imap_createmailbox($this->resource->getStream(), $this->server . \mb_convert_encoding($name, 'UTF7-IMAP', 'UTF-8'))) {
|
||||
@@ -196,11 +145,6 @@ final class Connection implements ConnectionInterface
|
||||
return $this->getMailbox($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create mailbox.
|
||||
*
|
||||
* @throws DeleteMailboxException
|
||||
*/
|
||||
public function deleteMailbox(MailboxInterface $mailbox): void
|
||||
{
|
||||
if (false === \imap_deletemailbox($this->resource->getStream(), $mailbox->getFullEncodedName())) {
|
||||
@@ -211,9 +155,6 @@ final class Connection implements ConnectionInterface
|
||||
$this->resource->clearLastMailboxUsedCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mailbox names.
|
||||
*/
|
||||
private function initMailboxNames(): void
|
||||
{
|
||||
if (null !== $this->mailboxNames) {
|
||||
@@ -227,8 +168,9 @@ final class Connection implements ConnectionInterface
|
||||
}
|
||||
|
||||
foreach ($mailboxesInfo as $mailboxInfo) {
|
||||
$name = \mb_convert_encoding(\str_replace($this->server, '', $mailboxInfo->name), 'UTF-8', 'UTF7-IMAP');
|
||||
$name = \mb_convert_encoding(\str_replace($this->server, '', $mailboxInfo->name), 'UTF-8', 'UTF7-IMAP');
|
||||
\assert(\is_string($name));
|
||||
|
||||
$this->mailboxNames[$name] = $mailboxInfo;
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Exception\CreateMailboxException;
|
||||
use Ddeboer\Imap\Exception\DeleteMailboxException;
|
||||
use Ddeboer\Imap\Exception\InvalidResourceException;
|
||||
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
|
||||
|
||||
/**
|
||||
* A connection to an IMAP server that is authenticated for a user.
|
||||
*/
|
||||
@@ -26,11 +31,15 @@ interface ConnectionInterface extends \Countable
|
||||
|
||||
/**
|
||||
* Check if the connection is still active.
|
||||
*
|
||||
* @throws InvalidResourceException If connection was closed
|
||||
*/
|
||||
public function ping(): bool;
|
||||
|
||||
/**
|
||||
* Get Mailbox quota.
|
||||
*
|
||||
* @return array<string, int>
|
||||
*/
|
||||
public function getQuota(string $root = 'INBOX'): array;
|
||||
|
||||
@@ -52,16 +61,22 @@ interface ConnectionInterface extends \Countable
|
||||
* Get a mailbox by its name.
|
||||
*
|
||||
* @param string $name Mailbox name
|
||||
*
|
||||
* @throws MailboxDoesNotExistException If mailbox does not exist
|
||||
*/
|
||||
public function getMailbox(string $name): MailboxInterface;
|
||||
|
||||
/**
|
||||
* Create mailbox.
|
||||
*
|
||||
* @throws CreateMailboxException
|
||||
*/
|
||||
public function createMailbox(string $name): MailboxInterface;
|
||||
|
||||
/**
|
||||
* Delete mailbox.
|
||||
*
|
||||
* @throws DeleteMailboxException
|
||||
*/
|
||||
public function deleteMailbox(MailboxInterface $mailbox): void;
|
||||
}
|
||||
|
@@ -6,10 +6,7 @@ namespace Ddeboer\Imap\Exception;
|
||||
|
||||
abstract class AbstractException extends \RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $errorLabels = [
|
||||
private const ERROR_LABELS = [
|
||||
\E_ERROR => 'E_ERROR',
|
||||
\E_WARNING => 'E_WARNING',
|
||||
\E_PARSE => 'E_PARSE',
|
||||
@@ -27,16 +24,11 @@ abstract class AbstractException extends \RuntimeException
|
||||
\E_USER_DEPRECATED => 'E_USER_DEPRECATED',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $message The exception message
|
||||
* @param int $code The exception code
|
||||
* @param \Throwable $previous The previous exception
|
||||
*/
|
||||
final public function __construct(string $message, int $code = 0, \Throwable $previous = null)
|
||||
{
|
||||
$errorType = '';
|
||||
if (isset(self::$errorLabels[$code])) {
|
||||
$errorType = \sprintf('[%s] ', self::$errorLabels[$code]);
|
||||
if (isset(self::ERROR_LABELS[$code])) {
|
||||
$errorType = \sprintf('[%s] ', self::ERROR_LABELS[$code]);
|
||||
}
|
||||
|
||||
$joinString = "\n- ";
|
||||
|
@@ -13,19 +13,11 @@ use Ddeboer\Imap\Exception\ReopenMailboxException;
|
||||
final class ImapResource implements ImapResourceInterface
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var null|MailboxInterface
|
||||
*/
|
||||
private $mailbox;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private static $lastMailboxUsedCache;
|
||||
private ?MailboxInterface $mailbox = null;
|
||||
private static ?string $lastMailboxUsedCache = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -38,13 +30,6 @@ final class ImapResource implements ImapResourceInterface
|
||||
$this->mailbox = $mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IMAP resource stream.
|
||||
*
|
||||
* @throws InvalidResourceException
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
if (false === \is_resource($this->resource) || 'imap' !== \get_resource_type($this->resource)) {
|
||||
@@ -56,9 +41,6 @@ final class ImapResource implements ImapResourceInterface
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear last mailbox used cache.
|
||||
*/
|
||||
public function clearLastMailboxUsedCache(): void
|
||||
{
|
||||
self::$lastMailboxUsedCache = null;
|
||||
@@ -85,7 +67,7 @@ final class ImapResource implements ImapResourceInterface
|
||||
/**
|
||||
* Check whether the current mailbox is open.
|
||||
*
|
||||
* @param mixed $resource
|
||||
* @param resource $resource
|
||||
*/
|
||||
private static function isMailboxOpen(MailboxInterface $mailbox, $resource): bool
|
||||
{
|
||||
|
@@ -4,11 +4,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Exception\InvalidResourceException;
|
||||
|
||||
interface ImapResourceInterface
|
||||
{
|
||||
/**
|
||||
* Get IMAP resource stream.
|
||||
*
|
||||
* @throws InvalidResourceException
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getStream();
|
||||
|
@@ -18,20 +18,9 @@ use Ddeboer\Imap\Search\LogicalOperator\All;
|
||||
*/
|
||||
final class Mailbox implements MailboxInterface
|
||||
{
|
||||
/**
|
||||
* @var ImapResourceInterface
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var \stdClass
|
||||
*/
|
||||
private $info;
|
||||
private ImapResourceInterface $resource;
|
||||
private string $name;
|
||||
private \stdClass $info;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -47,17 +36,11 @@ final class Mailbox implements MailboxInterface
|
||||
$this->info = $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mailbox decoded name.
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mailbox encoded path.
|
||||
*/
|
||||
public function getEncodedName(): string
|
||||
{
|
||||
/** @var string $name */
|
||||
@@ -66,35 +49,21 @@ final class Mailbox implements MailboxInterface
|
||||
return (string) \preg_replace('/^{.+}/', '', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mailbox encoded full name.
|
||||
*/
|
||||
public function getFullEncodedName(): string
|
||||
{
|
||||
return $this->info->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mailbox attributes.
|
||||
*/
|
||||
public function getAttributes(): int
|
||||
{
|
||||
return $this->info->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mailbox delimiter.
|
||||
*/
|
||||
public function getDelimiter(): string
|
||||
{
|
||||
return $this->info->delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of messages in this mailbox.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$return = \imap_num_msg($this->resource->getStream());
|
||||
@@ -106,9 +75,6 @@ final class Mailbox implements MailboxInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mailbox status.
|
||||
*/
|
||||
public function getStatus(int $flags = null): \stdClass
|
||||
{
|
||||
$return = \imap_status($this->resource->getStream(), $this->getFullEncodedName(), $flags ?? \SA_ALL);
|
||||
@@ -120,33 +86,16 @@ final class Mailbox implements MailboxInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk Set Flag for Messages.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
*/
|
||||
public function setFlag(string $flag, $numbers): bool
|
||||
{
|
||||
return \imap_setflag_full($this->resource->getStream(), $this->prepareMessageIds($numbers), $flag, \ST_UID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk Clear Flag for Messages.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
*/
|
||||
public function clearFlag(string $flag, $numbers): bool
|
||||
{
|
||||
return \imap_clearflag_full($this->resource->getStream(), $this->prepareMessageIds($numbers), $flag, \ST_UID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message ids.
|
||||
*
|
||||
* @param ConditionInterface $search Search expression (optional)
|
||||
*/
|
||||
public function getMessages(ConditionInterface $search = null, int $sortCriteria = null, bool $descending = false, string $charset = null): MessageIteratorInterface
|
||||
{
|
||||
if (null === $search) {
|
||||
@@ -199,11 +148,6 @@ final class Mailbox implements MailboxInterface
|
||||
return new MessageIterator($this->resource, $messageNumbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message iterator for a sequence.
|
||||
*
|
||||
* @param string $sequence Message numbers
|
||||
*/
|
||||
public function getMessageSequence(string $sequence): MessageIteratorInterface
|
||||
{
|
||||
\imap_errors();
|
||||
@@ -223,27 +167,16 @@ final class Mailbox implements MailboxInterface
|
||||
return new MessageIterator($this->resource, $messageNumbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message by message number.
|
||||
*
|
||||
* @param int $number Message number
|
||||
*/
|
||||
public function getMessage(int $number): MessageInterface
|
||||
{
|
||||
return new Message($this->resource, $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get messages in this mailbox.
|
||||
*/
|
||||
public function getIterator(): MessageIteratorInterface
|
||||
{
|
||||
return $this->getMessages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to the mailbox.
|
||||
*/
|
||||
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool
|
||||
{
|
||||
$arguments = [
|
||||
@@ -261,16 +194,13 @@ final class Mailbox implements MailboxInterface
|
||||
return \imap_append(...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a tree of threaded message for the current Mailbox.
|
||||
*/
|
||||
public function getThread(): array
|
||||
{
|
||||
\set_error_handler(static function (): bool {
|
||||
return true;
|
||||
});
|
||||
|
||||
/** @var array|false $tree */
|
||||
/** @var array<string, int>|false $tree */
|
||||
$tree = \imap_thread($this->resource->getStream(), \SE_UID);
|
||||
|
||||
\restore_error_handler();
|
||||
@@ -278,29 +208,13 @@ final class Mailbox implements MailboxInterface
|
||||
return false !== $tree ? $tree : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk move messages.
|
||||
*
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
* @param MailboxInterface $mailbox Destination Mailbox to move the messages to
|
||||
*
|
||||
* @throws \Ddeboer\Imap\Exception\MessageMoveException
|
||||
*/
|
||||
public function move($numbers, MailboxInterface $mailbox): void
|
||||
{
|
||||
if (!\imap_mail_move($this->resource->getStream(), $this->prepareMessageIds($numbers), $mailbox->getEncodedName(), \CP_UID)) {
|
||||
if (!\imap_mail_copy($this->resource->getStream(), $this->prepareMessageIds($numbers), $mailbox->getEncodedName(), \CP_UID | \CP_MOVE)) {
|
||||
throw new MessageMoveException(\sprintf('Messages cannot be moved to "%s"', $mailbox->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk copy messages.
|
||||
*
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
* @param MailboxInterface $mailbox Destination Mailbox to copy the messages to
|
||||
*
|
||||
* @throws \Ddeboer\Imap\Exception\MessageCopyException
|
||||
*/
|
||||
public function copy($numbers, MailboxInterface $mailbox): void
|
||||
{
|
||||
if (!\imap_mail_copy($this->resource->getStream(), $this->prepareMessageIds($numbers), $mailbox->getEncodedName(), \CP_UID)) {
|
||||
@@ -311,7 +225,7 @@ final class Mailbox implements MailboxInterface
|
||||
/**
|
||||
* Prepare message ids for the use with bulk functions.
|
||||
*
|
||||
* @param array|MessageIterator|string $messageIds Message numbers
|
||||
* @param array<int, int|string>|MessageIterator|string $messageIds Message numbers
|
||||
*/
|
||||
private function prepareMessageIds($messageIds): string
|
||||
{
|
||||
|
@@ -5,10 +5,13 @@ declare(strict_types=1);
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Ddeboer\Imap\Message\PartInterface;
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* An IMAP mailbox (commonly referred to as a 'folder').
|
||||
*
|
||||
* @extends \IteratorAggregate<int, MessageInterface>
|
||||
*/
|
||||
interface MailboxInterface extends \Countable, \IteratorAggregate
|
||||
{
|
||||
@@ -45,16 +48,16 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Bulk Set Flag for Messages.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
* @param array<int, int|string>|MessageIterator|string $numbers Message numbers
|
||||
*/
|
||||
public function setFlag(string $flag, $numbers): bool;
|
||||
|
||||
/**
|
||||
* Bulk Clear Flag for Messages.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
* @param array<int, int|string>|MessageIterator|string $numbers Message numbers
|
||||
*/
|
||||
public function clearFlag(string $flag, $numbers): bool;
|
||||
|
||||
@@ -76,6 +79,8 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
|
||||
* Get a message by message number.
|
||||
*
|
||||
* @param int $number Message number
|
||||
*
|
||||
* @return MessageInterface<PartInterface>
|
||||
*/
|
||||
public function getMessage(int $number): MessageInterface;
|
||||
|
||||
@@ -91,14 +96,16 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns a tree of threaded message for the current Mailbox.
|
||||
*
|
||||
* @return array<string, int>
|
||||
*/
|
||||
public function getThread(): array;
|
||||
|
||||
/**
|
||||
* Bulk move messages.
|
||||
*
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
* @param MailboxInterface $mailbox Destination Mailbox to move the messages to
|
||||
* @param array<int, int|string>|MessageIterator|string $numbers Message numbers
|
||||
* @param MailboxInterface $mailbox Destination Mailbox to move the messages to
|
||||
*
|
||||
* @throws \Ddeboer\Imap\Exception\MessageMoveException
|
||||
*/
|
||||
@@ -107,8 +114,8 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Bulk copy messages.
|
||||
*
|
||||
* @param array|MessageIterator|string $numbers Message numbers
|
||||
* @param MailboxInterface $mailbox Destination Mailbox to copy the messages to
|
||||
* @param array<int, int|string>|MessageIterator|string $numbers Message numbers
|
||||
* @param MailboxInterface $mailbox Destination Mailbox to copy the messages to
|
||||
*
|
||||
* @throws \Ddeboer\Imap\Exception\MessageCopyException
|
||||
*/
|
||||
|
116
data/web/inc/lib/vendor/ddeboer/imap/src/Message.php
vendored
116
data/web/inc/lib/vendor/ddeboer/imap/src/Message.php
vendored
@@ -18,35 +18,12 @@ use Ddeboer\Imap\Exception\MessageUndeleteException;
|
||||
*/
|
||||
final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $messageNumberVerified = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $imapMsgNo = 0;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $structureLoaded = false;
|
||||
|
||||
/**
|
||||
* @var null|Message\Headers
|
||||
*/
|
||||
private $headers;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $rawHeaders;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $rawMessage;
|
||||
private bool $messageNumberVerified = false;
|
||||
private int $imapMsgNo = 0;
|
||||
private bool $structureLoaded = false;
|
||||
private ?Message\Headers $headers = null;
|
||||
private ?string $rawHeaders = null;
|
||||
private ?string $rawMessage = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -59,9 +36,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
parent::__construct($resource, $messageNumber, '1', new \stdClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load structure.
|
||||
*/
|
||||
protected function lazyLoadStructure(): void
|
||||
{
|
||||
if (true === $this->structureLoaded) {
|
||||
@@ -99,9 +73,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
$this->setStructure($structure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure message exists.
|
||||
*/
|
||||
protected function assertMessageExists(int $messageNumber): void
|
||||
{
|
||||
if (true === $this->messageNumberVerified) {
|
||||
@@ -138,9 +109,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
return $this->imapMsgNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw message headers.
|
||||
*/
|
||||
public function getRawHeaders(): string
|
||||
{
|
||||
if (null === $this->rawHeaders) {
|
||||
@@ -156,11 +124,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
return $this->rawHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw message, including all headers, parts, etc. unencoded and unparsed.
|
||||
*
|
||||
* @return string the raw message
|
||||
*/
|
||||
public function getRawMessage(): string
|
||||
{
|
||||
if (null === $this->rawMessage) {
|
||||
@@ -170,9 +133,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
return $this->rawMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message headers.
|
||||
*/
|
||||
public function getHeaders(): Message\Headers
|
||||
{
|
||||
if (null === $this->headers) {
|
||||
@@ -198,67 +158,44 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
$this->headers = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message recent flag value (from headers).
|
||||
*/
|
||||
public function isRecent(): ?string
|
||||
{
|
||||
return $this->getHeaders()->get('recent');
|
||||
$recent = $this->getHeaders()->get('recent');
|
||||
\assert(null === $recent || \is_string($recent));
|
||||
|
||||
return $recent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message unseen flag value (from headers).
|
||||
*/
|
||||
public function isUnseen(): bool
|
||||
{
|
||||
return 'U' === $this->getHeaders()->get('unseen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message flagged flag value (from headers).
|
||||
*/
|
||||
public function isFlagged(): bool
|
||||
{
|
||||
return 'F' === $this->getHeaders()->get('flagged');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message answered flag value (from headers).
|
||||
*/
|
||||
public function isAnswered(): bool
|
||||
{
|
||||
return 'A' === $this->getHeaders()->get('answered');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message deleted flag value (from headers).
|
||||
*/
|
||||
public function isDeleted(): bool
|
||||
{
|
||||
return 'D' === $this->getHeaders()->get('deleted');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message draft flag value (from headers).
|
||||
*/
|
||||
public function isDraft(): bool
|
||||
{
|
||||
return 'X' === $this->getHeaders()->get('draft');
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the message been marked as read?
|
||||
*/
|
||||
public function isSeen(): bool
|
||||
{
|
||||
return 'N' !== $this->getHeaders()->get('recent') && 'U' !== $this->getHeaders()->get('unseen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark message as seen.
|
||||
*
|
||||
* @deprecated since version 1.1, to be removed in 2.0
|
||||
*/
|
||||
public function maskAsSeen(): bool
|
||||
{
|
||||
\trigger_error(\sprintf('%s is deprecated and will be removed in 2.0. Use %s::markAsSeen instead.', __METHOD__, __CLASS__), \E_USER_DEPRECATED);
|
||||
@@ -266,19 +203,11 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
return $this->markAsSeen();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark message as seen.
|
||||
*/
|
||||
public function markAsSeen(): bool
|
||||
{
|
||||
return $this->setFlag('\\Seen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Move message to another mailbox.
|
||||
*
|
||||
* @throws MessageCopyException
|
||||
*/
|
||||
public function copy(MailboxInterface $mailbox): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to true on header
|
||||
@@ -289,11 +218,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move message to another mailbox.
|
||||
*
|
||||
* @throws MessageMoveException
|
||||
*/
|
||||
public function move(MailboxInterface $mailbox): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to true on header
|
||||
@@ -304,11 +228,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete message.
|
||||
*
|
||||
* @throws MessageDeleteException
|
||||
*/
|
||||
public function delete(): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to true on header
|
||||
@@ -319,11 +238,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Undelete message.
|
||||
*
|
||||
* @throws MessageUndeleteException
|
||||
*/
|
||||
public function undelete(): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to false on header
|
||||
@@ -333,11 +247,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Flag Message.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
*/
|
||||
public function setFlag(string $flag): bool
|
||||
{
|
||||
$result = \imap_setflag_full($this->resource->getStream(), (string) $this->getNumber(), $flag, \ST_UID);
|
||||
@@ -347,11 +256,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Flag Message.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
*/
|
||||
public function clearFlag(string $flag): bool
|
||||
{
|
||||
$result = \imap_clearflag_full($this->resource->getStream(), (string) $this->getNumber(), $flag, \ST_UID);
|
||||
|
@@ -9,9 +9,9 @@ use Ddeboer\Imap\Exception\InvalidDateHeaderException;
|
||||
abstract class AbstractMessage extends AbstractPart
|
||||
{
|
||||
/**
|
||||
* @var null|array
|
||||
* @var null|Attachment[]
|
||||
*/
|
||||
private $attachments;
|
||||
private ?array $attachments = null;
|
||||
|
||||
/**
|
||||
* Get message headers.
|
||||
@@ -25,7 +25,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getId(): ?string
|
||||
{
|
||||
return $this->getHeaders()->get('message_id');
|
||||
$messageId = $this->getHeaders()->get('message_id');
|
||||
\assert(null === $messageId || \is_string($messageId));
|
||||
|
||||
return $messageId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,6 +37,7 @@ abstract class AbstractMessage extends AbstractPart
|
||||
final public function getFrom(): ?EmailAddress
|
||||
{
|
||||
$from = $this->getHeaders()->get('from');
|
||||
\assert(null === $from || \is_array($from));
|
||||
|
||||
return null !== $from ? $this->decodeEmailAddress($from[0]) : null;
|
||||
}
|
||||
@@ -45,7 +49,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getTo(): array
|
||||
{
|
||||
return $this->decodeEmailAddresses($this->getHeaders()->get('to') ?: []);
|
||||
$emails = $this->getHeaders()->get('to');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +62,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getCc(): array
|
||||
{
|
||||
return $this->decodeEmailAddresses($this->getHeaders()->get('cc') ?: []);
|
||||
$emails = $this->getHeaders()->get('cc');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +75,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getBcc(): array
|
||||
{
|
||||
return $this->decodeEmailAddresses($this->getHeaders()->get('bcc') ?: []);
|
||||
$emails = $this->getHeaders()->get('bcc');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +88,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getReplyTo(): array
|
||||
{
|
||||
return $this->decodeEmailAddresses($this->getHeaders()->get('reply_to') ?: []);
|
||||
$emails = $this->getHeaders()->get('reply_to');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +101,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getSender(): array
|
||||
{
|
||||
return $this->decodeEmailAddresses($this->getHeaders()->get('sender') ?: []);
|
||||
$emails = $this->getHeaders()->get('sender');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +114,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getReturnPath(): array
|
||||
{
|
||||
return $this->decodeEmailAddresses($this->getHeaders()->get('return_path') ?: []);
|
||||
$emails = $this->getHeaders()->get('return_path');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +159,10 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getSize()
|
||||
{
|
||||
return $this->getHeaders()->get('size');
|
||||
$size = $this->getHeaders()->get('size');
|
||||
\assert(null === $size || \is_int($size) || \is_string($size));
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,25 +170,34 @@ abstract class AbstractMessage extends AbstractPart
|
||||
*/
|
||||
final public function getSubject(): ?string
|
||||
{
|
||||
return $this->getHeaders()->get('subject');
|
||||
$subject = $this->getHeaders()->get('subject');
|
||||
\assert(null === $subject || \is_string($subject));
|
||||
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message In-Reply-To (from headers).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
final public function getInReplyTo(): array
|
||||
{
|
||||
$inReplyTo = $this->getHeaders()->get('in_reply_to');
|
||||
\assert(null === $inReplyTo || \is_string($inReplyTo));
|
||||
|
||||
return null !== $inReplyTo ? \explode(' ', $inReplyTo) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message References (from headers).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
final public function getReferences(): array
|
||||
{
|
||||
$references = $this->getHeaders()->get('references');
|
||||
\assert(null === $references || \is_string($references));
|
||||
|
||||
return null !== $references ? \explode(' ', $references) : [];
|
||||
}
|
||||
@@ -222,6 +256,11 @@ abstract class AbstractMessage extends AbstractPart
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PartInterface<PartInterface> $part
|
||||
*
|
||||
* @return Attachment[]
|
||||
*/
|
||||
private static function gatherAttachments(PartInterface $part): array
|
||||
{
|
||||
$attachments = [];
|
||||
@@ -247,6 +286,8 @@ abstract class AbstractMessage extends AbstractPart
|
||||
|
||||
/**
|
||||
* @param \stdClass[] $addresses
|
||||
*
|
||||
* @return EmailAddress[]
|
||||
*/
|
||||
private function decodeEmailAddresses(array $addresses): array
|
||||
{
|
||||
|
@@ -14,95 +14,7 @@ use Ddeboer\Imap\Message;
|
||||
*/
|
||||
abstract class AbstractPart implements PartInterface
|
||||
{
|
||||
/**
|
||||
* @var ImapResourceInterface
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $structureParsed = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $parts = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $partNumber;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $messageNumber;
|
||||
|
||||
/**
|
||||
* @var \stdClass
|
||||
*/
|
||||
private $structure;
|
||||
|
||||
/**
|
||||
* @var Parameters
|
||||
*/
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $subtype;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $encoding;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $disposition;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $bytes;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $lines;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $decodedContent;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $key = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $typesMap = [
|
||||
private const TYPES_MAP = [
|
||||
\TYPETEXT => self::TYPE_TEXT,
|
||||
\TYPEMULTIPART => self::TYPE_MULTIPART,
|
||||
\TYPEMESSAGE => self::TYPE_MESSAGE,
|
||||
@@ -114,10 +26,7 @@ abstract class AbstractPart implements PartInterface
|
||||
\TYPEOTHER => self::TYPE_OTHER,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $encodingsMap = [
|
||||
private const ENCODINGS_MAP = [
|
||||
\ENC7BIT => self::ENCODING_7BIT,
|
||||
\ENC8BIT => self::ENCODING_8BIT,
|
||||
\ENCBINARY => self::ENCODING_BINARY,
|
||||
@@ -125,16 +34,35 @@ abstract class AbstractPart implements PartInterface
|
||||
\ENCQUOTEDPRINTABLE => self::ENCODING_QUOTED_PRINTABLE,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $attachmentKeys = [
|
||||
private const ATTACHMENT_KEYS = [
|
||||
'name' => true,
|
||||
'filename' => true,
|
||||
'name*' => true,
|
||||
'filename*' => true,
|
||||
];
|
||||
|
||||
protected ImapResourceInterface $resource;
|
||||
private bool $structureParsed = false;
|
||||
/**
|
||||
* @var AbstractPart[]
|
||||
*/
|
||||
private array $parts = [];
|
||||
private string $partNumber;
|
||||
private int $messageNumber;
|
||||
private \stdClass $structure;
|
||||
private Parameters $parameters;
|
||||
private ?string $type = null;
|
||||
private ?string $subtype = null;
|
||||
private ?string $encoding = null;
|
||||
private ?string $disposition = null;
|
||||
private ?string $description = null;
|
||||
/** @var null|int|string */
|
||||
private $bytes;
|
||||
private ?string $lines = null;
|
||||
private ?string $content = null;
|
||||
private ?string $decodedContent = null;
|
||||
private int $key = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -155,9 +83,6 @@ abstract class AbstractPart implements PartInterface
|
||||
$this->setStructure($structure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message number (from headers).
|
||||
*/
|
||||
final public function getNumber(): int
|
||||
{
|
||||
$this->assertMessageExists($this->messageNumber);
|
||||
@@ -180,9 +105,6 @@ abstract class AbstractPart implements PartInterface
|
||||
$this->structure = $structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part structure.
|
||||
*/
|
||||
final public function getStructure(): \stdClass
|
||||
{
|
||||
$this->lazyLoadStructure();
|
||||
@@ -197,9 +119,6 @@ abstract class AbstractPart implements PartInterface
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Part parameters.
|
||||
*/
|
||||
final public function getParameters(): Parameters
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -207,19 +126,16 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part charset.
|
||||
*/
|
||||
final public function getCharset(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->parameters->get('charset') ?: null;
|
||||
$charset = $this->parameters->get('charset');
|
||||
\assert(null === $charset || \is_string($charset));
|
||||
|
||||
return '' !== $charset ? $charset : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part type.
|
||||
*/
|
||||
final public function getType(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -227,9 +143,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part subtype.
|
||||
*/
|
||||
final public function getSubtype(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -237,9 +150,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->subtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part encoding.
|
||||
*/
|
||||
final public function getEncoding(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -247,9 +157,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part disposition.
|
||||
*/
|
||||
final public function getDisposition(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -257,9 +164,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->disposition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part description.
|
||||
*/
|
||||
final public function getDescription(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -267,11 +171,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part bytes.
|
||||
*
|
||||
* @return null|int|string
|
||||
*/
|
||||
final public function getBytes()
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -279,9 +178,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part lines.
|
||||
*/
|
||||
final public function getLines(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -289,9 +185,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw part content.
|
||||
*/
|
||||
final public function getContent(): string
|
||||
{
|
||||
if (null === $this->content) {
|
||||
@@ -309,17 +202,11 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->partNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get part number.
|
||||
*/
|
||||
final public function getPartNumber(): string
|
||||
{
|
||||
return $this->partNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decoded part content.
|
||||
*/
|
||||
final public function getDecodedContent(): string
|
||||
{
|
||||
if (null === $this->decodedContent) {
|
||||
@@ -369,11 +256,6 @@ abstract class AbstractPart implements PartInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all parts for this message.
|
||||
*
|
||||
* @return PartInterface[]
|
||||
*/
|
||||
final public function getParts(): array
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -393,21 +275,11 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->parts[$this->key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current child part.
|
||||
*
|
||||
* @return \RecursiveIterator
|
||||
*/
|
||||
final public function getChildren()
|
||||
{
|
||||
return $this->current();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current child part.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final public function hasChildren()
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -416,8 +288,6 @@ abstract class AbstractPart implements PartInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current part key.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
final public function key()
|
||||
@@ -425,31 +295,16 @@ abstract class AbstractPart implements PartInterface
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move to next part.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public function next()
|
||||
{
|
||||
++$this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset part key.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public function rewind()
|
||||
{
|
||||
$this->key = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current part is a valid one.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final public function valid()
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
@@ -469,10 +324,10 @@ abstract class AbstractPart implements PartInterface
|
||||
|
||||
$this->lazyLoadStructure();
|
||||
|
||||
$this->type = self::$typesMap[$this->structure->type] ?? self::TYPE_UNKNOWN;
|
||||
$this->type = self::TYPES_MAP[$this->structure->type] ?? self::TYPE_UNKNOWN;
|
||||
|
||||
// In our context, \ENCOTHER is as useful as an unknown encoding
|
||||
$this->encoding = self::$encodingsMap[$this->structure->encoding] ?? self::ENCODING_UNKNOWN;
|
||||
$this->encoding = self::ENCODINGS_MAP[$this->structure->encoding] ?? self::ENCODING_UNKNOWN;
|
||||
if (isset($this->structure->subtype)) {
|
||||
$this->subtype = $this->structure->subtype;
|
||||
}
|
||||
@@ -527,7 +382,7 @@ abstract class AbstractPart implements PartInterface
|
||||
*/
|
||||
private static function isAttachment(\stdClass $part): bool
|
||||
{
|
||||
if (isset(self::$typesMap[$part->type]) && self::TYPE_MULTIPART === self::$typesMap[$part->type]) {
|
||||
if (isset(self::TYPES_MAP[$part->type]) && self::TYPE_MULTIPART === self::TYPES_MAP[$part->type]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -549,7 +404,7 @@ abstract class AbstractPart implements PartInterface
|
||||
// Attachment without Content-Disposition header
|
||||
if ($part->ifparameters) {
|
||||
foreach ($part->parameters as $parameter) {
|
||||
if (isset(self::$attachmentKeys[\strtolower($parameter->attribute)])) {
|
||||
if (isset(self::ATTACHMENT_KEYS[\strtolower($parameter->attribute)])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -11,43 +11,33 @@ use Ddeboer\Imap\Exception\NotEmbeddedMessageException;
|
||||
*/
|
||||
final class Attachment extends AbstractPart implements AttachmentInterface
|
||||
{
|
||||
/**
|
||||
* Get attachment filename.
|
||||
*/
|
||||
public function getFilename(): ?string
|
||||
{
|
||||
return $this->getParameters()->get('filename')
|
||||
?: $this->getParameters()->get('name');
|
||||
$filename = $this->getParameters()->get('filename');
|
||||
if (null === $filename || '' === $filename) {
|
||||
$filename = $this->getParameters()->get('name');
|
||||
}
|
||||
\assert(null === $filename || \is_string($filename));
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachment file size.
|
||||
*
|
||||
* @return null|int Number of bytes
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
$size = $this->getParameters()->get('size');
|
||||
if (\is_numeric($size)) {
|
||||
$size = (int) $size;
|
||||
}
|
||||
\assert(null === $size || \is_int($size));
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this attachment also an Embedded Message?
|
||||
*/
|
||||
public function isEmbeddedMessage(): bool
|
||||
{
|
||||
return self::TYPE_MESSAGE === $this->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return embedded message.
|
||||
*
|
||||
* @throws NotEmbeddedMessageException
|
||||
*/
|
||||
public function getEmbeddedMessage(): EmbeddedMessageInterface
|
||||
{
|
||||
if (!$this->isEmbeddedMessage()) {
|
||||
|
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
use Ddeboer\Imap\Exception\NotEmbeddedMessageException;
|
||||
|
||||
/**
|
||||
* An e-mail attachment.
|
||||
*/
|
||||
@@ -28,6 +30,10 @@ interface AttachmentInterface extends PartInterface
|
||||
|
||||
/**
|
||||
* Return embedded message.
|
||||
*
|
||||
* @throws NotEmbeddedMessageException
|
||||
*
|
||||
* @return EmbeddedMessageInterface<PartInterface>
|
||||
*/
|
||||
public function getEmbeddedMessage(): EmbeddedMessageInterface;
|
||||
}
|
||||
|
@@ -96,11 +96,15 @@ interface BasicMessageInterface extends PartInterface
|
||||
|
||||
/**
|
||||
* Get message In-Reply-To (from headers).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getInReplyTo(): array;
|
||||
|
||||
/**
|
||||
* Get message References (from headers).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getReferences(): array;
|
||||
|
||||
|
@@ -9,25 +9,10 @@ namespace Ddeboer\Imap\Message;
|
||||
*/
|
||||
final class EmailAddress
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mailbox;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $hostname;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $address;
|
||||
private string $mailbox;
|
||||
private ?string $hostname;
|
||||
private ?string $name;
|
||||
private ?string $address;
|
||||
|
||||
public function __construct(string $mailbox, string $hostname = null, string $name = null)
|
||||
{
|
||||
|
@@ -6,24 +6,10 @@ namespace Ddeboer\Imap\Message;
|
||||
|
||||
final class EmbeddedMessage extends AbstractMessage implements EmbeddedMessageInterface
|
||||
{
|
||||
/**
|
||||
* @var null|Headers
|
||||
*/
|
||||
private $headers;
|
||||
private ?Headers $headers = null;
|
||||
private ?string $rawHeaders = null;
|
||||
private ?string $rawMessage = null;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $rawHeaders;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $rawMessage;
|
||||
|
||||
/**
|
||||
* Get message headers.
|
||||
*/
|
||||
public function getHeaders(): Headers
|
||||
{
|
||||
if (null === $this->headers) {
|
||||
@@ -33,9 +19,6 @@ final class EmbeddedMessage extends AbstractMessage implements EmbeddedMessageIn
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw message headers.
|
||||
*/
|
||||
public function getRawHeaders(): string
|
||||
{
|
||||
if (null === $this->rawHeaders) {
|
||||
@@ -46,11 +29,6 @@ final class EmbeddedMessage extends AbstractMessage implements EmbeddedMessageIn
|
||||
return $this->rawHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw message, including all headers, parts, etc. unencoded and unparsed.
|
||||
*
|
||||
* @return string the raw message
|
||||
*/
|
||||
public function getRawMessage(): string
|
||||
{
|
||||
if (null === $this->rawMessage) {
|
||||
|
@@ -4,14 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
/**
|
||||
* Collection of message headers.
|
||||
*/
|
||||
final class Headers extends Parameters
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(\stdClass $headers)
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -27,7 +21,7 @@ final class Headers extends Parameters
|
||||
/**
|
||||
* Get header.
|
||||
*
|
||||
* @return mixed
|
||||
* @return null|int|\stdClass[]|string
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
@@ -37,14 +31,16 @@ final class Headers extends Parameters
|
||||
/**
|
||||
* Parse header.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param int|\stdClass[]|string $value
|
||||
*
|
||||
* @return mixed
|
||||
* @return int|\stdClass[]|string
|
||||
*/
|
||||
private function parseHeader(string $key, $value)
|
||||
{
|
||||
switch ($key) {
|
||||
case 'msgno':
|
||||
\assert(\is_string($value));
|
||||
|
||||
return (int) $value;
|
||||
case 'from':
|
||||
case 'to':
|
||||
@@ -53,6 +49,7 @@ final class Headers extends Parameters
|
||||
case 'reply_to':
|
||||
case 'sender':
|
||||
case 'return_path':
|
||||
\assert(\is_array($value));
|
||||
/** @var \stdClass $address */
|
||||
foreach ($value as $address) {
|
||||
if (isset($address->mailbox)) {
|
||||
@@ -64,6 +61,8 @@ final class Headers extends Parameters
|
||||
return $value;
|
||||
case 'date':
|
||||
case 'subject':
|
||||
\assert(\is_string($value));
|
||||
|
||||
return $this->decode($value);
|
||||
}
|
||||
|
||||
|
@@ -4,23 +4,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
/**
|
||||
* @extends \ArrayIterator<int|string, int|string|\stdClass[]>
|
||||
*/
|
||||
class Parameters extends \ArrayIterator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private static $attachmentCustomKeys = [
|
||||
private static array $attachmentCustomKeys = [
|
||||
'name*' => 'name',
|
||||
'filename*' => 'filename',
|
||||
];
|
||||
|
||||
public function __construct(array $parameters = [])
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->add($parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass[] $parameters
|
||||
*/
|
||||
public function add(array $parameters = []): void
|
||||
{
|
||||
foreach ($parameters as $parameter) {
|
||||
@@ -34,16 +33,13 @@ class Parameters extends \ArrayIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return null|int|\stdClass[]|string
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return $this[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode value.
|
||||
*/
|
||||
final protected function decode(string $value): string
|
||||
{
|
||||
$parts = \imap_mime_header_decode($value);
|
||||
|
@@ -9,14 +9,12 @@ use Ddeboer\Imap\Exception\UnsupportedCharsetException;
|
||||
final class Transcoder
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @see https://encoding.spec.whatwg.org/#encodings
|
||||
* @see https://dxr.mozilla.org/mozilla-central/source/dom/encoding/labelsencodings.properties
|
||||
* @see https://dxr.mozilla.org/mozilla1.9.1/source/intl/uconv/src/charsetalias.properties
|
||||
* @see https://msdn.microsoft.com/en-us/library/cc194829.aspx
|
||||
*/
|
||||
private static $charsetAliases = [
|
||||
private const CHARSET_ALIASES = [
|
||||
'128' => 'Shift_JIS',
|
||||
'129' => 'EUC-KR',
|
||||
'134' => 'GB2312',
|
||||
@@ -252,6 +250,7 @@ final class Transcoder
|
||||
'x-iso-10646-ucs-2-le' => 'UTF-16LE',
|
||||
'x-iso-10646-ucs-4-be' => 'UTF-32BE',
|
||||
'x-iso-10646-ucs-4-le' => 'UTF-32LE',
|
||||
'x-mac-ce' => 'windows-1250',
|
||||
'x-sjis' => 'Shift_JIS',
|
||||
'x-unicode-2-0-utf-7' => 'UTF-7',
|
||||
'x-x-big5' => 'Big5',
|
||||
@@ -282,8 +281,8 @@ final class Transcoder
|
||||
|
||||
$originalFromCharset = $fromCharset;
|
||||
$lowercaseFromCharset = \strtolower($fromCharset);
|
||||
if (isset(self::$charsetAliases[$lowercaseFromCharset])) {
|
||||
$fromCharset = self::$charsetAliases[$lowercaseFromCharset];
|
||||
if (isset(self::CHARSET_ALIASES[$lowercaseFromCharset])) {
|
||||
$fromCharset = self::CHARSET_ALIASES[$lowercaseFromCharset];
|
||||
}
|
||||
|
||||
\set_error_handler(static function (): bool {
|
||||
|
@@ -4,6 +4,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Exception\MessageCopyException;
|
||||
use Ddeboer\Imap\Exception\MessageDeleteException;
|
||||
use Ddeboer\Imap\Exception\MessageMoveException;
|
||||
use Ddeboer\Imap\Exception\MessageUndeleteException;
|
||||
|
||||
/**
|
||||
* An IMAP message (e-mail).
|
||||
*/
|
||||
@@ -63,21 +68,29 @@ interface MessageInterface extends Message\BasicMessageInterface
|
||||
|
||||
/**
|
||||
* Move message to another mailbox.
|
||||
*
|
||||
* @throws MessageCopyException
|
||||
*/
|
||||
public function copy(MailboxInterface $mailbox): void;
|
||||
|
||||
/**
|
||||
* Move message to another mailbox.
|
||||
*
|
||||
* @throws MessageMoveException
|
||||
*/
|
||||
public function move(MailboxInterface $mailbox): void;
|
||||
|
||||
/**
|
||||
* Delete message.
|
||||
*
|
||||
* @throws MessageDeleteException
|
||||
*/
|
||||
public function delete(): void;
|
||||
|
||||
/**
|
||||
* Undelete message.
|
||||
*
|
||||
* @throws MessageUndeleteException
|
||||
*/
|
||||
public function undelete(): void;
|
||||
|
||||
|
@@ -4,18 +4,20 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Message\PartInterface;
|
||||
|
||||
/**
|
||||
* @extends \ArrayIterator<int, MessageInterface>
|
||||
*/
|
||||
final class MessageIterator extends \ArrayIterator implements MessageIteratorInterface
|
||||
{
|
||||
/**
|
||||
* @var ImapResourceInterface
|
||||
*/
|
||||
private $resource;
|
||||
private ImapResourceInterface $resource;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ImapResourceInterface $resource IMAP resource
|
||||
* @param array $messageNumbers Array of message numbers
|
||||
* @param int[] $messageNumbers Array of message numbers
|
||||
*/
|
||||
public function __construct(ImapResourceInterface $resource, array $messageNumbers)
|
||||
{
|
||||
@@ -26,6 +28,8 @@ final class MessageIterator extends \ArrayIterator implements MessageIteratorInt
|
||||
|
||||
/**
|
||||
* Get current message.
|
||||
*
|
||||
* @return MessageInterface<PartInterface>
|
||||
*/
|
||||
public function current(): MessageInterface
|
||||
{
|
||||
|
@@ -4,10 +4,17 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Message\PartInterface;
|
||||
|
||||
/**
|
||||
* @extends \Iterator<MessageInterface>
|
||||
*/
|
||||
interface MessageIteratorInterface extends \Iterator
|
||||
{
|
||||
/**
|
||||
* Get current message.
|
||||
*
|
||||
* @return MessageInterface<PartInterface>
|
||||
*/
|
||||
public function current(): MessageInterface;
|
||||
}
|
||||
|
@@ -13,17 +13,13 @@ abstract class AbstractDate implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Format for dates to be sent to the IMAP server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $dateFormat;
|
||||
private string $dateFormat;
|
||||
|
||||
/**
|
||||
* The date to be used for the condition.
|
||||
*
|
||||
* @var DateTimeInterface
|
||||
*/
|
||||
private $date;
|
||||
private DateTimeInterface $date;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@@ -12,10 +12,8 @@ abstract class AbstractText implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Text to be used for the condition.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $text;
|
||||
private string $text;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@@ -15,10 +15,13 @@ final class OrConditions implements ConditionInterface
|
||||
/**
|
||||
* The conditions that together represent the expression.
|
||||
*
|
||||
* @var array
|
||||
* @var ConditionInterface[]
|
||||
*/
|
||||
private $conditions = [];
|
||||
private array $conditions = [];
|
||||
|
||||
/**
|
||||
* @param ConditionInterface[] $conditions
|
||||
*/
|
||||
public function __construct(array $conditions)
|
||||
{
|
||||
foreach ($conditions as $condition) {
|
||||
@@ -30,6 +33,8 @@ final class OrConditions implements ConditionInterface
|
||||
* Adds a new condition to the expression.
|
||||
*
|
||||
* @param ConditionInterface $condition the condition to be added
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addCondition(ConditionInterface $condition)
|
||||
{
|
||||
|
@@ -11,10 +11,8 @@ final class RawExpression implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Text to be used for the condition.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $expression;
|
||||
private string $expression;
|
||||
|
||||
/**
|
||||
* @param string $expression text for the condition
|
||||
|
@@ -14,9 +14,9 @@ final class SearchExpression implements ConditionInterface
|
||||
/**
|
||||
* The conditions that together represent the expression.
|
||||
*
|
||||
* @var array
|
||||
* @var ConditionInterface[]
|
||||
*/
|
||||
private $conditions = [];
|
||||
private array $conditions = [];
|
||||
|
||||
/**
|
||||
* Adds a new condition to the expression.
|
||||
|
@@ -12,46 +12,26 @@ use Ddeboer\Imap\Exception\ResourceCheckFailureException;
|
||||
*/
|
||||
final class Server implements ServerInterface
|
||||
{
|
||||
private string $hostname;
|
||||
private string $port;
|
||||
private string $flags;
|
||||
/**
|
||||
* @var string Internet domain name or bracketed IP address of server
|
||||
* @var mixed[]
|
||||
*/
|
||||
private $hostname;
|
||||
|
||||
/**
|
||||
* @var string TCP port number
|
||||
*/
|
||||
private $port;
|
||||
|
||||
/**
|
||||
* @var string Optional flags
|
||||
*/
|
||||
private $flags;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* @var int Connection options
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @var int Retries number
|
||||
*/
|
||||
private $retries;
|
||||
private array $parameters;
|
||||
private int $options;
|
||||
private int $retries;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $hostname Internet domain name or bracketed IP address
|
||||
* of server
|
||||
* @param string $port TCP port number
|
||||
* @param string $flags Optional flags
|
||||
* @param array $parameters Connection parameters
|
||||
* @param int $options Connection options
|
||||
* @param int $retries Retries number
|
||||
* @param string $hostname Internet domain name or bracketed IP address
|
||||
* of server
|
||||
* @param string $port TCP port number
|
||||
* @param string $flags Optional flags
|
||||
* @param mixed[] $parameters Connection parameters
|
||||
* @param int $options Connection options
|
||||
* @param int $retries Retries number
|
||||
*/
|
||||
public function __construct(
|
||||
string $hostname,
|
||||
|
@@ -4,14 +4,20 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Test;
|
||||
|
||||
use Ddeboer\Imap\Message\PartInterface;
|
||||
use Ddeboer\Imap\MessageInterface;
|
||||
use Ddeboer\Imap\MessageIteratorInterface;
|
||||
|
||||
/**
|
||||
* A MessageIterator to be used in a mocked environment.
|
||||
*
|
||||
* @extends \ArrayIterator<int, MessageInterface>
|
||||
*/
|
||||
final class RawMessageIterator extends \ArrayIterator implements MessageIteratorInterface
|
||||
{
|
||||
/**
|
||||
* @return MessageInterface<PartInterface>
|
||||
*/
|
||||
public function current(): MessageInterface
|
||||
{
|
||||
return parent::current();
|
||||
|
Reference in New Issue
Block a user