Passed
Push — master ( 295c7f...61bbf4 )
by Zaahid
09:01
created

AddressConsumer::isStartToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
122
            } else {
123 103
                $strEmail .= preg_replace('/\s+/', '', $part->getValue());
124
            }
125 103
            $strName .= $part->getValue();
126
        }
127 8
        return [ $this->partFactory->newAddressPart('', $strEmail) ];
128
    }
129
}
130