Passed
Push — master ( c4b8d1...e834ee )
by Eduardo Gulias
02:09
created

EmailValidator/Parser/LocalPart.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Egulias\EmailValidator\Parser;
4
5
use Egulias\EmailValidator\Exception\DotAtEnd;
6
use Egulias\EmailValidator\Exception\DotAtStart;
7
use Egulias\EmailValidator\EmailLexer;
8
use Egulias\EmailValidator\Exception\ExpectingAT;
9
use Egulias\EmailValidator\Exception\ExpectingATEXT;
10
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
11
use Egulias\EmailValidator\Exception\UnopenedComment;
12
use Egulias\EmailValidator\Warning\CFWSWithFWS;
13
use Egulias\EmailValidator\Warning\LocalTooLong;
14
15
class LocalPart extends Parser
16
{
17 129
    public function parse($localPart)
18
    {
19 129
        $parseDQuote = true;
20 129
        $closingQuote = false;
21 129
        $openedParenthesis = 0;
22
23 129
        while ($this->lexer->token['type'] !== EmailLexer::S_AT && null !== $this->lexer->token['type']) {
24 129 View Code Duplication
            if ($this->lexer->token['type'] === EmailLexer::S_DOT && null === $this->lexer->getPrevious()['type']) {
25 2
                throw new DotAtStart();
26
            }
27
28 127
            $closingQuote = $this->checkDQUOTE($closingQuote);
29 126
            if ($closingQuote && $parseDQuote) {
30 20
                $parseDQuote = $this->parseDoubleQuote();
31 12
            }
32
33 118
            if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
34 7
                $this->parseComments();
35 3
                $openedParenthesis += $this->getOpenedParenthesis();
36 3
            }
37 115 View Code Duplication
            if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
38 4
                if ($openedParenthesis === 0) {
39 2
                    throw new UnopenedComment();
40
                } else {
41 3
                    $openedParenthesis--;
42
                }
43 3
            }
44
45 115
            $this->checkConsecutiveDots();
46
47 115 View Code Duplication
            if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
48 3
                $this->lexer->isNextToken(EmailLexer::S_AT)
49 115
            ) {
50 2
                throw new DotAtEnd();
51
            }
52
53 115
            $this->warnEscaping();
54 110
            $this->isInvalidToken($this->lexer->token, $closingQuote);
55
56 109
            if ($this->isFWS()) {
57 7
                $this->parseFWS();
58 3
            }
59
60 109
            $this->lexer->moveNext();
61 109
        }
62
63 92
        $prev = $this->lexer->getPrevious();
64 92
        if (strlen($prev['value']) > LocalTooLong::LOCAL_PART_LENGTH) {
65 2
            $this->warnings[LocalTooLong::CODE] = new LocalTooLong();
66 2
        }
67 92
    }
68
69
    /**
70
     * @return bool
71
     */
72 20
    protected function parseDoubleQuote()
73
    {
74 20
        $parseAgain = true;
75
        $special = array(
76 20
            EmailLexer::S_CR => true,
77 20
            EmailLexer::S_HTAB => true,
78 20
            EmailLexer::S_LF => true
79 20
        );
80
81
        $invalid = array(
82 20
            EmailLexer::C_NUL => true,
83 20
            EmailLexer::S_HTAB => true,
84 20
            EmailLexer::S_CR => true,
85 20
            EmailLexer::S_LF => true
86 20
        );
87 20
        $setSpecialsWarning = true;
88
89 20
        $this->lexer->moveNext();
90
91 20
        while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && null !== $this->lexer->token['type']) {
92 18
            $parseAgain = false;
93 18
            if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
94 2
                $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
95 2
                $setSpecialsWarning = false;
96 2
            }
97 18 View Code Duplication
            if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) {
98 4
                $this->lexer->moveNext();
99 4
            }
100
101 18
            $this->lexer->moveNext();
102
103 18
            if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
104
                throw new ExpectingATEXT();
105
            }
106 18
        }
107
108 20
        $prev = $this->lexer->getPrevious();
109
110 20
        if ($prev['type'] === EmailLexer::S_BACKSLASH) {
111
            if (!$this->checkDQUOTE(false)) {
112
                throw new UnclosedQuotedString();
113
            }
114
        }
115
116 20
        if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
117 8
            throw new ExpectingAT();
118
        }
119
120 12
        return $parseAgain;
121
    }
122
123
    /**
124
     * @param bool $closingQuote
125
     */
126 110
    protected function isInvalidToken(array $token, $closingQuote)
127
    {
128
        $forbidden = array(
129 110
            EmailLexer::S_COMMA,
130 110
            EmailLexer::S_CLOSEBRACKET,
131 110
            EmailLexer::S_OPENBRACKET,
132 110
            EmailLexer::S_GREATERTHAN,
133 110
            EmailLexer::S_LOWERTHAN,
134 110
            EmailLexer::S_COLON,
135 110
            EmailLexer::S_SEMICOLON,
136
            EmailLexer::INVALID
137 110
        );
138
139 110
        if (in_array($token['type'], $forbidden) && !$closingQuote) {
140 4
            throw new ExpectingATEXT();
141
        }
142 109
    }
143
}
144