Completed
Branch master (b65d76)
by David
04:29
created

PluginIf   F

Complexity

Total Complexity 67

Size/Duplication

Total Lines 233
Duplicated Lines 43.35 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
dl 101
loc 233
rs 3.0612
c 0
b 0
f 0
wmc 67
lcom 0
cbo 3

4 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 3 1
D replaceKeywords() 101 177 63
A preProcessing() 0 4 1
A postProcessing() 0 14 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like PluginIf often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PluginIf, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Copyright (c) 2013-2016
4
 *
5
 * @category  Library
6
 * @package   Dwoo\Plugins\Blocks
7
 * @author    Jordi Boggiano <[email protected]>
8
 * @author    David Sanchez <[email protected]>
9
 * @copyright 2008-2013 Jordi Boggiano
10
 * @copyright 2013-2016 David Sanchez
11
 * @license   http://dwoo.org/LICENSE Modified BSD License
12
 * @version   1.3.0
13
 * @date      2016-09-19
14
 * @link      http://dwoo.org/
15
 */
16
17
namespace Dwoo\Plugins\Blocks;
18
19
use Dwoo\Compiler;
20
use Dwoo\IElseable;
21
use Dwoo\Block\Plugin as BlockPlugin;
22
use Dwoo\ICompilable\Block as ICompilableBlock;
23
use Dwoo\Compilation\Exception as CompilationException;
24
25
/**
26
 * Conditional block, the syntax is very similar to the php one, allowing () || && and
27
 * other php operators. Additional operators and their equivalent php syntax are as follow :.
28
 * eq -> ==
29
 * neq or ne -> !=
30
 * gte or ge -> >=
31
 * lte or le -> <=
32
 * gt -> >
33
 * lt -> <
34
 * mod -> %
35
 * not -> !
36
 * X is [not] div by Y -> (X % Y) == 0
37
 * X is [not] even [by Y] -> (X % 2) == 0 or ((X/Y) % 2) == 0
38
 * X is [not] odd [by Y] -> (X % 2) != 0 or ((X/Y) % 2) != 0
39
 * This software is provided 'as-is', without any express or implied warranty.
40
 * In no event will the authors be held liable for any damages arising from the use of this software.
41
 */
42
class PluginIf extends BlockPlugin implements ICompilableBlock, IElseable
43
{
44
    /**
45
     * @param array $rest
46
     */
47
    public function init(array $rest)
0 ignored issues
show
Unused Code introduced by
The parameter $rest 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...
48
    {
49
    }
50
51
    /**
52
     * @param array    $params
53
     * @param array    $tokens
54
     * @param Compiler $compiler
55
     *
56
     * @return array
57
     * @throws CompilationException
58
     */
59
    public static function replaceKeywords(array $params, array $tokens, Compiler $compiler)
60
    {
61
        $p = array();
62
63
        reset($params);
64
        while (list($k, $v) = each($params)) {
65
            $v = (string)$v;
66
            if (substr($v, 0, 1) === '"' || substr($v, 0, 1) === '\'') {
67
                $vmod = strtolower(substr($v, 1, - 1));
68
            } else {
69
                $vmod = strtolower($v);
70
            }
71
            switch ($vmod) {
72
73 View Code Duplication
                case 'and':
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...
74
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
75
                        $p[] = '&&';
76
                    } else {
77
                        $p[] = $v;
78
                    }
79
                    break;
80 View Code Duplication
                case 'or':
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...
81
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
82
                        $p[] = '||';
83
                    } else {
84
                        $p[] = $v;
85
                    }
86
                    break;
87 View Code Duplication
                case 'xor':
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...
88
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
89
                        $p[] = '^';
90
                    } else {
91
                        $p[] = $v;
92
                    }
93
                    break;
94 View Code Duplication
                case 'eq':
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...
95
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
96
                        $p[] = '==';
97
                    } else {
98
                        $p[] = $v;
99
                    }
100
                    break;
101
                case 'ne':
102 View Code Duplication
                case 'neq':
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...
103
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
104
                        $p[] = '!=';
105
                    } else {
106
                        $p[] = $v;
107
                    }
108
                    break;
109
                case 'gte':
110 View Code Duplication
                case 'ge':
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...
111
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
112
                        $p[] = '>=';
113
                    } else {
114
                        $p[] = $v;
115
                    }
116
                    break;
117
                case 'lte':
118 View Code Duplication
                case 'le':
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...
119
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
120
                        $p[] = '<=';
121
                    } else {
122
                        $p[] = $v;
123
                    }
124
                    break;
125 View Code Duplication
                case 'gt':
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...
126
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
127
                        $p[] = '>';
128
                    } else {
129
                        $p[] = $v;
130
                    }
131
                    break;
132 View Code Duplication
                case 'lt':
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...
133
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
134
                        $p[] = '<';
135
                    } else {
136
                        $p[] = $v;
137
                    }
138
                    break;
139 View Code Duplication
                case 'mod':
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...
140
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
141
                        $p[] = '%';
142
                    } else {
143
                        $p[] = $v;
144
                    }
145
                    break;
146 View Code Duplication
                case 'not':
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...
147
                    if ($tokens[$k] === Compiler::T_UNQUOTED_STRING) {
148
                        $p[] = '!';
149
                    } else {
150
                        $p[] = $v;
151
                    }
152
                    break;
153
                case '<>':
154
                    $p[] = '!=';
155
                    break;
156
                case '==':
157
                case '!=':
158
                case '>=':
159
                case '<=':
160
                case '>':
161
                case '<':
162
                case '===':
163
                case '!==':
164
                case '%':
165
                case '!':
166
                case '^':
167
                    $p[] = $vmod;
168
                    break;
169
                case 'is':
170
                    if ($tokens[$k] !== Compiler::T_UNQUOTED_STRING) {
171
                        $p[] = $v;
172
                        break;
173
                    }
174
                    if (isset($params[$k + 1]) && strtolower(trim($params[$k + 1], '"\'')) === 'not' && $tokens[$k + 1] === Compiler::T_UNQUOTED_STRING) {
175
                        $negate = true;
176
                        next($params);
177
                    } else {
178
                        $negate = false;
179
                    }
180
                    $ptr = 1 + (int)$negate;
181
                    if ($tokens[$k + $ptr] !== Compiler::T_UNQUOTED_STRING) {
182
                        break;
183
                    }
184
                    if (!isset($params[$k + $ptr])) {
185
                        $params[$k + $ptr] = '';
186
                    } else {
187
                        $params[$k + $ptr] = trim($params[$k + $ptr], '"\'');
188
                    }
189
                    switch ($params[$k + $ptr]) {
190
191
                        case 'div':
192
                            if (isset($params[$k + $ptr + 1]) && strtolower(trim($params[$k + $ptr + 1], '"\'')) === 'by') {
193
                                $p[] = ' % ' . $params[$k + $ptr + 2] . ' ' . ($negate ? '!' : '=') . '== 0';
194
                                next($params);
195
                                next($params);
196
                                next($params);
197
                            } else {
198
                                throw new CompilationException($compiler, 'If : Syntax error : syntax should be "if $a is [not] div by $b", found ' . $params[$k - 1] . ' is ' . ($negate ? 'not ' : '') . 'div ' . $params[$k + $ptr + 1] . ' ' . $params[$k + $ptr + 2]);
199
                            }
200
                            break;
201 View Code Duplication
                        case 'even':
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...
202
                            $a = array_pop($p);
203
                            if (isset($params[$k + $ptr + 1]) && strtolower(trim($params[$k + $ptr + 1], '"\'')) === 'by') {
204
                                $b   = $params[$k + $ptr + 2];
205
                                $p[] = '(' . $a . ' / ' . $b . ') % 2 ' . ($negate ? '!' : '=') . '== 0';
206
                                next($params);
207
                                next($params);
208
                            } else {
209
                                $p[] = $a . ' % 2 ' . ($negate ? '!' : '=') . '== 0';
210
                            }
211
                            next($params);
212
                            break;
213 View Code Duplication
                        case 'odd':
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...
214
                            $a = array_pop($p);
215
                            if (isset($params[$k + $ptr + 1]) && strtolower(trim($params[$k + $ptr + 1], '"\'')) === 'by') {
216
                                $b   = $params[$k + $ptr + 2];
217
                                $p[] = '(' . $a . ' / ' . $b . ') % 2 ' . ($negate ? '=' : '!') . '== 0';
218
                                next($params);
219
                                next($params);
220
                            } else {
221
                                $p[] = $a . ' % 2 ' . ($negate ? '=' : '!') . '== 0';
222
                            }
223
                            next($params);
224
                            break;
225
                        default:
226
                            throw new CompilationException($compiler, 'If : Syntax error : syntax should be "if $a is [not] (div|even|odd) [by $b]", found ' . $params[$k - 1] . ' is ' . $params[$k + $ptr + 1]);
227
                    }
228
                    break;
229
                default:
230
                    $p[] = $v;
231
            }
232
        }
233
234
        return $p;
235
    }
236
237
    /**
238
     * @param Compiler $compiler
239
     * @param array    $params
240
     * @param string   $prepend
241
     * @param string   $append
242
     * @param string   $type
243
     *
244
     * @return string
245
     */
246
    public static function preProcessing(Compiler $compiler, array $params, $prepend, $append, $type)
247
    {
248
        return '';
249
    }
250
251
    /**
252
     * @param Compiler $compiler
253
     * @param array    $params
254
     * @param string   $prepend
255
     * @param string   $append
256
     * @param string   $content
257
     *
258
     * @return string
259
     */
260
    public static function postProcessing(Compiler $compiler, array $params, $prepend, $append, $content)
261
    {
262
        $tokens = $compiler->getParamTokens($params);
263
        $params = $compiler->getCompiledParams($params);
264
        $pre    = Compiler::PHP_OPEN . 'if (' . implode(' ', self::replaceKeywords($params['*'], $tokens['*'], $compiler)) . ") {\n" . Compiler::PHP_CLOSE;
265
266
        $post = Compiler::PHP_OPEN . "\n}" . Compiler::PHP_CLOSE;
267
268
        if (isset($params['hasElse'])) {
269
            $post .= $params['hasElse'];
270
        }
271
272
        return $pre . $content . $post;
273
    }
274
}
275