master

laravel/framework

Last updated at: 29/12/2023 09:24

SesV2Transport.php

TLDR

This file, SesV2Transport.php, contains the SesV2Transport class, which is a transport implementation for sending emails using the Amazon SES V2 service. It extends the AbstractTransport class and implements the Stringable interface. The class provides a constructor, several methods for sending and retrieving emails, and getter and setter methods for handling the transport options.

Methods

__construct(SesV2Client $ses, $options = [])

This method is responsible for creating a new instance of the SesV2Transport class. It accepts an instance of the SesV2Client class as the first parameter and an optional array of transport options as the second parameter. It assigns the provided SES client and options to the corresponding properties of the class.

doSend(SentMessage $message): void

This method is called internally by the framework to send the email using the Amazon SES V2 service. It accepts an instance of the SentMessage class as a parameter. It retrieves the necessary information from the $message object, such as the original message, headers, sender, and recipients, and uses the SES client to send the email. If an error occurs during the sending process, a TransportException is thrown.

ses(): SesV2Client

This method returns the Amazon SES V2 client instance that is used by the SesV2Transport class.

getOptions(): array

This method returns the transmission options being used by the transport.

setOptions(array $options): array

This method updates the transmission options being used by the transport. It accepts an array of options as a parameter and updates the $options property accordingly.

__toString(): string

This method returns the string representation of the SesV2Transport class, which is 'ses-v2'.

<?php

namespace Illuminate\Mail\Transport;

use Aws\Exception\AwsException;
use Aws\SesV2\SesV2Client;
use Stringable;
use Symfony\Component\Mailer\Exception\TransportException;
use Symfony\Component\Mailer\Header\MetadataHeader;
use Symfony\Component\Mailer\SentMessage;
use Symfony\Component\Mailer\Transport\AbstractTransport;
use Symfony\Component\Mime\Message;

class SesV2Transport extends AbstractTransport implements Stringable
{
    /**
     * The Amazon SES V2 instance.
     *
     * @var \Aws\SesV2\SesV2Client
     */
    protected $ses;

    /**
     * The Amazon SES transmission options.
     *
     * @var array
     */
    protected $options = [];

    /**
     * Create a new SES V2 transport instance.
     *
     * @param  \Aws\SesV2\SesV2Client  $ses
     * @param  array  $options
     * @return void
     */
    public function __construct(SesV2Client $ses, $options = [])
    {
        $this->ses = $ses;
        $this->options = $options;

        parent::__construct();
    }

    /**
     * {@inheritDoc}
     */
    protected function doSend(SentMessage $message): void
    {
        $options = $this->options;

        if ($message->getOriginalMessage() instanceof Message) {
            foreach ($message->getOriginalMessage()->getHeaders()->all() as $header) {
                if ($header instanceof MetadataHeader) {
                    $options['Tags'][] = ['Name' => $header->getKey(), 'Value' => $header->getValue()];
                }
            }
        }

        try {
            $result = $this->ses->sendEmail(
                array_merge(
                    $options, [
                        'Source' => $message->getEnvelope()->getSender()->toString(),
                        'Destination' => [
                            'ToAddresses' => collect($message->getEnvelope()->getRecipients())
                                    ->map
                                    ->toString()
                                    ->values()
                                    ->all(),
                        ],
                        'Content' => [
                            'Raw' => [
                                'Data' => $message->toString(),
                            ],
                        ],
                    ]
                )
            );
        } catch (AwsException $e) {
            $reason = $e->getAwsErrorMessage() ?? $e->getMessage();

            throw new TransportException(
                sprintf('Request to AWS SES V2 API failed. Reason: %s.', $reason),
                is_int($e->getCode()) ? $e->getCode() : 0,
                $e
            );
        }

        $messageId = $result->get('MessageId');

        $message->getOriginalMessage()->getHeaders()->addHeader('X-Message-ID', $messageId);
        $message->getOriginalMessage()->getHeaders()->addHeader('X-SES-Message-ID', $messageId);
    }

    /**
     * Get the Amazon SES V2 client for the SesV2Transport instance.
     *
     * @return \Aws\SesV2\SesV2Client
     */
    public function ses()
    {
        return $this->ses;
    }

    /**
     * Get the transmission options being used by the transport.
     *
     * @return array
     */
    public function getOptions()
    {
        return $this->options;
    }

    /**
     * Set the transmission options being used by the transport.
     *
     * @param  array  $options
     * @return array
     */
    public function setOptions(array $options)
    {
        return $this->options = $options;
    }

    /**
     * Get the string representation of the transport.
     *
     * @return string
     */
    public function __toString(): string
    {
        return 'ses-v2';
    }
}