first
This commit is contained in:
commit
5aa7d034f7
3292 changed files with 465160 additions and 0 deletions
73
data/web/inc/lib/vendor/ddeboer/imap/.php-cs-fixer.php
vendored
Executable file
73
data/web/inc/lib/vendor/ddeboer/imap/.php-cs-fixer.php
vendored
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@DoctrineAnnotation' => true,
|
||||
'@Symfony' => true,
|
||||
'@Symfony:risky' => true,
|
||||
'@PHPUnit75Migration:risky' => true,
|
||||
'@PHP71Migration' => true,
|
||||
'@PHP70Migration:risky' => true, // @TODO with next major version
|
||||
'align_multiline_comment' => ['comment_type' => 'all_multiline'],
|
||||
'array_indentation' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'binary_operator_spaces' => ['default' => 'align_single_space'],
|
||||
'blank_line_before_statement' => true,
|
||||
'class_definition' => ['single_item_single_line' => true],
|
||||
'compact_nullable_typehint' => true,
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'echo_tag_syntax' => ['format' => 'long'],
|
||||
'error_suppression' => false,
|
||||
'escape_implicit_backslashes' => true,
|
||||
'explicit_indirect_variable' => true,
|
||||
'explicit_string_variable' => true,
|
||||
'fully_qualified_strict_types' => true,
|
||||
'heredoc_to_nowdoc' => true,
|
||||
'list_syntax' => ['syntax' => 'long'],
|
||||
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'],
|
||||
'method_chaining_indentation' => true,
|
||||
'multiline_comment_opening_closing' => true,
|
||||
'multiline_whitespace_before_semicolons' => ['strategy' => 'new_line_for_chained_calls'],
|
||||
'native_constant_invocation' => true,
|
||||
'native_function_invocation' => ['include' => ['@internal']],
|
||||
'no_alternative_syntax' => true,
|
||||
'no_break_comment' => true,
|
||||
'no_extra_blank_lines' => ['tokens' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']],
|
||||
'no_null_property_initialization' => true,
|
||||
'no_php4_constructor' => true,
|
||||
'no_superfluous_elseif' => true,
|
||||
'no_unneeded_curly_braces' => true,
|
||||
'no_unneeded_final_method' => true,
|
||||
'no_unreachable_default_argument_value' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_useless_return' => true,
|
||||
'ordered_imports' => true,
|
||||
'php_unit_method_casing' => true,
|
||||
'php_unit_set_up_tear_down_visibility' => true,
|
||||
'php_unit_strict' => true,
|
||||
'php_unit_test_annotation' => true,
|
||||
'php_unit_test_case_static_method_calls' => true,
|
||||
'php_unit_test_class_requires_covers' => false,
|
||||
'phpdoc_add_missing_param_annotation' => true,
|
||||
'phpdoc_order' => true,
|
||||
'phpdoc_order_by_value' => true,
|
||||
'phpdoc_types_order' => true,
|
||||
'random_api_migration' => true,
|
||||
'semicolon_after_instruction' => true,
|
||||
'simplified_null_return' => true,
|
||||
'single_line_comment_style' => true,
|
||||
'single_line_throw' => false,
|
||||
'space_after_semicolon' => true,
|
||||
'static_lambda' => true,
|
||||
'strict_comparison' => true,
|
||||
'string_line_ending' => true,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__ . '/src')
|
||||
->in(__DIR__ . '/tests')
|
||||
)
|
||||
;
|
||||
19
data/web/inc/lib/vendor/ddeboer/imap/LICENSE
vendored
Executable file
19
data/web/inc/lib/vendor/ddeboer/imap/LICENSE
vendored
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (C) 2013 David de Boer <david@ddeboer.nl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
307
data/web/inc/lib/vendor/ddeboer/imap/README.md
vendored
Executable file
307
data/web/inc/lib/vendor/ddeboer/imap/README.md
vendored
Executable file
|
|
@ -0,0 +1,307 @@
|
|||
# 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 IMAP library to read and process e-mails over IMAP protocol, built with robust Object-Oriented architecture.
|
||||
|
||||
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
|
||||
|
||||
The recommended way to install the IMAP library is through [Composer](https://getcomposer.org):
|
||||
|
||||
```bash
|
||||
$ composer require ddeboer/imap
|
||||
```
|
||||
|
||||
This command requires you to have Composer installed globally, as explained
|
||||
in the [installation chapter](https://getcomposer.org/doc/00-intro.md)
|
||||
of the Composer documentation.
|
||||
|
||||
## Usage
|
||||
|
||||
### Connect and Authenticate
|
||||
|
||||
```php
|
||||
use Ddeboer\Imap\Server;
|
||||
|
||||
$server = new Server('imap.gmail.com');
|
||||
|
||||
// $connection is instance of \Ddeboer\Imap\Connection
|
||||
$connection = $server->authenticate('my_username', 'my_password');
|
||||
```
|
||||
|
||||
You can specify port, [flags and parameters](https://secure.php.net/manual/en/function.imap-open.php)
|
||||
to the server:
|
||||
|
||||
```php
|
||||
$server = new Server(
|
||||
$hostname, // required
|
||||
$port, // defaults to '993'
|
||||
$flags, // defaults to '/imap/ssl/validate-cert'
|
||||
$parameters
|
||||
);
|
||||
```
|
||||
|
||||
### Mailboxes
|
||||
|
||||
Retrieve mailboxes (also known as mail folders) from the mail server and iterate
|
||||
over them:
|
||||
|
||||
```php
|
||||
$mailboxes = $connection->getMailboxes();
|
||||
|
||||
foreach ($mailboxes as $mailbox) {
|
||||
// Skip container-only mailboxes
|
||||
// @see https://secure.php.net/manual/en/function.imap-getmailboxes.php
|
||||
if ($mailbox->getAttributes() & \LATT_NOSELECT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// $mailbox is instance of \Ddeboer\Imap\Mailbox
|
||||
printf('Mailbox "%s" has %s messages', $mailbox->getName(), $mailbox->count());
|
||||
}
|
||||
```
|
||||
|
||||
Or retrieve a specific mailbox:
|
||||
|
||||
```php
|
||||
$mailbox = $connection->getMailbox('INBOX');
|
||||
```
|
||||
|
||||
Delete a mailbox:
|
||||
|
||||
```php
|
||||
$connection->deleteMailbox($mailbox);
|
||||
```
|
||||
|
||||
You can bulk set, or clear, any [flag](https://secure.php.net/manual/en/function.imap-setflag-full.php) of mailbox messages (by UIDs):
|
||||
|
||||
```php
|
||||
$mailbox->setFlag('\\Seen \\Flagged', ['1:5', '7', '9']);
|
||||
$mailbox->setFlag('\\Seen', '1,3,5,6:8');
|
||||
|
||||
$mailbox->clearFlag('\\Flagged', '1,3');
|
||||
```
|
||||
|
||||
**WARNING** You must retrieve new Message instances in case of bulk modify flags to refresh the single Messages flags.
|
||||
|
||||
### Messages
|
||||
|
||||
Retrieve messages (e-mails) from a mailbox and iterate over them:
|
||||
|
||||
```php
|
||||
$messages = $mailbox->getMessages();
|
||||
|
||||
foreach ($messages as $message) {
|
||||
// $message is instance of \Ddeboer\Imap\Message
|
||||
}
|
||||
```
|
||||
|
||||
To insert a new message (that just has been sent) into the Sent mailbox and flag it as seen:
|
||||
|
||||
```php
|
||||
$mailbox = $connection->getMailbox('Sent');
|
||||
$mailbox->addMessage($messageMIME, '\\Seen');
|
||||
```
|
||||
|
||||
Note that the message should be a string at MIME format (as described in the [RFC2045](https://tools.ietf.org/html/rfc2045)).
|
||||
|
||||
#### Searching for Messages
|
||||
|
||||
```php
|
||||
use Ddeboer\Imap\SearchExpression;
|
||||
use Ddeboer\Imap\Search\Email\To;
|
||||
use Ddeboer\Imap\Search\Text\Body;
|
||||
|
||||
$search = new SearchExpression();
|
||||
$search->addCondition(new To('me@here.com'));
|
||||
$search->addCondition(new Body('contents'));
|
||||
|
||||
$messages = $mailbox->getMessages($search);
|
||||
```
|
||||
|
||||
**WARNING** We are currently unable to have both spaces _and_ double-quotes
|
||||
escaped together. Only spaces are currently escaped correctly.
|
||||
You can use `Ddeboer\Imap\Search\RawExpression` to write the complete search
|
||||
condition by yourself.
|
||||
|
||||
Messages can also be retrieved sorted as per [imap_sort](https://secure.php.net/manual/en/function.imap-sort.php)
|
||||
function:
|
||||
|
||||
```php
|
||||
$today = new DateTimeImmutable();
|
||||
$thirtyDaysAgo = $today->sub(new DateInterval('P30D'));
|
||||
|
||||
$messages = $mailbox->getMessages(
|
||||
new Ddeboer\Imap\Search\Date\Since($thirtyDaysAgo),
|
||||
\SORTDATE, // Sort criteria
|
||||
true // Descending order
|
||||
);
|
||||
```
|
||||
|
||||
#### Unknown search criterion: OR
|
||||
|
||||
Note that PHP imap library relies on the `c-client` library available at https://www.washington.edu/imap/
|
||||
which doesn't fully support some IMAP4 search criteria like `OR`. If you want those unsupported criteria,
|
||||
you need to manually patch the latest version (`imap-2007f` of 23-Jul-2011 at the time of this commit)
|
||||
and recompile PHP onto your patched `c-client` library.
|
||||
|
||||
By the way most of the common search criteria are available and functioning, browse them in `./src/Search`.
|
||||
|
||||
References:
|
||||
|
||||
1. https://stackoverflow.com/questions/36356715/imap-search-unknown-search-criterion-or
|
||||
1. imap-2007f.tar.gz: `./src/c-client/mail.c` and `./docs/internal.txt`
|
||||
|
||||
#### Message Properties and Operations
|
||||
|
||||
Get message number and unique [message id](https://en.wikipedia.org/wiki/Message-ID)
|
||||
in the form <...>:
|
||||
|
||||
```php
|
||||
$message->getNumber();
|
||||
$message->getId();
|
||||
```
|
||||
|
||||
Get other message properties:
|
||||
|
||||
```php
|
||||
$message->getSubject();
|
||||
$message->getFrom(); // Message\EmailAddress
|
||||
$message->getTo(); // array of Message\EmailAddress
|
||||
$message->getDate(); // DateTimeImmutable
|
||||
$message->isAnswered();
|
||||
$message->isDeleted();
|
||||
$message->isDraft();
|
||||
$message->isSeen();
|
||||
```
|
||||
|
||||
Get message headers as a [\Ddeboer\Imap\Message\Headers](/src/Ddeboer/Imap/Message/Headers.php) object:
|
||||
|
||||
```php
|
||||
$message->getHeaders();
|
||||
```
|
||||
|
||||
Get message body as HTML or plain text:
|
||||
|
||||
```php
|
||||
$message->getBodyHtml(); // Content of text/html part, if present
|
||||
$message->getBodyText(); // Content of text/plain part, if present
|
||||
```
|
||||
|
||||
Reading the message body keeps the message as unseen.
|
||||
If you want to mark the message as seen:
|
||||
|
||||
```php
|
||||
$message->markAsSeen();
|
||||
```
|
||||
|
||||
Or you can set, or clear, any [flag](https://secure.php.net/manual/en/function.imap-setflag-full.php):
|
||||
|
||||
```php
|
||||
$message->setFlag('\\Seen \\Flagged');
|
||||
$message->clearFlag('\\Flagged');
|
||||
```
|
||||
|
||||
Move a message to another mailbox:
|
||||
|
||||
```php
|
||||
$mailbox = $connection->getMailbox('another-mailbox');
|
||||
$message->move($mailbox);
|
||||
```
|
||||
|
||||
Deleting messages:
|
||||
|
||||
```php
|
||||
$mailbox->getMessage(1)->delete();
|
||||
$mailbox->getMessage(2)->delete();
|
||||
$connection->expunge();
|
||||
```
|
||||
|
||||
### Message Attachments
|
||||
|
||||
Get message attachments (both inline and attached) and iterate over them:
|
||||
|
||||
```php
|
||||
$attachments = $message->getAttachments();
|
||||
|
||||
foreach ($attachments as $attachment) {
|
||||
// $attachment is instance of \Ddeboer\Imap\Message\Attachment
|
||||
}
|
||||
```
|
||||
|
||||
Download a message attachment to a local file:
|
||||
|
||||
```php
|
||||
// getDecodedContent() decodes the attachment’s contents automatically:
|
||||
file_put_contents(
|
||||
'/my/local/dir/' . $attachment->getFilename(),
|
||||
$attachment->getDecodedContent()
|
||||
);
|
||||
```
|
||||
|
||||
### Embedded Messages
|
||||
|
||||
Check if attachment is embedded message and get it:
|
||||
|
||||
```php
|
||||
$attachments = $message->getAttachments();
|
||||
|
||||
foreach ($attachments as $attachment) {
|
||||
if ($attachment->isEmbeddedMessage()) {
|
||||
$embeddedMessage = $attachment->getEmbeddedMessage();
|
||||
// $embeddedMessage is instance of \Ddeboer\Imap\Message\EmbeddedMessage
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
An EmbeddedMessage has the same API as a normal Message, apart from flags
|
||||
and operations like copy, move or delete.
|
||||
|
||||
### Timeouts
|
||||
|
||||
The IMAP extension provides the [imap_timeout](https://secure.php.net/manual/en/function.imap-timeout.php)
|
||||
function to adjust the timeout seconds for various operations.
|
||||
|
||||
However the extension's implementation doesn't link the functionality to a
|
||||
specific context or connection, instead they are global. So in order to not
|
||||
affect functionalities outside this library, we had to choose whether wrap
|
||||
every `imap_*` call around an optional user-provided timeout or leave this
|
||||
task to the user.
|
||||
|
||||
Because of the heterogeneous world of IMAP servers and the high complexity
|
||||
burden cost for such a little gain of the former, we chose the latter.
|
||||
|
||||
## Mock the library
|
||||
|
||||
Mockability is granted by interfaces present for each API.
|
||||
Dig into [MockabilityTest](tests/MockabilityTest.php) for an example of a
|
||||
mocked workflow.
|
||||
|
||||
## Running the Tests
|
||||
|
||||
This library is functionally tested on [Travis CI](https://travis-ci.org/ddeboer/imap)
|
||||
against a local Dovecot server.
|
||||
|
||||
If you have your own IMAP (test) account, you can run the tests locally by
|
||||
providing your IMAP credentials:
|
||||
|
||||
```bash
|
||||
$ composer install
|
||||
$ IMAP_SERVER_NAME="my.imap.server.com" IMAP_SERVER_PORT="60993" IMAP_USERNAME="johndoe" IMAP_PASSWORD="p4ssword" vendor/bin/phpunit
|
||||
```
|
||||
|
||||
You can also copy `phpunit.xml.dist` file to a custom `phpunit.xml` and put
|
||||
these environment variables in it.
|
||||
|
||||
**WARNING** Tests create new mailboxes without removing them.
|
||||
|
||||
```
|
||||
$ docker-compose run tests
|
||||
```
|
||||
54
data/web/inc/lib/vendor/ddeboer/imap/composer.json
vendored
Executable file
54
data/web/inc/lib/vendor/ddeboer/imap/composer.json
vendored
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"name": "ddeboer/imap",
|
||||
"description": "Object-oriented IMAP for PHP",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"email",
|
||||
"mail",
|
||||
"imap"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "David de Boer",
|
||||
"email": "david@ddeboer.nl"
|
||||
},
|
||||
{
|
||||
"name": "Filippo Tessarotto",
|
||||
"email": "zoeslam@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Community contributors",
|
||||
"homepage": "https://github.com/ddeboer/imap/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.1",
|
||||
"ext-iconv": "*",
|
||||
"ext-imap": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^v3.4.0",
|
||||
"laminas/laminas-mail": "^2.15.1",
|
||||
"malukenho/mcbumpface": "^1.1.5",
|
||||
"phpstan/phpstan": "^1.3.3",
|
||||
"phpstan/phpstan-phpunit": "^1.0.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.1.0",
|
||||
"phpunit/phpunit": "^9.5.11"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Ddeboer\\Imap\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Ddeboer\\Imap\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"malukenho/mcbumpface": true
|
||||
}
|
||||
}
|
||||
}
|
||||
178
data/web/inc/lib/vendor/ddeboer/imap/src/Connection.php
vendored
Executable file
178
data/web/inc/lib/vendor/ddeboer/imap/src/Connection.php
vendored
Executable file
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Exception\CreateMailboxException;
|
||||
use Ddeboer\Imap\Exception\DeleteMailboxException;
|
||||
use Ddeboer\Imap\Exception\ImapGetmailboxesException;
|
||||
use Ddeboer\Imap\Exception\ImapNumMsgException;
|
||||
use Ddeboer\Imap\Exception\ImapQuotaException;
|
||||
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
|
||||
|
||||
/**
|
||||
* A connection to an IMAP server that is authenticated for a user.
|
||||
*/
|
||||
final class Connection implements ConnectionInterface
|
||||
{
|
||||
private ImapResourceInterface $resource;
|
||||
private string $server;
|
||||
/**
|
||||
* @var null|MailboxInterface[]
|
||||
*/
|
||||
private ?array $mailboxes = null;
|
||||
/**
|
||||
* @var null|array<int|string, \stdClass>
|
||||
*/
|
||||
private ?array $mailboxNames = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ImapResourceInterface $resource, string $server)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function getResource(): ImapResourceInterface
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function expunge(): bool
|
||||
{
|
||||
return \imap_expunge($this->resource->getStream());
|
||||
}
|
||||
|
||||
public function close(int $flag = 0): bool
|
||||
{
|
||||
$this->resource->clearLastMailboxUsedCache();
|
||||
|
||||
return \imap_close($this->resource->getStream(), $flag);
|
||||
}
|
||||
|
||||
public function getQuota(string $root = 'INBOX'): array
|
||||
{
|
||||
$errorMessage = null;
|
||||
$errorNumber = 0;
|
||||
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
|
||||
$errorMessage = $message;
|
||||
$errorNumber = $nr;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$return = \imap_get_quotaroot($this->resource->getStream(), $root);
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
if (false === $return || null !== $errorMessage) {
|
||||
throw new ImapQuotaException(
|
||||
\sprintf(
|
||||
'IMAP Quota request failed for "%s"%s',
|
||||
$root,
|
||||
null !== $errorMessage ? ': ' . $errorMessage : ''
|
||||
),
|
||||
$errorNumber
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function getMailboxes(): array
|
||||
{
|
||||
$this->initMailboxNames();
|
||||
\assert(null !== $this->mailboxNames);
|
||||
|
||||
if (null === $this->mailboxes) {
|
||||
$this->mailboxes = [];
|
||||
foreach ($this->mailboxNames as $mailboxName => $mailboxInfo) {
|
||||
$this->mailboxes[(string) $mailboxName] = $this->getMailbox((string) $mailboxName);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->mailboxes;
|
||||
}
|
||||
|
||||
public function hasMailbox(string $name): bool
|
||||
{
|
||||
$this->initMailboxNames();
|
||||
\assert(null !== $this->mailboxNames);
|
||||
|
||||
return isset($this->mailboxNames[$name]);
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
$return = \imap_num_msg($this->resource->getStream());
|
||||
|
||||
if (false === $return) {
|
||||
throw new ImapNumMsgException('imap_num_msg failed');
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function ping(): bool
|
||||
{
|
||||
return \imap_ping($this->resource->getStream());
|
||||
}
|
||||
|
||||
public function createMailbox(string $name): MailboxInterface
|
||||
{
|
||||
if (false === \imap_createmailbox($this->resource->getStream(), $this->server . \mb_convert_encoding($name, 'UTF7-IMAP', 'UTF-8'))) {
|
||||
throw new CreateMailboxException(\sprintf('Can not create "%s" mailbox at "%s"', $name, $this->server));
|
||||
}
|
||||
|
||||
$this->mailboxNames = $this->mailboxes = null;
|
||||
$this->resource->clearLastMailboxUsedCache();
|
||||
|
||||
return $this->getMailbox($name);
|
||||
}
|
||||
|
||||
public function deleteMailbox(MailboxInterface $mailbox): void
|
||||
{
|
||||
if (false === \imap_deletemailbox($this->resource->getStream(), $mailbox->getFullEncodedName())) {
|
||||
throw new DeleteMailboxException(\sprintf('Mailbox "%s" could not be deleted', $mailbox->getName()));
|
||||
}
|
||||
|
||||
$this->mailboxes = $this->mailboxNames = null;
|
||||
$this->resource->clearLastMailboxUsedCache();
|
||||
}
|
||||
|
||||
private function initMailboxNames(): void
|
||||
{
|
||||
if (null !== $this->mailboxNames) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->mailboxNames = [];
|
||||
$mailboxesInfo = \imap_getmailboxes($this->resource->getStream(), $this->server, '*');
|
||||
if (!\is_array($mailboxesInfo)) {
|
||||
throw new ImapGetmailboxesException('imap_getmailboxes failed');
|
||||
}
|
||||
|
||||
foreach ($mailboxesInfo as $mailboxInfo) {
|
||||
$name = \mb_convert_encoding(\str_replace($this->server, '', $mailboxInfo->name), 'UTF-8', 'UTF7-IMAP');
|
||||
\assert(\is_string($name));
|
||||
|
||||
$this->mailboxNames[$name] = $mailboxInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
data/web/inc/lib/vendor/ddeboer/imap/src/ConnectionInterface.php
vendored
Executable file
82
data/web/inc/lib/vendor/ddeboer/imap/src/ConnectionInterface.php
vendored
Executable file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
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.
|
||||
*/
|
||||
interface ConnectionInterface extends \Countable
|
||||
{
|
||||
/**
|
||||
* Get IMAP resource.
|
||||
*/
|
||||
public function getResource(): ImapResourceInterface;
|
||||
|
||||
/**
|
||||
* Delete all messages marked for deletion.
|
||||
*/
|
||||
public function expunge(): bool;
|
||||
|
||||
/**
|
||||
* Close connection.
|
||||
*/
|
||||
public function close(int $flag = 0): bool;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Get a list of mailboxes (also known as folders).
|
||||
*
|
||||
* @return MailboxInterface[]
|
||||
*/
|
||||
public function getMailboxes(): array;
|
||||
|
||||
/**
|
||||
* Check that a mailbox with the given name exists.
|
||||
*
|
||||
* @param string $name Mailbox name
|
||||
*/
|
||||
public function hasMailbox(string $name): bool;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
49
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/AbstractException.php
vendored
Executable file
49
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/AbstractException.php
vendored
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
abstract class AbstractException extends \RuntimeException
|
||||
{
|
||||
private const ERROR_LABELS = [
|
||||
\E_ERROR => 'E_ERROR',
|
||||
\E_WARNING => 'E_WARNING',
|
||||
\E_PARSE => 'E_PARSE',
|
||||
\E_NOTICE => 'E_NOTICE',
|
||||
\E_CORE_ERROR => 'E_CORE_ERROR',
|
||||
\E_CORE_WARNING => 'E_CORE_WARNING',
|
||||
\E_COMPILE_ERROR => 'E_COMPILE_ERROR',
|
||||
\E_COMPILE_WARNING => 'E_COMPILE_WARNING',
|
||||
\E_USER_ERROR => 'E_USER_ERROR',
|
||||
\E_USER_WARNING => 'E_USER_WARNING',
|
||||
\E_USER_NOTICE => 'E_USER_NOTICE',
|
||||
\E_STRICT => 'E_STRICT',
|
||||
\E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
|
||||
\E_DEPRECATED => 'E_DEPRECATED',
|
||||
\E_USER_DEPRECATED => 'E_USER_DEPRECATED',
|
||||
];
|
||||
|
||||
final public function __construct(string $message, int $code = 0, \Throwable $previous = null)
|
||||
{
|
||||
$errorType = '';
|
||||
if (isset(self::ERROR_LABELS[$code])) {
|
||||
$errorType = \sprintf('[%s] ', self::ERROR_LABELS[$code]);
|
||||
}
|
||||
|
||||
$joinString = "\n- ";
|
||||
$alerts = \imap_alerts();
|
||||
$errors = \imap_errors();
|
||||
$completeMessage = \sprintf(
|
||||
"%s%s\nimap_alerts (%s):%s\nimap_errors (%s):%s",
|
||||
$errorType,
|
||||
$message,
|
||||
false !== $alerts ? \count($alerts) : 0,
|
||||
false !== $alerts ? $joinString . \implode($joinString, $alerts) : '',
|
||||
false !== $errors ? \count($errors) : 0,
|
||||
false !== $errors ? $joinString . \implode($joinString, $errors) : ''
|
||||
);
|
||||
|
||||
parent::__construct($completeMessage, $code, $previous);
|
||||
}
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/AuthenticationFailedException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/AuthenticationFailedException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class AuthenticationFailedException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/CreateMailboxException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/CreateMailboxException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class CreateMailboxException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/DeleteMailboxException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/DeleteMailboxException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class DeleteMailboxException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapFetchbodyException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapFetchbodyException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ImapFetchbodyException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapFetchheaderException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapFetchheaderException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ImapFetchheaderException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapGetmailboxesException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapGetmailboxesException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ImapGetmailboxesException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapMsgnoException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapMsgnoException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ImapMsgnoException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapNumMsgException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapNumMsgException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ImapNumMsgException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapQuotaException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapQuotaException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ImapQuotaException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapStatusException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ImapStatusException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ImapStatusException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidDateHeaderException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidDateHeaderException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class InvalidDateHeaderException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidHeadersException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidHeadersException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class InvalidHeadersException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidResourceException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidResourceException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class InvalidResourceException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidSearchCriteriaException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/InvalidSearchCriteriaException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class InvalidSearchCriteriaException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MailboxDoesNotExistException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MailboxDoesNotExistException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class MailboxDoesNotExistException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageCopyException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageCopyException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class MessageCopyException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageDeleteException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageDeleteException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class MessageDeleteException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageDoesNotExistException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageDoesNotExistException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class MessageDoesNotExistException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageMoveException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageMoveException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class MessageMoveException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageStructureException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageStructureException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class MessageStructureException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageUndeleteException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/MessageUndeleteException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class MessageUndeleteException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/NotEmbeddedMessageException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/NotEmbeddedMessageException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class NotEmbeddedMessageException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/OutOfBoundsException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/OutOfBoundsException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class OutOfBoundsException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ReopenMailboxException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ReopenMailboxException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ReopenMailboxException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ResourceCheckFailureException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/ResourceCheckFailureException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class ResourceCheckFailureException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/UnexpectedEncodingException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/UnexpectedEncodingException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class UnexpectedEncodingException extends AbstractException
|
||||
{
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/UnsupportedCharsetException.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Exception/UnsupportedCharsetException.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Exception;
|
||||
|
||||
final class UnsupportedCharsetException extends AbstractException
|
||||
{
|
||||
}
|
||||
99
data/web/inc/lib/vendor/ddeboer/imap/src/ImapResource.php
vendored
Executable file
99
data/web/inc/lib/vendor/ddeboer/imap/src/ImapResource.php
vendored
Executable file
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Exception\InvalidResourceException;
|
||||
use Ddeboer\Imap\Exception\ReopenMailboxException;
|
||||
use IMAP\Connection;
|
||||
|
||||
/**
|
||||
* An imap resource stream.
|
||||
*/
|
||||
final class ImapResource implements ImapResourceInterface
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
private ?MailboxInterface $mailbox = null;
|
||||
private static ?string $lastMailboxUsedCache = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Connection|resource $resource
|
||||
*/
|
||||
public function __construct($resource, MailboxInterface $mailbox = null)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->mailbox = $mailbox;
|
||||
}
|
||||
|
||||
public function getStream()
|
||||
{
|
||||
if (
|
||||
!$this->resource instanceof Connection
|
||||
&& (false === \is_resource($this->resource) || 'imap' !== \get_resource_type($this->resource))
|
||||
) {
|
||||
throw new InvalidResourceException('Supplied resource is not a valid imap resource');
|
||||
}
|
||||
|
||||
$this->initMailbox();
|
||||
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function clearLastMailboxUsedCache(): void
|
||||
{
|
||||
self::$lastMailboxUsedCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If connection is not currently in this mailbox, switch it to this mailbox.
|
||||
*/
|
||||
private function initMailbox(): void
|
||||
{
|
||||
if (null === $this->mailbox || self::isMailboxOpen($this->mailbox, $this->resource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
\set_error_handler(static function (): bool {
|
||||
return true;
|
||||
});
|
||||
|
||||
\imap_reopen($this->resource, $this->mailbox->getFullEncodedName());
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
if (self::isMailboxOpen($this->mailbox, $this->resource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ReopenMailboxException(\sprintf('Cannot reopen mailbox "%s"', $this->mailbox->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current mailbox is open.
|
||||
*
|
||||
* @param resource $resource
|
||||
*/
|
||||
private static function isMailboxOpen(MailboxInterface $mailbox, $resource): bool
|
||||
{
|
||||
$currentMailboxName = $mailbox->getFullEncodedName();
|
||||
if ($currentMailboxName === self::$lastMailboxUsedCache) {
|
||||
return true;
|
||||
}
|
||||
|
||||
self::$lastMailboxUsedCache = null;
|
||||
$check = \imap_check($resource);
|
||||
$return = false !== $check && $check->Mailbox === $currentMailboxName;
|
||||
|
||||
if (true === $return) {
|
||||
self::$lastMailboxUsedCache = $currentMailboxName;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
24
data/web/inc/lib/vendor/ddeboer/imap/src/ImapResourceInterface.php
vendored
Executable file
24
data/web/inc/lib/vendor/ddeboer/imap/src/ImapResourceInterface.php
vendored
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* Clear last mailbox used cache.
|
||||
*/
|
||||
public function clearLastMailboxUsedCache(): void;
|
||||
}
|
||||
241
data/web/inc/lib/vendor/ddeboer/imap/src/Mailbox.php
vendored
Executable file
241
data/web/inc/lib/vendor/ddeboer/imap/src/Mailbox.php
vendored
Executable file
|
|
@ -0,0 +1,241 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Ddeboer\Imap\Exception\ImapNumMsgException;
|
||||
use Ddeboer\Imap\Exception\ImapStatusException;
|
||||
use Ddeboer\Imap\Exception\InvalidSearchCriteriaException;
|
||||
use Ddeboer\Imap\Exception\MessageCopyException;
|
||||
use Ddeboer\Imap\Exception\MessageMoveException;
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
use Ddeboer\Imap\Search\LogicalOperator\All;
|
||||
|
||||
/**
|
||||
* An IMAP mailbox (commonly referred to as a 'folder').
|
||||
*/
|
||||
final class Mailbox implements MailboxInterface
|
||||
{
|
||||
private ImapResourceInterface $resource;
|
||||
private string $name;
|
||||
private \stdClass $info;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ImapResourceInterface $resource IMAP resource
|
||||
* @param string $name Mailbox decoded name
|
||||
* @param \stdClass $info Mailbox info
|
||||
*/
|
||||
public function __construct(ImapResourceInterface $resource, string $name, \stdClass $info)
|
||||
{
|
||||
$this->resource = new ImapResource($resource->getStream(), $this);
|
||||
$this->name = $name;
|
||||
$this->info = $info;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getEncodedName(): string
|
||||
{
|
||||
/** @var string $name */
|
||||
$name = $this->info->name;
|
||||
|
||||
return (string) \preg_replace('/^{.+}/', '', $name);
|
||||
}
|
||||
|
||||
public function getFullEncodedName(): string
|
||||
{
|
||||
return $this->info->name;
|
||||
}
|
||||
|
||||
public function getAttributes(): int
|
||||
{
|
||||
return $this->info->attributes;
|
||||
}
|
||||
|
||||
public function getDelimiter(): string
|
||||
{
|
||||
return $this->info->delimiter;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
$return = \imap_num_msg($this->resource->getStream());
|
||||
|
||||
if (false === $return) {
|
||||
throw new ImapNumMsgException('imap_num_msg failed');
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function getStatus(int $flags = null): \stdClass
|
||||
{
|
||||
$return = \imap_status($this->resource->getStream(), $this->getFullEncodedName(), $flags ?? \SA_ALL);
|
||||
|
||||
if (false === $return) {
|
||||
throw new ImapStatusException('imap_status failed');
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function setFlag(string $flag, $numbers): bool
|
||||
{
|
||||
return \imap_setflag_full($this->resource->getStream(), $this->prepareMessageIds($numbers), $flag, \ST_UID);
|
||||
}
|
||||
|
||||
public function clearFlag(string $flag, $numbers): bool
|
||||
{
|
||||
return \imap_clearflag_full($this->resource->getStream(), $this->prepareMessageIds($numbers), $flag, \ST_UID);
|
||||
}
|
||||
|
||||
public function getMessages(ConditionInterface $search = null, int $sortCriteria = null, bool $descending = false, string $charset = null): MessageIteratorInterface
|
||||
{
|
||||
if (null === $search) {
|
||||
$search = new All();
|
||||
}
|
||||
$query = $search->toString();
|
||||
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
$descending = (int) $descending;
|
||||
}
|
||||
|
||||
// We need to clear the stack to know whether imap_last_error()
|
||||
// is related to this imap_search
|
||||
\imap_errors();
|
||||
|
||||
if (null !== $sortCriteria) {
|
||||
$params = [
|
||||
$this->resource->getStream(),
|
||||
$sortCriteria,
|
||||
$descending,
|
||||
\SE_UID,
|
||||
$query,
|
||||
];
|
||||
if (null !== $charset) {
|
||||
$params[] = $charset;
|
||||
}
|
||||
$messageNumbers = \imap_sort(...$params);
|
||||
} else {
|
||||
$params = [
|
||||
$this->resource->getStream(),
|
||||
$query,
|
||||
\SE_UID,
|
||||
];
|
||||
if (null !== $charset) {
|
||||
$params[] = $charset;
|
||||
}
|
||||
$messageNumbers = \imap_search(...$params);
|
||||
}
|
||||
if (false !== \imap_last_error()) {
|
||||
// this way all errors occurred during search will be reported
|
||||
throw new InvalidSearchCriteriaException(
|
||||
\sprintf('Invalid search criteria [%s]', $query)
|
||||
);
|
||||
}
|
||||
if (false === $messageNumbers) {
|
||||
// imap_search can also return false
|
||||
$messageNumbers = [];
|
||||
}
|
||||
|
||||
return new MessageIterator($this->resource, $messageNumbers);
|
||||
}
|
||||
|
||||
public function getMessageSequence(string $sequence): MessageIteratorInterface
|
||||
{
|
||||
\imap_errors();
|
||||
|
||||
$overview = \imap_fetch_overview($this->resource->getStream(), $sequence, \FT_UID);
|
||||
if (false !== \imap_last_error()) {
|
||||
throw new InvalidSearchCriteriaException(
|
||||
\sprintf('Invalid sequence [%s]', $sequence)
|
||||
);
|
||||
}
|
||||
if (\is_array($overview) && [] !== $overview) {
|
||||
$messageNumbers = \array_column($overview, 'uid');
|
||||
} else {
|
||||
$messageNumbers = [];
|
||||
}
|
||||
|
||||
return new MessageIterator($this->resource, $messageNumbers);
|
||||
}
|
||||
|
||||
public function getMessage(int $number): MessageInterface
|
||||
{
|
||||
return new Message($this->resource, $number);
|
||||
}
|
||||
|
||||
public function getIterator(): MessageIteratorInterface
|
||||
{
|
||||
return $this->getMessages();
|
||||
}
|
||||
|
||||
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool
|
||||
{
|
||||
$arguments = [
|
||||
$this->resource->getStream(),
|
||||
$this->getFullEncodedName(),
|
||||
$message,
|
||||
$options ?? '',
|
||||
];
|
||||
if (null !== $internalDate) {
|
||||
$arguments[] = $internalDate->format('d-M-Y H:i:s O');
|
||||
}
|
||||
|
||||
return \imap_append(...$arguments);
|
||||
}
|
||||
|
||||
public function getThread(): array
|
||||
{
|
||||
\set_error_handler(static function (): bool {
|
||||
return true;
|
||||
});
|
||||
|
||||
/** @var array<string, int>|false $tree */
|
||||
$tree = \imap_thread($this->resource->getStream(), \SE_UID);
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
return false !== $tree ? $tree : [];
|
||||
}
|
||||
|
||||
public function move($numbers, MailboxInterface $mailbox): void
|
||||
{
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
public function copy($numbers, MailboxInterface $mailbox): void
|
||||
{
|
||||
if (!\imap_mail_copy($this->resource->getStream(), $this->prepareMessageIds($numbers), $mailbox->getEncodedName(), \CP_UID)) {
|
||||
throw new MessageCopyException(\sprintf('Messages cannot be copied to "%s"', $mailbox->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare message ids for the use with bulk functions.
|
||||
*
|
||||
* @param array<int, int|string>|MessageIterator|string $messageIds Message numbers
|
||||
*/
|
||||
private function prepareMessageIds($messageIds): string
|
||||
{
|
||||
if ($messageIds instanceof MessageIterator) {
|
||||
$messageIds = $messageIds->getArrayCopy();
|
||||
}
|
||||
|
||||
if (\is_array($messageIds)) {
|
||||
$messageIds = \implode(',', $messageIds);
|
||||
}
|
||||
|
||||
return $messageIds;
|
||||
}
|
||||
}
|
||||
123
data/web/inc/lib/vendor/ddeboer/imap/src/MailboxInterface.php
vendored
Executable file
123
data/web/inc/lib/vendor/ddeboer/imap/src/MailboxInterface.php
vendored
Executable file
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
* Get mailbox decoded name.
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Get mailbox encoded path.
|
||||
*/
|
||||
public function getEncodedName(): string;
|
||||
|
||||
/**
|
||||
* Get mailbox encoded full name.
|
||||
*/
|
||||
public function getFullEncodedName(): string;
|
||||
|
||||
/**
|
||||
* Get mailbox attributes.
|
||||
*/
|
||||
public function getAttributes(): int;
|
||||
|
||||
/**
|
||||
* Get mailbox delimiter.
|
||||
*/
|
||||
public function getDelimiter(): string;
|
||||
|
||||
/**
|
||||
* Get Mailbox status.
|
||||
*/
|
||||
public function getStatus(int $flags = null): \stdClass;
|
||||
|
||||
/**
|
||||
* Bulk Set Flag for Messages.
|
||||
*
|
||||
* @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<int, int|string>|MessageIterator|string $numbers Message numbers
|
||||
*/
|
||||
public function clearFlag(string $flag, $numbers): bool;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Get message iterator for a sequence.
|
||||
*
|
||||
* @param string $sequence Message numbers
|
||||
*/
|
||||
public function getMessageSequence(string $sequence): MessageIteratorInterface;
|
||||
|
||||
/**
|
||||
* Get a message by message number.
|
||||
*
|
||||
* @param int $number Message number
|
||||
*
|
||||
* @return MessageInterface<PartInterface>
|
||||
*/
|
||||
public function getMessage(int $number): MessageInterface;
|
||||
|
||||
/**
|
||||
* Get messages in this mailbox.
|
||||
*/
|
||||
public function getIterator(): MessageIteratorInterface;
|
||||
|
||||
/**
|
||||
* Add a message to the mailbox.
|
||||
*/
|
||||
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool;
|
||||
|
||||
/**
|
||||
* Returns a tree of threaded message for the current Mailbox.
|
||||
*
|
||||
* @return array<string, int>
|
||||
*/
|
||||
public function getThread(): array;
|
||||
|
||||
/**
|
||||
* Bulk move messages.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function move($numbers, self $mailbox): void;
|
||||
|
||||
/**
|
||||
* Bulk copy messages.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function copy($numbers, self $mailbox): void;
|
||||
}
|
||||
267
data/web/inc/lib/vendor/ddeboer/imap/src/Message.php
vendored
Executable file
267
data/web/inc/lib/vendor/ddeboer/imap/src/Message.php
vendored
Executable file
|
|
@ -0,0 +1,267 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Exception\ImapFetchheaderException;
|
||||
use Ddeboer\Imap\Exception\InvalidHeadersException;
|
||||
use Ddeboer\Imap\Exception\MessageCopyException;
|
||||
use Ddeboer\Imap\Exception\MessageDeleteException;
|
||||
use Ddeboer\Imap\Exception\MessageDoesNotExistException;
|
||||
use Ddeboer\Imap\Exception\MessageMoveException;
|
||||
use Ddeboer\Imap\Exception\MessageStructureException;
|
||||
use Ddeboer\Imap\Exception\MessageUndeleteException;
|
||||
|
||||
/**
|
||||
* An IMAP message (e-mail).
|
||||
*/
|
||||
final class Message extends Message\AbstractMessage implements MessageInterface
|
||||
{
|
||||
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.
|
||||
*
|
||||
* @param ImapResourceInterface $resource IMAP resource
|
||||
* @param int $messageNumber Message number
|
||||
*/
|
||||
public function __construct(ImapResourceInterface $resource, int $messageNumber)
|
||||
{
|
||||
parent::__construct($resource, $messageNumber, '1', new \stdClass());
|
||||
}
|
||||
|
||||
protected function lazyLoadStructure(): void
|
||||
{
|
||||
if (true === $this->structureLoaded) {
|
||||
return;
|
||||
}
|
||||
$this->structureLoaded = true;
|
||||
|
||||
$messageNumber = $this->getNumber();
|
||||
|
||||
$errorMessage = null;
|
||||
$errorNumber = 0;
|
||||
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
|
||||
$errorMessage = $message;
|
||||
$errorNumber = $nr;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$structure = \imap_fetchstructure(
|
||||
$this->resource->getStream(),
|
||||
$messageNumber,
|
||||
\FT_UID
|
||||
);
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
if (!$structure instanceof \stdClass) {
|
||||
throw new MessageStructureException(\sprintf(
|
||||
'Message "%s" structure is empty: %s',
|
||||
$messageNumber,
|
||||
$errorMessage
|
||||
), $errorNumber);
|
||||
}
|
||||
|
||||
$this->setStructure($structure);
|
||||
}
|
||||
|
||||
protected function assertMessageExists(int $messageNumber): void
|
||||
{
|
||||
if (true === $this->messageNumberVerified) {
|
||||
return;
|
||||
}
|
||||
$this->messageNumberVerified = true;
|
||||
|
||||
$msgno = null;
|
||||
\set_error_handler(static function (): bool {
|
||||
return true;
|
||||
});
|
||||
|
||||
$msgno = \imap_msgno($this->resource->getStream(), $messageNumber);
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
if (\is_numeric($msgno) && $msgno > 0) {
|
||||
$this->imapMsgNo = $msgno;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new MessageDoesNotExistException(\sprintf(
|
||||
'Message "%s" does not exist',
|
||||
$messageNumber
|
||||
));
|
||||
}
|
||||
|
||||
private function getMsgNo(): int
|
||||
{
|
||||
// Triggers assertMessageExists()
|
||||
$this->getNumber();
|
||||
|
||||
return $this->imapMsgNo;
|
||||
}
|
||||
|
||||
public function getRawHeaders(): string
|
||||
{
|
||||
if (null === $this->rawHeaders) {
|
||||
$rawHeaders = \imap_fetchheader($this->resource->getStream(), $this->getNumber(), \FT_UID);
|
||||
|
||||
if (false === $rawHeaders) {
|
||||
throw new ImapFetchheaderException('imap_fetchheader failed');
|
||||
}
|
||||
|
||||
$this->rawHeaders = $rawHeaders;
|
||||
}
|
||||
|
||||
return $this->rawHeaders;
|
||||
}
|
||||
|
||||
public function getRawMessage(): string
|
||||
{
|
||||
if (null === $this->rawMessage) {
|
||||
$this->rawMessage = $this->doGetContent('');
|
||||
}
|
||||
|
||||
return $this->rawMessage;
|
||||
}
|
||||
|
||||
public function getHeaders(): Message\Headers
|
||||
{
|
||||
if (null === $this->headers) {
|
||||
// imap_headerinfo is much faster than imap_fetchheader
|
||||
// imap_headerinfo returns only a subset of all mail headers,
|
||||
// but it does include the message flags.
|
||||
$headers = \imap_headerinfo($this->resource->getStream(), $this->getMsgNo());
|
||||
if (false === $headers) {
|
||||
// @see https://github.com/ddeboer/imap/issues/358
|
||||
throw new InvalidHeadersException(\sprintf('Message "%s" has invalid headers', $this->getNumber()));
|
||||
}
|
||||
$this->headers = new Message\Headers($headers);
|
||||
}
|
||||
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clearmessage headers.
|
||||
*/
|
||||
private function clearHeaders(): void
|
||||
{
|
||||
$this->headers = null;
|
||||
}
|
||||
|
||||
public function isRecent(): ?string
|
||||
{
|
||||
$recent = $this->getHeaders()->get('recent');
|
||||
\assert(null === $recent || \is_string($recent));
|
||||
|
||||
return $recent;
|
||||
}
|
||||
|
||||
public function isUnseen(): bool
|
||||
{
|
||||
return 'U' === $this->getHeaders()->get('unseen');
|
||||
}
|
||||
|
||||
public function isFlagged(): bool
|
||||
{
|
||||
return 'F' === $this->getHeaders()->get('flagged');
|
||||
}
|
||||
|
||||
public function isAnswered(): bool
|
||||
{
|
||||
return 'A' === $this->getHeaders()->get('answered');
|
||||
}
|
||||
|
||||
public function isDeleted(): bool
|
||||
{
|
||||
return 'D' === $this->getHeaders()->get('deleted');
|
||||
}
|
||||
|
||||
public function isDraft(): bool
|
||||
{
|
||||
return 'X' === $this->getHeaders()->get('draft');
|
||||
}
|
||||
|
||||
public function isSeen(): bool
|
||||
{
|
||||
return 'N' !== $this->getHeaders()->get('recent') && 'U' !== $this->getHeaders()->get('unseen');
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return $this->markAsSeen();
|
||||
}
|
||||
|
||||
public function markAsSeen(): bool
|
||||
{
|
||||
return $this->setFlag('\\Seen');
|
||||
}
|
||||
|
||||
public function copy(MailboxInterface $mailbox): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to true on header
|
||||
$this->clearHeaders();
|
||||
|
||||
if (!\imap_mail_copy($this->resource->getStream(), (string) $this->getNumber(), $mailbox->getEncodedName(), \CP_UID)) {
|
||||
throw new MessageCopyException(\sprintf('Message "%s" cannot be copied to "%s"', $this->getNumber(), $mailbox->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public function move(MailboxInterface $mailbox): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to true on header
|
||||
$this->clearHeaders();
|
||||
|
||||
if (!\imap_mail_move($this->resource->getStream(), (string) $this->getNumber(), $mailbox->getEncodedName(), \CP_UID)) {
|
||||
throw new MessageMoveException(\sprintf('Message "%s" cannot be moved to "%s"', $this->getNumber(), $mailbox->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to true on header
|
||||
$this->clearHeaders();
|
||||
|
||||
if (!\imap_delete($this->resource->getStream(), (string) $this->getNumber(), \FT_UID)) {
|
||||
throw new MessageDeleteException(\sprintf('Message "%s" cannot be deleted', $this->getNumber()));
|
||||
}
|
||||
}
|
||||
|
||||
public function undelete(): void
|
||||
{
|
||||
// 'deleted' header changed, force to reload headers, would be better to set deleted flag to false on header
|
||||
$this->clearHeaders();
|
||||
if (!\imap_undelete($this->resource->getStream(), (string) $this->getNumber(), \FT_UID)) {
|
||||
throw new MessageUndeleteException(\sprintf('Message "%s" cannot be undeleted', $this->getNumber()));
|
||||
}
|
||||
}
|
||||
|
||||
public function setFlag(string $flag): bool
|
||||
{
|
||||
$result = \imap_setflag_full($this->resource->getStream(), (string) $this->getNumber(), $flag, \ST_UID);
|
||||
|
||||
$this->clearHeaders();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function clearFlag(string $flag): bool
|
||||
{
|
||||
$result = \imap_clearflag_full($this->resource->getStream(), (string) $this->getNumber(), $flag, \ST_UID);
|
||||
|
||||
$this->clearHeaders();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
308
data/web/inc/lib/vendor/ddeboer/imap/src/Message/AbstractMessage.php
vendored
Executable file
308
data/web/inc/lib/vendor/ddeboer/imap/src/Message/AbstractMessage.php
vendored
Executable file
|
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
use Ddeboer\Imap\Exception\InvalidDateHeaderException;
|
||||
|
||||
abstract class AbstractMessage extends AbstractPart
|
||||
{
|
||||
/**
|
||||
* @var null|Attachment[]
|
||||
*/
|
||||
private ?array $attachments = null;
|
||||
|
||||
/**
|
||||
* Get message headers.
|
||||
*/
|
||||
abstract public function getHeaders(): Headers;
|
||||
|
||||
/**
|
||||
* Get message id.
|
||||
*
|
||||
* A unique message id in the form <...>
|
||||
*/
|
||||
final public function getId(): ?string
|
||||
{
|
||||
$messageId = $this->getHeaders()->get('message_id');
|
||||
\assert(null === $messageId || \is_string($messageId));
|
||||
|
||||
return $messageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message sender (from headers).
|
||||
*/
|
||||
final public function getFrom(): ?EmailAddress
|
||||
{
|
||||
$from = $this->getHeaders()->get('from');
|
||||
\assert(null === $from || \is_array($from));
|
||||
|
||||
return null !== $from ? $this->decodeEmailAddress($from[0]) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get To recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no To: recipients
|
||||
*/
|
||||
final public function getTo(): array
|
||||
{
|
||||
$emails = $this->getHeaders()->get('to');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cc recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no CC: recipients
|
||||
*/
|
||||
final public function getCc(): array
|
||||
{
|
||||
$emails = $this->getHeaders()->get('cc');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Bcc recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no BCC: recipients
|
||||
*/
|
||||
final public function getBcc(): array
|
||||
{
|
||||
$emails = $this->getHeaders()->get('bcc');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Reply-To recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no Reply-To: recipients
|
||||
*/
|
||||
final public function getReplyTo(): array
|
||||
{
|
||||
$emails = $this->getHeaders()->get('reply_to');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Sender.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no Sender: recipients
|
||||
*/
|
||||
final public function getSender(): array
|
||||
{
|
||||
$emails = $this->getHeaders()->get('sender');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Return-Path.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no Return-Path: recipients
|
||||
*/
|
||||
final public function getReturnPath(): array
|
||||
{
|
||||
$emails = $this->getHeaders()->get('return_path');
|
||||
\assert(null === $emails || \is_array($emails));
|
||||
|
||||
return $this->decodeEmailAddresses($emails ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date (from headers).
|
||||
*/
|
||||
final public function getDate(): ?\DateTimeImmutable
|
||||
{
|
||||
/** @var null|string $dateHeader */
|
||||
$dateHeader = $this->getHeaders()->get('date');
|
||||
if (null === $dateHeader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$alteredValue = $dateHeader;
|
||||
$alteredValue = \str_replace(',', '', $alteredValue);
|
||||
$alteredValue = (string) \preg_replace('/^[a-zA-Z]+ ?/', '', $alteredValue);
|
||||
$alteredValue = (string) \preg_replace('/\(.*\)/', '', $alteredValue);
|
||||
$alteredValue = (string) \preg_replace('/\<.*\>/', '', $alteredValue);
|
||||
$alteredValue = (string) \preg_replace('/\bUT\b/', 'UTC', $alteredValue);
|
||||
if (0 === \preg_match('/\d\d:\d\d:\d\d.* [\+\-]\d\d:?\d\d/', $alteredValue)) {
|
||||
$alteredValue .= ' +0000';
|
||||
}
|
||||
// Handle numeric months
|
||||
$alteredValue = (string) \preg_replace('/^(\d\d) (\d\d) (\d\d(?:\d\d)?) /', '$3-$2-$1 ', $alteredValue);
|
||||
|
||||
try {
|
||||
$date = new \DateTimeImmutable($alteredValue);
|
||||
} catch (\Throwable $ex) {
|
||||
throw new InvalidDateHeaderException(\sprintf('Invalid Date header found: "%s"', $dateHeader), 0, $ex);
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message size (from headers).
|
||||
*
|
||||
* @return null|int|string
|
||||
*/
|
||||
final public function getSize()
|
||||
{
|
||||
$size = $this->getHeaders()->get('size');
|
||||
\assert(null === $size || \is_int($size) || \is_string($size));
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message subject (from headers).
|
||||
*/
|
||||
final public function getSubject(): ?string
|
||||
{
|
||||
$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) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get body HTML.
|
||||
*/
|
||||
final public function getBodyHtml(): ?string
|
||||
{
|
||||
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
foreach ($iterator as $part) {
|
||||
if (self::SUBTYPE_HTML === $part->getSubtype()) {
|
||||
return $part->getDecodedContent();
|
||||
}
|
||||
}
|
||||
|
||||
// If message has no parts and is HTML, return content of message itself.
|
||||
if (self::SUBTYPE_HTML === $this->getSubtype()) {
|
||||
return $this->getDecodedContent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get body text.
|
||||
*/
|
||||
final public function getBodyText(): ?string
|
||||
{
|
||||
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
foreach ($iterator as $part) {
|
||||
if (self::SUBTYPE_PLAIN === $part->getSubtype()) {
|
||||
return $part->getDecodedContent();
|
||||
}
|
||||
}
|
||||
|
||||
// If message has no parts, return content of message itself.
|
||||
if (self::SUBTYPE_PLAIN === $this->getSubtype()) {
|
||||
return $this->getDecodedContent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachments (if any) linked to this e-mail.
|
||||
*
|
||||
* @return AttachmentInterface[]
|
||||
*/
|
||||
final public function getAttachments(): array
|
||||
{
|
||||
if (null === $this->attachments) {
|
||||
$this->attachments = self::gatherAttachments($this);
|
||||
}
|
||||
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PartInterface<PartInterface> $part
|
||||
*
|
||||
* @return Attachment[]
|
||||
*/
|
||||
private static function gatherAttachments(PartInterface $part): array
|
||||
{
|
||||
$attachments = [];
|
||||
foreach ($part->getParts() as $childPart) {
|
||||
if ($childPart instanceof Attachment) {
|
||||
$attachments[] = $childPart;
|
||||
}
|
||||
if ($childPart->hasChildren()) {
|
||||
$attachments = \array_merge($attachments, self::gatherAttachments($childPart));
|
||||
}
|
||||
}
|
||||
|
||||
return $attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this message have attachments?
|
||||
*/
|
||||
final public function hasAttachments(): bool
|
||||
{
|
||||
return \count($this->getAttachments()) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass[] $addresses
|
||||
*
|
||||
* @return EmailAddress[]
|
||||
*/
|
||||
private function decodeEmailAddresses(array $addresses): array
|
||||
{
|
||||
$return = [];
|
||||
foreach ($addresses as $address) {
|
||||
if (isset($address->mailbox)) {
|
||||
$return[] = $this->decodeEmailAddress($address);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
private function decodeEmailAddress(\stdClass $value): EmailAddress
|
||||
{
|
||||
return new EmailAddress($value->mailbox, $value->host, $value->personal);
|
||||
}
|
||||
}
|
||||
436
data/web/inc/lib/vendor/ddeboer/imap/src/Message/AbstractPart.php
vendored
Executable file
436
data/web/inc/lib/vendor/ddeboer/imap/src/Message/AbstractPart.php
vendored
Executable file
|
|
@ -0,0 +1,436 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
use Ddeboer\Imap\Exception\ImapFetchbodyException;
|
||||
use Ddeboer\Imap\Exception\UnexpectedEncodingException;
|
||||
use Ddeboer\Imap\ImapResourceInterface;
|
||||
use Ddeboer\Imap\Message;
|
||||
|
||||
/**
|
||||
* A message part.
|
||||
*/
|
||||
abstract class AbstractPart implements PartInterface
|
||||
{
|
||||
private const TYPES_MAP = [
|
||||
\TYPETEXT => self::TYPE_TEXT,
|
||||
\TYPEMULTIPART => self::TYPE_MULTIPART,
|
||||
\TYPEMESSAGE => self::TYPE_MESSAGE,
|
||||
\TYPEAPPLICATION => self::TYPE_APPLICATION,
|
||||
\TYPEAUDIO => self::TYPE_AUDIO,
|
||||
\TYPEIMAGE => self::TYPE_IMAGE,
|
||||
\TYPEVIDEO => self::TYPE_VIDEO,
|
||||
\TYPEMODEL => self::TYPE_MODEL,
|
||||
\TYPEOTHER => self::TYPE_OTHER,
|
||||
];
|
||||
|
||||
private const ENCODINGS_MAP = [
|
||||
\ENC7BIT => self::ENCODING_7BIT,
|
||||
\ENC8BIT => self::ENCODING_8BIT,
|
||||
\ENCBINARY => self::ENCODING_BINARY,
|
||||
\ENCBASE64 => self::ENCODING_BASE64,
|
||||
\ENCQUOTEDPRINTABLE => self::ENCODING_QUOTED_PRINTABLE,
|
||||
];
|
||||
|
||||
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.
|
||||
*
|
||||
* @param ImapResourceInterface $resource IMAP resource
|
||||
* @param int $messageNumber Message number
|
||||
* @param string $partNumber Part number
|
||||
* @param \stdClass $structure Part structure
|
||||
*/
|
||||
public function __construct(
|
||||
ImapResourceInterface $resource,
|
||||
int $messageNumber,
|
||||
string $partNumber,
|
||||
\stdClass $structure
|
||||
) {
|
||||
$this->resource = $resource;
|
||||
$this->messageNumber = $messageNumber;
|
||||
$this->partNumber = $partNumber;
|
||||
$this->setStructure($structure);
|
||||
}
|
||||
|
||||
final public function getNumber(): int
|
||||
{
|
||||
$this->assertMessageExists($this->messageNumber);
|
||||
|
||||
return $this->messageNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure message exists.
|
||||
*/
|
||||
protected function assertMessageExists(int $messageNumber): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $structure Part structure
|
||||
*/
|
||||
final protected function setStructure(\stdClass $structure): void
|
||||
{
|
||||
$this->structure = $structure;
|
||||
}
|
||||
|
||||
final public function getStructure(): \stdClass
|
||||
{
|
||||
$this->lazyLoadStructure();
|
||||
|
||||
return $this->structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load structure.
|
||||
*/
|
||||
protected function lazyLoadStructure(): void
|
||||
{
|
||||
}
|
||||
|
||||
final public function getParameters(): Parameters
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
final public function getCharset(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
$charset = $this->parameters->get('charset');
|
||||
\assert(null === $charset || \is_string($charset));
|
||||
|
||||
return '' !== $charset ? $charset : null;
|
||||
}
|
||||
|
||||
final public function getType(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
final public function getSubtype(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->subtype;
|
||||
}
|
||||
|
||||
final public function getEncoding(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->encoding;
|
||||
}
|
||||
|
||||
final public function getDisposition(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->disposition;
|
||||
}
|
||||
|
||||
final public function getDescription(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
final public function getBytes()
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->bytes;
|
||||
}
|
||||
|
||||
final public function getLines(): ?string
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
final public function getContent(): string
|
||||
{
|
||||
if (null === $this->content) {
|
||||
$this->content = $this->doGetContent($this->getContentPartNumber());
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content part number.
|
||||
*/
|
||||
protected function getContentPartNumber(): string
|
||||
{
|
||||
return $this->partNumber;
|
||||
}
|
||||
|
||||
final public function getPartNumber(): string
|
||||
{
|
||||
return $this->partNumber;
|
||||
}
|
||||
|
||||
final public function getDecodedContent(): string
|
||||
{
|
||||
if (null === $this->decodedContent) {
|
||||
if (self::ENCODING_UNKNOWN === $this->getEncoding()) {
|
||||
throw new UnexpectedEncodingException('Cannot decode a content with an uknown encoding');
|
||||
}
|
||||
|
||||
$content = $this->getContent();
|
||||
if (self::ENCODING_BASE64 === $this->getEncoding()) {
|
||||
$content = \base64_decode($content, false);
|
||||
} elseif (self::ENCODING_QUOTED_PRINTABLE === $this->getEncoding()) {
|
||||
$content = \quoted_printable_decode($content);
|
||||
}
|
||||
|
||||
if (false === $content) {
|
||||
throw new UnexpectedEncodingException('Cannot decode content');
|
||||
}
|
||||
|
||||
// If this part is a text part, convert its charset to UTF-8.
|
||||
// We don't want to decode an attachment's charset.
|
||||
if (!$this instanceof Attachment && null !== $this->getCharset() && self::TYPE_TEXT === $this->getType()) {
|
||||
$content = Transcoder::decode($content, $this->getCharset());
|
||||
}
|
||||
|
||||
$this->decodedContent = $content;
|
||||
}
|
||||
|
||||
return $this->decodedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw message content.
|
||||
*/
|
||||
final protected function doGetContent(string $partNumber): string
|
||||
{
|
||||
$return = \imap_fetchbody(
|
||||
$this->resource->getStream(),
|
||||
$this->getNumber(),
|
||||
$partNumber,
|
||||
\FT_UID | \FT_PEEK
|
||||
);
|
||||
|
||||
if (false === $return) {
|
||||
throw new ImapFetchbodyException('imap_fetchbody failed');
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
final public function getParts(): array
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current child part.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
final public function current()
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return $this->parts[$this->key];
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
final public function getChildren()
|
||||
{
|
||||
return $this->current();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
final public function hasChildren()
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return \count($this->parts) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
final public function key()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
final public function next()
|
||||
{
|
||||
++$this->key;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
final public function rewind()
|
||||
{
|
||||
$this->key = 0;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
final public function valid()
|
||||
{
|
||||
$this->lazyParseStructure();
|
||||
|
||||
return isset($this->parts[$this->key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse part structure.
|
||||
*/
|
||||
private function lazyParseStructure(): void
|
||||
{
|
||||
if (true === $this->structureParsed) {
|
||||
return;
|
||||
}
|
||||
$this->structureParsed = true;
|
||||
|
||||
$this->lazyLoadStructure();
|
||||
|
||||
$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::ENCODINGS_MAP[$this->structure->encoding] ?? self::ENCODING_UNKNOWN;
|
||||
if (isset($this->structure->subtype)) {
|
||||
$this->subtype = $this->structure->subtype;
|
||||
}
|
||||
|
||||
if (isset($this->structure->bytes)) {
|
||||
$this->bytes = $this->structure->bytes;
|
||||
}
|
||||
if ($this->structure->ifdisposition) {
|
||||
$this->disposition = $this->structure->disposition;
|
||||
}
|
||||
if ($this->structure->ifdescription) {
|
||||
$this->description = $this->structure->description;
|
||||
}
|
||||
|
||||
$this->parameters = new Parameters();
|
||||
if ($this->structure->ifparameters) {
|
||||
$this->parameters->add($this->structure->parameters);
|
||||
}
|
||||
|
||||
if ($this->structure->ifdparameters) {
|
||||
$this->parameters->add($this->structure->dparameters);
|
||||
}
|
||||
|
||||
// When the message is not multipart and the body is the attachment content
|
||||
// Prevents infinite recursion
|
||||
if (self::isAttachment($this->structure) && !$this instanceof Attachment) {
|
||||
$this->parts[] = new Attachment($this->resource, $this->getNumber(), '1', $this->structure);
|
||||
}
|
||||
|
||||
if (isset($this->structure->parts)) {
|
||||
$parts = $this->structure->parts;
|
||||
// https://secure.php.net/manual/en/function.imap-fetchbody.php#89002
|
||||
if ($this instanceof Attachment && $this->isEmbeddedMessage() && 1 === \count($parts) && \TYPEMULTIPART === $parts[0]->type) {
|
||||
$parts = $parts[0]->parts;
|
||||
}
|
||||
foreach ($parts as $key => $partStructure) {
|
||||
$partNumber = (!$this instanceof Message) ? $this->partNumber . '.' : '';
|
||||
$partNumber .= (string) ($key + 1);
|
||||
|
||||
$newPartClass = self::isAttachment($partStructure)
|
||||
? Attachment::class
|
||||
: SimplePart::class
|
||||
;
|
||||
|
||||
$this->parts[] = new $newPartClass($this->resource, $this->getNumber(), $partNumber, $partStructure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given part is an attachment.
|
||||
*/
|
||||
private static function isAttachment(\stdClass $part): bool
|
||||
{
|
||||
if (isset(self::TYPES_MAP[$part->type]) && self::TYPE_MULTIPART === self::TYPES_MAP[$part->type]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attachment with correct Content-Disposition header
|
||||
if ($part->ifdisposition) {
|
||||
if ('attachment' === \strtolower($part->disposition)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
'inline' === \strtolower($part->disposition)
|
||||
&& self::SUBTYPE_PLAIN !== \strtoupper($part->subtype)
|
||||
&& self::SUBTYPE_HTML !== \strtoupper($part->subtype)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Attachment without Content-Disposition header
|
||||
if ($part->ifparameters) {
|
||||
foreach ($part->parameters as $parameter) {
|
||||
if (isset(self::ATTACHMENT_KEYS[\strtolower($parameter->attribute)])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if ($part->ifdparameters) {
|
||||
foreach ($part->dparameters as $parameter) {
|
||||
if (isset(self::$attachmentKeys[\strtolower($parameter->attribute)])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (self::SUBTYPE_RFC822 === \strtoupper($part->subtype)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
53
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Attachment.php
vendored
Executable file
53
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Attachment.php
vendored
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
use Ddeboer\Imap\Exception\NotEmbeddedMessageException;
|
||||
|
||||
/**
|
||||
* An e-mail attachment.
|
||||
*/
|
||||
final class Attachment extends AbstractPart implements AttachmentInterface
|
||||
{
|
||||
public function getFilename(): ?string
|
||||
{
|
||||
$filename = $this->getParameters()->get('filename');
|
||||
if (null === $filename || '' === $filename) {
|
||||
$filename = $this->getParameters()->get('name');
|
||||
}
|
||||
\assert(null === $filename || \is_string($filename));
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
$size = $this->getParameters()->get('size');
|
||||
if (\is_numeric($size)) {
|
||||
$size = (int) $size;
|
||||
}
|
||||
\assert(null === $size || \is_int($size));
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
public function isEmbeddedMessage(): bool
|
||||
{
|
||||
return self::TYPE_MESSAGE === $this->getType();
|
||||
}
|
||||
|
||||
public function getEmbeddedMessage(): EmbeddedMessageInterface
|
||||
{
|
||||
if (!$this->isEmbeddedMessage()) {
|
||||
throw new NotEmbeddedMessageException(\sprintf(
|
||||
'Attachment "%s" in message "%s" is not embedded message',
|
||||
$this->getPartNumber(),
|
||||
$this->getNumber()
|
||||
));
|
||||
}
|
||||
|
||||
return new EmbeddedMessage($this->resource, $this->getNumber(), $this->getPartNumber(), $this->getStructure()->parts[0]);
|
||||
}
|
||||
}
|
||||
39
data/web/inc/lib/vendor/ddeboer/imap/src/Message/AttachmentInterface.php
vendored
Executable file
39
data/web/inc/lib/vendor/ddeboer/imap/src/Message/AttachmentInterface.php
vendored
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
use Ddeboer\Imap\Exception\NotEmbeddedMessageException;
|
||||
|
||||
/**
|
||||
* An e-mail attachment.
|
||||
*/
|
||||
interface AttachmentInterface extends PartInterface
|
||||
{
|
||||
/**
|
||||
* Get attachment filename.
|
||||
*/
|
||||
public function getFilename(): ?string;
|
||||
|
||||
/**
|
||||
* Get attachment file size.
|
||||
*
|
||||
* @return null|int Number of bytes
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Is this attachment also an Embedded Message?
|
||||
*/
|
||||
public function isEmbeddedMessage(): bool;
|
||||
|
||||
/**
|
||||
* Return embedded message.
|
||||
*
|
||||
* @throws NotEmbeddedMessageException
|
||||
*
|
||||
* @return EmbeddedMessageInterface<PartInterface>
|
||||
*/
|
||||
public function getEmbeddedMessage(): EmbeddedMessageInterface;
|
||||
}
|
||||
134
data/web/inc/lib/vendor/ddeboer/imap/src/Message/BasicMessageInterface.php
vendored
Executable file
134
data/web/inc/lib/vendor/ddeboer/imap/src/Message/BasicMessageInterface.php
vendored
Executable file
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
interface BasicMessageInterface extends PartInterface
|
||||
{
|
||||
/**
|
||||
* Get raw message headers.
|
||||
*/
|
||||
public function getRawHeaders(): string;
|
||||
|
||||
/**
|
||||
* Get the raw message, including all headers, parts, etc. unencoded and unparsed.
|
||||
*
|
||||
* @return string the raw message
|
||||
*/
|
||||
public function getRawMessage(): string;
|
||||
|
||||
/**
|
||||
* Get message headers.
|
||||
*/
|
||||
public function getHeaders(): Headers;
|
||||
|
||||
/**
|
||||
* Get message id.
|
||||
*
|
||||
* A unique message id in the form <...>
|
||||
*/
|
||||
public function getId(): ?string;
|
||||
|
||||
/**
|
||||
* Get message sender (from headers).
|
||||
*/
|
||||
public function getFrom(): ?EmailAddress;
|
||||
|
||||
/**
|
||||
* Get To recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no To: recipients
|
||||
*/
|
||||
public function getTo(): array;
|
||||
|
||||
/**
|
||||
* Get Cc recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no CC: recipients
|
||||
*/
|
||||
public function getCc(): array;
|
||||
|
||||
/**
|
||||
* Get Bcc recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no BCC: recipients
|
||||
*/
|
||||
public function getBcc(): array;
|
||||
|
||||
/**
|
||||
* Get Reply-To recipients.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no Reply-To: recipients
|
||||
*/
|
||||
public function getReplyTo(): array;
|
||||
|
||||
/**
|
||||
* Get Sender.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no Sender: recipients
|
||||
*/
|
||||
public function getSender(): array;
|
||||
|
||||
/**
|
||||
* Get Return-Path.
|
||||
*
|
||||
* @return EmailAddress[] Empty array in case message has no Return-Path: recipients
|
||||
*/
|
||||
public function getReturnPath(): array;
|
||||
|
||||
/**
|
||||
* Get date (from headers).
|
||||
*/
|
||||
public function getDate(): ?\DateTimeImmutable;
|
||||
|
||||
/**
|
||||
* Get message size (from headers).
|
||||
*
|
||||
* @return null|int|string
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Get message subject (from headers).
|
||||
*/
|
||||
public function getSubject(): ?string;
|
||||
|
||||
/**
|
||||
* Get message In-Reply-To (from headers).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getInReplyTo(): array;
|
||||
|
||||
/**
|
||||
* Get message References (from headers).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getReferences(): array;
|
||||
|
||||
/**
|
||||
* Get body HTML.
|
||||
*
|
||||
* @return null|string Null if message has no HTML message part
|
||||
*/
|
||||
public function getBodyHtml(): ?string;
|
||||
|
||||
/**
|
||||
* Get body text.
|
||||
*/
|
||||
public function getBodyText(): ?string;
|
||||
|
||||
/**
|
||||
* Get attachments (if any) linked to this e-mail.
|
||||
*
|
||||
* @return AttachmentInterface[]
|
||||
*/
|
||||
public function getAttachments(): array;
|
||||
|
||||
/**
|
||||
* Does this message have attachments?
|
||||
*/
|
||||
public function hasAttachments(): bool;
|
||||
}
|
||||
70
data/web/inc/lib/vendor/ddeboer/imap/src/Message/EmailAddress.php
vendored
Executable file
70
data/web/inc/lib/vendor/ddeboer/imap/src/Message/EmailAddress.php
vendored
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
/**
|
||||
* An e-mail address.
|
||||
*/
|
||||
final class EmailAddress
|
||||
{
|
||||
private string $mailbox;
|
||||
private ?string $hostname;
|
||||
private ?string $name;
|
||||
private ?string $address;
|
||||
|
||||
public function __construct(string $mailbox, string $hostname = null, string $name = null)
|
||||
{
|
||||
$this->mailbox = $mailbox;
|
||||
$this->hostname = $hostname;
|
||||
$this->name = $name;
|
||||
$this->address = null;
|
||||
|
||||
if (null !== $hostname) {
|
||||
$this->address = $mailbox . '@' . $hostname;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getAddress()
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns address with person name.
|
||||
*/
|
||||
public function getFullAddress(): string
|
||||
{
|
||||
$address = \sprintf('%s@%s', $this->mailbox, $this->hostname);
|
||||
if (null !== $this->name) {
|
||||
$address = \sprintf('"%s" <%s>', \addcslashes($this->name, '"'), $address);
|
||||
}
|
||||
|
||||
return $address;
|
||||
}
|
||||
|
||||
public function getMailbox(): string
|
||||
{
|
||||
return $this->mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getHostname()
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
53
data/web/inc/lib/vendor/ddeboer/imap/src/Message/EmbeddedMessage.php
vendored
Executable file
53
data/web/inc/lib/vendor/ddeboer/imap/src/Message/EmbeddedMessage.php
vendored
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
final class EmbeddedMessage extends AbstractMessage implements EmbeddedMessageInterface
|
||||
{
|
||||
private ?Headers $headers = null;
|
||||
private ?string $rawHeaders = null;
|
||||
private ?string $rawMessage = null;
|
||||
|
||||
public function getHeaders(): Headers
|
||||
{
|
||||
if (null === $this->headers) {
|
||||
$this->headers = new Headers(\imap_rfc822_parse_headers($this->getRawHeaders()));
|
||||
}
|
||||
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
public function getRawHeaders(): string
|
||||
{
|
||||
if (null === $this->rawHeaders) {
|
||||
$rawHeaders = \explode("\r\n\r\n", $this->getRawMessage(), 2);
|
||||
$this->rawHeaders = \current($rawHeaders);
|
||||
}
|
||||
|
||||
return $this->rawHeaders;
|
||||
}
|
||||
|
||||
public function getRawMessage(): string
|
||||
{
|
||||
if (null === $this->rawMessage) {
|
||||
$this->rawMessage = $this->doGetContent($this->getPartNumber());
|
||||
}
|
||||
|
||||
return $this->rawMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content part number.
|
||||
*/
|
||||
protected function getContentPartNumber(): string
|
||||
{
|
||||
$partNumber = $this->getPartNumber();
|
||||
if (0 === \count($this->getParts())) {
|
||||
$partNumber .= '.1';
|
||||
}
|
||||
|
||||
return $partNumber;
|
||||
}
|
||||
}
|
||||
9
data/web/inc/lib/vendor/ddeboer/imap/src/Message/EmbeddedMessageInterface.php
vendored
Executable file
9
data/web/inc/lib/vendor/ddeboer/imap/src/Message/EmbeddedMessageInterface.php
vendored
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
interface EmbeddedMessageInterface extends BasicMessageInterface
|
||||
{
|
||||
}
|
||||
71
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Headers.php
vendored
Executable file
71
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Headers.php
vendored
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
final class Headers extends Parameters
|
||||
{
|
||||
public function __construct(\stdClass $headers)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Store all headers as lowercase
|
||||
$headers = \array_change_key_case((array) $headers);
|
||||
|
||||
foreach ($headers as $key => $value) {
|
||||
$this[$key] = $this->parseHeader($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get header.
|
||||
*
|
||||
* @return null|int|\stdClass[]|string
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return parent::get(\strtolower($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse header.
|
||||
*
|
||||
* @param int|\stdClass[]|string $value
|
||||
*
|
||||
* @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':
|
||||
case 'cc':
|
||||
case 'bcc':
|
||||
case 'reply_to':
|
||||
case 'sender':
|
||||
case 'return_path':
|
||||
\assert(\is_array($value));
|
||||
/** @var \stdClass $address */
|
||||
foreach ($value as $address) {
|
||||
if (isset($address->mailbox)) {
|
||||
$address->host = $address->host ?? null;
|
||||
$address->personal = isset($address->personal) ? $this->decode($address->personal) : null;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
case 'date':
|
||||
case 'subject':
|
||||
\assert(\is_string($value));
|
||||
|
||||
return $this->decode($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
70
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Parameters.php
vendored
Executable file
70
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Parameters.php
vendored
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
/**
|
||||
* @extends \ArrayIterator<int|string, int|string|\stdClass[]>
|
||||
*/
|
||||
class Parameters extends \ArrayIterator
|
||||
{
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private static array $attachmentCustomKeys = [
|
||||
'name*' => 'name',
|
||||
'filename*' => 'filename',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param \stdClass[] $parameters
|
||||
*/
|
||||
public function add(array $parameters = []): void
|
||||
{
|
||||
foreach ($parameters as $parameter) {
|
||||
$key = \strtolower($parameter->attribute);
|
||||
if (isset(self::$attachmentCustomKeys[$key])) {
|
||||
$key = self::$attachmentCustomKeys[$key];
|
||||
}
|
||||
$value = $this->decode($parameter->value);
|
||||
$this[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int|\stdClass[]|string
|
||||
*/
|
||||
public function get(string $key)
|
||||
{
|
||||
return $this[$key] ?? null;
|
||||
}
|
||||
|
||||
final protected function decode(string $value): string
|
||||
{
|
||||
$parts = \imap_mime_header_decode($value);
|
||||
if (!\is_array($parts)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$decoded = '';
|
||||
foreach ($parts as $part) {
|
||||
$text = $part->text;
|
||||
if ('default' !== $part->charset) {
|
||||
$text = Transcoder::decode($text, $part->charset);
|
||||
}
|
||||
// RFC2231
|
||||
if (1 === \preg_match('/^(?<encoding>[^\']+)\'[^\']*?\'(?<urltext>.+)$/', $text, $matches)) {
|
||||
$hasInvalidChars = 1 === \preg_match('#[^%a-zA-Z0-9\-_\.\+]#', $matches['urltext']);
|
||||
$hasEscapedChars = 1 === \preg_match('#%[a-zA-Z0-9]{2}#', $matches['urltext']);
|
||||
if (!$hasInvalidChars && $hasEscapedChars) {
|
||||
$text = Transcoder::decode(\urldecode($matches['urltext']), $matches['encoding']);
|
||||
}
|
||||
}
|
||||
|
||||
$decoded .= $text;
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
112
data/web/inc/lib/vendor/ddeboer/imap/src/Message/PartInterface.php
vendored
Executable file
112
data/web/inc/lib/vendor/ddeboer/imap/src/Message/PartInterface.php
vendored
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
/**
|
||||
* A message part.
|
||||
*/
|
||||
interface PartInterface extends \RecursiveIterator
|
||||
{
|
||||
public const TYPE_TEXT = 'text';
|
||||
public const TYPE_MULTIPART = 'multipart';
|
||||
public const TYPE_MESSAGE = 'message';
|
||||
public const TYPE_APPLICATION = 'application';
|
||||
public const TYPE_AUDIO = 'audio';
|
||||
public const TYPE_IMAGE = 'image';
|
||||
public const TYPE_VIDEO = 'video';
|
||||
public const TYPE_MODEL = 'model';
|
||||
public const TYPE_OTHER = 'other';
|
||||
public const TYPE_UNKNOWN = 'unknown';
|
||||
|
||||
public const ENCODING_7BIT = '7bit';
|
||||
public const ENCODING_8BIT = '8bit';
|
||||
public const ENCODING_BINARY = 'binary';
|
||||
public const ENCODING_BASE64 = 'base64';
|
||||
public const ENCODING_QUOTED_PRINTABLE = 'quoted-printable';
|
||||
public const ENCODING_UNKNOWN = 'unknown';
|
||||
|
||||
public const SUBTYPE_PLAIN = 'PLAIN';
|
||||
public const SUBTYPE_HTML = 'HTML';
|
||||
public const SUBTYPE_RFC822 = 'RFC822';
|
||||
|
||||
/**
|
||||
* Get message number (from headers).
|
||||
*/
|
||||
public function getNumber(): int;
|
||||
|
||||
/**
|
||||
* Part charset.
|
||||
*/
|
||||
public function getCharset(): ?string;
|
||||
|
||||
/**
|
||||
* Part type.
|
||||
*/
|
||||
public function getType(): ?string;
|
||||
|
||||
/**
|
||||
* Part subtype.
|
||||
*/
|
||||
public function getSubtype(): ?string;
|
||||
|
||||
/**
|
||||
* Part encoding.
|
||||
*/
|
||||
public function getEncoding(): ?string;
|
||||
|
||||
/**
|
||||
* Part disposition.
|
||||
*/
|
||||
public function getDisposition(): ?string;
|
||||
|
||||
/**
|
||||
* Part description.
|
||||
*/
|
||||
public function getDescription(): ?string;
|
||||
|
||||
/**
|
||||
* Part bytes.
|
||||
*
|
||||
* @return null|int|string
|
||||
*/
|
||||
public function getBytes();
|
||||
|
||||
/**
|
||||
* Part lines.
|
||||
*/
|
||||
public function getLines(): ?string;
|
||||
|
||||
/**
|
||||
* Part parameters.
|
||||
*/
|
||||
public function getParameters(): Parameters;
|
||||
|
||||
/**
|
||||
* Get raw part content.
|
||||
*/
|
||||
public function getContent(): string;
|
||||
|
||||
/**
|
||||
* Get decoded part content.
|
||||
*/
|
||||
public function getDecodedContent(): string;
|
||||
|
||||
/**
|
||||
* Part structure.
|
||||
*/
|
||||
public function getStructure(): \stdClass;
|
||||
|
||||
/**
|
||||
* Get part number.
|
||||
*/
|
||||
public function getPartNumber(): string;
|
||||
|
||||
/**
|
||||
* Get an array of all parts for this message.
|
||||
*
|
||||
* @return PartInterface[]
|
||||
*/
|
||||
public function getParts(): array;
|
||||
}
|
||||
12
data/web/inc/lib/vendor/ddeboer/imap/src/Message/SimplePart.php
vendored
Executable file
12
data/web/inc/lib/vendor/ddeboer/imap/src/Message/SimplePart.php
vendored
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
/**
|
||||
* A message part.
|
||||
*/
|
||||
final class SimplePart extends AbstractPart
|
||||
{
|
||||
}
|
||||
333
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Transcoder.php
vendored
Executable file
333
data/web/inc/lib/vendor/ddeboer/imap/src/Message/Transcoder.php
vendored
Executable file
|
|
@ -0,0 +1,333 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Message;
|
||||
|
||||
use Ddeboer\Imap\Exception\UnsupportedCharsetException;
|
||||
|
||||
final class Transcoder
|
||||
{
|
||||
/**
|
||||
* @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 const CHARSET_ALIASES = [
|
||||
'128' => 'Shift_JIS',
|
||||
'129' => 'EUC-KR',
|
||||
'134' => 'GB2312',
|
||||
'136' => 'Big5',
|
||||
'161' => 'windows-1253',
|
||||
'162' => 'windows-1254',
|
||||
'177' => 'windows-1255',
|
||||
'178' => 'windows-1256',
|
||||
'186' => 'windows-1257',
|
||||
'204' => 'windows-1251',
|
||||
'222' => 'windows-874',
|
||||
'238' => 'windows-1250',
|
||||
'5601' => 'EUC-KR',
|
||||
'646' => 'us-ascii',
|
||||
'850' => 'IBM850',
|
||||
'852' => 'IBM852',
|
||||
'855' => 'IBM855',
|
||||
'857' => 'IBM857',
|
||||
'862' => 'IBM862',
|
||||
'864' => 'IBM864',
|
||||
'864i' => 'IBM864i',
|
||||
'866' => 'IBM866',
|
||||
'ansi-1251' => 'windows-1251',
|
||||
'ansi_x3.4-1968' => 'us-ascii',
|
||||
'arabic' => 'ISO-8859-6',
|
||||
'ascii' => 'us-ascii',
|
||||
'asmo-708' => 'ISO-8859-6',
|
||||
'big5-hkscs' => 'Big5',
|
||||
'chinese' => 'GB2312',
|
||||
'cn-big5' => 'Big5',
|
||||
'cns11643' => 'x-euc-tw',
|
||||
'cp-866' => 'IBM866',
|
||||
'cp1250' => 'windows-1250',
|
||||
'cp1251' => 'windows-1251',
|
||||
'cp1252' => 'windows-1252',
|
||||
'cp1253' => 'windows-1253',
|
||||
'cp1254' => 'windows-1254',
|
||||
'cp1255' => 'windows-1255',
|
||||
'cp1256' => 'windows-1256',
|
||||
'cp1257' => 'windows-1257',
|
||||
'cp1258' => 'windows-1258',
|
||||
'cp819' => 'ISO-8859-1',
|
||||
'cp850' => 'IBM850',
|
||||
'cp852' => 'IBM852',
|
||||
'cp855' => 'IBM855',
|
||||
'cp857' => 'IBM857',
|
||||
'cp862' => 'IBM862',
|
||||
'cp864' => 'IBM864',
|
||||
'cp864i' => 'IBM864i',
|
||||
'cp866' => 'IBM866',
|
||||
'cp932' => 'Shift_JIS',
|
||||
'csbig5' => 'Big5',
|
||||
'cseucjpkdfmtjapanese' => 'EUC-JP',
|
||||
'cseuckr' => 'EUC-KR',
|
||||
'cseucpkdfmtjapanese' => 'EUC-JP',
|
||||
'csgb2312' => 'GB2312',
|
||||
'csibm850' => 'IBM850',
|
||||
'csibm852' => 'IBM852',
|
||||
'csibm855' => 'IBM855',
|
||||
'csibm857' => 'IBM857',
|
||||
'csibm862' => 'IBM862',
|
||||
'csibm864' => 'IBM864',
|
||||
'csibm864i' => 'IBM864i',
|
||||
'csibm866' => 'IBM866',
|
||||
'csiso103t618bit' => 'T.61-8bit',
|
||||
'csiso111ecmacyrillic' => 'ISO-IR-111',
|
||||
'csiso2022jp' => 'ISO-2022-JP',
|
||||
'csiso2022jp2' => 'ISO-2022-JP',
|
||||
'csiso2022kr' => 'ISO-2022-KR',
|
||||
'csiso58gb231280' => 'GB2312',
|
||||
'csiso88596e' => 'ISO-8859-6-E',
|
||||
'csiso88596i' => 'ISO-8859-6-I',
|
||||
'csiso88598e' => 'ISO-8859-8-E',
|
||||
'csiso88598i' => 'ISO-8859-8-I',
|
||||
'csisolatin1' => 'ISO-8859-1',
|
||||
'csisolatin2' => 'ISO-8859-2',
|
||||
'csisolatin3' => 'ISO-8859-3',
|
||||
'csisolatin4' => 'ISO-8859-4',
|
||||
'csisolatin5' => 'ISO-8859-9',
|
||||
'csisolatin6' => 'ISO-8859-10',
|
||||
'csisolatin9' => 'ISO-8859-15',
|
||||
'csisolatinarabic' => 'ISO-8859-6',
|
||||
'csisolatincyrillic' => 'ISO-8859-5',
|
||||
'csisolatingreek' => 'ISO-8859-7',
|
||||
'csisolatinhebrew' => 'ISO-8859-8',
|
||||
'cskoi8r' => 'KOI8-R',
|
||||
'csksc56011987' => 'EUC-KR',
|
||||
'csmacintosh' => 'x-mac-roman',
|
||||
'csshiftjis' => 'Shift_JIS',
|
||||
'csueckr' => 'EUC-KR',
|
||||
'csunicode' => 'UTF-16BE',
|
||||
'csunicode11' => 'UTF-16BE',
|
||||
'csunicode11utf7' => 'UTF-7',
|
||||
'csunicodeascii' => 'UTF-16BE',
|
||||
'csunicodelatin1' => 'UTF-16BE',
|
||||
'csviqr' => 'VIQR',
|
||||
'csviscii' => 'VISCII',
|
||||
'cyrillic' => 'ISO-8859-5',
|
||||
'dos-874' => 'windows-874',
|
||||
'ecma-114' => 'ISO-8859-6',
|
||||
'ecma-118' => 'ISO-8859-7',
|
||||
'ecma-cyrillic' => 'ISO-IR-111',
|
||||
'elot_928' => 'ISO-8859-7',
|
||||
'gb_2312' => 'GB2312',
|
||||
'gb_2312-80' => 'GB2312',
|
||||
'greek' => 'ISO-8859-7',
|
||||
'greek8' => 'ISO-8859-7',
|
||||
'hebrew' => 'ISO-8859-8',
|
||||
'ibm-864' => 'IBM864',
|
||||
'ibm-864i' => 'IBM864i',
|
||||
'ibm819' => 'ISO-8859-1',
|
||||
'ibm874' => 'windows-874',
|
||||
'iso-10646' => 'UTF-16BE',
|
||||
'iso-10646-j-1' => 'UTF-16BE',
|
||||
'iso-10646-ucs-2' => 'UTF-16BE',
|
||||
'iso-10646-ucs-4' => 'UTF-32BE',
|
||||
'iso-10646-ucs-basic' => 'UTF-16BE',
|
||||
'iso-10646-unicode-latin1' => 'UTF-16BE',
|
||||
'iso-2022-cn-ext' => 'ISO-2022-CN',
|
||||
'iso-2022-jp-2' => 'ISO-2022-JP',
|
||||
'iso-8859-8i' => 'ISO-8859-8-I',
|
||||
'iso-ir-100' => 'ISO-8859-1',
|
||||
'iso-ir-101' => 'ISO-8859-2',
|
||||
'iso-ir-103' => 'T.61-8bit',
|
||||
'iso-ir-109' => 'ISO-8859-3',
|
||||
'iso-ir-110' => 'ISO-8859-4',
|
||||
'iso-ir-126' => 'ISO-8859-7',
|
||||
'iso-ir-127' => 'ISO-8859-6',
|
||||
'iso-ir-138' => 'ISO-8859-8',
|
||||
'iso-ir-144' => 'ISO-8859-5',
|
||||
'iso-ir-148' => 'ISO-8859-9',
|
||||
'iso-ir-149' => 'EUC-KR',
|
||||
'iso-ir-157' => 'ISO-8859-10',
|
||||
'iso-ir-58' => 'GB2312',
|
||||
'iso8859-1' => 'ISO-8859-1',
|
||||
'iso8859-10' => 'ISO-8859-10',
|
||||
'iso8859-11' => 'ISO-8859-11',
|
||||
'iso8859-13' => 'ISO-8859-13',
|
||||
'iso8859-14' => 'ISO-8859-14',
|
||||
'iso8859-15' => 'ISO-8859-15',
|
||||
'iso8859-2' => 'ISO-8859-2',
|
||||
'iso8859-3' => 'ISO-8859-3',
|
||||
'iso8859-4' => 'ISO-8859-4',
|
||||
'iso8859-5' => 'ISO-8859-5',
|
||||
'iso8859-6' => 'ISO-8859-6',
|
||||
'iso8859-7' => 'ISO-8859-7',
|
||||
'iso8859-8' => 'ISO-8859-8',
|
||||
'iso8859-9' => 'ISO-8859-9',
|
||||
'iso88591' => 'ISO-8859-1',
|
||||
'iso885910' => 'ISO-8859-10',
|
||||
'iso885911' => 'ISO-8859-11',
|
||||
'iso885912' => 'ISO-8859-12',
|
||||
'iso885913' => 'ISO-8859-13',
|
||||
'iso885914' => 'ISO-8859-14',
|
||||
'iso885915' => 'ISO-8859-15',
|
||||
'iso88592' => 'ISO-8859-2',
|
||||
'iso88593' => 'ISO-8859-3',
|
||||
'iso88594' => 'ISO-8859-4',
|
||||
'iso88595' => 'ISO-8859-5',
|
||||
'iso88596' => 'ISO-8859-6',
|
||||
'iso88597' => 'ISO-8859-7',
|
||||
'iso88598' => 'ISO-8859-8',
|
||||
'iso88599' => 'ISO-8859-9',
|
||||
'iso_8859-1' => 'ISO-8859-1',
|
||||
'iso_8859-15' => 'ISO-8859-15',
|
||||
'iso_8859-1:1987' => 'ISO-8859-1',
|
||||
'iso_8859-2' => 'ISO-8859-2',
|
||||
'iso_8859-2:1987' => 'ISO-8859-2',
|
||||
'iso_8859-3' => 'ISO-8859-3',
|
||||
'iso_8859-3:1988' => 'ISO-8859-3',
|
||||
'iso_8859-4' => 'ISO-8859-4',
|
||||
'iso_8859-4:1988' => 'ISO-8859-4',
|
||||
'iso_8859-5' => 'ISO-8859-5',
|
||||
'iso_8859-5:1988' => 'ISO-8859-5',
|
||||
'iso_8859-6' => 'ISO-8859-6',
|
||||
'iso_8859-6:1987' => 'ISO-8859-6',
|
||||
'iso_8859-7' => 'ISO-8859-7',
|
||||
'iso_8859-7:1987' => 'ISO-8859-7',
|
||||
'iso_8859-8' => 'ISO-8859-8',
|
||||
'iso_8859-8:1988' => 'ISO-8859-8',
|
||||
'iso_8859-9' => 'ISO-8859-9',
|
||||
'iso_8859-9:1989' => 'ISO-8859-9',
|
||||
'koi' => 'KOI8-R',
|
||||
'koi8' => 'KOI8-R',
|
||||
'koi8-ru' => 'KOI8-U',
|
||||
'koi8_r' => 'KOI8-R',
|
||||
'korean' => 'EUC-KR',
|
||||
'ks_c_5601-1987' => 'EUC-KR',
|
||||
'ks_c_5601-1989' => 'EUC-KR',
|
||||
'ksc5601' => 'EUC-KR',
|
||||
'ksc_5601' => 'EUC-KR',
|
||||
'l1' => 'ISO-8859-1',
|
||||
'l2' => 'ISO-8859-2',
|
||||
'l3' => 'ISO-8859-3',
|
||||
'l4' => 'ISO-8859-4',
|
||||
'l5' => 'ISO-8859-9',
|
||||
'l6' => 'ISO-8859-10',
|
||||
'l9' => 'ISO-8859-15',
|
||||
'latin1' => 'ISO-8859-1',
|
||||
'latin2' => 'ISO-8859-2',
|
||||
'latin3' => 'ISO-8859-3',
|
||||
'latin4' => 'ISO-8859-4',
|
||||
'latin5' => 'ISO-8859-9',
|
||||
'latin6' => 'ISO-8859-10',
|
||||
'logical' => 'ISO-8859-8-I',
|
||||
'mac' => 'x-mac-roman',
|
||||
'macintosh' => 'x-mac-roman',
|
||||
'ms932' => 'Shift_JIS',
|
||||
'ms_kanji' => 'Shift_JIS',
|
||||
'shift-jis' => 'Shift_JIS',
|
||||
'sjis' => 'Shift_JIS',
|
||||
'sun_eu_greek' => 'ISO-8859-7',
|
||||
't.61' => 'T.61-8bit',
|
||||
'tis620' => 'TIS-620',
|
||||
'unicode-1-1-utf-7' => 'UTF-7',
|
||||
'unicode-1-1-utf-8' => 'UTF-8',
|
||||
'unicode-2-0-utf-7' => 'UTF-7',
|
||||
'visual' => 'ISO-8859-8',
|
||||
'windows-31j' => 'Shift_JIS',
|
||||
'windows-949' => 'EUC-KR',
|
||||
'x-cp1250' => 'windows-1250',
|
||||
'x-cp1251' => 'windows-1251',
|
||||
'x-cp1252' => 'windows-1252',
|
||||
'x-cp1253' => 'windows-1253',
|
||||
'x-cp1254' => 'windows-1254',
|
||||
'x-cp1255' => 'windows-1255',
|
||||
'x-cp1256' => 'windows-1256',
|
||||
'x-cp1257' => 'windows-1257',
|
||||
'x-cp1258' => 'windows-1258',
|
||||
'x-euc-jp' => 'EUC-JP',
|
||||
'x-gbk' => 'gbk',
|
||||
'x-iso-10646-ucs-2-be' => 'UTF-16BE',
|
||||
'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',
|
||||
'zh_cn.euc' => 'GB2312',
|
||||
'zh_tw-big5' => 'Big5',
|
||||
'zh_tw-euc' => 'x-euc-tw',
|
||||
];
|
||||
|
||||
/**
|
||||
* Decode text to UTF-8.
|
||||
*
|
||||
* @param string $text Text to decode
|
||||
* @param string $fromCharset Original charset
|
||||
*/
|
||||
public static function decode(string $text, string $fromCharset): string
|
||||
{
|
||||
static $utf8Aliases = [
|
||||
'unicode-1-1-utf-8' => true,
|
||||
'utf8' => true,
|
||||
'utf-8' => true,
|
||||
'UTF8' => true,
|
||||
'UTF-8' => true,
|
||||
];
|
||||
|
||||
if (isset($utf8Aliases[$fromCharset])) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$originalFromCharset = $fromCharset;
|
||||
$lowercaseFromCharset = \strtolower($fromCharset);
|
||||
if (isset(self::CHARSET_ALIASES[$lowercaseFromCharset])) {
|
||||
$fromCharset = self::CHARSET_ALIASES[$lowercaseFromCharset];
|
||||
}
|
||||
|
||||
\set_error_handler(static function (): bool {
|
||||
return true;
|
||||
});
|
||||
|
||||
$iconvDecodedText = \iconv($fromCharset, 'UTF-8', $text);
|
||||
if (false === $iconvDecodedText) {
|
||||
$iconvDecodedText = \iconv($originalFromCharset, 'UTF-8', $text);
|
||||
}
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
if (false !== $iconvDecodedText) {
|
||||
return $iconvDecodedText;
|
||||
}
|
||||
|
||||
$errorMessage = null;
|
||||
$errorNumber = 0;
|
||||
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
|
||||
$errorMessage = $message;
|
||||
$errorNumber = $nr;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$decodedText = '';
|
||||
|
||||
try {
|
||||
$decodedText = \mb_convert_encoding($text, 'UTF-8', $fromCharset);
|
||||
} catch (\Error $error) {
|
||||
$errorMessage = $error->getMessage();
|
||||
}
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
if (null !== $errorMessage) {
|
||||
throw new UnsupportedCharsetException(\sprintf(
|
||||
'Unsupported charset "%s"%s: %s',
|
||||
$originalFromCharset,
|
||||
($fromCharset !== $originalFromCharset) ? \sprintf(' (alias found: "%s")', $fromCharset) : '',
|
||||
$errorMessage
|
||||
), $errorNumber);
|
||||
}
|
||||
|
||||
return $decodedText;
|
||||
}
|
||||
}
|
||||
110
data/web/inc/lib/vendor/ddeboer/imap/src/MessageInterface.php
vendored
Executable file
110
data/web/inc/lib/vendor/ddeboer/imap/src/MessageInterface.php
vendored
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
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).
|
||||
*/
|
||||
interface MessageInterface extends Message\BasicMessageInterface
|
||||
{
|
||||
/**
|
||||
* Get raw part content.
|
||||
*/
|
||||
public function getContent(): string;
|
||||
|
||||
/**
|
||||
* Get message recent flag value (from headers).
|
||||
*/
|
||||
public function isRecent(): ?string;
|
||||
|
||||
/**
|
||||
* Get message unseen flag value (from headers).
|
||||
*/
|
||||
public function isUnseen(): bool;
|
||||
|
||||
/**
|
||||
* Get message flagged flag value (from headers).
|
||||
*/
|
||||
public function isFlagged(): bool;
|
||||
|
||||
/**
|
||||
* Get message answered flag value (from headers).
|
||||
*/
|
||||
public function isAnswered(): bool;
|
||||
|
||||
/**
|
||||
* Get message deleted flag value (from headers).
|
||||
*/
|
||||
public function isDeleted(): bool;
|
||||
|
||||
/**
|
||||
* Get message draft flag value (from headers).
|
||||
*/
|
||||
public function isDraft(): bool;
|
||||
|
||||
/**
|
||||
* Has the message been marked as read?
|
||||
*/
|
||||
public function isSeen(): bool;
|
||||
|
||||
/**
|
||||
* Mark message as seen.
|
||||
*
|
||||
* @deprecated since version 1.1, to be removed in 2.0
|
||||
*/
|
||||
public function maskAsSeen(): bool;
|
||||
|
||||
/**
|
||||
* Mark message as seen.
|
||||
*/
|
||||
public function markAsSeen(): bool;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Set Flag Message.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
*/
|
||||
public function setFlag(string $flag): bool;
|
||||
|
||||
/**
|
||||
* Clear Flag Message.
|
||||
*
|
||||
* @param string $flag \Seen, \Answered, \Flagged, \Deleted, and \Draft
|
||||
*/
|
||||
public function clearFlag(string $flag): bool;
|
||||
}
|
||||
49
data/web/inc/lib/vendor/ddeboer/imap/src/MessageIterator.php
vendored
Executable file
49
data/web/inc/lib/vendor/ddeboer/imap/src/MessageIterator.php
vendored
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Message\PartInterface;
|
||||
|
||||
/**
|
||||
* @extends \ArrayIterator<int, MessageInterface>
|
||||
*/
|
||||
final class MessageIterator extends \ArrayIterator implements MessageIteratorInterface
|
||||
{
|
||||
private ImapResourceInterface $resource;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ImapResourceInterface $resource IMAP resource
|
||||
* @param int[] $messageNumbers Array of message numbers
|
||||
*/
|
||||
public function __construct(ImapResourceInterface $resource, array $messageNumbers)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
|
||||
parent::__construct($messageNumbers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current message.
|
||||
*
|
||||
* @return MessageInterface<PartInterface>
|
||||
*/
|
||||
public function current(): MessageInterface
|
||||
{
|
||||
$current = parent::current();
|
||||
if (!\is_int($current)) {
|
||||
throw new Exception\OutOfBoundsException(\sprintf(
|
||||
'The current value "%s" isn\'t an integer and doesn\'t represent a message;'
|
||||
. ' try to cycle this "%s" with a native php function like foreach or with the method getArrayCopy(),'
|
||||
. ' or check it by calling the methods valid().',
|
||||
\is_object($current) ? \get_class($current) : \gettype($current),
|
||||
static::class
|
||||
));
|
||||
}
|
||||
|
||||
return new Message($this->resource, $current);
|
||||
}
|
||||
}
|
||||
20
data/web/inc/lib/vendor/ddeboer/imap/src/MessageIteratorInterface.php
vendored
Executable file
20
data/web/inc/lib/vendor/ddeboer/imap/src/MessageIteratorInterface.php
vendored
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Message\PartInterface;
|
||||
|
||||
/**
|
||||
* @extends \Iterator<MessageInterface>
|
||||
*/
|
||||
interface MessageIteratorInterface extends \Iterator, \Countable
|
||||
{
|
||||
/**
|
||||
* Get current message.
|
||||
*
|
||||
* @return MessageInterface<PartInterface>
|
||||
*/
|
||||
public function current(): MessageInterface;
|
||||
}
|
||||
47
data/web/inc/lib/vendor/ddeboer/imap/src/Search/AbstractDate.php
vendored
Executable file
47
data/web/inc/lib/vendor/ddeboer/imap/src/Search/AbstractDate.php
vendored
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
* Represents a date condition.
|
||||
*/
|
||||
abstract class AbstractDate implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Format for dates to be sent to the IMAP server.
|
||||
*/
|
||||
private string $dateFormat;
|
||||
|
||||
/**
|
||||
* The date to be used for the condition.
|
||||
*/
|
||||
private DateTimeInterface $date;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param DateTimeInterface $date optional date for the condition
|
||||
*/
|
||||
public function __construct(DateTimeInterface $date, string $dateFormat = 'j-M-Y')
|
||||
{
|
||||
$this->date = $date;
|
||||
$this->dateFormat = $dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the condition to a string that can be sent to the IMAP server.
|
||||
*/
|
||||
final public function toString(): string
|
||||
{
|
||||
return \sprintf('%s "%s"', $this->getKeyword(), $this->date->format($this->dateFormat));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
abstract protected function getKeyword(): string;
|
||||
}
|
||||
40
data/web/inc/lib/vendor/ddeboer/imap/src/Search/AbstractText.php
vendored
Executable file
40
data/web/inc/lib/vendor/ddeboer/imap/src/Search/AbstractText.php
vendored
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search;
|
||||
|
||||
/**
|
||||
* Represents a text based condition. Text based conditions use a contains
|
||||
* restriction.
|
||||
*/
|
||||
abstract class AbstractText implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Text to be used for the condition.
|
||||
*/
|
||||
private string $text;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $text optional text for the condition
|
||||
*/
|
||||
public function __construct(string $text)
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the condition to a string that can be sent to the IMAP server.
|
||||
*/
|
||||
final public function toString(): string
|
||||
{
|
||||
return \sprintf('%s "%s"', $this->getKeyword(), $this->text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
abstract protected function getKeyword(): string;
|
||||
}
|
||||
16
data/web/inc/lib/vendor/ddeboer/imap/src/Search/ConditionInterface.php
vendored
Executable file
16
data/web/inc/lib/vendor/ddeboer/imap/src/Search/ConditionInterface.php
vendored
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search;
|
||||
|
||||
/**
|
||||
* Represents a condition that can be used in a search expression.
|
||||
*/
|
||||
interface ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Converts the condition to a string that can be sent to the IMAP server.
|
||||
*/
|
||||
public function toString(): string;
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Date/Before.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Date/Before.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Date;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractDate;
|
||||
|
||||
/**
|
||||
* Represents a date before condition. Messages must have a date before the
|
||||
* specified date in order to match the condition.
|
||||
*/
|
||||
final class Before extends AbstractDate
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'BEFORE';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Date/On.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Date/On.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Date;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractDate;
|
||||
|
||||
/**
|
||||
* Represents a date on condition. Messages must have a date matching the
|
||||
* specified date in order to match the condition.
|
||||
*/
|
||||
final class On extends AbstractDate
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'ON';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Date/Since.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Date/Since.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Date;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractDate;
|
||||
|
||||
/**
|
||||
* Represents a date after condition. Messages must have a date after the
|
||||
* specified date in order to match the condition.
|
||||
*/
|
||||
final class Since extends AbstractDate
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'SINCE';
|
||||
}
|
||||
}
|
||||
23
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/Bcc.php
vendored
Executable file
23
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/Bcc.php
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Email;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a "Bcc" email address condition. Messages must have been addressed
|
||||
* to the specified recipient (along with any others) in order to match the
|
||||
* condition.
|
||||
*/
|
||||
final class Bcc extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'BCC';
|
||||
}
|
||||
}
|
||||
23
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/Cc.php
vendored
Executable file
23
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/Cc.php
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Email;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a "Cc" email address condition. Messages must have been addressed
|
||||
* to the specified recipient (along with any others) in order to match the
|
||||
* condition.
|
||||
*/
|
||||
final class Cc extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'CC';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/From.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/From.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Email;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a "From" email address condition. Messages must have been sent
|
||||
* from the specified email address in order to match the condition.
|
||||
*/
|
||||
final class From extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'FROM';
|
||||
}
|
||||
}
|
||||
23
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/To.php
vendored
Executable file
23
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Email/To.php
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Email;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a "To" email address condition. Messages must have been addressed
|
||||
* to the specified recipient (along with any others) in order to match the
|
||||
* condition.
|
||||
*/
|
||||
final class To extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'TO';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Answered.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Answered.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Flag;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an ANSWERED flag condition. Messages must have the \\ANSWERED flag
|
||||
* set in order to match the condition.
|
||||
*/
|
||||
final class Answered implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'ANSWERED';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Flagged.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Flagged.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Flag;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents a FLAGGED flag condition. Messages must have the \\FLAGGED flag
|
||||
* (i.e. urgent or important) set in order to match the condition.
|
||||
*/
|
||||
final class Flagged implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'FLAGGED';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Recent.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Recent.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Flag;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an RECENT flag condition. Messages must have the \\RECENT flag
|
||||
* set in order to match the condition.
|
||||
*/
|
||||
final class Recent implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'RECENT';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Seen.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Seen.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Flag;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an SEEN flag condition. Messages must have the \\SEEN flag
|
||||
* set in order to match the condition.
|
||||
*/
|
||||
final class Seen implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'SEEN';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Unanswered.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Unanswered.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Flag;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an UNANSWERED flag condition. Messages must not have the
|
||||
* \\ANSWERED flag set in order to match the condition.
|
||||
*/
|
||||
final class Unanswered implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'UNANSWERED';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Unflagged.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Unflagged.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Flag;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents a UNFLAGGED flag condition. Messages must no have the \\FLAGGED
|
||||
* flag (i.e. urgent or important) set in order to match the condition.
|
||||
*/
|
||||
final class Unflagged implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'UNFLAGGED';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Unseen.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Flag/Unseen.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Flag;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an UNSEEN flag condition. Messages must not have the \\SEEN flag
|
||||
* set in order to match the condition.
|
||||
*/
|
||||
final class Unseen implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'UNSEEN';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/LogicalOperator/All.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/LogicalOperator/All.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\LogicalOperator;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an ALL operator. Messages must match all conditions following this
|
||||
* operator in order to match the expression.
|
||||
*/
|
||||
final class All implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'ALL';
|
||||
}
|
||||
}
|
||||
55
data/web/inc/lib/vendor/ddeboer/imap/src/Search/LogicalOperator/OrConditions.php
vendored
Executable file
55
data/web/inc/lib/vendor/ddeboer/imap/src/Search/LogicalOperator/OrConditions.php
vendored
Executable file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\LogicalOperator;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an OR operator. Messages only need to match one of the conditions
|
||||
* after this operator to match the expression.
|
||||
*/
|
||||
final class OrConditions implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* The conditions that together represent the expression.
|
||||
*
|
||||
* @var ConditionInterface[]
|
||||
*/
|
||||
private array $conditions = [];
|
||||
|
||||
/**
|
||||
* @param ConditionInterface[] $conditions
|
||||
*/
|
||||
public function __construct(array $conditions)
|
||||
{
|
||||
foreach ($conditions as $condition) {
|
||||
$this->addCondition($condition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new condition to the expression.
|
||||
*
|
||||
* @param ConditionInterface $condition the condition to be added
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addCondition(ConditionInterface $condition)
|
||||
{
|
||||
$this->conditions[] = $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
$conditions = \array_map(static function (ConditionInterface $condition): string {
|
||||
return $condition->toString();
|
||||
}, $this->conditions);
|
||||
|
||||
return \sprintf('( %s )', \implode(' OR ', $conditions));
|
||||
}
|
||||
}
|
||||
29
data/web/inc/lib/vendor/ddeboer/imap/src/Search/RawExpression.php
vendored
Executable file
29
data/web/inc/lib/vendor/ddeboer/imap/src/Search/RawExpression.php
vendored
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search;
|
||||
|
||||
/**
|
||||
* Represents a raw expression.
|
||||
*/
|
||||
final class RawExpression implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Text to be used for the condition.
|
||||
*/
|
||||
private string $expression;
|
||||
|
||||
/**
|
||||
* @param string $expression text for the condition
|
||||
*/
|
||||
public function __construct(string $expression)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->expression;
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/Deleted.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/Deleted.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\State;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents a DELETED condition. Messages must have been marked for deletion
|
||||
* but not yet expunged in order to match the condition.
|
||||
*/
|
||||
final class Deleted implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'DELETED';
|
||||
}
|
||||
}
|
||||
21
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/NewMessage.php
vendored
Executable file
21
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/NewMessage.php
vendored
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\State;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents a NEW condition. Only new messages will match this condition.
|
||||
*/
|
||||
final class NewMessage implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'NEW';
|
||||
}
|
||||
}
|
||||
21
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/Old.php
vendored
Executable file
21
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/Old.php
vendored
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\State;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents an OLD condition. Only old messages will match this condition.
|
||||
*/
|
||||
final class Old implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'OLD';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/Undeleted.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/State/Undeleted.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\State;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Represents a UNDELETED condition. Messages must not have been marked for
|
||||
* deletion in order to match the condition.
|
||||
*/
|
||||
final class Undeleted implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return 'UNDELETED';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Body.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Body.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Text;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a body text contains condition. Messages must have a body
|
||||
* containing the specified text in order to match the condition.
|
||||
*/
|
||||
final class Body extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'BODY';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Keyword.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Keyword.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Text;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a keyword text contains condition. Messages must have a keyword
|
||||
* matching the specified text in order to match the condition.
|
||||
*/
|
||||
final class Keyword extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'KEYWORD';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Subject.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Subject.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Text;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a subject contains condition. Messages must have a subject
|
||||
* containing the specified text in order to match the condition.
|
||||
*/
|
||||
final class Subject extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'SUBJECT';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Text.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Text.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Text;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a message text contains condition. Messages must contain the
|
||||
* specified text in order to match the condition.
|
||||
*/
|
||||
final class Text extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'TEXT';
|
||||
}
|
||||
}
|
||||
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Unkeyword.php
vendored
Executable file
22
data/web/inc/lib/vendor/ddeboer/imap/src/Search/Text/Unkeyword.php
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap\Search\Text;
|
||||
|
||||
use Ddeboer\Imap\Search\AbstractText;
|
||||
|
||||
/**
|
||||
* Represents a keyword text does not contain condition. Messages must not have
|
||||
* a keyword matching the specified text in order to match the condition.
|
||||
*/
|
||||
final class Unkeyword extends AbstractText
|
||||
{
|
||||
/**
|
||||
* Returns the keyword that the condition represents.
|
||||
*/
|
||||
protected function getKeyword(): string
|
||||
{
|
||||
return 'UNKEYWORD';
|
||||
}
|
||||
}
|
||||
44
data/web/inc/lib/vendor/ddeboer/imap/src/SearchExpression.php
vendored
Executable file
44
data/web/inc/lib/vendor/ddeboer/imap/src/SearchExpression.php
vendored
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Search\ConditionInterface;
|
||||
|
||||
/**
|
||||
* Defines a search expression that can be used to look up email messages.
|
||||
*/
|
||||
final class SearchExpression implements ConditionInterface
|
||||
{
|
||||
/**
|
||||
* The conditions that together represent the expression.
|
||||
*
|
||||
* @var ConditionInterface[]
|
||||
*/
|
||||
private array $conditions = [];
|
||||
|
||||
/**
|
||||
* Adds a new condition to the expression.
|
||||
*
|
||||
* @param ConditionInterface $condition the condition to be added
|
||||
*/
|
||||
public function addCondition(ConditionInterface $condition): self
|
||||
{
|
||||
$this->conditions[] = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the expression to a string that can be sent to the IMAP server.
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
$conditions = \array_map(static function (ConditionInterface $condition): string {
|
||||
return $condition->toString();
|
||||
}, $this->conditions);
|
||||
|
||||
return \implode(' ', $conditions);
|
||||
}
|
||||
}
|
||||
126
data/web/inc/lib/vendor/ddeboer/imap/src/Server.php
vendored
Executable file
126
data/web/inc/lib/vendor/ddeboer/imap/src/Server.php
vendored
Executable file
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
use Ddeboer\Imap\Exception\AuthenticationFailedException;
|
||||
use Ddeboer\Imap\Exception\ResourceCheckFailureException;
|
||||
|
||||
/**
|
||||
* An IMAP server.
|
||||
*/
|
||||
final class Server implements ServerInterface
|
||||
{
|
||||
private string $hostname;
|
||||
private string $port;
|
||||
private string $flags;
|
||||
/**
|
||||
* @var mixed[]
|
||||
*/
|
||||
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 mixed[] $parameters Connection parameters
|
||||
* @param int $options Connection options
|
||||
* @param int $retries Retries number
|
||||
*/
|
||||
public function __construct(
|
||||
string $hostname,
|
||||
string $port = '993',
|
||||
string $flags = '/imap/ssl/validate-cert',
|
||||
array $parameters = [],
|
||||
int $options = 0,
|
||||
int $retries = 1
|
||||
) {
|
||||
if (!\function_exists('imap_open')) {
|
||||
throw new \RuntimeException('IMAP extension must be enabled');
|
||||
}
|
||||
|
||||
$this->hostname = $hostname;
|
||||
$this->port = $port;
|
||||
$this->flags = '' !== $flags ? '/' . \ltrim($flags, '/') : '';
|
||||
$this->parameters = $parameters;
|
||||
$this->options = $options;
|
||||
$this->retries = $retries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate connection.
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $password Password
|
||||
*
|
||||
* @throws AuthenticationFailedException
|
||||
*/
|
||||
public function authenticate(string $username, string $password): ConnectionInterface
|
||||
{
|
||||
$errorMessage = null;
|
||||
$errorNumber = 0;
|
||||
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
|
||||
$errorMessage = $message;
|
||||
$errorNumber = $nr;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$resource = \imap_open(
|
||||
$this->getServerString(),
|
||||
$username,
|
||||
$password,
|
||||
$this->options,
|
||||
$this->retries,
|
||||
$this->parameters
|
||||
);
|
||||
|
||||
\restore_error_handler();
|
||||
|
||||
if (false === $resource || null !== $errorMessage) {
|
||||
throw new AuthenticationFailedException(\sprintf(
|
||||
'Authentication failed for user "%s"%s',
|
||||
$username,
|
||||
null !== $errorMessage ? ': ' . $errorMessage : ''
|
||||
), $errorNumber);
|
||||
}
|
||||
|
||||
$check = \imap_check($resource);
|
||||
|
||||
if (false === $check) {
|
||||
throw new ResourceCheckFailureException('Resource check failure');
|
||||
}
|
||||
|
||||
$mailbox = $check->Mailbox;
|
||||
$connection = $mailbox;
|
||||
$curlyPosition = \strpos($mailbox, '}');
|
||||
if (false !== $curlyPosition) {
|
||||
$connection = \substr($mailbox, 0, $curlyPosition + 1);
|
||||
}
|
||||
|
||||
// These are necessary to get rid of PHP throwing IMAP errors
|
||||
\imap_errors();
|
||||
\imap_alerts();
|
||||
|
||||
return new Connection(new ImapResource($resource), $connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Glues hostname, port and flags and returns result.
|
||||
*/
|
||||
private function getServerString(): string
|
||||
{
|
||||
return \sprintf(
|
||||
'{%s%s%s}',
|
||||
$this->hostname,
|
||||
'' !== $this->port ? ':' . $this->port : '',
|
||||
$this->flags
|
||||
);
|
||||
}
|
||||
}
|
||||
19
data/web/inc/lib/vendor/ddeboer/imap/src/ServerInterface.php
vendored
Executable file
19
data/web/inc/lib/vendor/ddeboer/imap/src/ServerInterface.php
vendored
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ddeboer\Imap;
|
||||
|
||||
/**
|
||||
* An IMAP server.
|
||||
*/
|
||||
interface ServerInterface
|
||||
{
|
||||
/**
|
||||
* Authenticate connection.
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $password Password
|
||||
*/
|
||||
public function authenticate(string $username, string $password): ConnectionInterface;
|
||||
}
|
||||
25
data/web/inc/lib/vendor/ddeboer/imap/src/Test/RawMessageIterator.php
vendored
Executable file
25
data/web/inc/lib/vendor/ddeboer/imap/src/Test/RawMessageIterator.php
vendored
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue