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\Mime\Header;
13
 
14
use Symfony\Component\Mime\Address;
15
use Symfony\Component\Mime\Exception\LogicException;
16
 
17
/**
18
 * A collection of headers.
19
 *
20
 * @author Fabien Potencier <fabien@symfony.com>
21
 */
22
final class Headers
23
{
24
    private const UNIQUE_HEADERS = [
25
        'date', 'from', 'sender', 'reply-to', 'to', 'cc', 'bcc',
26
        'message-id', 'in-reply-to', 'references', 'subject',
27
    ];
28
    private const HEADER_CLASS_MAP = [
29
        'date' => DateHeader::class,
30
        'from' => MailboxListHeader::class,
31
        'sender' => MailboxHeader::class,
32
        'reply-to' => MailboxListHeader::class,
33
        'to' => MailboxListHeader::class,
34
        'cc' => MailboxListHeader::class,
35
        'bcc' => MailboxListHeader::class,
36
        'message-id' => IdentificationHeader::class,
37
        'in-reply-to' => [UnstructuredHeader::class, IdentificationHeader::class], // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ...
38
        'references' => [UnstructuredHeader::class, IdentificationHeader::class], // ... `Message-ID`, even if that is no valid `msg-id`
39
        'return-path' => PathHeader::class,
40
    ];
41
 
42
    /**
43
     * @var HeaderInterface[][]
44
     */
45
    private array $headers = [];
46
    private int $lineLength = 76;
47
 
48
    public function __construct(HeaderInterface ...$headers)
49
    {
50
        foreach ($headers as $header) {
51
            $this->add($header);
52
        }
53
    }
54
 
55
    public function __clone()
56
    {
57
        foreach ($this->headers as $name => $collection) {
58
            foreach ($collection as $i => $header) {
59
                $this->headers[$name][$i] = clone $header;
60
            }
61
        }
62
    }
63
 
64
    public function setMaxLineLength(int $lineLength)
65
    {
66
        $this->lineLength = $lineLength;
67
        foreach ($this->all() as $header) {
68
            $header->setMaxLineLength($lineLength);
69
        }
70
    }
71
 
72
    public function getMaxLineLength(): int
73
    {
74
        return $this->lineLength;
75
    }
76
 
77
    /**
78
     * @param array<Address|string> $addresses
79
     *
80
     * @return $this
81
     */
82
    public function addMailboxListHeader(string $name, array $addresses): static
83
    {
84
        return $this->add(new MailboxListHeader($name, Address::createArray($addresses)));
85
    }
86
 
87
    /**
88
     * @return $this
89
     */
90
    public function addMailboxHeader(string $name, Address|string $address): static
91
    {
92
        return $this->add(new MailboxHeader($name, Address::create($address)));
93
    }
94
 
95
    /**
96
     * @return $this
97
     */
98
    public function addIdHeader(string $name, string|array $ids): static
99
    {
100
        return $this->add(new IdentificationHeader($name, $ids));
101
    }
102
 
103
    /**
104
     * @return $this
105
     */
106
    public function addPathHeader(string $name, Address|string $path): static
107
    {
108
        return $this->add(new PathHeader($name, $path instanceof Address ? $path : new Address($path)));
109
    }
110
 
111
    /**
112
     * @return $this
113
     */
114
    public function addDateHeader(string $name, \DateTimeInterface $dateTime): static
115
    {
116
        return $this->add(new DateHeader($name, $dateTime));
117
    }
118
 
119
    /**
120
     * @return $this
121
     */
122
    public function addTextHeader(string $name, string $value): static
123
    {
124
        return $this->add(new UnstructuredHeader($name, $value));
125
    }
126
 
127
    /**
128
     * @return $this
129
     */
130
    public function addParameterizedHeader(string $name, string $value, array $params = []): static
131
    {
132
        return $this->add(new ParameterizedHeader($name, $value, $params));
133
    }
134
 
135
    /**
136
     * @return $this
137
     */
138
    public function addHeader(string $name, mixed $argument, array $more = []): static
139
    {
140
        $headerClass = self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class;
141
        if (\is_array($headerClass)) {
142
            $headerClass = $headerClass[0];
143
        }
144
        $parts = explode('\\', $headerClass);
145
        $method = 'add'.ucfirst(array_pop($parts));
146
        if ('addUnstructuredHeader' === $method) {
147
            $method = 'addTextHeader';
148
        } elseif ('addIdentificationHeader' === $method) {
149
            $method = 'addIdHeader';
150
        }
151
 
152
        return $this->$method($name, $argument, $more);
153
    }
154
 
155
    public function has(string $name): bool
156
    {
157
        return isset($this->headers[strtolower($name)]);
158
    }
159
 
160
    /**
161
     * @return $this
162
     */
163
    public function add(HeaderInterface $header): static
164
    {
165
        self::checkHeaderClass($header);
166
 
167
        $header->setMaxLineLength($this->lineLength);
168
        $name = strtolower($header->getName());
169
 
170
        if (\in_array($name, self::UNIQUE_HEADERS, true) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) {
171
            throw new LogicException(sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.', $header->getName()));
172
        }
173
 
174
        $this->headers[$name][] = $header;
175
 
176
        return $this;
177
    }
178
 
179
    public function get(string $name): ?HeaderInterface
180
    {
181
        $name = strtolower($name);
182
        if (!isset($this->headers[$name])) {
183
            return null;
184
        }
185
 
186
        $values = array_values($this->headers[$name]);
187
 
188
        return array_shift($values);
189
    }
190
 
191
    public function all(string $name = null): iterable
192
    {
193
        if (null === $name) {
194
            foreach ($this->headers as $name => $collection) {
195
                foreach ($collection as $header) {
196
                    yield $name => $header;
197
                }
198
            }
199
        } elseif (isset($this->headers[strtolower($name)])) {
200
            foreach ($this->headers[strtolower($name)] as $header) {
201
                yield $header;
202
            }
203
        }
204
    }
205
 
206
    public function getNames(): array
207
    {
208
        return array_keys($this->headers);
209
    }
210
 
211
    public function remove(string $name): void
212
    {
213
        unset($this->headers[strtolower($name)]);
214
    }
215
 
216
    public static function isUniqueHeader(string $name): bool
217
    {
218
        return \in_array(strtolower($name), self::UNIQUE_HEADERS, true);
219
    }
220
 
221
    /**
222
     * @throws LogicException if the header name and class are not compatible
223
     */
224
    public static function checkHeaderClass(HeaderInterface $header): void
225
    {
226
        $name = strtolower($header->getName());
227
        $headerClasses = self::HEADER_CLASS_MAP[$name] ?? [];
228
        if (!\is_array($headerClasses)) {
229
            $headerClasses = [$headerClasses];
230
        }
231
 
232
        if (!$headerClasses) {
233
            return;
234
        }
235
 
236
        foreach ($headerClasses as $c) {
237
            if ($header instanceof $c) {
238
                return;
239
            }
240
        }
241
 
242
        throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), implode('" or "', $headerClasses), get_debug_type($header)));
243
    }
244
 
245
    public function toString(): string
246
    {
247
        $string = '';
248
        foreach ($this->toArray() as $str) {
249
            $string .= $str."\r\n";
250
        }
251
 
252
        return $string;
253
    }
254
 
255
    public function toArray(): array
256
    {
257
        $arr = [];
258
        foreach ($this->all() as $header) {
259
            if ('' !== $header->getBodyAsString()) {
260
                $arr[] = $header->toString();
261
            }
262
        }
263
 
264
        return $arr;
265
    }
266
 
267
    public function getHeaderBody(string $name)
268
    {
269
        return $this->has($name) ? $this->get($name)->getBody() : null;
270
    }
271
 
272
    /**
273
     * @internal
274
     */
275
    public function setHeaderBody(string $type, string $name, mixed $body): void
276
    {
277
        if ($this->has($name)) {
278
            $this->get($name)->setBody($body);
279
        } else {
280
            $this->{'add'.$type.'Header'}($name, $body);
281
        }
282
    }
283
 
284
    public function getHeaderParameter(string $name, string $parameter): ?string
285
    {
286
        if (!$this->has($name)) {
287
            return null;
288
        }
289
 
290
        $header = $this->get($name);
291
        if (!$header instanceof ParameterizedHeader) {
292
            throw new LogicException(sprintf('Unable to get parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class));
293
        }
294
 
295
        return $header->getParameter($parameter);
296
    }
297
 
298
    /**
299
     * @internal
300
     */
301
    public function setHeaderParameter(string $name, string $parameter, ?string $value): void
302
    {
303
        if (!$this->has($name)) {
304
            throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not defined.', $parameter, $name));
305
        }
306
 
307
        $header = $this->get($name);
308
        if (!$header instanceof ParameterizedHeader) {
309
            throw new LogicException(sprintf('Unable to set parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class));
310
        }
311
 
312
        $header->setParameter($parameter, $value);
313
    }
314
}