package and depencies
This commit is contained in:
45
vendor/symfony/mime/Address.php
vendored
45
vendor/symfony/mime/Address.php
vendored
@@ -33,11 +33,11 @@ final class Address
|
||||
*/
|
||||
private const FROM_STRING_PATTERN = '~(?<displayName>[^<]*)<(?<addrSpec>.*)>[^>]*~';
|
||||
|
||||
private static $validator;
|
||||
private static $encoder;
|
||||
private static EmailValidator $validator;
|
||||
private static IdnAddressEncoder $encoder;
|
||||
|
||||
private $address;
|
||||
private $name;
|
||||
private string $address;
|
||||
private string $name;
|
||||
|
||||
public function __construct(string $address, string $name = '')
|
||||
{
|
||||
@@ -45,9 +45,7 @@ final class Address
|
||||
throw new LogicException(sprintf('The "%s" class cannot be used as it needs "%s"; try running "composer require egulias/email-validator".', __CLASS__, EmailValidator::class));
|
||||
}
|
||||
|
||||
if (null === self::$validator) {
|
||||
self::$validator = new EmailValidator();
|
||||
}
|
||||
self::$validator ??= new EmailValidator();
|
||||
|
||||
$this->address = trim($address);
|
||||
$this->name = trim(str_replace(["\n", "\r"], '', $name));
|
||||
@@ -69,9 +67,7 @@ final class Address
|
||||
|
||||
public function getEncodedAddress(): string
|
||||
{
|
||||
if (null === self::$encoder) {
|
||||
self::$encoder = new IdnAddressEncoder();
|
||||
}
|
||||
self::$encoder ??= new IdnAddressEncoder();
|
||||
|
||||
return self::$encoder->encodeString($this->address);
|
||||
}
|
||||
@@ -90,20 +86,13 @@ final class Address
|
||||
return sprintf('"%s"', preg_replace('/"/u', '\"', $this->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string $address
|
||||
*/
|
||||
public static function create($address): self
|
||||
public static function create(self|string $address): self
|
||||
{
|
||||
if ($address instanceof self) {
|
||||
return $address;
|
||||
}
|
||||
|
||||
if (!\is_string($address)) {
|
||||
throw new InvalidArgumentException(sprintf('An address can be an instance of Address or a string ("%s" given).', get_debug_type($address)));
|
||||
}
|
||||
|
||||
if (false === strpos($address, '<')) {
|
||||
if (!str_contains($address, '<')) {
|
||||
return new self($address);
|
||||
}
|
||||
|
||||
@@ -128,22 +117,4 @@ final class Address
|
||||
|
||||
return $addrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 5.2, use "create()" instead.
|
||||
*/
|
||||
public static function fromString(string $string): self
|
||||
{
|
||||
trigger_deprecation('symfony/mime', '5.2', '"%s()" is deprecated, use "%s::create()" instead.', __METHOD__, __CLASS__);
|
||||
|
||||
if (!str_contains($string, '<')) {
|
||||
return new self($string, '');
|
||||
}
|
||||
|
||||
if (!preg_match(self::FROM_STRING_PATTERN, $string, $matches)) {
|
||||
throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.', $string, self::class));
|
||||
}
|
||||
|
||||
return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"'));
|
||||
}
|
||||
}
|
||||
|
18
vendor/symfony/mime/CHANGELOG.md
vendored
18
vendor/symfony/mime/CHANGELOG.md
vendored
@@ -1,6 +1,24 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
6.2
|
||||
---
|
||||
|
||||
* Add `File`
|
||||
* Deprecate `Email::attachPart()`, use `addPart()` instead
|
||||
* Deprecate calling `Message::setBody()` without arguments
|
||||
|
||||
6.1
|
||||
---
|
||||
|
||||
* Add `DataPart::getFilename()` and `DataPart::getContentType()`
|
||||
|
||||
6.0
|
||||
---
|
||||
|
||||
* Remove `Address::fromString()`, use `Address::create()` instead
|
||||
* Remove `Serializable` interface from `RawMessage`
|
||||
|
||||
5.2.0
|
||||
-----
|
||||
|
||||
|
47
vendor/symfony/mime/CharacterStream.php
vendored
47
vendor/symfony/mime/CharacterStream.php
vendored
@@ -55,12 +55,12 @@ final class CharacterStream
|
||||
"\xf8" => 5, "\xf9" => 5, "\xfa" => 5, "\xfb" => 5, "\xfc" => 6, "\xfd" => 6, "\xfe" => 0, "\xff" => 0,
|
||||
];
|
||||
|
||||
private $data = '';
|
||||
private $dataSize = 0;
|
||||
private $map = [];
|
||||
private $charCount = 0;
|
||||
private $currentPos = 0;
|
||||
private $fixedWidth = 0;
|
||||
private string $data = '';
|
||||
private int $dataSize = 0;
|
||||
private array $map = [];
|
||||
private int $charCount = 0;
|
||||
private int $currentPos = 0;
|
||||
private int $fixedWidth = 0;
|
||||
|
||||
/**
|
||||
* @param resource|string $input
|
||||
@@ -72,29 +72,22 @@ final class CharacterStream
|
||||
$this->fixedWidth = 0;
|
||||
$this->map = ['p' => [], 'i' => []];
|
||||
} else {
|
||||
switch ($charset) {
|
||||
$this->fixedWidth = match ($charset) {
|
||||
// 16 bits
|
||||
case 'ucs2':
|
||||
case 'ucs-2':
|
||||
case 'utf16':
|
||||
case 'utf-16':
|
||||
$this->fixedWidth = 2;
|
||||
break;
|
||||
|
||||
// 32 bits
|
||||
case 'ucs4':
|
||||
case 'ucs-4':
|
||||
case 'utf32':
|
||||
case 'utf-32':
|
||||
$this->fixedWidth = 4;
|
||||
break;
|
||||
|
||||
// 7-8 bit charsets: (us-)?ascii, (iso|iec)-?8859-?[0-9]+, windows-?125[0-9], cp-?[0-9]+, ansi, macintosh,
|
||||
'ucs2',
|
||||
'ucs-2',
|
||||
'utf16',
|
||||
'utf-16' => 2,
|
||||
// 32 bits
|
||||
'ucs4',
|
||||
'ucs-4',
|
||||
'utf32',
|
||||
'utf-32' => 4,
|
||||
// 7-8 bit charsets: (us-)?ascii, (iso|iec)-?8859-?[0-9]+, windows-?125[0-9], cp-?[0-9]+, ansi, macintosh,
|
||||
// koi-?7, koi-?8-?.+, mik, (cork|t1), v?iscii
|
||||
// and fallback
|
||||
default:
|
||||
$this->fixedWidth = 1;
|
||||
}
|
||||
// and fallback
|
||||
default => 1,
|
||||
};
|
||||
}
|
||||
if (\is_resource($input)) {
|
||||
$blocks = 16372;
|
||||
|
16
vendor/symfony/mime/Crypto/DkimOptions.php
vendored
16
vendor/symfony/mime/Crypto/DkimOptions.php
vendored
@@ -18,7 +18,7 @@ namespace Symfony\Component\Mime\Crypto;
|
||||
*/
|
||||
final class DkimOptions
|
||||
{
|
||||
private $options = [];
|
||||
private array $options = [];
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
@@ -28,7 +28,7 @@ final class DkimOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function algorithm(string $algo): self
|
||||
public function algorithm(string $algo): static
|
||||
{
|
||||
$this->options['algorithm'] = $algo;
|
||||
|
||||
@@ -38,7 +38,7 @@ final class DkimOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function signatureExpirationDelay(int $show): self
|
||||
public function signatureExpirationDelay(int $show): static
|
||||
{
|
||||
$this->options['signature_expiration_delay'] = $show;
|
||||
|
||||
@@ -48,7 +48,7 @@ final class DkimOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function bodyMaxLength(int $max): self
|
||||
public function bodyMaxLength(int $max): static
|
||||
{
|
||||
$this->options['body_max_length'] = $max;
|
||||
|
||||
@@ -58,7 +58,7 @@ final class DkimOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function bodyShowLength(bool $show): self
|
||||
public function bodyShowLength(bool $show): static
|
||||
{
|
||||
$this->options['body_show_length'] = $show;
|
||||
|
||||
@@ -68,7 +68,7 @@ final class DkimOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function headerCanon(string $canon): self
|
||||
public function headerCanon(string $canon): static
|
||||
{
|
||||
$this->options['header_canon'] = $canon;
|
||||
|
||||
@@ -78,7 +78,7 @@ final class DkimOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function bodyCanon(string $canon): self
|
||||
public function bodyCanon(string $canon): static
|
||||
{
|
||||
$this->options['body_canon'] = $canon;
|
||||
|
||||
@@ -88,7 +88,7 @@ final class DkimOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function headersToIgnore(array $headers): self
|
||||
public function headersToIgnore(array $headers): static
|
||||
{
|
||||
$this->options['headers_to_ignore'] = $headers;
|
||||
|
||||
|
13
vendor/symfony/mime/Crypto/DkimSigner.php
vendored
13
vendor/symfony/mime/Crypto/DkimSigner.php
vendored
@@ -30,10 +30,10 @@ final class DkimSigner
|
||||
public const ALGO_SHA256 = 'rsa-sha256';
|
||||
public const ALGO_ED25519 = 'ed25519-sha256'; // RFC 8463
|
||||
|
||||
private $key;
|
||||
private $domainName;
|
||||
private $selector;
|
||||
private $defaultOptions;
|
||||
private \OpenSSLAsymmetricKey $key;
|
||||
private string $domainName;
|
||||
private string $selector;
|
||||
private array $defaultOptions;
|
||||
|
||||
/**
|
||||
* @param string $pk The private key as a string or the path to the file containing the private key, should be prefixed with file:// (in PEM format)
|
||||
@@ -44,10 +44,7 @@ final class DkimSigner
|
||||
if (!\extension_loaded('openssl')) {
|
||||
throw new \LogicException('PHP extension "openssl" is required to use DKIM.');
|
||||
}
|
||||
if (!$this->key = openssl_pkey_get_private($pk, $passphrase)) {
|
||||
throw new InvalidArgumentException('Unable to load DKIM private key: '.openssl_error_string());
|
||||
}
|
||||
|
||||
$this->key = openssl_pkey_get_private($pk, $passphrase) ?: throw new InvalidArgumentException('Unable to load DKIM private key: '.openssl_error_string());
|
||||
$this->domainName = $domainName;
|
||||
$this->selector = $selector;
|
||||
$this->defaultOptions = $defaultOptions + [
|
||||
|
@@ -19,21 +19,21 @@ use Symfony\Component\Mime\Message;
|
||||
*/
|
||||
final class SMimeEncrypter extends SMime
|
||||
{
|
||||
private $certs;
|
||||
private $cipher;
|
||||
private string|array $certs;
|
||||
private int $cipher;
|
||||
|
||||
/**
|
||||
* @param string|string[] $certificate The path (or array of paths) of the file(s) containing the X.509 certificate(s)
|
||||
* @param int|null $cipher A set of algorithms used to encrypt the message. Must be one of these PHP constants: https://www.php.net/manual/en/openssl.ciphers.php
|
||||
*/
|
||||
public function __construct($certificate, int $cipher = null)
|
||||
public function __construct(string|array $certificate, int $cipher = null)
|
||||
{
|
||||
if (!\extension_loaded('openssl')) {
|
||||
throw new \LogicException('PHP extension "openssl" is required to use SMime.');
|
||||
}
|
||||
|
||||
if (\is_array($certificate)) {
|
||||
$this->certs = array_map([$this, 'normalizeFilePath'], $certificate);
|
||||
$this->certs = array_map($this->normalizeFilePath(...), $certificate);
|
||||
} else {
|
||||
$this->certs = $this->normalizeFilePath($certificate);
|
||||
}
|
||||
|
8
vendor/symfony/mime/Crypto/SMimeSigner.php
vendored
8
vendor/symfony/mime/Crypto/SMimeSigner.php
vendored
@@ -19,10 +19,10 @@ use Symfony\Component\Mime\Message;
|
||||
*/
|
||||
final class SMimeSigner extends SMime
|
||||
{
|
||||
private $signCertificate;
|
||||
private $signPrivateKey;
|
||||
private $signOptions;
|
||||
private $extraCerts;
|
||||
private string $signCertificate;
|
||||
private string|array $signPrivateKey;
|
||||
private int $signOptions;
|
||||
private ?string $extraCerts;
|
||||
|
||||
/**
|
||||
* @param string $certificate The path of the file containing the signing certificate (in PEM format)
|
||||
|
@@ -22,27 +22,11 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*/
|
||||
class AddMimeTypeGuesserPass implements CompilerPassInterface
|
||||
{
|
||||
private $mimeTypesService;
|
||||
private $mimeTypeGuesserTag;
|
||||
|
||||
public function __construct(string $mimeTypesService = 'mime_types', string $mimeTypeGuesserTag = 'mime.mime_type_guesser')
|
||||
{
|
||||
if (0 < \func_num_args()) {
|
||||
trigger_deprecation('symfony/mime', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
|
||||
}
|
||||
|
||||
$this->mimeTypesService = $mimeTypesService;
|
||||
$this->mimeTypeGuesserTag = $mimeTypeGuesserTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if ($container->has($this->mimeTypesService)) {
|
||||
$definition = $container->findDefinition($this->mimeTypesService);
|
||||
foreach ($container->findTaggedServiceIds($this->mimeTypeGuesserTag, true) as $id => $attributes) {
|
||||
if ($container->has('mime_types')) {
|
||||
$definition = $container->findDefinition('mime_types');
|
||||
foreach ($container->findTaggedServiceIds('mime.mime_type_guesser', true) as $id => $attributes) {
|
||||
$definition->addMethodCall('registerGuesser', [new Reference($id)]);
|
||||
}
|
||||
}
|
||||
|
45
vendor/symfony/mime/DraftEmail.php
vendored
Normal file
45
vendor/symfony/mime/DraftEmail.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Mime;
|
||||
|
||||
use Symfony\Component\Mime\Header\Headers;
|
||||
use Symfony\Component\Mime\Part\AbstractPart;
|
||||
|
||||
/**
|
||||
* @author Kevin Bond <kevinbond@gmail.com>
|
||||
*/
|
||||
class DraftEmail extends Email
|
||||
{
|
||||
public function __construct(Headers $headers = null, AbstractPart $body = null)
|
||||
{
|
||||
parent::__construct($headers, $body);
|
||||
|
||||
$this->getHeaders()->addTextHeader('X-Unsent', '1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default behavior as draft emails do not require From/Sender/Date/Message-ID headers.
|
||||
* These are added by the client that actually sends the email.
|
||||
*/
|
||||
public function getPreparedHeaders(): Headers
|
||||
{
|
||||
$headers = clone $this->getHeaders();
|
||||
|
||||
if (!$headers->has('MIME-Version')) {
|
||||
$headers->addTextHeader('MIME-Version', '1.0');
|
||||
}
|
||||
|
||||
$headers->remove('Bcc');
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
223
vendor/symfony/mime/Email.php
vendored
223
vendor/symfony/mime/Email.php
vendored
@@ -14,6 +14,7 @@ namespace Symfony\Component\Mime;
|
||||
use Symfony\Component\Mime\Exception\LogicException;
|
||||
use Symfony\Component\Mime\Part\AbstractPart;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
use Symfony\Component\Mime\Part\File;
|
||||
use Symfony\Component\Mime\Part\Multipart\AlternativePart;
|
||||
use Symfony\Component\Mime\Part\Multipart\MixedPart;
|
||||
use Symfony\Component\Mime\Part\Multipart\RelatedPart;
|
||||
@@ -38,20 +39,26 @@ class Email extends Message
|
||||
self::PRIORITY_LOWEST => 'Lowest',
|
||||
];
|
||||
|
||||
private $text;
|
||||
private $textCharset;
|
||||
private $html;
|
||||
private $htmlCharset;
|
||||
private $attachments = [];
|
||||
/**
|
||||
* @var AbstractPart|null
|
||||
* @var resource|string|null
|
||||
*/
|
||||
private $cachedBody; // Used to avoid wrong body hash in DKIM signatures with multiple parts (e.g. HTML + TEXT) due to multiple boundaries.
|
||||
private $text;
|
||||
|
||||
private ?string $textCharset = null;
|
||||
|
||||
/**
|
||||
* @var resource|string|null
|
||||
*/
|
||||
private $html;
|
||||
|
||||
private ?string $htmlCharset = null;
|
||||
private array $attachments = [];
|
||||
private ?AbstractPart $cachedBody = null; // Used to avoid wrong body hash in DKIM signatures with multiple parts (e.g. HTML + TEXT) due to multiple boundaries.
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function subject(string $subject)
|
||||
public function subject(string $subject): static
|
||||
{
|
||||
return $this->setHeaderBody('Text', 'Subject', $subject);
|
||||
}
|
||||
@@ -64,7 +71,7 @@ class Email extends Message
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function date(\DateTimeInterface $dateTime)
|
||||
public function date(\DateTimeInterface $dateTime): static
|
||||
{
|
||||
return $this->setHeaderBody('Date', 'Date', $dateTime);
|
||||
}
|
||||
@@ -75,11 +82,9 @@ class Email extends Message
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string $address
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function returnPath($address)
|
||||
public function returnPath(Address|string $address): static
|
||||
{
|
||||
return $this->setHeaderBody('Path', 'Return-Path', Address::create($address));
|
||||
}
|
||||
@@ -90,11 +95,9 @@ class Email extends Message
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string $address
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function sender($address)
|
||||
public function sender(Address|string $address): static
|
||||
{
|
||||
return $this->setHeaderBody('Mailbox', 'Sender', Address::create($address));
|
||||
}
|
||||
@@ -105,21 +108,17 @@ class Email extends Message
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addFrom(...$addresses)
|
||||
public function addFrom(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->addListAddressHeaderBody('From', $addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function from(...$addresses)
|
||||
public function from(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->setListAddressHeaderBody('From', $addresses);
|
||||
}
|
||||
@@ -133,21 +132,17 @@ class Email extends Message
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addReplyTo(...$addresses)
|
||||
public function addReplyTo(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->addListAddressHeaderBody('Reply-To', $addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function replyTo(...$addresses)
|
||||
public function replyTo(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->setListAddressHeaderBody('Reply-To', $addresses);
|
||||
}
|
||||
@@ -161,21 +156,17 @@ class Email extends Message
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addTo(...$addresses)
|
||||
public function addTo(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->addListAddressHeaderBody('To', $addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function to(...$addresses)
|
||||
public function to(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->setListAddressHeaderBody('To', $addresses);
|
||||
}
|
||||
@@ -189,21 +180,17 @@ class Email extends Message
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCc(...$addresses)
|
||||
public function addCc(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->addListAddressHeaderBody('Cc', $addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cc(...$addresses)
|
||||
public function cc(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->setListAddressHeaderBody('Cc', $addresses);
|
||||
}
|
||||
@@ -217,21 +204,17 @@ class Email extends Message
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addBcc(...$addresses)
|
||||
public function addBcc(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->addListAddressHeaderBody('Bcc', $addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string ...$addresses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function bcc(...$addresses)
|
||||
public function bcc(Address|string ...$addresses): static
|
||||
{
|
||||
return $this->setListAddressHeaderBody('Bcc', $addresses);
|
||||
}
|
||||
@@ -251,7 +234,7 @@ class Email extends Message
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function priority(int $priority)
|
||||
public function priority(int $priority): static
|
||||
{
|
||||
if ($priority > 5) {
|
||||
$priority = 5;
|
||||
@@ -280,7 +263,7 @@ class Email extends Message
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function text($body, string $charset = 'utf-8')
|
||||
public function text($body, string $charset = 'utf-8'): static
|
||||
{
|
||||
if (null !== $body && !\is_string($body) && !\is_resource($body)) {
|
||||
throw new \TypeError(sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body)));
|
||||
@@ -311,7 +294,7 @@ class Email extends Message
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function html($body, string $charset = 'utf-8')
|
||||
public function html($body, string $charset = 'utf-8'): static
|
||||
{
|
||||
if (null !== $body && !\is_string($body) && !\is_resource($body)) {
|
||||
throw new \TypeError(sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body)));
|
||||
@@ -342,27 +325,17 @@ class Email extends Message
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function attach($body, string $name = null, string $contentType = null)
|
||||
public function attach($body, string $name = null, string $contentType = null): static
|
||||
{
|
||||
if (!\is_string($body) && !\is_resource($body)) {
|
||||
throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body)));
|
||||
}
|
||||
|
||||
$this->cachedBody = null;
|
||||
$this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => false];
|
||||
|
||||
return $this;
|
||||
return $this->addPart(new DataPart($body, $name, $contentType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function attachFromPath(string $path, string $name = null, string $contentType = null)
|
||||
public function attachFromPath(string $path, string $name = null, string $contentType = null): static
|
||||
{
|
||||
$this->cachedBody = null;
|
||||
$this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => false];
|
||||
|
||||
return $this;
|
||||
return $this->addPart(new DataPart(new File($path), $name, $contentType));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,51 +343,48 @@ class Email extends Message
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function embed($body, string $name = null, string $contentType = null)
|
||||
public function embed($body, string $name = null, string $contentType = null): static
|
||||
{
|
||||
if (!\is_string($body) && !\is_resource($body)) {
|
||||
throw new \TypeError(sprintf('The body must be a string or a resource (got "%s").', get_debug_type($body)));
|
||||
}
|
||||
|
||||
$this->cachedBody = null;
|
||||
$this->attachments[] = ['body' => $body, 'name' => $name, 'content-type' => $contentType, 'inline' => true];
|
||||
|
||||
return $this;
|
||||
return $this->addPart((new DataPart($body, $name, $contentType))->asInline());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function embedFromPath(string $path, string $name = null, string $contentType = null)
|
||||
public function embedFromPath(string $path, string $name = null, string $contentType = null): static
|
||||
{
|
||||
$this->cachedBody = null;
|
||||
$this->attachments[] = ['path' => $path, 'name' => $name, 'content-type' => $contentType, 'inline' => true];
|
||||
return $this->addPart((new DataPart(new File($path), $name, $contentType))->asInline());
|
||||
}
|
||||
|
||||
return $this;
|
||||
/**
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since Symfony 6.2, use addPart() instead
|
||||
*/
|
||||
public function attachPart(DataPart $part): static
|
||||
{
|
||||
@trigger_deprecation('symfony/mime', '6.2', 'The "%s()" method is deprecated, use "addPart()" instead.', __METHOD__);
|
||||
|
||||
return $this->addPart($part);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function attachPart(DataPart $part)
|
||||
public function addPart(DataPart $part): static
|
||||
{
|
||||
$this->cachedBody = null;
|
||||
$this->attachments[] = ['part' => $part];
|
||||
$this->attachments[] = $part;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|DataPart[]
|
||||
* @return DataPart[]
|
||||
*/
|
||||
public function getAttachments(): array
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($this->attachments as $attachment) {
|
||||
$parts[] = $this->createDataPart($attachment);
|
||||
}
|
||||
|
||||
return $parts;
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
public function getBody(): AbstractPart
|
||||
@@ -428,13 +398,22 @@ class Email extends Message
|
||||
|
||||
public function ensureValidity()
|
||||
{
|
||||
if (null === $this->text && null === $this->html && !$this->attachments) {
|
||||
throw new LogicException('A message must have a text or an HTML part or attachments.');
|
||||
$this->ensureBodyValid();
|
||||
|
||||
if ('1' === $this->getHeaders()->getHeaderBody('X-Unsent')) {
|
||||
throw new LogicException('Cannot send messages marked as "draft".');
|
||||
}
|
||||
|
||||
parent::ensureValidity();
|
||||
}
|
||||
|
||||
private function ensureBodyValid(): void
|
||||
{
|
||||
if (null === $this->text && null === $this->html && !$this->attachments) {
|
||||
throw new LogicException('A message must have a text or an HTML part or attachments.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an AbstractPart based on the raw body of a message.
|
||||
*
|
||||
@@ -461,7 +440,7 @@ class Email extends Message
|
||||
return $this->cachedBody;
|
||||
}
|
||||
|
||||
$this->ensureValidity();
|
||||
$this->ensureBodyValid();
|
||||
|
||||
[$htmlPart, $otherParts, $relatedParts] = $this->prepareParts();
|
||||
|
||||
@@ -497,43 +476,37 @@ class Email extends Message
|
||||
if (null !== $html) {
|
||||
$htmlPart = new TextPart($html, $this->htmlCharset, 'html');
|
||||
$html = $htmlPart->getBody();
|
||||
preg_match_all('(<img\s+[^>]*src\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+)))i', $html, $names);
|
||||
$names = array_filter(array_unique(array_merge($names[2], $names[3])));
|
||||
|
||||
$regexes = [
|
||||
'<img\s+[^>]*src\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+))',
|
||||
'<\w+\s+[^>]*background\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+))',
|
||||
];
|
||||
$tmpMatches = [];
|
||||
foreach ($regexes as $regex) {
|
||||
preg_match_all('/'.$regex.'/i', $html, $tmpMatches);
|
||||
$names = array_merge($names, $tmpMatches[2], $tmpMatches[3]);
|
||||
}
|
||||
$names = array_filter(array_unique($names));
|
||||
}
|
||||
|
||||
// usage of reflection is a temporary workaround for missing getters that will be added in 6.2
|
||||
$nameRef = new \ReflectionProperty(TextPart::class, 'name');
|
||||
$nameRef->setAccessible(true);
|
||||
$otherParts = $relatedParts = [];
|
||||
foreach ($this->attachments as $attachment) {
|
||||
$part = $this->createDataPart($attachment);
|
||||
if (isset($attachment['part'])) {
|
||||
$attachment['name'] = $nameRef->getValue($part);
|
||||
}
|
||||
|
||||
$related = false;
|
||||
foreach ($this->attachments as $part) {
|
||||
foreach ($names as $name) {
|
||||
if ($name !== $attachment['name']) {
|
||||
if ($name !== $part->getName()) {
|
||||
continue;
|
||||
}
|
||||
if (isset($relatedParts[$name])) {
|
||||
continue 2;
|
||||
}
|
||||
$part->setDisposition('inline');
|
||||
|
||||
$html = str_replace('cid:'.$name, 'cid:'.$part->getContentId(), $html, $count);
|
||||
if ($count) {
|
||||
$related = true;
|
||||
}
|
||||
$part->setName($part->getContentId());
|
||||
$relatedParts[$name] = $part;
|
||||
$part->setName($part->getContentId())->asInline();
|
||||
|
||||
break;
|
||||
continue 2;
|
||||
}
|
||||
|
||||
if ($related) {
|
||||
$relatedParts[$attachment['name']] = $part;
|
||||
} else {
|
||||
$otherParts[] = $part;
|
||||
}
|
||||
$otherParts[] = $part;
|
||||
}
|
||||
if (null !== $htmlPart) {
|
||||
$htmlPart = new TextPart($html, $this->htmlCharset, 'html');
|
||||
@@ -542,28 +515,10 @@ class Email extends Message
|
||||
return [$htmlPart, $otherParts, array_values($relatedParts)];
|
||||
}
|
||||
|
||||
private function createDataPart(array $attachment): DataPart
|
||||
{
|
||||
if (isset($attachment['part'])) {
|
||||
return $attachment['part'];
|
||||
}
|
||||
|
||||
if (isset($attachment['body'])) {
|
||||
$part = new DataPart($attachment['body'], $attachment['name'] ?? null, $attachment['content-type'] ?? null);
|
||||
} else {
|
||||
$part = DataPart::fromPath($attachment['path'] ?? '', $attachment['name'] ?? null, $attachment['content-type'] ?? null);
|
||||
}
|
||||
if ($attachment['inline']) {
|
||||
$part->asInline();
|
||||
}
|
||||
|
||||
return $part;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
private function setHeaderBody(string $type, string $name, $body): object
|
||||
private function setHeaderBody(string $type, string $name, $body): static
|
||||
{
|
||||
$this->getHeaders()->setHeaderBody($type, $name, $body);
|
||||
|
||||
@@ -583,7 +538,7 @@ class Email extends Message
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
private function setListAddressHeaderBody(string $name, array $addresses)
|
||||
private function setListAddressHeaderBody(string $name, array $addresses): static
|
||||
{
|
||||
$addresses = Address::createArray($addresses);
|
||||
$headers = $this->getHeaders();
|
||||
@@ -609,12 +564,6 @@ class Email extends Message
|
||||
$this->html = (new TextPart($this->html))->getBody();
|
||||
}
|
||||
|
||||
foreach ($this->attachments as $i => $attachment) {
|
||||
if (isset($attachment['body']) && \is_resource($attachment['body'])) {
|
||||
$this->attachments[$i]['body'] = (new TextPart($attachment['body']))->getBody();
|
||||
}
|
||||
}
|
||||
|
||||
return [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, parent::__serialize()];
|
||||
}
|
||||
|
||||
|
15
vendor/symfony/mime/Encoder/QpContentEncoder.php
vendored
15
vendor/symfony/mime/Encoder/QpContentEncoder.php
vendored
@@ -46,15 +46,10 @@ final class QpContentEncoder implements ContentEncoderInterface
|
||||
// transform =0D=0A to CRLF
|
||||
$string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string);
|
||||
|
||||
switch (\ord(substr($string, -1))) {
|
||||
case 0x09:
|
||||
$string = substr_replace($string, '=09', -1);
|
||||
break;
|
||||
case 0x20:
|
||||
$string = substr_replace($string, '=20', -1);
|
||||
break;
|
||||
}
|
||||
|
||||
return $string;
|
||||
return match (\ord(substr($string, -1))) {
|
||||
0x09 => substr_replace($string, '=09', -1),
|
||||
0x20 => substr_replace($string, '=20', -1),
|
||||
default => $string,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
17
vendor/symfony/mime/Encoder/QpEncoder.php
vendored
17
vendor/symfony/mime/Encoder/QpEncoder.php
vendored
@@ -76,7 +76,7 @@ class QpEncoder implements EncoderInterface
|
||||
255 => '=FF',
|
||||
];
|
||||
|
||||
private static $safeMapShare = [];
|
||||
private static array $safeMapShare = [];
|
||||
|
||||
/**
|
||||
* A map of non-encoded ascii characters.
|
||||
@@ -85,7 +85,7 @@ class QpEncoder implements EncoderInterface
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected $safeMap = [];
|
||||
protected array $safeMap = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -106,8 +106,6 @@ class QpEncoder implements EncoderInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Takes an unencoded string and produces a QP encoded string from it.
|
||||
*
|
||||
* QP encoded strings have a maximum line length of 76 characters.
|
||||
@@ -184,12 +182,11 @@ class QpEncoder implements EncoderInterface
|
||||
private function standardize(string $string): string
|
||||
{
|
||||
$string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string);
|
||||
switch ($end = \ord(substr($string, -1))) {
|
||||
case 0x09:
|
||||
case 0x20:
|
||||
$string = substr_replace($string, self::QP_MAP[$end], -1);
|
||||
}
|
||||
|
||||
return $string;
|
||||
return match ($end = \ord(substr($string, -1))) {
|
||||
0x09,
|
||||
0x20 => substr_replace($string, self::QP_MAP[$end], -1),
|
||||
default => $string,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ use Symfony\Component\Mime\Exception\LogicException;
|
||||
*/
|
||||
class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
{
|
||||
private $cmd;
|
||||
private string $cmd;
|
||||
|
||||
/**
|
||||
* The $cmd pattern must contain a "%s" string that will be replaced
|
||||
@@ -36,9 +36,6 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
$this->cmd = $cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isGuesserSupported(): bool
|
||||
{
|
||||
static $supported = null;
|
||||
@@ -58,9 +55,6 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
return $supported = 0 === $exitStatus && '' !== $binPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function guessMimeType(string $path): ?string
|
||||
{
|
||||
if (!is_file($path) || !is_readable($path)) {
|
||||
|
@@ -21,7 +21,7 @@ use Symfony\Component\Mime\Exception\LogicException;
|
||||
*/
|
||||
class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
{
|
||||
private $magicFile;
|
||||
private ?string $magicFile;
|
||||
|
||||
/**
|
||||
* @param string $magicFile A magic file to use with the finfo instance
|
||||
@@ -33,17 +33,11 @@ class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
$this->magicFile = $magicFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isGuesserSupported(): bool
|
||||
{
|
||||
return \function_exists('finfo_open');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function guessMimeType(string $path): ?string
|
||||
{
|
||||
if (!is_file($path) || !is_readable($path)) {
|
||||
|
18
vendor/symfony/mime/Header/AbstractHeader.php
vendored
18
vendor/symfony/mime/Header/AbstractHeader.php
vendored
@@ -22,12 +22,12 @@ abstract class AbstractHeader implements HeaderInterface
|
||||
{
|
||||
public const PHRASE_PATTERN = '(?:(?:(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]+(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?)|(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?"((?:(?:[ \t]*(?:\r\n))?[ \t])?(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21\x23-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])))*(?:(?:[ \t]*(?:\r\n))?[ \t])?"(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?))+?)';
|
||||
|
||||
private static $encoder;
|
||||
private static QpMimeHeaderEncoder $encoder;
|
||||
|
||||
private $name;
|
||||
private $lineLength = 76;
|
||||
private $lang;
|
||||
private $charset = 'utf-8';
|
||||
private string $name;
|
||||
private int $lineLength = 76;
|
||||
private ?string $lang = null;
|
||||
private string $charset = 'utf-8';
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
@@ -188,9 +188,7 @@ abstract class AbstractHeader implements HeaderInterface
|
||||
*/
|
||||
protected function getTokenAsEncodedWord(string $token, int $firstLineOffset = 0): string
|
||||
{
|
||||
if (null === self::$encoder) {
|
||||
self::$encoder = new QpMimeHeaderEncoder();
|
||||
}
|
||||
self::$encoder ??= new QpMimeHeaderEncoder();
|
||||
|
||||
// Adjust $firstLineOffset to account for space needed for syntax
|
||||
$charsetDecl = $this->charset;
|
||||
@@ -233,9 +231,7 @@ abstract class AbstractHeader implements HeaderInterface
|
||||
*/
|
||||
protected function toTokens(string $string = null): array
|
||||
{
|
||||
if (null === $string) {
|
||||
$string = $this->getBodyAsString();
|
||||
}
|
||||
$string ??= $this->getBodyAsString();
|
||||
|
||||
$tokens = [];
|
||||
// Generate atoms; split at all invisible boundaries followed by WSP
|
||||
|
4
vendor/symfony/mime/Header/DateHeader.php
vendored
4
vendor/symfony/mime/Header/DateHeader.php
vendored
@@ -18,7 +18,7 @@ namespace Symfony\Component\Mime\Header;
|
||||
*/
|
||||
final class DateHeader extends AbstractHeader
|
||||
{
|
||||
private $dateTime;
|
||||
private \DateTimeImmutable $dateTime;
|
||||
|
||||
public function __construct(string $name, \DateTimeInterface $date)
|
||||
{
|
||||
@@ -30,7 +30,7 @@ final class DateHeader extends AbstractHeader
|
||||
/**
|
||||
* @param \DateTimeInterface $body
|
||||
*/
|
||||
public function setBody($body)
|
||||
public function setBody(mixed $body)
|
||||
{
|
||||
$this->setDateTime($body);
|
||||
}
|
||||
|
@@ -22,19 +22,15 @@ interface HeaderInterface
|
||||
* Sets the body.
|
||||
*
|
||||
* The type depends on the Header concrete class.
|
||||
*
|
||||
* @param mixed $body
|
||||
*/
|
||||
public function setBody($body);
|
||||
public function setBody(mixed $body);
|
||||
|
||||
/**
|
||||
* Gets the body.
|
||||
*
|
||||
* The return type depends on the Header concrete class.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBody();
|
||||
public function getBody(): mixed;
|
||||
|
||||
public function setCharset(string $charset);
|
||||
|
||||
|
61
vendor/symfony/mime/Header/Headers.php
vendored
61
vendor/symfony/mime/Header/Headers.php
vendored
@@ -34,16 +34,16 @@ final class Headers
|
||||
'cc' => MailboxListHeader::class,
|
||||
'bcc' => MailboxListHeader::class,
|
||||
'message-id' => IdentificationHeader::class,
|
||||
'in-reply-to' => UnstructuredHeader::class, // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ...
|
||||
'references' => UnstructuredHeader::class, // ... `Message-ID`, even if that is no valid `msg-id`
|
||||
'in-reply-to' => [UnstructuredHeader::class, IdentificationHeader::class], // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ...
|
||||
'references' => [UnstructuredHeader::class, IdentificationHeader::class], // ... `Message-ID`, even if that is no valid `msg-id`
|
||||
'return-path' => PathHeader::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var HeaderInterface[][]
|
||||
*/
|
||||
private $headers = [];
|
||||
private $lineLength = 76;
|
||||
private array $headers = [];
|
||||
private int $lineLength = 76;
|
||||
|
||||
public function __construct(HeaderInterface ...$headers)
|
||||
{
|
||||
@@ -79,37 +79,31 @@ final class Headers
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addMailboxListHeader(string $name, array $addresses): self
|
||||
public function addMailboxListHeader(string $name, array $addresses): static
|
||||
{
|
||||
return $this->add(new MailboxListHeader($name, Address::createArray($addresses)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string $address
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addMailboxHeader(string $name, $address): self
|
||||
public function addMailboxHeader(string $name, Address|string $address): static
|
||||
{
|
||||
return $this->add(new MailboxHeader($name, Address::create($address)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $ids
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addIdHeader(string $name, $ids): self
|
||||
public function addIdHeader(string $name, string|array $ids): static
|
||||
{
|
||||
return $this->add(new IdentificationHeader($name, $ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Address|string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPathHeader(string $name, $path): self
|
||||
public function addPathHeader(string $name, Address|string $path): static
|
||||
{
|
||||
return $this->add(new PathHeader($name, $path instanceof Address ? $path : new Address($path)));
|
||||
}
|
||||
@@ -117,7 +111,7 @@ final class Headers
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addDateHeader(string $name, \DateTimeInterface $dateTime): self
|
||||
public function addDateHeader(string $name, \DateTimeInterface $dateTime): static
|
||||
{
|
||||
return $this->add(new DateHeader($name, $dateTime));
|
||||
}
|
||||
@@ -125,7 +119,7 @@ final class Headers
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addTextHeader(string $name, string $value): self
|
||||
public function addTextHeader(string $name, string $value): static
|
||||
{
|
||||
return $this->add(new UnstructuredHeader($name, $value));
|
||||
}
|
||||
@@ -133,7 +127,7 @@ final class Headers
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addParameterizedHeader(string $name, string $value, array $params = []): self
|
||||
public function addParameterizedHeader(string $name, string $value, array $params = []): static
|
||||
{
|
||||
return $this->add(new ParameterizedHeader($name, $value, $params));
|
||||
}
|
||||
@@ -141,9 +135,13 @@ final class Headers
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addHeader(string $name, $argument, array $more = []): self
|
||||
public function addHeader(string $name, mixed $argument, array $more = []): static
|
||||
{
|
||||
$parts = explode('\\', self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class);
|
||||
$headerClass = self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class;
|
||||
if (\is_array($headerClass)) {
|
||||
$headerClass = $headerClass[0];
|
||||
}
|
||||
$parts = explode('\\', $headerClass);
|
||||
$method = 'add'.ucfirst(array_pop($parts));
|
||||
if ('addUnstructuredHeader' === $method) {
|
||||
$method = 'addTextHeader';
|
||||
@@ -162,7 +160,7 @@ final class Headers
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function add(HeaderInterface $header): self
|
||||
public function add(HeaderInterface $header): static
|
||||
{
|
||||
self::checkHeaderClass($header);
|
||||
|
||||
@@ -226,10 +224,22 @@ final class Headers
|
||||
public static function checkHeaderClass(HeaderInterface $header): void
|
||||
{
|
||||
$name = strtolower($header->getName());
|
||||
|
||||
if (($c = self::HEADER_CLASS_MAP[$name] ?? null) && !$header instanceof $c) {
|
||||
throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), $c, get_debug_type($header)));
|
||||
$headerClasses = self::HEADER_CLASS_MAP[$name] ?? [];
|
||||
if (!\is_array($headerClasses)) {
|
||||
$headerClasses = [$headerClasses];
|
||||
}
|
||||
|
||||
if (!$headerClasses) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($headerClasses as $c) {
|
||||
if ($header instanceof $c) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), implode('" or "', $headerClasses), get_debug_type($header)));
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
@@ -254,9 +264,6 @@ final class Headers
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function getHeaderBody(string $name)
|
||||
{
|
||||
return $this->has($name) ? $this->get($name)->getBody() : null;
|
||||
@@ -265,7 +272,7 @@ final class Headers
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function setHeaderBody(string $type, string $name, $body): void
|
||||
public function setHeaderBody(string $type, string $name, mixed $body): void
|
||||
{
|
||||
if ($this->has($name)) {
|
||||
$this->get($name)->setBody($body);
|
||||
|
@@ -21,13 +21,10 @@ use Symfony\Component\Mime\Exception\RfcComplianceException;
|
||||
*/
|
||||
final class IdentificationHeader extends AbstractHeader
|
||||
{
|
||||
private $ids = [];
|
||||
private $idsAsAddresses = [];
|
||||
private array $ids = [];
|
||||
private array $idsAsAddresses = [];
|
||||
|
||||
/**
|
||||
* @param string|array $ids
|
||||
*/
|
||||
public function __construct(string $name, $ids)
|
||||
public function __construct(string $name, string|array $ids)
|
||||
{
|
||||
parent::__construct($name);
|
||||
|
||||
@@ -35,11 +32,11 @@ final class IdentificationHeader extends AbstractHeader
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $body a string ID or an array of IDs
|
||||
* @param string|string[] $body a string ID or an array of IDs
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*/
|
||||
public function setBody($body)
|
||||
public function setBody(mixed $body)
|
||||
{
|
||||
$this->setId($body);
|
||||
}
|
||||
@@ -52,11 +49,11 @@ final class IdentificationHeader extends AbstractHeader
|
||||
/**
|
||||
* Set the ID used in the value of this header.
|
||||
*
|
||||
* @param string|array $id
|
||||
* @param string|string[] $id
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*/
|
||||
public function setId($id)
|
||||
public function setId(string|array $id)
|
||||
{
|
||||
$this->setIds(\is_array($id) ? $id : [$id]);
|
||||
}
|
||||
|
4
vendor/symfony/mime/Header/MailboxHeader.php
vendored
4
vendor/symfony/mime/Header/MailboxHeader.php
vendored
@@ -21,7 +21,7 @@ use Symfony\Component\Mime\Exception\RfcComplianceException;
|
||||
*/
|
||||
final class MailboxHeader extends AbstractHeader
|
||||
{
|
||||
private $address;
|
||||
private Address $address;
|
||||
|
||||
public function __construct(string $name, Address $address)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ final class MailboxHeader extends AbstractHeader
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*/
|
||||
public function setBody($body)
|
||||
public function setBody(mixed $body)
|
||||
{
|
||||
$this->setAddress($body);
|
||||
}
|
||||
|
12
vendor/symfony/mime/Header/MailboxListHeader.php
vendored
12
vendor/symfony/mime/Header/MailboxListHeader.php
vendored
@@ -21,7 +21,7 @@ use Symfony\Component\Mime\Exception\RfcComplianceException;
|
||||
*/
|
||||
final class MailboxListHeader extends AbstractHeader
|
||||
{
|
||||
private $addresses = [];
|
||||
private array $addresses = [];
|
||||
|
||||
/**
|
||||
* @param Address[] $addresses
|
||||
@@ -38,15 +38,15 @@ final class MailboxListHeader extends AbstractHeader
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*/
|
||||
public function setBody($body)
|
||||
public function setBody(mixed $body)
|
||||
{
|
||||
$this->setAddresses($body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RfcComplianceException
|
||||
*
|
||||
* @return Address[]
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*/
|
||||
public function getBody(): array
|
||||
{
|
||||
@@ -99,9 +99,9 @@ final class MailboxListHeader extends AbstractHeader
|
||||
/**
|
||||
* Gets the full mailbox list of this Header as an array of valid RFC 2822 strings.
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*
|
||||
* @return string[]
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*/
|
||||
public function getAddressStrings(): array
|
||||
{
|
||||
|
@@ -25,8 +25,8 @@ final class ParameterizedHeader extends UnstructuredHeader
|
||||
*/
|
||||
public const TOKEN_REGEX = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)';
|
||||
|
||||
private $encoder;
|
||||
private $parameters = [];
|
||||
private ?Rfc2231Encoder $encoder = null;
|
||||
private array $parameters = [];
|
||||
|
||||
public function __construct(string $name, string $value, array $parameters = [])
|
||||
{
|
||||
|
4
vendor/symfony/mime/Header/PathHeader.php
vendored
4
vendor/symfony/mime/Header/PathHeader.php
vendored
@@ -21,7 +21,7 @@ use Symfony\Component\Mime\Exception\RfcComplianceException;
|
||||
*/
|
||||
final class PathHeader extends AbstractHeader
|
||||
{
|
||||
private $address;
|
||||
private Address $address;
|
||||
|
||||
public function __construct(string $name, Address $address)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ final class PathHeader extends AbstractHeader
|
||||
*
|
||||
* @throws RfcComplianceException
|
||||
*/
|
||||
public function setBody($body)
|
||||
public function setBody(mixed $body)
|
||||
{
|
||||
$this->setAddress($body);
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ namespace Symfony\Component\Mime\Header;
|
||||
*/
|
||||
class UnstructuredHeader extends AbstractHeader
|
||||
{
|
||||
private $value;
|
||||
private string $value;
|
||||
|
||||
public function __construct(string $name, string $value)
|
||||
{
|
||||
@@ -30,15 +30,12 @@ class UnstructuredHeader extends AbstractHeader
|
||||
/**
|
||||
* @param string $body
|
||||
*/
|
||||
public function setBody($body)
|
||||
public function setBody(mixed $body)
|
||||
{
|
||||
$this->setValue($body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBody()
|
||||
public function getBody(): string
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
|
23
vendor/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php
vendored
Normal file
23
vendor/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Mime\HtmlToTextConverter;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class DefaultHtmlToTextConverter implements HtmlToTextConverterInterface
|
||||
{
|
||||
public function convert(string $html, string $charset): string
|
||||
{
|
||||
return strip_tags(preg_replace('{<(head|style)\b.*?</\1>}is', '', $html));
|
||||
}
|
||||
}
|
25
vendor/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php
vendored
Normal file
25
vendor/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Mime\HtmlToTextConverter;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface HtmlToTextConverterInterface
|
||||
{
|
||||
/**
|
||||
* Converts an HTML representation of a Message to a text representation.
|
||||
*
|
||||
* The output must use the same charset as the HTML one.
|
||||
*/
|
||||
public function convert(string $html, string $charset): string;
|
||||
}
|
35
vendor/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php
vendored
Normal file
35
vendor/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Mime\HtmlToTextConverter;
|
||||
|
||||
use League\HTMLToMarkdown\HtmlConverter;
|
||||
use League\HTMLToMarkdown\HtmlConverterInterface;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class LeagueHtmlToMarkdownConverter implements HtmlToTextConverterInterface
|
||||
{
|
||||
public function __construct(
|
||||
private HtmlConverterInterface $converter = new HtmlConverter([
|
||||
'hard_break' => true,
|
||||
'strip_tags' => true,
|
||||
'remove_nodes' => 'head style',
|
||||
]),
|
||||
) {
|
||||
}
|
||||
|
||||
public function convert(string $html, string $charset): string
|
||||
{
|
||||
return $this->converter->convert($html);
|
||||
}
|
||||
}
|
11
vendor/symfony/mime/Message.php
vendored
11
vendor/symfony/mime/Message.php
vendored
@@ -21,8 +21,8 @@ use Symfony\Component\Mime\Part\TextPart;
|
||||
*/
|
||||
class Message extends RawMessage
|
||||
{
|
||||
private $headers;
|
||||
private $body;
|
||||
private Headers $headers;
|
||||
private ?AbstractPart $body;
|
||||
|
||||
public function __construct(Headers $headers = null, AbstractPart $body = null)
|
||||
{
|
||||
@@ -42,8 +42,11 @@ class Message extends RawMessage
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setBody(AbstractPart $body = null)
|
||||
public function setBody(AbstractPart $body = null): static
|
||||
{
|
||||
if (1 > \func_num_args()) {
|
||||
trigger_deprecation('symfony/mime', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
|
||||
}
|
||||
$this->body = $body;
|
||||
|
||||
return $this;
|
||||
@@ -57,7 +60,7 @@ class Message extends RawMessage
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeaders(Headers $headers)
|
||||
public function setHeaders(Headers $headers): static
|
||||
{
|
||||
$this->headers = $headers;
|
||||
|
||||
|
11
vendor/symfony/mime/MessageConverter.php
vendored
11
vendor/symfony/mime/MessageConverter.php
vendored
@@ -58,7 +58,7 @@ final class MessageConverter
|
||||
throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
|
||||
}
|
||||
|
||||
return self::attachParts($email, \array_slice($parts, 1));
|
||||
return self::addParts($email, \array_slice($parts, 1));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
|
||||
@@ -104,20 +104,17 @@ final class MessageConverter
|
||||
throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
|
||||
}
|
||||
|
||||
return self::attachParts($email, \array_slice($parts, 1));
|
||||
return self::addParts($email, \array_slice($parts, 1));
|
||||
}
|
||||
|
||||
private static function attachParts(Email $email, array $parts): Email
|
||||
private static function addParts(Email $email, array $parts): Email
|
||||
{
|
||||
foreach ($parts as $part) {
|
||||
if (!$part instanceof DataPart) {
|
||||
throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($email)));
|
||||
}
|
||||
|
||||
$headers = $part->getPreparedHeaders();
|
||||
$method = 'inline' === $headers->getHeaderBody('Content-Disposition') ? 'embed' : 'attach';
|
||||
$name = $headers->getHeaderParameter('Content-Disposition', 'filename');
|
||||
$email->$method($part->getBody(), $name, $part->getMediaType().'/'.$part->getMediaSubtype());
|
||||
$email->addPart($part);
|
||||
}
|
||||
|
||||
return $email;
|
||||
|
21
vendor/symfony/mime/MimeTypes.php
vendored
21
vendor/symfony/mime/MimeTypes.php
vendored
@@ -36,14 +36,14 @@ use Symfony\Component\Mime\Exception\LogicException;
|
||||
*/
|
||||
final class MimeTypes implements MimeTypesInterface
|
||||
{
|
||||
private $extensions = [];
|
||||
private $mimeTypes = [];
|
||||
private array $extensions = [];
|
||||
private array $mimeTypes = [];
|
||||
|
||||
/**
|
||||
* @var MimeTypeGuesserInterface[]
|
||||
*/
|
||||
private $guessers = [];
|
||||
private static $default;
|
||||
private array $guessers = [];
|
||||
private static MimeTypes $default;
|
||||
|
||||
public function __construct(array $map = [])
|
||||
{
|
||||
@@ -65,7 +65,7 @@ final class MimeTypes implements MimeTypesInterface
|
||||
|
||||
public static function getDefault(): self
|
||||
{
|
||||
return self::$default ?? self::$default = new self();
|
||||
return self::$default ??= new self();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,9 +78,6 @@ final class MimeTypes implements MimeTypesInterface
|
||||
array_unshift($this->guessers, $guesser);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtensions(string $mimeType): array
|
||||
{
|
||||
if ($this->extensions) {
|
||||
@@ -90,9 +87,6 @@ final class MimeTypes implements MimeTypesInterface
|
||||
return $extensions ?? self::MAP[$mimeType] ?? self::MAP[$lcMimeType ?? strtolower($mimeType)] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMimeTypes(string $ext): array
|
||||
{
|
||||
if ($this->mimeTypes) {
|
||||
@@ -102,9 +96,6 @@ final class MimeTypes implements MimeTypesInterface
|
||||
return $mimeTypes ?? self::REVERSE_MAP[$ext] ?? self::REVERSE_MAP[$lcExt ?? strtolower($ext)] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isGuesserSupported(): bool
|
||||
{
|
||||
foreach ($this->guessers as $guesser) {
|
||||
@@ -117,8 +108,6 @@ final class MimeTypes implements MimeTypesInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* The file is passed to each registered MIME type guesser in reverse order
|
||||
* of their registration (last registered is queried first). Once a guesser
|
||||
* returns a value that is not null, this method terminates and returns the
|
||||
|
@@ -90,10 +90,6 @@ abstract class AbstractMultipartPart extends AbstractPart
|
||||
|
||||
private function getBoundary(): string
|
||||
{
|
||||
if (null === $this->boundary) {
|
||||
$this->boundary = strtr(base64_encode(random_bytes(6)), '+/', '-_');
|
||||
}
|
||||
|
||||
return $this->boundary;
|
||||
return $this->boundary ??= strtr(base64_encode(random_bytes(6)), '+/', '-_');
|
||||
}
|
||||
}
|
||||
|
80
vendor/symfony/mime/Part/DataPart.php
vendored
80
vendor/symfony/mime/Part/DataPart.php
vendored
@@ -13,7 +13,6 @@ namespace Symfony\Component\Mime\Part;
|
||||
|
||||
use Symfony\Component\Mime\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Mime\Header\Headers;
|
||||
use Symfony\Component\Mime\MimeTypes;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
@@ -23,23 +22,22 @@ class DataPart extends TextPart
|
||||
/** @internal */
|
||||
protected $_parent;
|
||||
|
||||
private static $mimeTypes;
|
||||
|
||||
private $filename;
|
||||
private $mediaType;
|
||||
private $cid;
|
||||
private $handle;
|
||||
|
||||
/**
|
||||
* @param resource|string $body
|
||||
* @param resource|string|File $body Use a File instance to defer loading the file until rendering
|
||||
*/
|
||||
public function __construct($body, string $filename = null, string $contentType = null, string $encoding = null)
|
||||
{
|
||||
unset($this->_parent);
|
||||
|
||||
if (null === $contentType) {
|
||||
$contentType = 'application/octet-stream';
|
||||
if ($body instanceof File && !$filename) {
|
||||
$filename = $body->getFilename();
|
||||
}
|
||||
|
||||
$contentType ??= $body instanceof File ? $body->getContentType() : 'application/octet-stream';
|
||||
[$this->mediaType, $subtype] = explode('/', $contentType);
|
||||
|
||||
parent::__construct($body, null, $subtype, $encoding);
|
||||
@@ -53,42 +51,31 @@ class DataPart extends TextPart
|
||||
|
||||
public static function fromPath(string $path, string $name = null, string $contentType = null): self
|
||||
{
|
||||
if (null === $contentType) {
|
||||
$ext = strtolower(substr($path, strrpos($path, '.') + 1));
|
||||
if (null === self::$mimeTypes) {
|
||||
self::$mimeTypes = new MimeTypes();
|
||||
}
|
||||
$contentType = self::$mimeTypes->getMimeTypes($ext)[0] ?? 'application/octet-stream';
|
||||
}
|
||||
|
||||
if ((is_file($path) && !is_readable($path)) || is_dir($path)) {
|
||||
throw new InvalidArgumentException(sprintf('Path "%s" is not readable.', $path));
|
||||
}
|
||||
|
||||
if (false === $handle = @fopen($path, 'r', false)) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to open path "%s".', $path));
|
||||
}
|
||||
|
||||
if (!is_file($path)) {
|
||||
$cache = fopen('php://temp', 'r+');
|
||||
stream_copy_to_stream($handle, $cache);
|
||||
$handle = $cache;
|
||||
}
|
||||
|
||||
$p = new self($handle, $name ?: basename($path), $contentType);
|
||||
$p->handle = $handle;
|
||||
|
||||
return $p;
|
||||
return new self(new File($path), $name, $contentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function asInline()
|
||||
public function asInline(): static
|
||||
{
|
||||
return $this->setDisposition('inline');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setContentId(string $cid): static
|
||||
{
|
||||
if (!str_contains($cid, '@')) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid cid "%s".', $cid));
|
||||
}
|
||||
|
||||
$this->cid = $cid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContentId(): string
|
||||
{
|
||||
return $this->cid ?: $this->cid = $this->generateContentId();
|
||||
@@ -129,22 +116,22 @@ class DataPart extends TextPart
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function getFilename(): ?string
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
public function getContentType(): string
|
||||
{
|
||||
return implode('/', [$this->getMediaType(), $this->getMediaSubtype()]);
|
||||
}
|
||||
|
||||
private function generateContentId(): string
|
||||
{
|
||||
return bin2hex(random_bytes(16)).'@symfony';
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (null !== $this->handle && \is_resource($this->handle)) {
|
||||
fclose($this->handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
public function __sleep(): array
|
||||
{
|
||||
// converts the body to a string
|
||||
parent::__sleep();
|
||||
@@ -152,7 +139,6 @@ class DataPart extends TextPart
|
||||
$this->_parent = [];
|
||||
foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) {
|
||||
$r = new \ReflectionProperty(TextPart::class, $name);
|
||||
$r->setAccessible(true);
|
||||
$this->_parent[$name] = $r->getValue($this);
|
||||
}
|
||||
$this->_headers = $this->getHeaders();
|
||||
@@ -163,7 +149,6 @@ class DataPart extends TextPart
|
||||
public function __wakeup()
|
||||
{
|
||||
$r = new \ReflectionProperty(AbstractPart::class, 'headers');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this, $this->_headers);
|
||||
unset($this->_headers);
|
||||
|
||||
@@ -175,7 +160,6 @@ class DataPart extends TextPart
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
$r = new \ReflectionProperty(TextPart::class, $name);
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this, $this->_parent[$name]);
|
||||
}
|
||||
unset($this->_parent);
|
||||
|
51
vendor/symfony/mime/Part/File.php
vendored
Normal file
51
vendor/symfony/mime/Part/File.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Mime\Part;
|
||||
|
||||
use Symfony\Component\Mime\MimeTypes;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class File
|
||||
{
|
||||
private static $mimeTypes;
|
||||
|
||||
public function __construct(
|
||||
private string $path,
|
||||
private ?string $filename = null,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getContentType(): string
|
||||
{
|
||||
$ext = strtolower(pathinfo($this->path, \PATHINFO_EXTENSION));
|
||||
self::$mimeTypes ??= new MimeTypes();
|
||||
|
||||
return self::$mimeTypes->getMimeTypes($ext)[0] ?? 'application/octet-stream';
|
||||
}
|
||||
|
||||
public function getSize(): int
|
||||
{
|
||||
return filesize($this->path);
|
||||
}
|
||||
|
||||
public function getFilename(): string
|
||||
{
|
||||
return $this->filename ??= basename($this->getPath());
|
||||
}
|
||||
}
|
5
vendor/symfony/mime/Part/MessagePart.php
vendored
5
vendor/symfony/mime/Part/MessagePart.php
vendored
@@ -60,10 +60,7 @@ class MessagePart extends DataPart
|
||||
return $this->message->toIterable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
public function __sleep(): array
|
||||
{
|
||||
return ['message'];
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ final class FormDataPart extends AbstractMultipartPart
|
||||
|
||||
foreach ($fields as $name => $value) {
|
||||
if (!\is_string($value) && !\is_array($value) && !$value instanceof TextPart) {
|
||||
throw new InvalidArgumentException(sprintf('A form field value can only be a string, an array, or an instance of TextPart ("%s" given).', get_debug_type($value)));
|
||||
throw new InvalidArgumentException(sprintf('The value of the form field "%s" can only be a string, an array, or an instance of TextPart ("%s" given).', $name, get_debug_type($value)));
|
||||
}
|
||||
|
||||
$this->fields[$name] = $value;
|
||||
@@ -83,7 +83,7 @@ final class FormDataPart extends AbstractMultipartPart
|
||||
return $values;
|
||||
}
|
||||
|
||||
private function preparePart(string $name, $value): TextPart
|
||||
private function preparePart(string $name, string|TextPart $value): TextPart
|
||||
{
|
||||
if (\is_string($value)) {
|
||||
return $this->configurePart($name, new TextPart($value, 'utf-8', 'plain', '8bit'));
|
||||
@@ -96,10 +96,7 @@ final class FormDataPart extends AbstractMultipartPart
|
||||
{
|
||||
static $r;
|
||||
|
||||
if (null === $r) {
|
||||
$r = new \ReflectionProperty(TextPart::class, 'encoding');
|
||||
$r->setAccessible(true);
|
||||
}
|
||||
$r ??= new \ReflectionProperty(TextPart::class, 'encoding');
|
||||
|
||||
$part->setDisposition('form-data');
|
||||
$part->setName($name);
|
||||
|
10
vendor/symfony/mime/Part/SMimePart.php
vendored
10
vendor/symfony/mime/Part/SMimePart.php
vendored
@@ -26,19 +26,12 @@ class SMimePart extends AbstractPart
|
||||
private $subtype;
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* @param iterable|string $body
|
||||
*/
|
||||
public function __construct($body, string $type, string $subtype, array $parameters)
|
||||
public function __construct(iterable|string $body, string $type, string $subtype, array $parameters)
|
||||
{
|
||||
unset($this->_headers);
|
||||
|
||||
parent::__construct();
|
||||
|
||||
if (!\is_string($body) && !is_iterable($body)) {
|
||||
throw new \TypeError(sprintf('The body of "%s" must be a string or a iterable (got "%s").', self::class, get_debug_type($body)));
|
||||
}
|
||||
|
||||
$this->body = $body;
|
||||
$this->type = $type;
|
||||
$this->subtype = $subtype;
|
||||
@@ -114,7 +107,6 @@ class SMimePart extends AbstractPart
|
||||
public function __wakeup(): void
|
||||
{
|
||||
$r = new \ReflectionProperty(AbstractPart::class, 'headers');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this, $this->_headers);
|
||||
unset($this->_headers);
|
||||
}
|
||||
|
52
vendor/symfony/mime/Part/TextPart.php
vendored
52
vendor/symfony/mime/Part/TextPart.php
vendored
@@ -40,7 +40,7 @@ class TextPart extends AbstractPart
|
||||
private $seekable;
|
||||
|
||||
/**
|
||||
* @param resource|string $body
|
||||
* @param resource|string|File $body Use a File instance to defer loading the file until rendering
|
||||
*/
|
||||
public function __construct($body, ?string $charset = 'utf-8', string $subtype = 'plain', string $encoding = null)
|
||||
{
|
||||
@@ -48,8 +48,15 @@ class TextPart extends AbstractPart
|
||||
|
||||
parent::__construct();
|
||||
|
||||
if (!\is_string($body) && !\is_resource($body)) {
|
||||
throw new \TypeError(sprintf('The body of "%s" must be a string or a resource (got "%s").', self::class, get_debug_type($body)));
|
||||
if (!\is_string($body) && !\is_resource($body) && !$body instanceof File) {
|
||||
throw new \TypeError(sprintf('The body of "%s" must be a string, a resource, or an instance of "%s" (got "%s").', self::class, File::class, get_debug_type($body)));
|
||||
}
|
||||
|
||||
if ($body instanceof File) {
|
||||
$path = $body->getPath();
|
||||
if ((is_file($path) && !is_readable($path)) || is_dir($path)) {
|
||||
throw new InvalidArgumentException(sprintf('Path "%s" is not readable.', $path));
|
||||
}
|
||||
}
|
||||
|
||||
$this->body = $body;
|
||||
@@ -82,7 +89,7 @@ class TextPart extends AbstractPart
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDisposition(string $disposition)
|
||||
public function setDisposition(string $disposition): static
|
||||
{
|
||||
$this->disposition = $disposition;
|
||||
|
||||
@@ -94,15 +101,27 @@ class TextPart extends AbstractPart
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setName(string $name)
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the file.
|
||||
*/
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getBody(): string
|
||||
{
|
||||
if ($this->body instanceof File) {
|
||||
return file_get_contents($this->body->getPath());
|
||||
}
|
||||
|
||||
if (null === $this->seekable) {
|
||||
return $this->body;
|
||||
}
|
||||
@@ -121,7 +140,14 @@ class TextPart extends AbstractPart
|
||||
|
||||
public function bodyToIterable(): iterable
|
||||
{
|
||||
if (null !== $this->seekable) {
|
||||
if ($this->body instanceof File) {
|
||||
$path = $this->body->getPath();
|
||||
if (false === $handle = @fopen($path, 'r', false)) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to open path "%s".', $path));
|
||||
}
|
||||
|
||||
yield from $this->getEncoder()->encodeByteStream($handle);
|
||||
} elseif (null !== $this->seekable) {
|
||||
if ($this->seekable) {
|
||||
rewind($this->body);
|
||||
}
|
||||
@@ -170,14 +196,14 @@ class TextPart extends AbstractPart
|
||||
private function getEncoder(): ContentEncoderInterface
|
||||
{
|
||||
if ('8bit' === $this->encoding) {
|
||||
return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new EightBitContentEncoder());
|
||||
return self::$encoders[$this->encoding] ??= new EightBitContentEncoder();
|
||||
}
|
||||
|
||||
if ('quoted-printable' === $this->encoding) {
|
||||
return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new QpContentEncoder());
|
||||
return self::$encoders[$this->encoding] ??= new QpContentEncoder();
|
||||
}
|
||||
|
||||
return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new Base64ContentEncoder());
|
||||
return self::$encoders[$this->encoding] ??= new Base64ContentEncoder();
|
||||
}
|
||||
|
||||
private function chooseEncoding(): string
|
||||
@@ -189,13 +215,10 @@ class TextPart extends AbstractPart
|
||||
return 'quoted-printable';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
public function __sleep(): array
|
||||
{
|
||||
// convert resources to strings for serialization
|
||||
if (null !== $this->seekable) {
|
||||
if (null !== $this->seekable || $this->body instanceof File) {
|
||||
$this->body = $this->getBody();
|
||||
$this->seekable = null;
|
||||
}
|
||||
@@ -208,7 +231,6 @@ class TextPart extends AbstractPart
|
||||
public function __wakeup()
|
||||
{
|
||||
$r = new \ReflectionProperty(AbstractPart::class, 'headers');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this, $this->_headers);
|
||||
unset($this->_headers);
|
||||
}
|
||||
|
23
vendor/symfony/mime/RawMessage.php
vendored
23
vendor/symfony/mime/RawMessage.php
vendored
@@ -16,14 +16,11 @@ use Symfony\Component\Mime\Exception\LogicException;
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RawMessage implements \Serializable
|
||||
class RawMessage
|
||||
{
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* @param iterable|string $message
|
||||
*/
|
||||
public function __construct($message)
|
||||
public function __construct(iterable|string $message)
|
||||
{
|
||||
$this->message = $message;
|
||||
}
|
||||
@@ -63,22 +60,6 @@ class RawMessage implements \Serializable
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function serialize(): string
|
||||
{
|
||||
return serialize($this->__serialize());
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function unserialize($serialized)
|
||||
{
|
||||
$this->__unserialize(unserialize($serialized));
|
||||
}
|
||||
|
||||
public function __serialize(): array
|
||||
{
|
||||
return [$this->toString()];
|
||||
|
@@ -18,8 +18,8 @@ use Symfony\Component\Mime\RawMessage;
|
||||
|
||||
final class EmailAddressContains extends Constraint
|
||||
{
|
||||
private $headerName;
|
||||
private $expectedValue;
|
||||
private string $headerName;
|
||||
private string $expectedValue;
|
||||
|
||||
public function __construct(string $headerName, string $expectedValue)
|
||||
{
|
||||
@@ -27,9 +27,6 @@ final class EmailAddressContains extends Constraint
|
||||
$this->expectedValue = $expectedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('contains address "%s" with value "%s"', $this->headerName, $this->expectedValue);
|
||||
@@ -37,12 +34,10 @@ final class EmailAddressContains extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($message): bool
|
||||
{
|
||||
if (RawMessage::class === \get_class($message)) {
|
||||
if (RawMessage::class === $message::class) {
|
||||
throw new \LogicException('Unable to test a message address on a RawMessage instance.');
|
||||
}
|
||||
|
||||
@@ -64,8 +59,6 @@ final class EmailAddressContains extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($message): string
|
||||
{
|
||||
|
@@ -17,8 +17,8 @@ use Symfony\Component\Mime\RawMessage;
|
||||
|
||||
final class EmailAttachmentCount extends Constraint
|
||||
{
|
||||
private $expectedValue;
|
||||
private $transport;
|
||||
private int $expectedValue;
|
||||
private ?string $transport;
|
||||
|
||||
public function __construct(int $expectedValue, string $transport = null)
|
||||
{
|
||||
@@ -26,9 +26,6 @@ final class EmailAttachmentCount extends Constraint
|
||||
$this->transport = $transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('has sent "%d" attachment(s)', $this->expectedValue);
|
||||
@@ -36,12 +33,10 @@ final class EmailAttachmentCount extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($message): bool
|
||||
{
|
||||
if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) {
|
||||
if (RawMessage::class === $message::class || Message::class === $message::class) {
|
||||
throw new \LogicException('Unable to test a message attachment on a RawMessage or Message instance.');
|
||||
}
|
||||
|
||||
@@ -50,8 +45,6 @@ final class EmailAttachmentCount extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($message): string
|
||||
{
|
||||
|
@@ -16,16 +16,13 @@ use Symfony\Component\Mime\RawMessage;
|
||||
|
||||
final class EmailHasHeader extends Constraint
|
||||
{
|
||||
private $headerName;
|
||||
private string $headerName;
|
||||
|
||||
public function __construct(string $headerName)
|
||||
{
|
||||
$this->headerName = $headerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('has header "%s"', $this->headerName);
|
||||
@@ -33,12 +30,10 @@ final class EmailHasHeader extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($message): bool
|
||||
{
|
||||
if (RawMessage::class === \get_class($message)) {
|
||||
if (RawMessage::class === $message::class) {
|
||||
throw new \LogicException('Unable to test a message header on a RawMessage instance.');
|
||||
}
|
||||
|
||||
@@ -47,8 +42,6 @@ final class EmailHasHeader extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($message): string
|
||||
{
|
||||
|
@@ -17,8 +17,8 @@ use Symfony\Component\Mime\RawMessage;
|
||||
|
||||
final class EmailHeaderSame extends Constraint
|
||||
{
|
||||
private $headerName;
|
||||
private $expectedValue;
|
||||
private string $headerName;
|
||||
private string $expectedValue;
|
||||
|
||||
public function __construct(string $headerName, string $expectedValue)
|
||||
{
|
||||
@@ -26,9 +26,6 @@ final class EmailHeaderSame extends Constraint
|
||||
$this->expectedValue = $expectedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('has header "%s" with value "%s"', $this->headerName, $this->expectedValue);
|
||||
@@ -36,12 +33,10 @@ final class EmailHeaderSame extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($message): bool
|
||||
{
|
||||
if (RawMessage::class === \get_class($message)) {
|
||||
if (RawMessage::class === $message::class) {
|
||||
throw new \LogicException('Unable to test a message header on a RawMessage instance.');
|
||||
}
|
||||
|
||||
@@ -50,8 +45,6 @@ final class EmailHeaderSame extends Constraint
|
||||
|
||||
/**
|
||||
* @param RawMessage $message
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($message): string
|
||||
{
|
||||
|
@@ -17,38 +17,31 @@ use Symfony\Component\Mime\RawMessage;
|
||||
|
||||
final class EmailHtmlBodyContains extends Constraint
|
||||
{
|
||||
private $expectedText;
|
||||
private string $expectedText;
|
||||
|
||||
public function __construct(string $expectedText)
|
||||
{
|
||||
$this->expectedText = $expectedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('contains "%s"', $this->expectedText);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param RawMessage $message
|
||||
*/
|
||||
protected function matches($message): bool
|
||||
{
|
||||
if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) {
|
||||
if (RawMessage::class === $message::class || Message::class === $message::class) {
|
||||
throw new \LogicException('Unable to test a message HTML body on a RawMessage or Message instance.');
|
||||
}
|
||||
|
||||
return false !== mb_strpos($message->getHtmlBody(), $this->expectedText);
|
||||
return str_contains($message->getHtmlBody(), $this->expectedText);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param RawMessage $message
|
||||
*/
|
||||
protected function failureDescription($message): string
|
||||
|
@@ -17,38 +17,31 @@ use Symfony\Component\Mime\RawMessage;
|
||||
|
||||
final class EmailTextBodyContains extends Constraint
|
||||
{
|
||||
private $expectedText;
|
||||
private string $expectedText;
|
||||
|
||||
public function __construct(string $expectedText)
|
||||
{
|
||||
$this->expectedText = $expectedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('contains "%s"', $this->expectedText);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param RawMessage $message
|
||||
*/
|
||||
protected function matches($message): bool
|
||||
{
|
||||
if (RawMessage::class === \get_class($message) || Message::class === \get_class($message)) {
|
||||
if (RawMessage::class === $message::class || Message::class === $message::class) {
|
||||
throw new \LogicException('Unable to test a message text body on a RawMessage or Message instance.');
|
||||
}
|
||||
|
||||
return false !== mb_strpos($message->getTextBody(), $this->expectedText);
|
||||
return str_contains($message->getTextBody(), $this->expectedText);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param RawMessage $message
|
||||
*/
|
||||
protected function failureDescription($message): string
|
||||
|
19
vendor/symfony/mime/composer.json
vendored
19
vendor/symfony/mime/composer.json
vendored
@@ -16,26 +16,25 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"php": ">=8.1",
|
||||
"symfony/polyfill-intl-idn": "^1.10",
|
||||
"symfony/polyfill-mbstring": "^1.0",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
"symfony/polyfill-mbstring": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"egulias/email-validator": "^2.1.10|^3.1",
|
||||
"league/html-to-markdown": "^5.0",
|
||||
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
|
||||
"symfony/dependency-injection": "^4.4|^5.0|^6.0",
|
||||
"symfony/property-access": "^4.4|^5.1|^6.0",
|
||||
"symfony/property-info": "^4.4|^5.1|^6.0",
|
||||
"symfony/serializer": "^5.4.14|~6.0.14|^6.1.6"
|
||||
"symfony/dependency-injection": "^5.4|^6.0",
|
||||
"symfony/property-access": "^5.4|^6.0",
|
||||
"symfony/property-info": "^5.4|^6.0",
|
||||
"symfony/serializer": "^6.2"
|
||||
},
|
||||
"conflict": {
|
||||
"egulias/email-validator": "~3.0.0",
|
||||
"phpdocumentor/reflection-docblock": "<3.2.2",
|
||||
"phpdocumentor/type-resolver": "<1.4.0",
|
||||
"symfony/mailer": "<4.4",
|
||||
"symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6"
|
||||
"symfony/mailer": "<5.4",
|
||||
"symfony/serializer": "<6.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\Mime\\": "" },
|
||||
|
Reference in New Issue
Block a user