Completed
Push — master ( a73d41...46f3eb )
by Mathieu
06:08 queued 33s
created

Parser::parse()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Charcoal\Email\Services;
6
7
use InvalidArgumentException;
8
9
/**
10
 * Parser service
11
 */
12
class Parser
13
{
14
    /**
15
     * @var string
16
     */
17
    public const REGEXP = '/(.+[\s]+)?(<)?(([\w\-\._\+]+)@((?:[\w\-_]+\.)+)([a-zA-Z]*))?(>)?/u';
18
19
    /**
20
     * @param string|array $email An email value (either a string or an array).
21
     * @throws InvalidArgumentException If the email is invalid.
22
     * @return string
23
     */
24
    public function parse($email): string
25
    {
26
        if (is_array($email)) {
27
            return $this->emailFromArray($email);
28
        } elseif (is_string($email)) {
29
            $arr = $this->emailToArray($email);
30
            return $this->emailFromArray($arr);
31
        } else {
32
            throw new InvalidArgumentException(
33
                'Can not parse email: must be an array or a string'
34
            );
35
        }
36
    }
37
38
    /**
39
     * Convert an email address (RFC822) into a proper array notation.
40
     *
41
     * @param  string $var An email array (containing an "email" key and optionally a "name" key).
42
     * @throws InvalidArgumentException If the email is invalid.
43
     * @return array
44
     */
45
    public function emailToArray(string $var) : array
46
    {
47
        preg_match(self::REGEXP, $var, $out);
48
        return [
49
            'email' => (isset($out[3]) ? trim($out[3]) : ''),
50
            'name'  => (isset($out[1]) ? trim(trim($out[1]), '\'"') : '')
51
        ];
52
    }
53
54
    /**
55
     * Convert an email address array to a RFC-822 string notation.
56
     *
57
     * @param  array $arr An email array (containing an "email" key and optionally a "name" key).
58
     * @throws InvalidArgumentException If the email array is invalid.
59
     * @return string
60
     */
61
    public function emailFromArray(array $arr) : string
62
    {
63
        if (!isset($arr['email'])) {
64
            throw new InvalidArgumentException(
65
                'The array must contain at least the "email" key.'
66
            );
67
        }
68
69
        $email = strval(filter_var($arr['email'], FILTER_SANITIZE_EMAIL));
70
71
        if (!isset($arr['name']) || $arr['name'] === '') {
72
            return $email;
73
        }
74
75
        $name = str_replace('"', '', filter_var($arr['name'], FILTER_SANITIZE_STRING));
76
        return sprintf('"%s" <%s>', $name, $email);
77
    }
78
}
79