Completed
Branch conditions-refactoring (e50fd3)
by Romain
02:01
created

BooleanNode   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 1
dl 0
loc 201
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getCssResult() 0 4 1
A getJavaScriptResult() 0 4 1
A getPhpResult() 0 4 1
A getLogicalResult() 0 15 3
A processLogicalAndCss() 0 14 3
A processLogicalOrCss() 0 7 1
A processLogicalAndJavaScript() 0 14 3
A processLogicalOrJavaScript() 0 7 1
A processLogicalAndPhp() 0 4 2
A processLogicalOrPhp() 0 4 2
1
<?php
2
/*
3
 * 2016 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 Formz project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\Formz\Condition\Parser\Node;
15
16
use Romm\Formz\Condition\Parser\ConditionParser;
17
18
/**
19
 * A boolean node, which contains two sides and an operator.
20
 */
21
class BooleanNode extends AbstractNode
22
{
23
24
    /**
25
     * @var string
26
     */
27
    protected $operator;
28
29
    /**
30
     * @var AbstractNode
31
     */
32
    protected $leftSide;
33
34
    /**
35
     * @var AbstractNode
36
     */
37
    protected $rightSide;
38
39
    /**
40
     * Constructor.
41
     *
42
     * @param AbstractNode $leftSide  Left side of the boolean expression.
43
     * @param AbstractNode $rightSide Right side of the boolean expression.
44
     * @param string       $operator  One of the `ConditionParser::LOGICAL_*` constants.
45
     */
46
    public function __construct(AbstractNode $leftSide, AbstractNode $rightSide, $operator)
47
    {
48
        $this->leftSide = $leftSide;
49
        $this->rightSide = $rightSide;
50
        $this->operator = $operator;
51
    }
52
53
    /**
54
     * @inheritdoc
55
     */
56
    public function getCssResult()
57
    {
58
        return $this->getLogicalResult('processLogicalAndCss', 'processLogicalOrCss');
59
    }
60
61
    /**
62
     * @inheritdoc
63
     */
64
    public function getJavaScriptResult()
65
    {
66
        return $this->getLogicalResult('processLogicalAndJavaScript', 'processLogicalOrJavaScript');
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public function getPhpResult()
73
    {
74
        return $this->getLogicalResult('processLogicalAndPhp', 'processLogicalOrPhp');
75
    }
76
77
    /**
78
     * Global function to get the result of a logical operation, the processor
79
     * does not matter.
80
     *
81
     * @param string $logicalAndFunction Name of the internal function called for a logical "and" operation.
82
     * @param string $logicalOrFunction  Name of the internal function called for a logical "or" operation.
83
     * @return null
84
     * @throws \Exception
85
     */
86
    protected function getLogicalResult($logicalAndFunction, $logicalOrFunction)
87
    {
88
        switch ($this->operator) {
89
            case ConditionParser::LOGICAL_AND:
90
                $result = $this->$logicalAndFunction($this->leftSide, $this->rightSide);
91
                break;
92
            case ConditionParser::LOGICAL_OR:
93
                $result = $this->$logicalOrFunction($this->leftSide, $this->rightSide);
94
                break;
95
            default:
96
                throw new \Exception('The boolean node has a wrong operator: "' . $this->operator . '".', 1458150438);
97
        }
98
99
        return $result;
100
    }
101
102
    /**
103
     * Will process a logical "and" operation on the two given nodes. The result
104
     * will be an array containing all the result of the "and" operation on
105
     * every existing results of the two nodes.
106
     *
107
     * With CSS, it means to concatenate two condition strings. Example:
108
     *
109
     * Left   = [foo="bar"]
110
     * Right  = [pet="dog"]
111
     * Result = [foo="bar"][pet="dog"]
112
     *
113
     * @param AbstractNode $left  Left node instance.
114
     * @param AbstractNode $right Right node instance.
115
     * @return array
116
     */
117
    protected function processLogicalAndCss(AbstractNode $left, AbstractNode $right)
118
    {
119
        $leftResults = $this->toArray($left->getCssResult());
120
        $rightResults = $this->toArray($right->getCssResult());
121
122
        $result = [];
123
        foreach ($leftResults as $leftResult) {
124
            foreach ($rightResults as $rightResult) {
125
                $result[] = $leftResult . $rightResult;
126
            }
127
        }
128
129
        return $result;
130
    }
131
132
    /**
133
     * Will process a logical "or" operation on the two given nodes. The result
134
     * will be an array containing all the result of the "or" operation on
135
     * every existing results of the two nodes.
136
     *
137
     * @param AbstractNode $left  Left node instance.
138
     * @param AbstractNode $right Right node instance.
139
     * @return array
140
     */
141
    protected function processLogicalOrCss(AbstractNode $left, AbstractNode $right)
142
    {
143
        return array_merge(
144
            $this->toArray($left->getCssResult()),
145
            $this->toArray($right->getCssResult())
146
        );
147
    }
148
149
    /**
150
     * Will process a logical "and" operation on the two given nodes. The result
151
     * will be an array containing all the result of the "and" operation on
152
     * every existing results of the two nodes.
153
     *
154
     * With JavaScript, it means adding the operator `&&` between the two
155
     * expressions.
156
     *
157
     * @param AbstractNode $left  Left node instance.
158
     * @param AbstractNode $right Right node instance.
159
     * @return array
160
     */
161
    protected function processLogicalAndJavaScript(AbstractNode $left, AbstractNode $right)
162
    {
163
        $leftResults = $this->toArray($left->getJavaScriptResult());
164
        $rightResults = $this->toArray($right->getJavaScriptResult());
165
166
        $result = [];
167
        foreach ($leftResults as $leftResult) {
168
            foreach ($rightResults as $rightResult) {
169
                $result[] = $leftResult . ' && ' . $rightResult;
170
            }
171
        }
172
173
        return $result;
174
    }
175
176
    /**
177
     * Will process a logical "or" operation on the two given nodes. The result
178
     * will be an array containing all the result of the "or" operation on
179
     * every existing results of the two nodes.
180
     *
181
     * @param AbstractNode $left  Left node instance.
182
     * @param AbstractNode $right Right node instance.
183
     * @return array
184
     */
185
    protected function processLogicalOrJavaScript(AbstractNode $left, AbstractNode $right)
186
    {
187
        return array_merge(
188
            $this->toArray($left->getJavaScriptResult()),
189
            $this->toArray($right->getJavaScriptResult())
190
        );
191
    }
192
193
    /**
194
     * Will process a logical "and" operation on the two given nodes. The result
195
     * will be an array containing all the result of the "and" operation on
196
     * every existing results of the two nodes.
197
     *
198
     * With JavaScript, it means that the left and the right nodes are both
199
     * true.
200
     *
201
     * @param AbstractNode $left  Left node instance.
202
     * @param AbstractNode $right Right node instance.
203
     * @return bool
204
     */
205
    protected function processLogicalAndPhp(AbstractNode $left, AbstractNode $right)
206
    {
207
        return ($left->getPhpResult() && $right->getPhpResult());
208
    }
209
210
    /**
211
     * Will process a logical "or" operation on the two given nodes.
212
     *
213
     * @param AbstractNode $left  Left node instance.
214
     * @param AbstractNode $right Right node instance.
215
     * @return bool
216
     */
217
    protected function processLogicalOrPhp(AbstractNode $left, AbstractNode $right)
218
    {
219
        return ($left->getPhpResult() || $right->getPhpResult());
220
    }
221
}
222