Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | 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;
13
 
14
use Psr\EventDispatcher\EventDispatcherInterface;
15
use Psr\Log\LoggerInterface;
16
use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesTransportFactory;
17
use Symfony\Component\Mailer\Bridge\Google\Transport\GmailTransportFactory;
18
use Symfony\Component\Mailer\Bridge\Infobip\Transport\InfobipTransportFactory;
19
use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillTransportFactory;
20
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory;
21
use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory;
22
use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory;
23
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory;
24
use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory;
25
use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory;
26
use Symfony\Component\Mailer\Exception\InvalidArgumentException;
27
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
28
use Symfony\Component\Mailer\Transport\Dsn;
29
use Symfony\Component\Mailer\Transport\FailoverTransport;
30
use Symfony\Component\Mailer\Transport\NativeTransportFactory;
31
use Symfony\Component\Mailer\Transport\NullTransportFactory;
32
use Symfony\Component\Mailer\Transport\RoundRobinTransport;
33
use Symfony\Component\Mailer\Transport\SendmailTransportFactory;
34
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory;
35
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
36
use Symfony\Component\Mailer\Transport\TransportInterface;
37
use Symfony\Component\Mailer\Transport\Transports;
38
use Symfony\Contracts\HttpClient\HttpClientInterface;
39
 
40
/**
41
 * @author Fabien Potencier <fabien@symfony.com>
42
 * @author Konstantin Myakshin <molodchick@gmail.com>
43
 */
44
final class Transport
45
{
46
    private const FACTORY_CLASSES = [
47
        GmailTransportFactory::class,
48
        InfobipTransportFactory::class,
49
        MailgunTransportFactory::class,
50
        MailjetTransportFactory::class,
51
        MandrillTransportFactory::class,
52
        OhMySmtpTransportFactory::class,
53
        PostmarkTransportFactory::class,
54
        SendgridTransportFactory::class,
55
        SendinblueTransportFactory::class,
56
        SesTransportFactory::class,
57
    ];
58
 
59
    private iterable $factories;
60
 
61
    public static function fromDsn(string $dsn, EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null): TransportInterface
62
    {
63
        $factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger)));
64
 
65
        return $factory->fromString($dsn);
66
    }
67
 
68
    public static function fromDsns(array $dsns, EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null): TransportInterface
69
    {
70
        $factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger)));
71
 
72
        return $factory->fromStrings($dsns);
73
    }
74
 
75
    /**
76
     * @param TransportFactoryInterface[] $factories
77
     */
78
    public function __construct(iterable $factories)
79
    {
80
        $this->factories = $factories;
81
    }
82
 
83
    public function fromStrings(array $dsns): Transports
84
    {
85
        $transports = [];
86
        foreach ($dsns as $name => $dsn) {
87
            $transports[$name] = $this->fromString($dsn);
88
        }
89
 
90
        return new Transports($transports);
91
    }
92
 
93
    public function fromString(string $dsn): TransportInterface
94
    {
95
        [$transport, $offset] = $this->parseDsn($dsn);
96
        if ($offset !== \strlen($dsn)) {
97
            throw new InvalidArgumentException(sprintf('The DSN has some garbage at the end: "%s".', substr($dsn, $offset)));
98
        }
99
 
100
        return $transport;
101
    }
102
 
103
    private function parseDsn(string $dsn, int $offset = 0): array
104
    {
105
        static $keywords = [
106
            'failover' => FailoverTransport::class,
107
            'roundrobin' => RoundRobinTransport::class,
108
        ];
109
 
110
        while (true) {
111
            foreach ($keywords as $name => $class) {
112
                $name .= '(';
113
                if ($name === substr($dsn, $offset, \strlen($name))) {
114
                    $offset += \strlen($name) - 1;
115
                    preg_match('{\(([^()]|(?R))*\)}A', $dsn, $matches, 0, $offset);
116
                    if (!isset($matches[0])) {
117
                        continue;
118
                    }
119
 
120
                    ++$offset;
121
                    $args = [];
122
                    while (true) {
123
                        [$arg, $offset] = $this->parseDsn($dsn, $offset);
124
                        $args[] = $arg;
125
                        if (\strlen($dsn) === $offset) {
126
                            break;
127
                        }
128
                        ++$offset;
129
                        if (')' === $dsn[$offset - 1]) {
130
                            break;
131
                        }
132
                    }
133
 
134
                    return [new $class($args), $offset];
135
                }
136
            }
137
 
138
            if (preg_match('{(\w+)\(}A', $dsn, $matches, 0, $offset)) {
139
                throw new InvalidArgumentException(sprintf('The "%s" keyword is not valid (valid ones are "%s"), ', $matches[1], implode('", "', array_keys($keywords))));
140
            }
141
 
142
            if ($pos = strcspn($dsn, ' )', $offset)) {
143
                return [$this->fromDsnObject(Dsn::fromString(substr($dsn, $offset, $pos))), $offset + $pos];
144
            }
145
 
146
            return [$this->fromDsnObject(Dsn::fromString(substr($dsn, $offset))), \strlen($dsn)];
147
        }
148
    }
149
 
150
    public function fromDsnObject(Dsn $dsn): TransportInterface
151
    {
152
        foreach ($this->factories as $factory) {
153
            if ($factory->supports($dsn)) {
154
                return $factory->create($dsn);
155
            }
156
        }
157
 
158
        throw new UnsupportedSchemeException($dsn);
159
    }
160
 
161
    /**
162
     * @return \Traversable<int, TransportFactoryInterface>
163
     */
164
    public static function getDefaultFactories(EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null): \Traversable
165
    {
166
        foreach (self::FACTORY_CLASSES as $factoryClass) {
167
            if (class_exists($factoryClass)) {
168
                yield new $factoryClass($dispatcher, $client, $logger);
169
            }
170
        }
171
 
172
        yield new NullTransportFactory($dispatcher, $client, $logger);
173
 
174
        yield new SendmailTransportFactory($dispatcher, $client, $logger);
175
 
176
        yield new EsmtpTransportFactory($dispatcher, $client, $logger);
177
 
178
        yield new NativeTransportFactory($dispatcher, $client, $logger);
179
    }
180
}