Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Zur aktuellen Revision | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Symfony\Component\Mailer\Transport;
13
 
14
use Psr\EventDispatcher\EventDispatcherInterface;
15
use Psr\Log\LoggerInterface;
16
use Psr\Log\NullLogger;
17
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
18
use Symfony\Component\Mailer\Envelope;
19
use Symfony\Component\Mailer\Event\FailedMessageEvent;
20
use Symfony\Component\Mailer\Event\MessageEvent;
21
use Symfony\Component\Mailer\Event\SentMessageEvent;
22
use Symfony\Component\Mailer\Exception\LogicException;
23
use Symfony\Component\Mailer\SentMessage;
24
use Symfony\Component\Mime\Address;
25
use Symfony\Component\Mime\BodyRendererInterface;
26
use Symfony\Component\Mime\RawMessage;
27
 
28
/**
29
 * @author Fabien Potencier <fabien@symfony.com>
30
 */
31
abstract class AbstractTransport implements TransportInterface
32
{
33
    private ?EventDispatcherInterface $dispatcher;
34
    private LoggerInterface $logger;
35
    private float $rate = 0;
36
    private float $lastSent = 0;
37
 
38
    public function __construct(EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
39
    {
40
        $this->dispatcher = $dispatcher;
41
        $this->logger = $logger ?? new NullLogger();
42
    }
43
 
44
    /**
45
     * Sets the maximum number of messages to send per second (0 to disable).
46
     *
47
     * @return $this
48
     */
49
    public function setMaxPerSecond(float $rate): static
50
    {
51
        if (0 >= $rate) {
52
            $rate = 0;
53
        }
54
 
55
        $this->rate = $rate;
56
        $this->lastSent = 0;
57
 
58
        return $this;
59
    }
60
 
61
    public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage
62
    {
63
        $message = clone $message;
64
        $envelope = null !== $envelope ? clone $envelope : Envelope::create($message);
65
 
66
        try {
67
            if (!$this->dispatcher) {
68
                $sentMessage = new SentMessage($message, $envelope);
69
                $this->doSend($sentMessage);
70
 
71
                return $sentMessage;
72
            }
73
 
74
            $event = new MessageEvent($message, $envelope, (string) $this);
75
            $this->dispatcher->dispatch($event);
150 lars 76
            if ($event->isRejected()) {
77
                return null;
78
            }
79
 
148 lars 80
            $envelope = $event->getEnvelope();
81
            $message = $event->getMessage();
82
 
83
            if ($message instanceof TemplatedEmail && !$message->isRendered()) {
84
                throw new LogicException(sprintf('You must configure a "%s" when a "%s" instance has a text or HTML template set.', BodyRendererInterface::class, get_debug_type($message)));
85
            }
86
 
87
            $sentMessage = new SentMessage($message, $envelope);
88
 
89
            try {
90
                $this->doSend($sentMessage);
91
            } catch (\Throwable $error) {
92
                $this->dispatcher->dispatch(new FailedMessageEvent($message, $error));
93
                $this->checkThrottling();
94
 
95
                throw $error;
96
            }
97
 
98
            $this->dispatcher->dispatch(new SentMessageEvent($sentMessage));
99
 
100
            return $sentMessage;
101
        } finally {
102
            $this->checkThrottling();
103
        }
104
    }
105
 
106
    abstract protected function doSend(SentMessage $message): void;
107
 
108
    /**
109
     * @param Address[] $addresses
110
     *
111
     * @return string[]
112
     */
113
    protected function stringifyAddresses(array $addresses): array
114
    {
150 lars 115
        return array_map(fn (Address $a) => $a->toString(), $addresses);
148 lars 116
    }
117
 
118
    protected function getLogger(): LoggerInterface
119
    {
120
        return $this->logger;
121
    }
122
 
123
    private function checkThrottling()
124
    {
125
        if (0 == $this->rate) {
126
            return;
127
        }
128
 
129
        $sleep = (1 / $this->rate) - (microtime(true) - $this->lastSent);
130
        if (0 < $sleep) {
131
            $this->logger->debug(sprintf('Email transport "%s" sleeps for %.2f seconds', __CLASS__, $sleep));
132
            usleep($sleep * 1000000);
133
        }
134
        $this->lastSent = microtime(true);
135
    }
136
}