This commit is contained in:
Paolo A
2024-08-13 13:44:16 +00:00
parent 1bbb23088d
commit e796d76612
4001 changed files with 30101 additions and 40075 deletions

View File

@@ -18,6 +18,7 @@ use Postmark\ThrowExceptionOnFailurePlugin;
use Postmark\Transport as PostmarkTransport;
use Psr\Log\LoggerInterface;
use Swift_DependencyContainer;
use Swift_FailoverTransport as FailoverTransport;
use Swift_Mailer;
use Swift_SendmailTransport as SendmailTransport;
use Swift_SmtpTransport as SmtpTransport;
@@ -63,7 +64,7 @@ class MailManager implements FactoryContract
* Get a mailer instance by name.
*
* @param string|null $name
* @return \Illuminate\Mail\Mailer
* @return \Illuminate\Contracts\Mail\Mailer
*/
public function mailer($name = null)
{
@@ -156,6 +157,8 @@ class MailManager implements FactoryContract
*
* @param array $config
* @return \Swift_Transport
*
* @throws \InvalidArgumentException
*/
public function createTransport(array $config)
{
@@ -168,7 +171,7 @@ class MailManager implements FactoryContract
return call_user_func($this->customCreators[$transport], $config);
}
if (trim($transport) === '' || ! method_exists($this, $method = 'create'.ucfirst($transport).'Transport')) {
if (trim($transport ?? '') === '' || ! method_exists($this, $method = 'create'.ucfirst($transport).'Transport')) {
throw new InvalidArgumentException("Unsupported mail transport [{$transport}].");
}
@@ -260,11 +263,11 @@ class MailManager implements FactoryContract
*/
protected function createSesTransport(array $config)
{
if (! isset($config['secret'])) {
$config = array_merge($this->app['config']->get('services.ses', []), [
'version' => 'latest', 'service' => 'email',
]);
}
$config = array_merge(
$this->app['config']->get('services.ses', []),
['version' => 'latest', 'service' => 'email'],
$config
);
$config = Arr::except($config, ['transport']);
@@ -327,13 +330,46 @@ class MailManager implements FactoryContract
*/
protected function createPostmarkTransport(array $config)
{
$headers = isset($config['message_stream_id']) ? [
'X-PM-Message-Stream' => $config['message_stream_id'],
] : [];
return tap(new PostmarkTransport(
$config['token'] ?? $this->app['config']->get('services.postmark.token')
$config['token'] ?? $this->app['config']->get('services.postmark.token'),
$headers
), function ($transport) {
$transport->registerPlugin(new ThrowExceptionOnFailurePlugin());
$transport->registerPlugin(new ThrowExceptionOnFailurePlugin);
});
}
/**
* Create an instance of the Failover Swift Transport driver.
*
* @param array $config
* @return \Swift_FailoverTransport
*/
protected function createFailoverTransport(array $config)
{
$transports = [];
foreach ($config['mailers'] as $name) {
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Mailer [{$name}] is not defined.");
}
// Now, we will check if the "driver" key exists and if it does we will set
// the transport configuration parameter in order to offer compatibility
// with any Laravel <= 6.x application style mail configuration files.
$transports[] = $this->app['config']['mail.driver']
? $this->createTransport(array_merge($config, ['transport' => $name]))
: $this->createTransport($config);
}
return new FailoverTransport($transports);
}
/**
* Create an instance of the Log Swift Transport driver.
*
@@ -440,6 +476,19 @@ class MailManager implements FactoryContract
$this->app['config']['mail.default'] = $name;
}
/**
* Disconnect the given mailer and remove from local cache.
*
* @param string|null $name
* @return void
*/
public function purge($name = null)
{
$name = $name ?: $this->getDefaultDriver();
unset($this->mailers[$name]);
}
/**
* Register a custom transport creator Closure.
*
@@ -454,6 +503,41 @@ class MailManager implements FactoryContract
return $this;
}
/**
* Get the application instance used by the manager.
*
* @return \Illuminate\Contracts\Foundation\Application
*/
public function getApplication()
{
return $this->app;
}
/**
* Set the application instance used by the manager.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return $this
*/
public function setApplication($app)
{
$this->app = $app;
return $this;
}
/**
* Forget all of the resolved mailer instances.
*
* @return $this
*/
public function forgetMailers()
{
$this->mailers = [];
return $this;
}
/**
* Dynamically call the default driver instance.
*

View File

View File

@@ -7,18 +7,21 @@ use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
use Illuminate\Contracts\Mail\Factory as MailFactory;
use Illuminate\Contracts\Mail\Mailable as MailableContract;
use Illuminate\Contracts\Queue\Factory as Queue;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Conditionable;
use Illuminate\Support\Traits\ForwardsCalls;
use Illuminate\Support\Traits\Localizable;
use PHPUnit\Framework\Assert as PHPUnit;
use ReflectionClass;
use ReflectionProperty;
class Mailable implements MailableContract, Renderable
{
use ForwardsCalls, Localizable;
use Conditionable, ForwardsCalls, Localizable;
/**
* The locale of the message.
@@ -74,7 +77,7 @@ class Mailable implements MailableContract, Renderable
*
* @var string
*/
protected $markdown;
public $markdown;
/**
* The HTML to use for the message.
@@ -146,6 +149,13 @@ class Mailable implements MailableContract, Renderable
*/
public $mailer;
/**
* The rendered mailable views for testing / assertions.
*
* @var array
*/
protected $assertionableRenderStrings;
/**
* The callback that should be invoked while building the view data.
*
@@ -161,7 +171,7 @@ class Mailable implements MailableContract, Renderable
*/
public function send($mailer)
{
return $this->withLocale($this->locale, function () use ($mailer) {
$this->withLocale($this->locale, function () use ($mailer) {
Container::getInstance()->call([$this, 'build']);
$mailer = $mailer instanceof MailFactory
@@ -224,7 +234,11 @@ class Mailable implements MailableContract, Renderable
*/
protected function newQueuedJob()
{
return new SendQueuedMailable($this);
return (new SendQueuedMailable($this))
->through(array_merge(
method_exists($this, 'middleware') ? $this->middleware() : [],
$this->middleware ?? []
));
}
/**
@@ -604,6 +618,10 @@ class Mailable implements MailableContract, Renderable
*/
protected function setAddress($address, $name = null, $property = 'to')
{
if (empty($address)) {
return $this;
}
foreach ($this->addressesToArray($address, $name) as $recipient) {
$recipient = $this->normalizeRecipient($recipient);
@@ -665,6 +683,10 @@ class Mailable implements MailableContract, Renderable
*/
protected function hasRecipient($address, $name = null, $property = 'to')
{
if (empty($address)) {
return false;
}
$expected = $this->normalizeRecipient(
$this->addressesToArray($address, $name)[0]
);
@@ -844,6 +866,114 @@ class Mailable implements MailableContract, Renderable
return $this;
}
/**
* Assert that the given text is present in the HTML email body.
*
* @param string $string
* @return $this
*/
public function assertSeeInHtml($string)
{
[$html, $text] = $this->renderForAssertions();
PHPUnit::assertTrue(
Str::contains($html, $string),
"Did not see expected text [{$string}] within email body."
);
return $this;
}
/**
* Assert that the given text is not present in the HTML email body.
*
* @param string $string
* @return $this
*/
public function assertDontSeeInHtml($string)
{
[$html, $text] = $this->renderForAssertions();
PHPUnit::assertFalse(
Str::contains($html, $string),
"Saw unexpected text [{$string}] within email body."
);
return $this;
}
/**
* Assert that the given text is present in the plain-text email body.
*
* @param string $string
* @return $this
*/
public function assertSeeInText($string)
{
[$html, $text] = $this->renderForAssertions();
PHPUnit::assertTrue(
Str::contains($text, $string),
"Did not see expected text [{$string}] within text email body."
);
return $this;
}
/**
* Assert that the given text is not present in the plain-text email body.
*
* @param string $string
* @return $this
*/
public function assertDontSeeInText($string)
{
[$html, $text] = $this->renderForAssertions();
PHPUnit::assertFalse(
Str::contains($text, $string),
"Saw unexpected text [{$string}] within text email body."
);
return $this;
}
/**
* Render the HTML and plain-text version of the mailable into views for assertions.
*
* @return array
*
* @throws \ReflectionException
*/
protected function renderForAssertions()
{
if ($this->assertionableRenderStrings) {
return $this->assertionableRenderStrings;
}
return $this->assertionableRenderStrings = $this->withLocale($this->locale, function () {
Container::getInstance()->call([$this, 'build']);
$html = Container::getInstance()->make('mailer')->render(
$view = $this->buildView(), $this->buildViewData()
);
if (is_array($view) && isset($view[1])) {
$text = $view[1];
}
$text = $text ?? $view['text'] ?? '';
if (! empty($text) && ! $text instanceof Htmlable) {
$text = Container::getInstance()->make('mailer')->render(
$text, $this->buildViewData()
);
}
return [(string) $html, (string) $text];
});
}
/**
* Set the name of the mailer that should send the message.
*
@@ -881,25 +1011,6 @@ class Mailable implements MailableContract, Renderable
static::$viewDataCallback = $callback;
}
/**
* Apply the callback's message changes if the given "value" is true.
*
* @param mixed $value
* @param callable $callback
* @param mixed $default
* @return mixed|$this
*/
public function when($value, $callback, $default = null)
{
if ($value) {
return $callback($this, $value) ?: $this;
} elseif ($default) {
return $default($this, $value) ?: $this;
}
return $this;
}
/**
* Dynamically bind parameters to the message.
*

6
vendor/laravel/framework/src/Illuminate/Mail/Mailer.php vendored Normal file → Executable file
View File

@@ -197,7 +197,7 @@ class Mailer implements MailerContract, MailQueueContract
*/
public function html($html, $callback)
{
return $this->send(['html' => new HtmlString($html)], [], $callback);
$this->send(['html' => new HtmlString($html)], [], $callback);
}
/**
@@ -209,7 +209,7 @@ class Mailer implements MailerContract, MailQueueContract
*/
public function raw($text, $callback)
{
return $this->send(['raw' => $text], [], $callback);
$this->send(['raw' => $text], [], $callback);
}
/**
@@ -222,7 +222,7 @@ class Mailer implements MailerContract, MailQueueContract
*/
public function plain($view, array $data, $callback)
{
return $this->send(['text' => $view], $data, $callback);
$this->send(['text' => $view], $data, $callback);
}
/**

View File

@@ -6,7 +6,6 @@ use Illuminate\Contracts\View\Factory as ViewFactory;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment;
use League\CommonMark\Extension\Table\TableExtension;
use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;
@@ -63,9 +62,13 @@ class Markdown
'mail', $this->htmlComponentPaths()
)->make($view, $data)->render();
$theme = Str::contains($this->theme, '::')
? $this->theme
: 'mail::themes.'.$this->theme;
if ($this->view->exists($customTheme = Str::start($this->theme, 'mail.'))) {
$theme = $customTheme;
} else {
$theme = Str::contains($this->theme, '::')
? $this->theme
: 'mail::themes.'.$this->theme;
}
return new HtmlString(($inliner ?: new CssToInlineStyles)->convert(
$contents, $this->view->make($theme, $data)->render()
@@ -100,15 +103,13 @@ class Markdown
*/
public static function parse($text)
{
$environment = Environment::createCommonMarkEnvironment();
$environment->addExtension(new TableExtension);
$converter = new CommonMarkConverter([
'allow_unsafe_links' => false,
], $environment);
]);
return new HtmlString($converter->convertToHtml($text));
$converter->getEnvironment()->addExtension(new TableExtension());
return new HtmlString((string) $converter->convertToHtml($text));
}
/**
@@ -170,4 +171,14 @@ class Markdown
return $this;
}
/**
* Get the theme currently being used by the renderer.
*
* @return string
*/
public function getTheme()
{
return $this->theme;
}
}

2
vendor/laravel/framework/src/Illuminate/Mail/Message.php vendored Normal file → Executable file
View File

@@ -137,7 +137,7 @@ class Message
}
/**
* Add a reply to address to the message.
* Add a "reply to" address to the message.
*
* @param string|array $address
* @param string|null $name

View File

@@ -5,9 +5,12 @@ namespace Illuminate\Mail;
use Illuminate\Contracts\Mail\Mailable as MailableContract;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Support\Traits\Conditionable;
class PendingMail
{
use Conditionable;
/**
* The mailer instance.
*
@@ -114,24 +117,11 @@ class PendingMail
* Send a new mailable message instance.
*
* @param \Illuminate\Contracts\Mail\Mailable $mailable
* @return mixed
* @return void
*/
public function send(MailableContract $mailable)
{
return $this->mailer->send($this->fill($mailable));
}
/**
* Send a mailable message immediately.
*
* @param \Illuminate\Contracts\Mail\Mailable $mailable
* @return mixed
*
* @deprecated Use send() instead.
*/
public function sendNow(MailableContract $mailable)
{
return $this->mailer->send($this->fill($mailable));
$this->mailer->send($this->fill($mailable));
}
/**

View File

@@ -2,11 +2,15 @@
namespace Illuminate\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Mail\Factory as MailFactory;
use Illuminate\Contracts\Mail\Mailable as MailableContract;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
class SendQueuedMailable
{
use Queueable;
/**
* The mailable message instance.
*
@@ -28,6 +32,13 @@ class SendQueuedMailable
*/
public $timeout;
/**
* Indicates if the job should be encrypted.
*
* @var bool
*/
public $shouldBeEncrypted = false;
/**
* Create a new job instance.
*
@@ -39,6 +50,8 @@ class SendQueuedMailable
$this->mailable = $mailable;
$this->tries = property_exists($mailable, 'tries') ? $mailable->tries : null;
$this->timeout = property_exists($mailable, 'timeout') ? $mailable->timeout : null;
$this->afterCommit = property_exists($mailable, 'afterCommit') ? $mailable->afterCommit : null;
$this->shouldBeEncrypted = $mailable instanceof ShouldBeEncrypted;
}
/**
@@ -76,17 +89,17 @@ class SendQueuedMailable
}
/**
* Get the retry delay for the mailable object.
* Get the number of seconds before a released mailable will be available.
*
* @return mixed
*/
public function retryAfter()
public function backoff()
{
if (! method_exists($this->mailable, 'retryAfter') && ! isset($this->mailable->retryAfter)) {
if (! method_exists($this->mailable, 'backoff') && ! isset($this->mailable->backoff)) {
return;
}
return $this->mailable->retryAfter ?? $this->mailable->retryAfter();
return $this->mailable->backoff ?? $this->mailable->backoff();
}
/**

View File

@@ -26,6 +26,8 @@ class ArrayTransport extends Transport
/**
* {@inheritdoc}
*
* @return int
*/
public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
{

View File

@@ -28,6 +28,8 @@ class LogTransport extends Transport
/**
* {@inheritdoc}
*
* @return int
*/
public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
{

View File

@@ -3,7 +3,9 @@
namespace Illuminate\Mail\Transport;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use Swift_Mime_SimpleMessage;
use Swift_TransportException;
class MailgunTransport extends Transport
{
@@ -55,6 +57,8 @@ class MailgunTransport extends Transport
/**
* {@inheritdoc}
*
* @return int
*/
public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
{
@@ -66,15 +70,20 @@ class MailgunTransport extends Transport
$message->setBcc([]);
$response = $this->client->request(
'POST',
"https://{$this->endpoint}/v3/{$this->domain}/messages.mime",
$this->payload($message, $to)
);
try {
$response = $this->client->request(
'POST',
"https://{$this->endpoint}/v3/{$this->domain}/messages.mime",
$this->payload($message, $to)
);
} catch (GuzzleException $e) {
throw new Swift_TransportException('Request to Mailgun API failed.', $e->getCode(), $e);
}
$message->getHeaders()->addTextHeader(
'X-Mailgun-Message-ID', $this->getMessageId($response)
);
$messageId = $this->getMessageId($response);
$message->getHeaders()->addTextHeader('X-Message-ID', $messageId);
$message->getHeaders()->addTextHeader('X-Mailgun-Message-ID', $messageId);
$message->setBcc($bcc);

View File

@@ -2,8 +2,10 @@
namespace Illuminate\Mail\Transport;
use Aws\Exception\AwsException;
use Aws\Ses\SesClient;
use Swift_Mime_SimpleMessage;
use Swift_TransportException;
class SesTransport extends Transport
{
@@ -36,23 +38,32 @@ class SesTransport extends Transport
/**
* {@inheritdoc}
*
* @return int
*/
public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
{
$this->beforeSendPerformed($message);
$result = $this->ses->sendRawEmail(
array_merge(
$this->options, [
'Source' => key($message->getSender() ?: $message->getFrom()),
'RawMessage' => [
'Data' => $message->toString(),
],
]
)
);
try {
$result = $this->ses->sendRawEmail(
array_merge(
$this->options, [
'Source' => key($message->getSender() ?: $message->getFrom()),
'RawMessage' => [
'Data' => $message->toString(),
],
]
)
);
} catch (AwsException $e) {
throw new Swift_TransportException('Request to AWS SES API failed.', $e->getCode(), $e);
}
$message->getHeaders()->addTextHeader('X-SES-Message-ID', $result->get('MessageId'));
$messageId = $result->get('MessageId');
$message->getHeaders()->addTextHeader('X-Message-ID', $messageId);
$message->getHeaders()->addTextHeader('X-SES-Message-ID', $messageId);
$this->sendPerformed($message);

View File

@@ -18,6 +18,8 @@ abstract class Transport implements Swift_Transport
/**
* {@inheritdoc}
*
* @return bool
*/
public function isStarted()
{
@@ -42,6 +44,8 @@ abstract class Transport implements Swift_Transport
/**
* {@inheritdoc}
*
* @return bool
*/
public function ping()
{

22
vendor/laravel/framework/src/Illuminate/Mail/composer.json vendored Normal file → Executable file
View File

@@ -14,14 +14,16 @@
}
],
"require": {
"php": "^7.2.5|^8.0",
"php": "^7.3|^8.0",
"ext-json": "*",
"illuminate/container": "^7.0",
"illuminate/contracts": "^7.0",
"illuminate/support": "^7.0",
"league/commonmark": "^1.3",
"psr/log": "^1.0",
"swiftmailer/swiftmailer": "^6.0",
"illuminate/collections": "^8.0",
"illuminate/container": "^8.0",
"illuminate/contracts": "^8.0",
"illuminate/macroable": "^8.0",
"illuminate/support": "^8.0",
"league/commonmark": "^1.3|^2.0.2",
"psr/log": "^1.0|^2.0",
"swiftmailer/swiftmailer": "^6.3",
"tijsverkoyen/css-to-inline-styles": "^2.2.2"
},
"autoload": {
@@ -31,12 +33,12 @@
},
"extra": {
"branch-alias": {
"dev-master": "7.x-dev"
"dev-master": "8.x-dev"
}
},
"suggest": {
"aws/aws-sdk-php": "Required to use the SES mail driver (^3.155).",
"guzzlehttp/guzzle": "Required to use the Mailgun mail driver (^6.3.1|^7.0.1).",
"aws/aws-sdk-php": "Required to use the SES mail driver (^3.198.1).",
"guzzlehttp/guzzle": "Required to use the Mailgun mail driver (^6.5.5|^7.0.1).",
"wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)."
},
"config": {

View File

@@ -3,8 +3,8 @@
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<meta name="color-scheme" content="light">
<meta name="supported-color-schemes" content="light">
<style>
@media only screen and (max-width: 600px) {
.inner-body {
@@ -22,6 +22,8 @@ width: 100% !important;
}
}
</style>
</head>
<body>
<table class="wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>

View File

@@ -113,6 +113,7 @@ img {
.logo {
height: 75px;
max-height: 75px;
width: 75px;
}