Passed
Pull Request — master (#15)
by Sebastian
04:12
created

BreakAtTrait::setBreakAt()   B

Complexity

Conditions 7
Paths 14

Size

Total Lines 42
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 23
c 1
b 0
f 0
nc 14
nop 1
dl 0
loc 42
rs 8.6186
1
<?php
2
/**
3
 * File containing the {@see \Mailcode\Traits\Commands\Validation\BreakAtTrait} trait.
4
 *
5
 * @see \Mailcode\Traits\Commands\Validation\BreakAtTrait
6
 * @subpackage Validation
7
 * @package Mailcode
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode\Traits\Commands\Validation;
13
14
use Mailcode\Commands\CommandException;
15
use Mailcode\Commands\ParamsException;
16
use Mailcode\Interfaces\Commands\Validation\BreakAtInterface;
17
use Mailcode\Mailcode_Commands_Keywords;
18
use Mailcode\Mailcode_Exception;
19
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Process_StringLiterals;
20
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token;
21
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token_Number;
22
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral;
23
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token_Variable;
24
use Mailcode\Mailcode_Variables_Variable;
25
use function Mailcode\t;
26
27
/**
28
 * Command validation drop-in: checks for the presence
29
 * of the `break-at` parameter in the command statement.
30
 *
31
 * @package Mailcode
32
 * @subpackage Validation
33
 * @author Olaf Böcker <[email protected]>
34
 *
35
 * @see BreakAtInterface
36
 */
37
trait BreakAtTrait
38
{
39
    private bool $breakAtEnabled = false;
40
41
    private ?Mailcode_Parser_Statement_Tokenizer_Token $breakAtToken = null;
42
43
    protected function validateSyntax_check_break_at(): void
44
    {
45
        $this->breakAtToken = $this
46
            ->requireParams()
0 ignored issues
show
Bug introduced by
It seems like requireParams() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

46
            ->/** @scrutinizer ignore-call */ requireParams()
Loading history...
47
            ->getInfo()
48
            ->getTokenByParamName(BreakAtInterface::PARAMETER_NAME);
49
50
        if($this->breakAtToken === null) {
51
            $this->breakAtEnabled = false;
52
            return;
53
        }
54
55
        if (!$this->breakAtToken instanceof Mailcode_Parser_Statement_Tokenizer_Token_Number &&
56
            !$this->breakAtToken instanceof Mailcode_Parser_Statement_Tokenizer_Token_Variable) {
57
            $this->validationResult->makeError(
58
                t('Invalid break-at value:') . ' ' . t('Expected a number or variable.'),
59
                BreakAtInterface::VALIDATION_BREAK_AT_CODE_WRONG_TYPE
60
            );
61
            return;
62
        }
63
64
        $this->breakAtEnabled = true;
65
    }
66
67
    public function isBreakAtEnabled(): bool
68
    {
69
        return $this->breakAtEnabled;
70
    }
71
72
    public function getBreakAtToken(): ?Mailcode_Parser_Statement_Tokenizer_Token
73
    {
74
        return $this->breakAtToken;
75
    }
76
77
    /**
78
     * @return Mailcode_Variables_Variable|int|NULL
79
     */
80
    public function getBreakAt()
81
    {
82
        $token = $this->getBreakAtToken();
83
        if($token === null) {
84
            return null;
85
        }
86
87
        if($token instanceof Mailcode_Parser_Statement_Tokenizer_Token_Variable) {
88
            return $token->getVariable();
89
        }
90
91
        if($token instanceof Mailcode_Parser_Statement_Tokenizer_Token_Number) {
92
            return (int)$token->getValue();
93
        }
94
95
        if($token instanceof Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral) {
96
            return (int)$token->getText();
97
        }
98
99
        return null;
100
    }
101
102
    /**
103
     * @param Mailcode_Variables_Variable|number|NULL $breakAt
104
     * @return $this
105
     * @throws CommandException {@see BreakAtInterface::ERROR_INVALID_BREAK_AT_VALUE}
106
     * @throws ParamsException
107
     */
108
    public function setBreakAt($breakAt) : self
109
    {
110
        $info = $this->requireParams()->getInfo();
111
112
        if(isset($this->breakAtToken)) {
113
            $info->removeToken($this->breakAtToken);
114
        }
115
116
        $this->breakAtEnabled = false;
117
        $this->breakAtToken = null;
118
119
        if($breakAt === null) {
120
            return $this;
121
        }
122
123
        $token = null;
124
125
        if(is_numeric($breakAt))
126
        {
127
            $token = $info->addNumber((string)(int)$breakAt);
128
        }
129
        else if($breakAt instanceof Mailcode_Variables_Variable)
0 ignored issues
show
introduced by
$breakAt is always a sub-type of Mailcode\Mailcode_Variables_Variable.
Loading history...
130
        {
131
            $token = $info->addVariable($breakAt);
132
        }
133
134
        if($token !== null)
135
        {
136
            $info->setParamName($token, BreakAtInterface::PARAMETER_NAME);
137
138
            $this->breakAtEnabled = true;
139
            $this->breakAtToken = $token;
140
            return $this;
141
        }
142
143
        throw new CommandException(
144
            'Invalid break-at value',
145
            sprintf(
146
                'Expected a number or variable, got: %s',
147
                $breakAt instanceof Mailcode_Variables_Variable ? $breakAt->getFullName() : $breakAt
148
            ),
149
            BreakAtInterface::ERROR_INVALID_BREAK_AT_VALUE
150
        );
151
    }
152
}
153