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