[Web] Update composer libraries

This commit is contained in:
FreddleSpl0it committed 2026-10-28 11:56:29 +01:00
1 parent 9cc8ac2908
commit bd8c784118
1297 files changed
+71585 -24460

No files matched your search

+4 -2
View File
@@ -50,9 +50,11 @@ final class Connection implements ConnectionInterface
public function close(int $flag = 0): bool
{
$stream = $this->resource->getStream();
$this->resource->clearLastMailboxUsedCache();
return \imap_close($this->resource->getStream(), $flag);
return \imap_close($stream, $flag);
}
public function getQuota(string $root = 'INBOX'): array
@@ -61,7 +63,7 @@ final class Connection implements ConnectionInterface
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});
@@ -6,7 +6,6 @@ namespace Ddeboer\Imap;
use Ddeboer\Imap\Exception\CreateMailboxException;
use Ddeboer\Imap\Exception\DeleteMailboxException;
use Ddeboer\Imap\Exception\InvalidResourceException;
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
/**
@@ -31,8 +30,6 @@ interface ConnectionInterface extends \Countable
/**
* Check if the connection is still active.
*
* @throws InvalidResourceException If connection was closed
*/
public function ping(): bool;
@@ -4,6 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap\Exception;
final class InvalidResourceException extends AbstractException
final class RenameMailboxException extends AbstractException
{
}
+5 -20
View File
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap;
use Ddeboer\Imap\Exception\InvalidResourceException;
use Ddeboer\Imap\Exception\ReopenMailboxException;
use IMAP\Connection;
@@ -13,33 +12,21 @@ use IMAP\Connection;
*/
final class ImapResource implements ImapResourceInterface
{
/**
* @var resource
*/
private $resource;
private ?MailboxInterface $mailbox = null;
private Connection $resource;
private ?MailboxInterface $mailbox;
private static ?string $lastMailboxUsedCache = null;
/**
* Constructor.
*
* @param Connection|resource $resource
*/
public function __construct($resource, MailboxInterface $mailbox = null)
public function __construct(Connection $resource, MailboxInterface $mailbox = null)
{
$this->resource = $resource;
$this->mailbox = $mailbox;
}
public function getStream()
public function getStream(): Connection
{
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;
@@ -76,10 +63,8 @@ final class ImapResource implements ImapResourceInterface
/**
* Check whether the current mailbox is open.
*
* @param resource $resource
*/
private static function isMailboxOpen(MailboxInterface $mailbox, $resource): bool
private static function isMailboxOpen(MailboxInterface $mailbox, Connection $resource): bool
{
$currentMailboxName = $mailbox->getFullEncodedName();
if ($currentMailboxName === self::$lastMailboxUsedCache) {
@@ -4,18 +4,14 @@ declare(strict_types=1);
namespace Ddeboer\Imap;
use Ddeboer\Imap\Exception\InvalidResourceException;
use IMAP\Connection;
interface ImapResourceInterface
{
/**
* Get IMAP resource stream.
*
* @throws InvalidResourceException
*
* @return resource
*/
public function getStream();
public function getStream(): Connection;
/**
* Clear last mailbox used cache.
+19 -6
View File
@@ -4,12 +4,12 @@ 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\Exception\RenameMailboxException;
use Ddeboer\Imap\Search\ConditionInterface;
use Ddeboer\Imap\Search\LogicalOperator\All;
@@ -41,6 +41,23 @@ final class Mailbox implements MailboxInterface
return $this->name;
}
public function renameTo(string $name): bool
{
$encodedName = \mb_convert_encoding($name, 'UTF7-IMAP', 'UTF-8');
$oldFullName = $this->getFullEncodedName();
$newFullName = \preg_replace('/' . \preg_quote(\mb_convert_encoding($this->name, 'UTF7-IMAP', 'UTF-8')) . '$/', $encodedName, $oldFullName);
\assert(null !== $newFullName);
$return = \imap_renamemailbox($this->resource->getStream(), $oldFullName, $newFullName);
if (false === $return) {
throw new RenameMailboxException('Could not rename mailbox');
}
$this->name = $name;
$this->info->name = $newFullName;
return true;
}
public function getEncodedName(): string
{
/** @var string $name */
@@ -104,10 +121,6 @@ final class Mailbox implements MailboxInterface
}
$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();
@@ -178,7 +191,7 @@ final class Mailbox implements MailboxInterface
return $this->getMessages();
}
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool
public function addMessage(string $message, string $options = null, \DateTimeInterface $internalDate = null): bool
{
$arguments = [
$this->resource->getStream(),
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap;
use DateTimeInterface;
use Ddeboer\Imap\Message\PartInterface;
use Ddeboer\Imap\Search\ConditionInterface;
@@ -20,6 +19,11 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
*/
public function getName(): string;
/**
* Set new mailbox name.
*/
public function renameTo(string $name): bool;
/**
* Get mailbox encoded path.
*/
@@ -92,7 +96,7 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
/**
* Add a message to the mailbox.
*/
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool;
public function addMessage(string $message, string $options = null, \DateTimeInterface $internalDate = null): bool;
/**
* Returns a tree of threaded message for the current Mailbox.
+10 -5
View File
@@ -49,7 +49,7 @@ final class Message extends Message\AbstractMessage implements MessageInterface
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});
@@ -80,7 +80,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
}
$this->messageNumberVerified = true;
$msgno = null;
\set_error_handler(static function (): bool {
return true;
});
@@ -89,7 +88,7 @@ final class Message extends Message\AbstractMessage implements MessageInterface
\restore_error_handler();
if (\is_numeric($msgno) && $msgno > 0) {
if ($msgno > 0) {
$this->imapMsgNo = $msgno;
return;
@@ -133,6 +132,14 @@ final class Message extends Message\AbstractMessage implements MessageInterface
return $this->rawMessage;
}
/**
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
public function saveRawMessage($file): void
{
$this->doSaveContent($file, '');
}
public function getHeaders(): Message\Headers
{
if (null === $this->headers) {
@@ -198,8 +205,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
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();
}
@@ -203,23 +203,86 @@ abstract class AbstractMessage extends AbstractPart
}
/**
* Get body HTML.
* Get first body HTML part.
*/
final public function getBodyHtml(): ?string
{
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
$htmlParts = $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
return $htmlParts[0] ?? null;
}
/**
* Get all contents parts of specific subtype (self::SUBTYPE_HTML or self::SUBTYPE_PLAIN).
*
* @return string[]
*/
final public function getAllContentsBySubtype(string $subtype): array
{
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
$parts = [];
/** @var PartInterface $part */
foreach ($iterator as $part) {
if (self::SUBTYPE_HTML === $part->getSubtype()) {
return $part->getDecodedContent();
if ($subtype === $part->getSubtype()) {
$parts[] = $part->getDecodedContent();
}
}
if (\count($parts) > 0) {
return $parts;
}
// If message has no parts and is of right type, return content of message.
if ($subtype === $this->getSubtype()) {
return [$this->getDecodedContent()];
}
return [];
}
/**
* Get body HTML parts.
*
* @return string[]
*/
final public function getBodyHtmlParts(): array
{
return $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
}
/**
* Get all body HTML parts merged into 1 html.
*/
final public function getCompleteBodyHtml(): ?string
{
$htmlParts = $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
if (1 === \count($htmlParts)) {
return $htmlParts[0];
}
if (0 === \count($htmlParts)) {
return null;
}
\libxml_use_internal_errors(true); // Suppress parse errors, get errors with libxml_get_errors();
$newDom = new \DOMDocument();
$newBody = '';
$newDom->loadHTML(\implode('', $htmlParts));
$bodyTags = $newDom->getElementsByTagName('body');
foreach ($bodyTags as $body) {
foreach ($body->childNodes as $node) {
$newBody .= $newDom->saveHTML($node);
}
}
// If message has no parts and is HTML, return content of message itself.
if (self::SUBTYPE_HTML === $this->getSubtype()) {
return $this->getDecodedContent();
}
$newDom = new \DOMDocument();
$newDom->loadHTML($newBody);
return null;
$completeHtml = $newDom->saveHTML();
return false === $completeHtml ? null : $completeHtml;
}
/**
@@ -227,19 +290,28 @@ abstract class AbstractMessage extends AbstractPart
*/
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();
}
$plainParts = $this->getAllContentsBySubtype(self::SUBTYPE_PLAIN);
return $plainParts[0] ?? null;
}
/**
* Get all body PLAIN parts merged into 1 string.
*
* @return null|string Null if message has no PLAIN message parts
*/
final public function getCompleteBodyText(): ?string
{
$plainParts = $this->getAllContentsBySubtype(self::SUBTYPE_PLAIN);
if (1 === \count($plainParts)) {
return $plainParts[0];
}
if (0 === \count($plainParts)) {
return null;
}
// If message has no parts, return content of message itself.
if (self::SUBTYPE_PLAIN === $this->getSubtype()) {
return $this->getDecodedContent();
}
return null;
return \implode("\n", $plainParts);
}
/**
@@ -269,7 +341,7 @@ abstract class AbstractMessage extends AbstractPart
$attachments[] = $childPart;
}
if ($childPart->hasChildren()) {
$attachments = \array_merge($attachments, self::gatherAttachments($childPart));
$attachments = [...$attachments, ...self::gatherAttachments($childPart)];
}
}
@@ -56,8 +56,7 @@ abstract class AbstractPart implements PartInterface
private ?string $encoding = null;
private ?string $disposition = null;
private ?string $description = null;
/** @var null|int|string */
private $bytes;
private string|int|null $bytes;
private ?string $lines = null;
private ?string $content = null;
private ?string $decodedContent = null;
@@ -256,6 +255,26 @@ abstract class AbstractPart implements PartInterface
return $return;
}
/**
* Save raw message content to file.
*
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
final protected function doSaveContent($file, string $partNumber): void
{
$return = \imap_savebody(
$this->resource->getStream(),
$file,
$this->getNumber(),
$partNumber,
\FT_UID | \FT_PEEK
);
if (false === $return) {
throw new ImapFetchbodyException('imap_savebody failed');
}
}
final public function getParts(): array
{
$this->lazyParseStructure();
@@ -265,8 +284,6 @@ abstract class AbstractPart implements PartInterface
/**
* Get current child part.
*
* @return mixed
*/
#[\ReturnTypeWillChange]
final public function current()
@@ -360,7 +377,7 @@ abstract class AbstractPart implements PartInterface
// When the message is not multipart and the body is the attachment content
// Prevents infinite recursion
if (self::isAttachment($this->structure) && !$this instanceof Attachment) {
if (!$this instanceof Attachment && self::isAttachment($this->structure)) {
$this->parts[] = new Attachment($this->resource, $this->getNumber(), '1', $this->structure);
}
@@ -372,12 +389,11 @@ abstract class AbstractPart implements PartInterface
}
foreach ($parts as $key => $partStructure) {
$partNumber = (!$this instanceof Message) ? $this->partNumber . '.' : '';
$partNumber .= (string) ($key + 1);
$partNumber .= $key + 1;
$newPartClass = self::isAttachment($partStructure)
? Attachment::class
: SimplePart::class
;
: SimplePart::class;
$this->parts[] = new $newPartClass($this->resource, $this->getNumber(), $partNumber, $partStructure);
}
@@ -400,9 +416,9 @@ abstract class AbstractPart implements PartInterface
}
if (
'inline' === \strtolower($part->disposition)
'inline' === \strtolower($part->disposition)
&& self::SUBTYPE_PLAIN !== \strtoupper($part->subtype)
&& self::SUBTYPE_HTML !== \strtoupper($part->subtype)
&& self::SUBTYPE_HTML !== \strtoupper($part->subtype)
) {
return true;
}
@@ -427,10 +443,6 @@ abstract class AbstractPart implements PartInterface
}
*/
if (self::SUBTYPE_RFC822 === \strtoupper($part->subtype)) {
return true;
}
return false;
return self::SUBTYPE_RFC822 === \strtoupper($part->subtype);
}
}
@@ -18,6 +18,13 @@ interface BasicMessageInterface extends PartInterface
*/
public function getRawMessage(): string;
/**
* Save the raw message, including all headers, parts, etc. unencoded and unparsed to file.
*
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
public function saveRawMessage($file): void;
/**
* Get message headers.
*/
@@ -109,17 +116,45 @@ interface BasicMessageInterface extends PartInterface
public function getReferences(): array;
/**
* Get body HTML.
* Get message parts by type.
*
* @return string[]
*/
public function getAllContentsBySubtype(string $subtype): array;
/**
* Get first body HTML part.
*
* @return null|string Null if message has no HTML message part
*/
public function getBodyHtml(): ?string;
/**
* Get all body HTML parts as array.
*
* @return string[]
*/
public function getBodyHtmlParts(): array;
/**
* Get all body HTML parts merged into 1 html.
*
* @return null|string Null if message has no HTML message parts
*/
public function getCompleteBodyHtml(): ?string;
/**
* Get body text.
*/
public function getBodyText(): ?string;
/**
* Get all body PLAIN parts merged into 1 string.
*
* @return null|string Null if message has no PLAIN message parts
*/
public function getCompleteBodyText(): ?string;
/**
* Get attachments (if any) linked to this e-mail.
*
@@ -38,6 +38,14 @@ final class EmbeddedMessage extends AbstractMessage implements EmbeddedMessageIn
return $this->rawMessage;
}
/**
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
public function saveRawMessage($file): void
{
$this->doSaveContent($file, $this->getPartNumber());
}
/**
* Get content part number.
*/
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Ddeboer\Imap\Message;
use Ddeboer\Imap\Exception\UnsupportedCharsetException;
final class Headers extends Parameters
{
public function __construct(\stdClass $headers)
@@ -14,7 +16,11 @@ final class Headers extends Parameters
$headers = \array_change_key_case((array) $headers);
foreach ($headers as $key => $value) {
$this[$key] = $this->parseHeader($key, $value);
try {
$this[$key] = $this->parseHeader($key, $value);
} catch (UnsupportedCharsetException) {
// safely skip header with unsupported charset
}
}
}
@@ -50,7 +56,6 @@ final class Headers extends Parameters
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;
@@ -304,7 +304,7 @@ final class Transcoder
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});
@@ -39,8 +39,8 @@ final class MessageIterator extends \ArrayIterator implements MessageIteratorInt
'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
\get_debug_type($current),
self::class
));
}
@@ -4,8 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap\Search;
use DateTimeInterface;
/**
* Represents a date condition.
*/
@@ -19,14 +17,14 @@ abstract class AbstractDate implements ConditionInterface
/**
* The date to be used for the condition.
*/
private DateTimeInterface $date;
private \DateTimeInterface $date;
/**
* Constructor.
*
* @param DateTimeInterface $date optional date for the condition
* @param \DateTimeInterface $date optional date for the condition
*/
public function __construct(DateTimeInterface $date, string $dateFormat = 'j-M-Y')
public function __construct(\DateTimeInterface $date, string $dateFormat = 'j-M-Y')
{
$this->date = $date;
$this->dateFormat = $dateFormat;
+1 -1
View File
@@ -67,7 +67,7 @@ final class Server implements ServerInterface
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});