blob: 2f7d8a1b5789a866057d83fd58d311a21626d880 [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001<?php
2
3declare(strict_types=1);
4
5namespace Ddeboer\Imap\Message;
6
7class Parameters extends \ArrayIterator
8{
9 /**
10 * @var array
11 */
12 private static $attachmentCustomKeys = [
13 'name*' => 'name',
14 'filename*' => 'filename',
15 ];
16
17 public function __construct(array $parameters = [])
18 {
19 parent::__construct();
20
21 $this->add($parameters);
22 }
23
24 public function add(array $parameters = []): void
25 {
26 foreach ($parameters as $parameter) {
27 $key = \strtolower($parameter->attribute);
28 if (isset(self::$attachmentCustomKeys[$key])) {
29 $key = self::$attachmentCustomKeys[$key];
30 }
31 $value = $this->decode($parameter->value);
32 $this[$key] = $value;
33 }
34 }
35
36 /**
37 * @return mixed
38 */
39 public function get(string $key)
40 {
41 return $this[$key] ?? null;
42 }
43
44 /**
45 * Decode value.
46 */
47 final protected function decode(string $value): string
48 {
49 $parts = \imap_mime_header_decode($value);
50 if (!\is_array($parts)) {
51 return $value;
52 }
53
54 $decoded = '';
55 foreach ($parts as $part) {
56 $text = $part->text;
57 if ('default' !== $part->charset) {
58 $text = Transcoder::decode($text, $part->charset);
59 }
60 // RFC2231
61 if (1 === \preg_match('/^(?<encoding>[^\']+)\'[^\']*?\'(?<urltext>.+)$/', $text, $matches)) {
62 $hasInvalidChars = 1 === \preg_match('#[^%a-zA-Z0-9\-_\.\+]#', $matches['urltext']);
63 $hasEscapedChars = 1 === \preg_match('#%[a-zA-Z0-9]{2}#', $matches['urltext']);
64 if (!$hasInvalidChars && $hasEscapedChars) {
65 $text = Transcoder::decode(\urldecode($matches['urltext']), $matches['encoding']);
66 }
67 }
68
69 $decoded .= $text;
70 }
71
72 return $decoded;
73 }
74}