Passed
Push — master ( 46ed75...ca2387 )
by Zaahid
03:33
created

AddressConsumerService::processParts()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7

Importance

Changes 0
Metric Value
eloc 16
c 0
b 0
f 0
dl 0
loc 22
ccs 18
cts 18
cp 1
rs 8.8333
cc 7
nc 5
nop 1
crap 7
1
<?php
2
/**
3
 * This file is part of the ZBateson\MailMimeParser project.
4
 *
5
 * @license http://opensource.org/licenses/bsd-license.php BSD
6
 */
7
8
namespace ZBateson\MailMimeParser\Header\Consumer;
9
10
use ZBateson\MailMimeParser\Header\Part\AddressGroupPart;
11
use ZBateson\MailMimeParser\Header\Part\AddressPart;
12
use ZBateson\MailMimeParser\Header\Part\CommentPart;
13
use ZBateson\MailMimeParser\Header\Part\HeaderPartFactory;
14
use ZBateson\MailMimeParser\Header\Part\LiteralPart;
15
16
/**
17
 * Parses a single part of an address header.
18
 *
19
 * Represents a single part of a list of addresses.  A part could be one email
20
 * address, or one 'group' containing multiple addresses.  The consumer ends on
21
 * finding either a comma token, representing a separation between addresses, or
22
 * a semi-colon token representing the end of a group.
23
 *
24
 * A single email address may consist of just an email, or a name and an email
25
 * address.  Both of these are valid examples of a From header:
26
 *  - From: [email protected]
27
 *  - From: Jon Snow <[email protected]>
28
 *
29
 * Groups must be named, for example:
30
 *  - To: Winterfell: [email protected], Arya Stark <[email protected]>;
31
 *
32
 * Addresses may contain quoted parts and comments, and names may be mime-header
33
 * encoded.
34
 *
35
 * @author Zaahid Bateson
36
 */
37
class AddressConsumerService extends AbstractConsumerService
38
{
39 9
    public function __construct(
40
        HeaderPartFactory $partFactory,
41
        AddressGroupConsumerService $addressGroupConsumerService,
42
        AddressEmailConsumerService $addressEmailConsumerService,
43
        CommentConsumerService $commentConsumerService,
44
        QuotedStringConsumerService $quotedStringConsumerService
45
    ) {
46 9
        $addressGroupConsumerService->setAddressConsumerService($this);
47 9
        parent::__construct(
48 9
            $partFactory,
49 9
            [
50 9
                $addressGroupConsumerService,
51 9
                $addressEmailConsumerService,
52 9
                $commentConsumerService,
53 9
                $quotedStringConsumerService
54 9
            ]
55 9
        );
56
    }
57
58
    /**
59
     * Overridden to return patterns matching end tokens ("," and ";"), and
60
     * whitespace.
61
     *
62
     * @return string[] the patterns
63
     */
64 10
    public function getTokenSeparators() : array
65
    {
66 10
        return [',', ';', '\s+'];
67
    }
68
69
    /**
70
     * Returns true for commas and semi-colons.
71
     *
72
     * Although the semi-colon is not strictly the end token of an
73
     * AddressConsumerService, it could end a parent
74
     * {@see AddressGroupConsumerService}.
75
     */
76 104
    protected function isEndToken(string $token) : bool
77
    {
78 104
        return ($token === ',' || $token === ';');
79
    }
80
81
    /**
82
     * AddressConsumer is "greedy", so this always returns true.
83
     */
84 95
    protected function isStartToken(string $token) : bool
85
    {
86 95
        return true;
87
    }
88
89
    /**
90
     * Performs final processing on parsed parts.
91
     *
92
     * AddressConsumerService's implementation looks for tokens representing the
93
     * beginning of an address part, to create a {@see AddressPart} out of a
94
     * name/address pair, or assign the name part to a parsed
95
     * {@see AddressGroupPart} returned from its AddressGroupConsumerService
96
     * sub-consumer.
97
     *
98
     * The returned array consists of a single element - either an
99
     * {@see AddressPart} or an {@see AddressGroupPart}.
100
     *
101
     * @param \ZBateson\MailMimeParser\Header\IHeaderPart[] $parts
102
     * @return \ZBateson\MailMimeParser\Header\IHeaderPart[]|array
103
     */
104 104
    protected function processParts(array $parts) : array
105
    {
106 104
        $strName = '';
107 104
        $strEmail = '';
108 104
        foreach ($parts as $part) {
109 104
            if ($part instanceof AddressGroupPart) {
110 1
                return [
111 1
                    $this->partFactory->newAddressGroupPart(
112 1
                        $part->getAddresses(),
113 1
                        $strName
114 1
                    )
115 1
                ];
116 104
            } elseif ($part instanceof AddressPart) {
117 96
                return [$this->partFactory->newAddressPart($strName, $part->getEmail())];
118 104
            } elseif ((($part instanceof LiteralPart) && !($part instanceof CommentPart)) && $part->getValue() !== '') {
119 56
                $strEmail .= '"' . \preg_replace('/(["\\\])/', '\\\$1', $part->getValue()) . '"';
120
            } else {
121 104
                $strEmail .= \preg_replace('/\s+/', '', $part->getValue());
122
            }
123 104
            $strName .= $part->getValue();
124
        }
125 7
        return [$this->partFactory->newAddressPart('', $strEmail)];
126
    }
127
}
128