Test Failed
Push — master ( 36c5b6...af11e6 )
by Sebastian
04:51
created

validateSyntax_statement()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
c 2
b 0
f 0
nc 2
nop 0
dl 0
loc 16
rs 9.9666
1
<?php
2
/**
3
 * File containing the {@see Mailcode_Commands_Command_For} class.
4
 *
5
 * @package Mailcode
6
 * @subpackage Commands
7
 * @see Mailcode_Commands_Command_For
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode;
13
14
/**
15
 * Mailcode command: opening FOR statement.
16
 *
17
 * @package Mailcode
18
 * @subpackage Commands
19
 * @author Sebastian Mordziol <[email protected]>
20
 */
21
class Mailcode_Commands_Command_For extends Mailcode_Commands_Command implements Mailcode_Commands_Command_Type_Opening, Mailcode_Interfaces_Commands_ListVariables
22
{
23
    use Mailcode_Traits_Commands_ListVariables;
24
    use Mailcode_Traits_Commands_Type_Opening;
25
26
    public const ERROR_SOURCE_VARIABLE_NOT_AVAILABLE = 64101;
27
    public const ERROR_LOOP_VARIABLE_NOT_AVAILABLE = 64102;
28
    public const ERROR_KEYWORD_NOT_AVAILABLE = 64103;
29
    
30
    public const VALIDATION_INVALID_FOR_STATEMENT = 49701;
31
    public const VALIDATION_WRONG_KEYWORD = 49702;
32
    public const VALIDATION_VARIABLE_NAME_IS_THE_SAME = 49703;
33
    public const VALIDATION_VARIABLE_NAME_WITH_DOT = 49704;
34
    public const VALIDATION_LOOP_VARIABLE_NAME_WITH_DOT = 49705;
35
    
36
   /**
37
    * @var Mailcode_Parser_Statement_Tokenizer_Token_Variable|NULL
38
    */
39
    private ?Mailcode_Parser_Statement_Tokenizer_Token_Variable $loopVar = null;
40
    
41
   /**
42
    * @var Mailcode_Parser_Statement_Tokenizer_Token_Variable|NULL
43
    */
44
    private ?Mailcode_Parser_Statement_Tokenizer_Token_Variable $sourceVar = null;
45
    
46
   /**
47
    * @var Mailcode_Parser_Statement_Tokenizer_Token_Keyword|NULL
48
    */
49
    private ?Mailcode_Parser_Statement_Tokenizer_Token_Keyword $keyword = null;
50
    
51
    public function getName() : string
52
    {
53
        return 'for';
54
    }
55
    
56
    public function getLabel() : string
57
    {
58
        return t('FOR loop');
59
    }
60
    
61
    public function supportsType(): bool
62
    {
63
        return false;
64
    }
65
66
    public function supportsURLEncoding() : bool
67
    {
68
        return false;
69
    }
70
71
    public function getDefaultType() : string
72
    {
73
        return '';
74
    }
75
    
76
    public function requiresParameters(): bool
77
    {
78
        return true;
79
    }
80
    
81
    public function supportsLogicKeywords() : bool
82
    {
83
        return false;
84
    }
85
    
86
    protected function getValidations() : array
87
    {
88
        return array(
89
            'statement',
90
            'keyword',
91
            'variable_names',
92
            'list_var',
93
            'record_var'
94
        );
95
    }
96
    
97
    public function generatesContent() : bool
98
    {
99
        return false;
100
    }
101
    
102
    public function getSourceVariable() : Mailcode_Variables_Variable
103
    {
104
        if(isset($this->sourceVar))
105
        {
106
            return $this->sourceVar->getVariable();
0 ignored issues
show
Bug introduced by
The method getVariable() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

106
            return $this->sourceVar->/** @scrutinizer ignore-call */ getVariable();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
107
        }
108
        
109
        throw new Mailcode_Exception(
110
            'No source variable available',
111
            null,
112
            self::ERROR_SOURCE_VARIABLE_NOT_AVAILABLE
113
        );
114
    }
115
    
116
    public function getLoopVariable() : Mailcode_Variables_Variable
117
    {
118
        if(isset($this->loopVar))
119
        {
120
            return $this->loopVar->getVariable();
0 ignored issues
show
Bug introduced by
The method getVariable() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

120
            return $this->loopVar->/** @scrutinizer ignore-call */ getVariable();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
121
        }
122
        
123
        throw new Mailcode_Exception(
124
            'No loop variable available',
125
            null,
126
            self::ERROR_LOOP_VARIABLE_NOT_AVAILABLE
127
        );
128
    }
129
    
130
    protected function validateSyntax_statement() : void
131
    {
132
        $info = $this->requireParams()->getInfo();
133
        
134
        $this->loopVar = $info->getVariableByIndex(0);
135
        $this->keyword = $info->getKeywordByIndex(1);
136
        $this->sourceVar = $info->getVariableByIndex(2);
137
        
138
        if(!$this->loopVar || !$this->keyword || !$this->sourceVar)
139
        {
140
            $this->validationResult->makeError(
141
                t('Not a valid for loop.').' '.t('Is the %1$s keyword missing?', 'in:'),
142
                self::VALIDATION_INVALID_FOR_STATEMENT
143
            );
144
            
145
            return;
146
        }
147
    }
148
    
149
    protected function validateSyntax_keyword() : void
150
    {
151
        $keyword = $this->getInKeyword();
152
153
        if($keyword->isForIn())
154
        {
155
            return;
156
        }
157
         
158
        $this->validationResult->makeError(
159
            t('The %1$s keyword cannot be used in this command.', $keyword->getKeyword()),
160
            self::VALIDATION_WRONG_KEYWORD
161
        );
162
    }
163
    
164
    protected function validateSyntax_variable_names() : void
165
    {
166
        if($this->getSourceVariable()->getFullName() !== $this->getLoopVariable()->getFullName())
167
        {
168
            return;
169
        }
170
        
171
        $this->validationResult->makeError(
172
            t('The source and loop variables have the same name.'),
173
            self::VALIDATION_VARIABLE_NAME_IS_THE_SAME
174
        );
175
    }
176
177
    protected function validateSyntax_list_var() : void
178
    {
179
        $name = $this->getSourceVariable()->getFullName();
180
181
        $parts = explode('.', $name);
182
183
        if(count($parts) === 1) {
184
            return;
185
        }
186
187
        $this->validationResult->makeError(
188
            t('The source variable is not a list variable:').' '.
189
            t('Expected a variable without dot, like %1$s.', '<code>$'.t('LIST').'</code>'),
190
            self::VALIDATION_VARIABLE_NAME_WITH_DOT
191
        );
192
    }
193
194
    protected function validateSyntax_record_var() : void
195
    {
196
        $name = $this->getLoopVariable()->getFullName();
197
198
        $parts = explode('.', $name);
199
200
        if(count($parts) === 1) {
201
            return;
202
        }
203
204
        $this->validationResult->makeError(
205
            t('The loop record variable may not have a dot in its name.'),
206
            self::VALIDATION_LOOP_VARIABLE_NAME_WITH_DOT
207
        );
208
    }
209
210
    protected function _collectListVariables(Mailcode_Variables_Collection_Regular $collection): void
211
    {
212
        $collection->add($this->getSourceVariable());
213
    }
214
215
    public function getInKeyword() : Mailcode_Parser_Statement_Tokenizer_Token_Keyword
216
    {
217
        if(isset($this->keyword))
218
        {
219
            return $this->keyword;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->keyword could return the type null which is incompatible with the type-hinted return Mailcode\Mailcode_Parser...Tokenizer_Token_Keyword. Consider adding an additional type-check to rule them out.
Loading history...
220
        }
221
222
        throw new Mailcode_Exception(
223
            'No keyword available.',
224
            'The keyword variable has not been set.',
225
            self::ERROR_KEYWORD_NOT_AVAILABLE
226
        );
227
    }
228
}
229