Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 150 | 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);
76
            $envelope = $event->getEnvelope();
77
            $message = $event->getMessage();
78
 
79
            if ($message instanceof TemplatedEmail && !$message->isRendered()) {
80
                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)));
81
            }
82
 
83
            $sentMessage = new SentMessage($message, $envelope);
84
 
85
            try {
86
                $this->doSend($sentMessage);
87
            } catch (\Throwable $error) {
88
                $this->dispatcher->dispatch(new FailedMessageEvent($message, $error));
89
                $this->checkThrottling();
90
 
91
                throw $error;
92
            }
93
 
94
            $this->dispatcher->dispatch(new SentMessageEvent($sentMessage));
95
 
96
            return $sentMessage;
97
        } finally {
98
            $this->checkThrottling();
99
        }
100
    }
101
 
102
    abstract protected function doSend(SentMessage $message): void;
103
 
104
    /**
105
     * @param Address[] $addresses
106
     *
107
     * @return string[]
108
     */
109
    protected function stringifyAddresses(array $addresses): array
110
    {
200 lars 111
        return array_map(function (Address $a) {
112
            return $a->toString();
113
        }, $addresses);
148 lars 114
    }
115
 
116
    protected function getLogger(): LoggerInterface
117
    {
118
        return $this->logger;
119
    }
120
 
121
    private function checkThrottling()
122
    {
123
        if (0 == $this->rate) {
124
            return;
125
        }
126
 
127
        $sleep = (1 / $this->rate) - (microtime(true) - $this->lastSent);
128
        if (0 < $sleep) {
129
            $this->logger->debug(sprintf('Email transport "%s" sleeps for %.2f seconds', __CLASS__, $sleep));
130
            usleep($sleep * 1000000);
131
        }
132
        $this->lastSent = microtime(true);
133
    }
134
}