Passed
Push — 3.x ( 451b43...8e526a )
by Eduardo Gulias
02:05
created

LocalPart::validateTokens()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17

Duplication

Lines 3
Ratio 17.65 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 3
loc 17
ccs 5
cts 5
cp 1
rs 9.7
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Egulias\EmailValidator\Parser;
4
5
use Egulias\EmailValidator\EmailLexer;
6
use Egulias\EmailValidator\Result\Result;
7
use Egulias\EmailValidator\Result\ValidEmail;
8
use Egulias\EmailValidator\Result\InvalidEmail;
9
use Egulias\EmailValidator\Warning\LocalTooLong;
10
use Egulias\EmailValidator\Result\Reason\DotAtEnd;
11
use Egulias\EmailValidator\Result\Reason\DotAtStart;
12
use Egulias\EmailValidator\Result\Reason\ConsecutiveDot;
13
use Egulias\EmailValidator\Result\Reason\ExpectingATEXT;
14
use Egulias\EmailValidator\Parser\CommentStrategy\LocalComment;
15
16
class LocalPart extends PartParser
17
{
18
    /**
19
     * @var string
20
     */
21
    private $localPart = '';
22
23
24 185
    public function parse() : Result
25
    {
26 185
        $this->lexer->startRecording();
27
28 185
        while ($this->lexer->token['type'] !== EmailLexer::S_AT && null !== $this->lexer->token['type']) {
29 185
            if ($this->hasDotAtStart()) {
30 2
                return new InvalidEmail(new DotAtStart(), $this->lexer->token['value']);
31
            }
32
33 183
            if ($this->lexer->token['type'] === EmailLexer::S_DQUOTE) {
34 23
                $dquoteParsingResult = $this->parseDoubleQuote();
35
36
                //Invalid double quote parsing
37 23
                if($dquoteParsingResult->isInvalid()) {
38 10
                    return $dquoteParsingResult;
39
                }
40
            }
41
42 174 View Code Duplication
            if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS || 
0 ignored issues
show
Duplication introduced by
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...
43 174
                $this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS ) {
44 9
                $commentsResult = $this->parseComments();
45
46
                //Invalid comment parsing
47 9
                if($commentsResult->isInvalid()) {
48 6
                    return $commentsResult;
49
                }
50
            }
51
52 172 View Code Duplication
            if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_DOT)) {
0 ignored issues
show
Duplication introduced by
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...
53 1
                return new InvalidEmail(new ConsecutiveDot(), $this->lexer->token['value']);
54
            }
55
56 172 View Code Duplication
            if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
0 ignored issues
show
Duplication introduced by
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...
57 172
                $this->lexer->isNextToken(EmailLexer::S_AT)
58
            ) {
59 2
                return new InvalidEmail(new DotAtEnd(), $this->lexer->token['value']);
60
            }
61
62 172
            $resultEscaping = $this->validateEscaping();
63 172
            if ($resultEscaping->isInvalid()) {
64 6
                return $resultEscaping;
65
            }
66
67 167
            $resultToken = $this->validateTokens(false);
68 167
            if ($resultToken->isInvalid()) {
69 4
                return $resultToken;
70
            }
71
72 166
            $resultFWS = $this->parseLocalFWS();
73 166
            if($resultFWS->isInvalid()) {
74 7
                return $resultFWS;
75
            }
76
77 165
            $this->lexer->moveNext();
78
        }
79
80 147
        $this->lexer->stopRecording();
81 147
        $this->localPart = rtrim($this->lexer->getAccumulatedValues(), '@');
82 147
        if (strlen($this->localPart) > LocalTooLong::LOCAL_PART_LENGTH) {
83 2
            $this->warnings[LocalTooLong::CODE] = new LocalTooLong();
84
        }
85
86 147
        return new ValidEmail();
87
    }
88
89 167
    protected function validateTokens(bool $hasComments) : Result
0 ignored issues
show
Unused Code introduced by
The parameter $hasComments is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
90
    {
91
        $invalidTokens = array(
92 167
            EmailLexer::S_COMMA => EmailLexer::S_COMMA,
93
            EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET,
94
            EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET,
95
            EmailLexer::S_GREATERTHAN => EmailLexer::S_GREATERTHAN,
96
            EmailLexer::S_LOWERTHAN => EmailLexer::S_LOWERTHAN,
97
            EmailLexer::S_COLON => EmailLexer::S_COLON,
98
            EmailLexer::S_SEMICOLON => EmailLexer::S_SEMICOLON,
99
            EmailLexer::INVALID => EmailLexer::INVALID
100
        );
101 167 View Code Duplication
        if (isset($invalidTokens[$this->lexer->token['type']])) {
0 ignored issues
show
Duplication introduced by
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...
102 4
            return new InvalidEmail(new ExpectingATEXT('Invalid token found'), $this->lexer->token['value']);
103
        }
104 166
        return new ValidEmail();
105
    }
106
107 185
    public function localPart() : string
108
    {
109 185
        return $this->localPart;
110
    }
111
112 166
    private function parseLocalFWS() : Result 
113
    {
114 166
        $foldingWS = new FoldingWhiteSpace($this->lexer);
115 166
        $resultFWS = $foldingWS->parse();
116 166
        if ($resultFWS->isValid()) {
117 165
            $this->warnings = array_merge($this->warnings, $foldingWS->getWarnings());
118
        }
119 166
        return $resultFWS;
120
    }
121
122 185
    private function hasDotAtStart() : bool
123
    {
124 185
            return $this->lexer->token['type'] === EmailLexer::S_DOT && null === $this->lexer->getPrevious()['type'];
125
    }
126
127 23
    private function parseDoubleQuote() : Result
128
    {
129 23
        $dquoteParser = new DoubleQuote($this->lexer);
130 23
        $parseAgain = $dquoteParser->parse();
131 23
        $this->warnings = array_merge($this->warnings, $dquoteParser->getWarnings());
132
133 23
        return $parseAgain;
134
    }
135
136 8
    protected function parseComments(): Result
137
    {
138 8
        $commentParser = new Comment($this->lexer, new LocalComment());
139 8
        $result = $commentParser->parse();
140 8
        $this->warnings = array_merge($this->warnings, $commentParser->getWarnings());
141 8
        if($result->isInvalid()) {
142 5
            return $result;
143
        }
144 3
        return $result;
145
    }
146
147 172
    private function validateEscaping() : Result
148
    {
149
        //Backslash found
150 172
        if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
151 167
            return new ValidEmail();
152
        }
153
154 7
        if ($this->lexer->isNextToken(EmailLexer::GENERIC)) {
155 6
            return new InvalidEmail(new ExpectingATEXT('Found ATOM after escaping'), $this->lexer->token['value']);
156
        }
157
158 1 View Code Duplication
        if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) {
0 ignored issues
show
Duplication introduced by
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...
159
            return new ValidEmail();
160
        }
161
162 1
        return new ValidEmail();
163
    }
164
}