Passed
Push — develop ( 067c9c...bf1d25 )
by nguereza
04:45
created

AbstractCondition::evaluateCondition()   D

Complexity

Conditions 22
Paths 37

Size

Total Lines 63
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 22
eloc 40
nc 37
nop 4
dl 0
loc 63
rs 4.1666
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Platine Template
5
 *
6
 * Platine Template is a template engine that has taken a lot of inspiration from Django.
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine Template
11
 * Copyright (c) 2014 Guz Alexander, http://guzalexander.com
12
 * Copyright (c) 2011, 2012 Harald Hanek, http://www.delacap.com
13
 * Copyright (c) 2006 Mateo Murphy
14
 *
15
 * Permission is hereby granted, free of charge, to any person obtaining a copy
16
 * of this software and associated documentation files (the "Software"), to deal
17
 * in the Software without restriction, including without limitation the rights
18
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
 * copies of the Software, and to permit persons to whom the Software is
20
 * furnished to do so, subject to the following conditions:
21
 *
22
 * The above copyright notice and this permission notice shall be included in all
23
 * copies or substantial portions of the Software.
24
 *
25
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
 * SOFTWARE.
32
 */
33
34
/**
35
 *  @file AbstractCondition.php
36
 *
37
 *  The Base Template Condition class
38
 *
39
 *  @package    Platine\Template\Parser
40
 *  @author Platine Developers Team
41
 *  @copyright  Copyright (c) 2020
42
 *  @license    http://opensource.org/licenses/MIT  MIT License
43
 *  @link   http://www.iacademy.cf
44
 *  @version 1.0.0
45
 *  @filesource
46
 */
47
48
declare(strict_types=1);
49
50
namespace Platine\Template\Parser;
51
52
use Generator;
53
use Platine\Template\Exception\RenderException;
54
55
/**
56
 * Class AbstractCondition
57
 * @package Platine\Template\Parser
58
 */
59
abstract class AbstractCondition extends AbstractBlock
60
{
61
62
    /**
63
     * The current left variable to compare
64
     * @var mixed
65
     */
66
    protected $left = null;
67
68
    /**
69
     * The current right variable to compare
70
     * @var mixed
71
     */
72
    protected $right = null;
73
74
    /**
75
     * Returns a string value of an array or object for comparisons
76
     * @param mixed|null $value
77
     * @return string|mixed|null
78
     */
79
    protected function stringValue($value)
80
    {
81
        if (is_object($value)) {
82
            if (method_exists($value, '__toString')) {
83
                return (string) $value;
84
            }
85
86
            if ($value instanceof Generator) {
87
                return (string) $value->valid();
88
            }
89
90
            $class = get_class($value);
91
            throw new RenderException(sprintf(
92
                'The value of type [%s] has no "toObject" nor "__toString" methods',
93
                $class
94
            ));
95
        }
96
97
        if (is_array($value)) {
98
            return $value;
99
        }
100
101
        return $value;
102
    }
103
104
    /**
105
     * Check to see if to variables are equal in a given context
106
     * @param string|null $left
107
     * @param string|null $right
108
     * @param Context $context
109
     * @return bool
110
     */
111
    protected function variableIsEqual(?string $left, ?string $right, Context $context): bool
112
    {
113
        $leftValue = $left;
114
        $rightValue = $right;
115
        if (is_string($left) && $context->hasKey($left)) {
116
            $leftValue = $context->get($left);
117
        }
118
119
        if (is_string($right) && $context->hasKey($right)) {
120
            $rightValue = $context->get($right);
121
        }
122
123
        $leftStr = $this->stringValue($leftValue);
124
        $rightStr = $this->stringValue($rightValue);
125
126
        return $leftStr == $rightStr;
127
    }
128
129
    /**
130
     * Evaluate a comparison
131
     * @param mixed $left
132
     * @param mixed $right
133
     * @param string|null $operator
134
     * @param Context $context
135
     * @return bool
136
     */
137
    protected function evaluateCondition(
138
        $left,
139
        $right,
140
        ?string $operator,
141
        Context $context
142
    ): bool {
143
        if ($operator === null) {
144
            $value = $this->stringValue($context->get($left));
145
146
            return (bool) $value;
147
        }
148
149
        // values of 'empty' have a special meaning in array comparisons
150
        if ($right == 'empty' && is_array($context->get($left))) {
151
            $left = $context->get($left);
152
            $right = 0;
153
        } elseif ($left == 'empty' && is_array($context->get($right))) {
154
            $right = $context->get($right);
155
            $left = 0;
156
        } else {
157
            $leftValue = $context->get($left);
158
            $rightValue = $context->get($right);
159
160
            $left = $this->stringValue($leftValue);
161
            $right = $this->stringValue($rightValue);
162
        }
163
164
        // special rules for null values
165
        if (is_null($left) || is_null($right)) {
166
            //null == null => true
167
            if ($operator === '==' && is_null($left) && is_null($right)) {
168
                return true;
169
            }
170
171
            //null != anything other than null => true
172
            if ($operator === '!=' && (is_null($left) || is_null($right))) {
173
                return true;
174
            }
175
176
            return false;
177
        }
178
179
        //regular rules
180
        switch ($operator) {
181
            case '==':
182
                return ($left == $right);
183
            case '!=':
184
                return ($left != $right);
185
            case '>':
186
                return ($left > $right);
187
            case '<':
188
                return ($left < $right);
189
            case '>=':
190
                return ($left >= $right);
191
            case '<=':
192
                return ($left <= $right);
193
            case 'contains':
194
                return (is_array($left) ? in_array($right, $left) : (strpos($left, $right) !== false));
195
            default:
196
                throw new RenderException(sprintf(
197
                    'Error in tag [%s] - Unknown operator [%s]',
198
                    $this->getTagName(),
199
                    $operator
200
                ));
201
        }
202
    }
203
}
204