Completed
Push — develop ( cb7ecf...5e631f )
by Dmytro
17s
created

Modifiers::getValueFromPreset()   F

Complexity

Conditions 394
Paths 891

Size

Total Lines 943
Code Lines 771

Duplication

Lines 33
Ratio 3.5 %

Importance

Changes 0
Metric Value
cc 394
eloc 771
nc 891
nop 4
dl 33
loc 943
rs 2
c 0
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 namespace EvolutionCMS\Legacy;
2
3
use EvolutionCMS\Interfaces\ModifiersInterface;
4
use EvolutionCMS\Support\DataGrid;
5
6
class Modifiers implements ModifiersInterface
7
{
8
    /**
9
     * @var array
10
     */
11
    public $placeholders = array();
12
    /**
13
     * @var array
14
     */
15
    public $vars = array();
16
    /**
17
     * @var array
18
     */
19
    public $tmpCache = array();
20
    /**
21
     * @var
22
     */
23
    public $bt;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $bt. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
24
    /**
25
     * @var
26
     */
27
    public $srcValue;
28
    /**
29
     * @var array
30
     */
31
    public $condition = array();
32
    /**
33
     * @var string
34
     */
35
    public $condModifiers;
36
37
    /**
38
     * @var
39
     */
40
    public $key;
41
    /**
42
     * @var
43
     */
44
    public $value;
45
    /**
46
     * @var
47
     */
48
    public $opt;
49
    /**
50
     * @var
51
     */
52
    public $elmName;
53
54
    /**
55
     * @var array
56
     */
57
    public $documentObject = array();
58
59
    /**
60
     * MODIFIERS constructor.
61
     */
62
    public function __construct()
63
    {
64
        $modx = evolutionCMS();
65
        if (function_exists('mb_internal_encoding')) {
66
            mb_internal_encoding($modx->config['modx_charset']);
67
        }
68
        $this->condModifiers = '=,is,eq,equals,ne,neq,notequals,isnot,isnt,not,%,isempty,isnotempty,isntempty,>=,gte,eg,gte,greaterthan,>,gt,isgreaterthan,isgt,lowerthan,<,lt,<=,lte,islte,islowerthan,islt,el,find,in,inarray,in_array,fnmatch,wcard,wcard_match,wildcard,wildcard_match,is_file,is_dir,file_exists,is_readable,is_writable,is_image,regex,preg,preg_match,memberof,mo,isinrole,ir';
69
    }
70
71
    /**
72
     * @param string $key
73
     * @param string $value
74
     * @param string $modifiers
75
     * @return bool|mixed|string
76
     */
77
    public function phxFilter($key, $value, $modifiers)
78
    {
79
        $modx = evolutionCMS();
0 ignored issues
show
Unused Code introduced by
$modx is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
80
        if (substr($modifiers, 0, 3) !== 'id(') {
81
            $value = $this->parseDocumentSource($value);
82
        }
83
        $this->srcValue = $value;
84
        $modifiers = trim($modifiers);
85
        $modifiers = ':' . trim($modifiers, ':');
86
        $modifiers = str_replace(array("\r\n", "\r"), "\n", $modifiers);
87
        $modifiers = $this->splitEachModifiers($modifiers);
88
89
        $this->placeholders = array();
90
        $this->placeholders['phx'] = '';
91
        $this->placeholders['dummy'] = '';
92
        $this->condition = array();
93
        $this->vars = array();
94
        $this->vars['name'] = &$key;
95
        $value = $this->parsePhx($key, $value, $modifiers);
96
        $this->vars = array();
97
98
        return $value;
99
    }
100
101
    /**
102
     * @param string $mode
103
     * @param string $modifiers
104
     * @return bool|string
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|string.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
105
     */
106
    public function _getDelim($mode, $modifiers)
107
    {
108
        $c = substr($modifiers, 0, 1);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $c. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
109
        if (!in_array($c, array('"', "'", '`'))) {
110
            return false;
111
        }
112
113
        $modifiers = substr($modifiers, 1);
114
        $closure = $mode == '(' ? "{$c})" : $c;
115
        if (strpos($modifiers, $closure) === false) {
116
            return false;
117
        }
118
119
        return $c;
120
    }
121
122
    /**
123
     * @param string $mode
124
     * @param string $delim
125
     * @param string $modifiers
126
     * @return bool|string
127
     */
128
    public function _getOpt($mode, $delim, $modifiers)
129
    {
130
        if ($delim) {
131
            if ($mode == '(') {
132
                return substr($modifiers, 1, strpos($modifiers, $delim . ')') - 1);
133
            }
134
135
            return substr($modifiers, 1, strpos($modifiers, $delim, 1) - 1);
136
        } else {
137
            if ($mode == '(') {
138
                return substr($modifiers, 0, strpos($modifiers, ')'));
139
            }
140
141
            $chars = str_split($modifiers);
142
            $opt = '';
143
            foreach ($chars as $c) {
144
                if ($c == ':' || $c == ')') {
145
                    break;
146
                }
147
                $opt .= $c;
148
            }
149
150
            return $opt;
151
        }
152
    }
153
154
    public function _getRemainModifiers($mode, $delim, $modifiers)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
155
    {
156
        if ($delim) {
157
            if ($mode == '(') {
158
                return $this->_fetchContent($modifiers, $delim . ')');
159
            } else {
160
                $modifiers = trim($modifiers);
161
                $modifiers = substr($modifiers, 1);
162
163
                return $this->_fetchContent($modifiers, $delim);
164
            }
165
        } else {
166
            if ($mode == '(') {
167
                return $this->_fetchContent($modifiers, ')');
168
            }
169
            $chars = str_split($modifiers);
170
            foreach ($chars as $c) {
171
                if ($c == ':') {
172
                    return $modifiers;
173
                } else {
174
                    $modifiers = substr($modifiers, 1);
175
                }
176
            }
177
178
            return $modifiers;
179
        }
180
    }
181
182
    public function _fetchContent($string, $delim)
183
    {
184
        $len = strlen($delim);
185
        $string = $this->parseDocumentSource($string);
186
187
        return substr($string, strpos($string, $delim) + $len);
188
    }
189
190
    public function splitEachModifiers($modifiers)
191
    {
192
        $modx = evolutionCMS();
193
194
        $cmd = '';
195
        $bt = '';
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $bt. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
196
        $result = array();
197
        while ($bt !== $modifiers) {
198
            $bt = $modifiers;
199
            $c = substr($modifiers, 0, 1);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $c. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
200
            $modifiers = substr($modifiers, 1);
201
202
            if ($c === ':' && preg_match('@^(!?[<>=]{1,2})@', $modifiers, $match)) { // :=, :!=, :<=, :>=, :!<=, :!>=
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
203
                $c = substr($modifiers, strlen($match[1]), 1);
204
                $debuginfo = "#i=0 #c=[{$c}] #m=[{$modifiers}]";
205
                if ($c === '(') {
206
                    $modifiers = substr($modifiers, strlen($match[1]) + 1);
207
                } else {
208
                    $modifiers = substr($modifiers, strlen($match[1]));
209
                }
210
211
                $delim = $this->_getDelim($c, $modifiers);
212
                $opt = $this->_getOpt($c, $delim, $modifiers);
0 ignored issues
show
Security Bug introduced by
It seems like $delim defined by $this->_getDelim($c, $modifiers) on line 211 can also be of type false; however, EvolutionCMS\Legacy\Modifiers::_getOpt() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
213
                $modifiers = trim($this->_getRemainModifiers($c, $delim, $modifiers));
214
215
                $result[] = array('cmd' => trim($match[1]), 'opt' => $opt, 'debuginfo' => $debuginfo);
216
                $cmd = '';
217
            } elseif (in_array($c, array('+', '-', '*', '/')) && preg_match('@^[0-9]+@', $modifiers,
218
                    $match)) { // :+3, :-3, :*3 ...
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
219
                $modifiers = substr($modifiers, strlen($match[0]));
220
                $result[] = array('cmd' => 'math', 'opt' => '%s' . $c . $match[0]);
221
                $cmd = '';
222
            } elseif ($c === '(' || $c === '=') {
223
                $modifiers = $m1 = trim($modifiers);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $m1. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
224
                $delim = $this->_getDelim($c, $modifiers);
225
                $opt = $this->_getOpt($c, $delim, $modifiers);
0 ignored issues
show
Security Bug introduced by
It seems like $delim defined by $this->_getDelim($c, $modifiers) on line 224 can also be of type false; however, EvolutionCMS\Legacy\Modifiers::_getOpt() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
226
                $modifiers = trim($this->_getRemainModifiers($c, $delim, $modifiers));
227
                $debuginfo = "#i=1 #c=[{$c}] #delim=[{$delim}] #m1=[{$m1}] remainMdf=[{$modifiers}]";
228
229
                $result[] = array('cmd' => trim($cmd), 'opt' => $opt, 'debuginfo' => $debuginfo);
230
231
                $cmd = '';
232
            } elseif ($c == ':') {
233
                $debuginfo = "#i=2 #c=[{$c}] #m=[{$modifiers}]";
234
                if ($cmd !== '') {
235
                    $result[] = array('cmd' => trim($cmd), 'opt' => '', 'debuginfo' => $debuginfo);
236
                }
237
238
                $cmd = '';
239
            } elseif (trim($modifiers) == '' && trim($cmd) !== '') {
240
                $debuginfo = "#i=3 #c=[{$c}] #m=[{$modifiers}]";
241
                $cmd .= $c;
242
                $result[] = array('cmd' => trim($cmd), 'opt' => '', 'debuginfo' => $debuginfo);
243
244
                break;
245
            } else {
246
                $cmd .= $c;
247
            }
248
        }
249
250
        if (empty($result)) {
251
            return array();
252
        }
253
254
        foreach ($result as $i => $a) {
255
            $a['opt'] = $this->parseDocumentSource($a['opt']);
256
            $result[$i]['opt'] = $modx->mergePlaceholderContent($a['opt'], $this->placeholders);
257
        }
258
259
        return $result;
260
    }
261
262
    public function parsePhx($key, $value, $modifiers)
263
    {
264
        $modx = evolutionCMS();
0 ignored issues
show
Unused Code introduced by
$modx is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
265
        $lastKey = '';
266
        $cacheKey = md5(sprintf('parsePhx#%s#%s#%s', $key, $value, print_r($modifiers, true)));
267
        if (isset($this->tmpCache[$cacheKey])) {
268
            return $this->tmpCache[$cacheKey];
269
        }
270
        if (empty($modifiers)) {
271
            return '';
272
        }
273
274
        foreach ($modifiers as $m) {
275
            $lastKey = strtolower($m['cmd']);
276
        }
277
        $_ = explode(',', $this->condModifiers);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $_. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
278
        if (in_array($lastKey, $_)) {
279
            $modifiers[] = array('cmd' => 'then', 'opt' => '1');
280
            $modifiers[] = array('cmd' => 'else', 'opt' => '0');
281
        }
282
283
        foreach ($modifiers as $i => $a) {
284
            $value = $this->Filter($key, $value, $a['cmd'], $a['opt']);
285
        }
286
        $this->tmpCache[$cacheKey] = $value;
287
288
        return $value;
289
    }
290
291
    // Parser: modifier detection and eXtended processing if needed
292
    public function Filter($key, $value, $cmd, $opt = '')
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
293
    {
294
        $modx = evolutionCMS();
295
296
        if ($key === 'documentObject') {
297
            $value = $modx->documentIdentifier;
298
        }
299
        $cmd = $this->parseDocumentSource($cmd);
300 View Code Duplication
        if (preg_match('@^[1-9][/0-9]*$@', $cmd)) {
301
            if (strpos($cmd, '/') !== false) {
302
                $cmd = $this->substr($cmd, strrpos($cmd, '/') + 1);
303
            }
304
            $opt = $cmd;
305
            $cmd = 'id';
306
        }
307
308
        if (isset($modx->snippetCache["phx:{$cmd}"])) {
309
            $this->elmName = "phx:{$cmd}";
310
        } elseif (isset($modx->chunkCache["phx:{$cmd}"])) {
311
            $this->elmName = "phx:{$cmd}";
312
        } else {
313
            $this->elmName = '';
314
        }
315
316
        $cmd = strtolower($cmd);
317
        if ($this->elmName !== '') {
318
            $value = $this->getValueFromElement($key, $value, $cmd, $opt);
319
        } else {
320
            $value = $this->getValueFromPreset($key, $value, $cmd, $opt);
321
        }
322
323
        $value = str_replace('[+key+]', $key, $value);
324
325
        return $value;
326
    }
327
328
    public function isEmpty($cmd, $value)
329
    {
330
        if ($value !== '') {
331
            return false;
332
        }
333
334
        $_ = explode(',',
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $_. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
335
            $this->condModifiers . ',_default,default,if,input,or,and,show,this,select,switch,then,else,id,ifempty,smart_desc,smart_description,summary');
336
        if (in_array($cmd, $_)) {
0 ignored issues
show
Coding Style introduced by
The if-else statement can be simplified to return !in_array($cmd, $_);.
Loading history...
337
            return false;
338
        } else {
339
            return true;
340
        }
341
    }
342
343
    public function getValueFromPreset($key, $value, $cmd, $opt)
344
    {
345
        $modx = evolutionCMS();
346
347
        if ($this->isEmpty($cmd, $value)) {
348
            return '';
349
        }
350
351
        $this->key = $key;
352
        $this->value = $value;
353
        $this->opt = $opt;
354
355
        switch ($cmd) {
356
            #####  Conditional Modifiers
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
357
            case 'input':
358
            case 'if':
359
                if (!$opt) {
360
                    return $value;
361
                }
362
363
                return $opt;
364
            case '=':
365
            case 'eq':
366
            case 'is':
367
            case 'equals':
368
                $this->condition[] = (int)($value == $opt);
369
                break;
370
            case 'neq':
371
            case 'ne':
372
            case 'notequals':
373
            case 'isnot':
374
            case 'isnt':
375
            case 'not':
376
                $this->condition[] = (int)($value != $opt);
377
                break;
378
            case '%':
379
                $this->condition[] = (int)($value % $opt == 0);
380
                break;
381
            case 'isempty':
382
                $this->condition[] = (int)(empty($value));
383
                break;
384
            case 'isntempty':
385
            case 'isnotempty':
386
                $this->condition[] = (int)(!empty($value));
387
                break;
388
            case '>=':
389
            case 'gte':
390
            case 'eg':
391
            case 'isgte':
392
                $this->condition[] = (int)($value >= $opt);
393
                break;
394
            case '<=':
395
            case 'lte':
396
            case 'el':
397
            case 'islte':
398
                $this->condition[] = (int)($value <= $opt);
399
                break;
400
            case '>':
401
            case 'gt':
402
            case 'greaterthan':
403
            case 'isgreaterthan':
404
            case 'isgt':
405
                $this->condition[] = (int)($value > $opt);
406
                break;
407
            case '<':
408
            case 'lt':
409
            case 'lowerthan':
410
            case 'islowerthan':
411
            case 'islt':
412
                $this->condition[] = (int)($value < $opt);
413
                break;
414
            case 'find':
415
                $this->condition[] = (int)(strpos($value, $opt) !== false);
416
                break;
417
            case 'inarray':
418
            case 'in_array':
419
            case 'in':
420
                $opt = explode(',', $opt);
421
                $this->condition[] = (int)(in_array($value, $opt) !== false);
422
                break;
423
            case 'wildcard_match':
424
            case 'wcard_match':
425
            case 'wildcard':
426
            case 'wcard':
427
            case 'fnmatch':
428
                $this->condition[] = (int)(fnmatch($opt, $value) !== false);
429
                break;
430
            case 'is_file':
431
            case 'is_dir':
432
            case 'file_exists':
433
            case 'is_readable':
434
            case 'is_writable':
435
                if (!$opt) {
436
                    $path = $value;
437
                } else {
438
                    $path = $opt;
439
                }
440
                if (strpos($path, MODX_MANAGER_PATH) !== false) {
441
                    exit('Can not read core path');
0 ignored issues
show
Coding Style Compatibility introduced by
The method getValueFromPreset() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
442
                }
443
                if (strpos($path, $modx->config['base_path']) === false) {
444
                    $path = ltrim($path, '/');
445
                }
446
                $this->condition[] = (int)($cmd($path) !== false);
447
                break;
448
            case 'is_image':
449
                if (!$opt) {
450
                    $path = $value;
451
                } else {
452
                    $path = $opt;
453
                }
454
                if (!is_file($path)) {
455
                    $this->condition[] = '0';
456
                    break;
457
                }
458
                $_ = getimagesize($path);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $_. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
459
                $this->condition[] = (int)($_[0]);
460
                break;
461
            case 'regex':
462
            case 'preg':
463
            case 'preg_match':
464
            case 'isinrole':
465
                $this->condition[] = (int)(preg_match($opt, $value));
466
                break;
467
            case 'ir':
468
            case 'memberof':
469
            case 'mo':
470
                // Is Member Of  (same as inrole but this one can be stringed as a conditional)
471
                $this->condition[] = $this->includeMdfFile('memberof');
472
                break;
473
            case 'or':
474
                $this->condition[] = '||';
475
                break;
476
            case 'and':
477
                $this->condition[] = '&&';
478
                break;
479
            case 'show':
480 View Code Duplication
            case 'this':
481
                $conditional = implode(' ', $this->condition);
482
                $isvalid = (int)(eval("return ({$conditional});"));
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
483
                if ($isvalid) {
484
                    return $this->srcValue;
485
                }
486
487
                return null;
488 View Code Duplication
            case 'then':
489
                $conditional = implode(' ', $this->condition);
490
                $isvalid = (int)eval("return ({$conditional});");
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
491
                if ($isvalid) {
492
                    return $opt;
493
                }
494
495
                return null;
496 View Code Duplication
            case 'else':
497
                $conditional = implode(' ', $this->condition);
498
                $isvalid = (int)eval("return ({$conditional});");
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
499
                if (!$isvalid) {
500
                    return $opt;
501
                }
502
                break;
503
            case 'select':
504
            case 'switch':
505
                $raw = explode('&', $opt);
506
                $map = array();
507
                $c = count($raw);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $c. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
508
                for ($m = 0; $m < $c; $m++) {
509
                    $mi = explode('=', $raw[$m], 2);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $mi. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
510
                    $map[$mi[0]] = $mi[1];
511
                }
512
                if (isset($map[$value])) {
513
                    return $map[$value];
514
                } else {
515
                    return '';
516
                }
517
            ##### End of Conditional Modifiers
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
518
519
            #####  Encode / Decode / Hash / Escape
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
520
            case 'htmlent':
521
            case 'htmlentities':
522
                return htmlentities($value, ENT_QUOTES, $modx->config['modx_charset']);
523
            case 'html_entity_decode':
524
            case 'decode_html':
525
            case 'html_decode':
526
                return html_entity_decode($value, ENT_QUOTES, $modx->config['modx_charset']);
527
            case 'esc':
528
            case 'escape':
529
                $value = preg_replace('/&amp;(#[0-9]+|[a-z]+);/i', '&$1;',
530
                    htmlspecialchars($value, ENT_QUOTES, $modx->config['modx_charset']));
531
532
                return str_replace(array('[', ']', '`'), array('&#91;', '&#93;', '&#96;'), $value);
533
            case 'sql_escape':
534
            case 'encode_js':
535
                return $modx->getDatabase()->escape($value);
536
            case 'htmlspecialchars':
537
            case 'hsc':
538
            case 'encode_html':
539
            case 'html_encode':
540
                return preg_replace('/&amp;(#[0-9]+|[a-z]+);/i', '&$1;',
541
                    htmlspecialchars($value, ENT_QUOTES, $modx->config['modx_charset']));
542
            case 'spam_protect':
543
                return str_replace(array('@', '.'), array('&#64;', '&#46;'), $value);
544
            case 'strip':
545
                if ($opt === '') {
546
                    $opt = ' ';
547
                }
548
549
                return preg_replace('/[\n\r\t\s]+/', $opt, $value);
550
            case 'strip_linefeeds':
551
                return str_replace(array("\n", "\r"), '', $value);
552
            case 'notags':
553
            case 'strip_tags':
554
            case 'remove_html':
555
                if ($opt !== '') {
556
                    $param = array();
557
                    foreach (explode(',', $opt) as $v) {
558
                        $v = trim($v, '</> ');
559
                        $param[] = "<{$v}>";
560
                    }
561
                    $params = implode(',', $param);
562
                } else {
563
                    $params = '';
564
                }
565 View Code Duplication
                if (!strpos($params, '<br>') === false) {
566
                    $value = preg_replace('@(<br[ /]*>)\n@', '$1', $value);
567
                    $value = preg_replace('@<br[ /]*>@', "\n", $value);
568
                }
569
570
                return $this->strip_tags($value, $params);
571
            case 'urlencode':
572
            case 'url_encode':
573
            case 'encode_url':
574
                return urlencode($value);
575
            case 'base64_decode':
576
                if ($opt !== 'false') {
577
                    $opt = true;
578
                } else {
579
                    $opt = false;
580
                }
581
582
                return base64_decode($value, $opt);
583
            case 'encode_sha1':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
584
                $cmd = 'sha1';
585
            case 'addslashes':
586
            case 'urldecode':
587
            case 'url_decode':
588
            case 'rawurlencode':
589
            case 'rawurldecode':
590
            case 'base64_encode':
591
            case 'md5':
592
            case 'sha1':
593
            case 'json_encode':
594
            case 'json_decode':
595
                return $cmd($value);
596
597
            #####  String Modifiers
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
598
            case 'lcase':
599
            case 'strtolower':
600
            case 'lower_case':
601
                return $this->strtolower($value);
602
            case 'ucase':
603
            case 'strtoupper':
604
            case 'upper_case':
605
                return $this->strtoupper($value);
606
            case 'capitalize':
607
                $_ = explode(' ', $value);
608
                foreach ($_ as $i => $v) {
609
                    $_[$i] = ucfirst($v);
610
                }
611
612
                return implode(' ', $_);
613 View Code Duplication
            case 'zenhan':
614
                if (empty($opt)) {
615
                    $opt = 'VKas';
616
                }
617
618
                return mb_convert_kana($value, $opt, $modx->config['modx_charset']);
619 View Code Duplication
            case 'hanzen':
620
                if (empty($opt)) {
621
                    $opt = 'VKAS';
622
                }
623
624
                return mb_convert_kana($value, $opt, $modx->config['modx_charset']);
625
            case 'str_shuffle':
626
            case 'shuffle':
627
                return $this->str_shuffle($value);
628
            case 'reverse':
629
            case 'strrev':
630
                return $this->strrev($value);
631
            case 'length':
632
            case 'len':
633
            case 'strlen':
634
            case 'count_characters':
635
                return $this->strlen($value);
636
            case 'count_words':
637
                $value = trim($value);
638
639
                return count(preg_split('/\s+/', $value));
640
            case 'str_word_count':
641
            case 'word_count':
642
            case 'wordcount':
643
                return $this->str_word_count($value);
644
            case 'count_paragraphs':
645
                $value = trim($value);
646
                $value = preg_replace('/\r/', '', $value);
647
648
                return count(preg_split('/\n+/', $value));
649
            case 'strpos':
650
                if ($opt != 0 && empty($opt)) {
651
                    return $value;
652
                }
653
654
                return $this->strpos($value, $opt);
655
            case 'wordwrap':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
656
                // default: 70
657
                $wrapat = (int)$opt > 0 ? (int)$opt : 70;
0 ignored issues
show
Unused Code introduced by
$wrapat is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
658
                if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
659
                    return $this->includeMdfFile('wordwrap');
660
                } else {
661
                    return preg_replace("@(\b\w+\b)@e", "wordwrap('\\1',\$wrapat,' ',1)", $value);
662
                }
663
            case 'wrap_text':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
664
                $width = preg_match('/^[1-9][0-9]*$/', $opt) ? $opt : 70;
665
                if ($modx->config['manager_language'] === 'japanese-utf8') {
666
                    $chunk = array();
667
                    $bt = '';
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $bt. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
668
                    while ($bt != $value) {
669
                        $bt = $value;
670
                        if ($this->strlen($value) < $width) {
671
                            $chunk[] = $value;
672
                            break;
673
                        }
674
                        $chunk[] = $this->substr($value, 0, $width);
675
                        $value = $this->substr($value, $width);
676
                    }
677
678
                    return implode("\n", $chunk);
679
                } else {
680
                    return wordwrap($value, $width, "\n", true);
681
                }
682
            case 'substr':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
683
                if (empty($opt)) {
684
                    break;
685
                }
686
                if (strpos($opt, ',') !== false) {
687
                    list($b, $e) = explode(',', $opt, 2);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $b. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $e. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
688
689
                    return $this->substr($value, $b, (int)$e);
690
                } else {
691
                    return $this->substr($value, $opt);
692
                }
693
            case 'limit':
694
            case 'trim_to': // http://www.movabletype.jp/documentation/appendices/modifiers/trim_to.html
695 View Code Duplication
                if (strpos($opt, '+') !== false) {
696
                    list($len, $str) = explode('+', $opt, 2);
697
                } else {
698
                    $len = $opt;
699
                    $str = '';
700
                }
701
                if ($len === '') {
702
                    $len = 100;
703
                }
704
                if (abs($len) > $this->strlen($value)) {
705
                    $str = '';
706
                }
707
                if (preg_match('/^[1-9][0-9]*$/', $len)) {
708
                    return $this->substr($value, 0, $len) . $str;
709
                } elseif (preg_match('/^\-[1-9][0-9]*$/', $len)) {
710
                    return $str . $this->substr($value, $len);
711
                }
712
                break;
713
            case 'summary':
714
            case 'smart_description':
715
            case 'smart_desc':
716
                return $this->includeMdfFile('summary');
717
            case 'replace':
718
            case 'str_replace':
719
                if (empty($opt) || strpos($opt, ',') === false) {
720
                    break;
721
                }
722
                if (substr_count($opt, ',') == 1) {
723
                    $delim = ',';
724
                } elseif (substr_count($opt, '|') == 1) {
725
                    $delim = '|';
726
                } elseif (substr_count($opt, '=>') == 1) {
727
                    $delim = '=>';
728
                } elseif (substr_count($opt, '/') == 1) {
729
                    $delim = '/';
730
                } else {
731
                    break;
732
                }
733
                list($s, $r) = explode($delim, $opt);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $s. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
734
                if ($value !== '') {
735
                    return str_replace($s, $r, $value);
736
                }
737
                break;
738
            case 'replace_to':
739
            case 'tpl':
740 View Code Duplication
                if ($value !== '') {
741
                    return str_replace(array('[+value+]', '[+output+]', '{value}', '%s'), $value, $opt);
742
                }
743
                break;
744
            case 'eachtpl':
745
                $value = explode('||', $value);
746
                $_ = array();
747
                foreach ($value as $v) {
748
                    $_[] = str_replace(array('[+value+]', '[+output+]', '{value}', '%s'), $v, $opt);
749
                }
750
751
                return implode("\n", $_);
752
            case 'array_pop':
753
            case 'array_shift':
754
                if (strpos($value, '||') !== false) {
755
                    $delim = '||';
756
                } else {
757
                    $delim = ',';
758
                }
759
760
                return $cmd(explode($delim, $value));
761
            case 'preg_replace':
762
            case 'regex_replace':
763
                if (empty($opt) || strpos($opt, ',') === false) {
764
                    break;
765
                }
766
                list($s, $r) = explode(',', $opt, 2);
767
                if ($value !== '') {
768
                    return preg_replace($s, $r, $value);
769
                }
770
                break;
771
            case 'cat':
772
            case 'concatenate':
773
            case '.':
774
                if ($value !== '') {
775
                    return $value . $opt;
776
                }
777
                break;
778
            case 'sprintf':
779
            case 'string_format':
780
                if ($value !== '') {
781
                    return sprintf($opt, $value);
782
                }
783
                break;
784
            case 'number_format':
785
                if ($opt == '') {
786
                    $opt = 0;
787
                }
788
789
                return number_format($value, $opt);
790
            case 'money_format':
791
                setlocale(LC_MONETARY, setlocale(LC_TIME, 0));
792
                if ($value !== '') {
793
                    return money_format($opt, (double)$value);
794
                }
795
                break;
796
            case 'tobool':
797
                return boolval($value);
798
            case 'nl2lf':
799 View Code Duplication
                if ($value !== '') {
800
                    return str_replace(array("\r\n", "\n", "\r"), '\n', $value);
801
                }
802
                break;
803
            case 'br2nl':
804
                return preg_replace('@<br[\s/]*>@i', "\n", $value);
805
            case 'nl2br':
806
                if (version_compare(PHP_VERSION, '5.3.0', '<')) {
807
                    return nl2br($value);
808
                }
809
                if ($opt !== '') {
810
                    $opt = trim($opt);
811
                    $opt = strtolower($opt);
812
                    if ($opt === 'false') {
813
                        $opt = false;
814
                    } elseif ($opt === '0') {
815
                        $opt = false;
816
                    } else {
817
                        $opt = true;
818
                    }
819
                } elseif (isset($modx->config['mce_element_format']) && $modx->config['mce_element_format'] === 'html') {
820
                    $opt = false;
821
                } else {
822
                    $opt = true;
823
                }
824
825
                return nl2br($value, $opt);
826
            case 'ltrim':
827
            case 'rtrim':
828
            case 'trim': // ref http://mblo.info/modifiers/custom-modifiers/rtrim_opt.html
829
                if ($opt === '') {
830
                    return $cmd($value);
831
                } else {
832
                    return $cmd($value, $opt);
833
                }
834
            // These are all straight wrappers for PHP functions
835
            case 'ucfirst':
836
            case 'lcfirst':
837
            case 'ucwords':
838
                return $cmd($value);
839
840
            #####  Date time format
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
841
            case 'strftime':
842
            case 'date':
843
            case 'dateformat':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
844
                if (empty($opt)) {
845
                    $opt = $modx->toDateFormat(null, 'formatOnly');
846
                }
847
                if (!preg_match('@^[0-9]+$@', $value)) {
848
                    $value = strtotime($value);
849
                }
850
                if (strpos($opt, '%') !== false) {
851
                    return strftime($opt, 0 + $value);
852
                } else {
853
                    return date($opt, 0 + $value);
854
                }
855
            case 'time':
856
                if (empty($opt)) {
857
                    $opt = '%H:%M';
858
                }
859
                if (!preg_match('@^[0-9]+$@', $value)) {
860
                    $value = strtotime($value);
861
                }
862
863
                return strftime($opt, 0 + $value);
864
            case 'strtotime':
865
                return strtotime($value);
866
            #####  mathematical function
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
867
            case 'toint':
868
                return (int)$value;
869
            case 'tofloat':
870
                return floatval($value);
871
            case 'round':
872
                if (!$opt) {
873
                    $opt = 0;
874
                }
875
876
                return $cmd($value, $opt);
877
            case 'max':
878
            case 'min':
879
                return $cmd(explode(',', $value));
880
            case 'floor':
881
            case 'ceil':
882
            case 'abs':
883
                return $cmd($value);
884
            case 'math':
885
            case 'calc':
886
                $value = (int)$value;
887
                if (empty($value)) {
888
                    $value = '0';
889
                }
890
                $filter = str_replace(array('[+value+]', '[+output+]', '{value}', '%s'), '?', $opt);
891
                $filter = preg_replace('@([a-zA-Z\n\r\t\s])@', '', $filter);
892
                if (strpos($filter, '?') === false) {
893
                    $filter = "?{$filter}";
894
                }
895
                $filter = str_replace('?', $value, $filter);
896
897
                return eval("return {$filter};");
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
898
            case 'count':
899
                if ($value == '') {
900
                    return 0;
901
                }
902
                $value = explode(',', $value);
903
904
                return count($value);
905
            case 'sort':
906
            case 'rsort':
907
                if (strpos($value, "\n") !== false) {
908
                    $delim = "\n";
909
                } else {
910
                    $delim = ',';
911
                }
912
                $swap = explode($delim, $value);
913
                if (!$opt) {
914
                    $opt = SORT_REGULAR;
915
                } else {
916
                    $opt = constant($opt);
917
                }
918
                $cmd($swap, $opt);
919
920
                return implode($delim, $swap);
921
            #####  Resource fields
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
922
            case 'id':
923
                if ($opt) {
924
                    return $this->getDocumentObject($opt, $key);
925
                }
926
                break;
927
            case 'type':
928
            case 'contenttype':
929
            case 'pagetitle':
930
            case 'longtitle':
931
            case 'description':
932
            case 'alias':
933
            case 'introtext':
934
            case 'link_attributes':
935
            case 'published':
936
            case 'pub_date':
937
            case 'unpub_date':
938
            case 'parent':
939
            case 'isfolder':
940
            case 'content':
941
            case 'richtext':
942
            case 'template':
943
            case 'menuindex':
944
            case 'searchable':
945
            case 'cacheable':
946
            case 'createdby':
947
            case 'createdon':
948
            case 'editedby':
949
            case 'editedon':
950
            case 'deleted':
951
            case 'deletedon':
952
            case 'deletedby':
953
            case 'publishedon':
954
            case 'publishedby':
955
            case 'menutitle':
956
            case 'donthit':
957
            case 'haskeywords':
958
            case 'privateweb':
959
            case 'privatemgr':
960
            case 'content_dispo':
961
            case 'hidemenu':
962
                if ($cmd === 'contenttype') {
963
                    $cmd = 'contentType';
964
                }
965
966
                return $this->getDocumentObject($value, $cmd);
967
            case 'title':
968
                $pagetitle = $this->getDocumentObject($value, 'pagetitle');
969
                $longtitle = $this->getDocumentObject($value, 'longtitle');
970
971
                return $longtitle ? $longtitle : $pagetitle;
972
            case 'shorttitle':
973
                $pagetitle = $this->getDocumentObject($value, 'pagetitle');
974
                $menutitle = $this->getDocumentObject($value, 'menutitle');
975
976
                return $menutitle ? $menutitle : $pagetitle;
977
            case 'templatename':
978
                $rs = $modx->getDatabase()->select('templatename', '[+prefix+]site_templates', "id='{$value}'");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
979
                $templateName = $modx->getDatabase()->getValue($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs defined by $modx->getDatabase()->se...ates', "id='{$value}'") on line 978 can also be of type boolean; however, EvolutionCMS\Database::getValue() does only seem to accept object<mysqli_result>|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
980
981
                return !$templateName ? '(blank)' : $templateName;
982
            case 'getfield':
983
                if (!$opt) {
984
                    $opt = 'content';
985
                }
986
987
                return $modx->getField($opt, $value);
988
            case 'children':
989
            case 'childids':
990
                if ($value == '') {
991
                    $value = 0;
992
                } // 値がない場合はルートと見なす
993
                $published = 1;
994
                if ($opt == '') {
995
                    $opt = 'page';
996
                }
997
                $_ = explode(',', $opt);
998
                $where = array();
999
                foreach ($_ as $opt) {
1000
                    switch (trim($opt)) {
1001
                        case 'page';
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1002
                        case '!folder';
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1003
                        case '!isfolder':
1004
                            $where[] = 'sc.isfolder=0';
1005
                            break;
1006
                        case 'folder';
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1007
                        case 'isfolder':
1008
                            $where[] = 'sc.isfolder=1';
1009
                            break;
1010
                        case  'menu';
0 ignored issues
show
Coding Style introduced by
As per coding-style, case should be followed by a single space.

As per the PSR-2 coding standard, there must be a space after the case keyword, instead of the test immediately following it.

switch (true) {
    case!isset($a):  //wrong
        doSomething();
        break;
    case !isset($b):  //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1011
                        case  'show_menu':
0 ignored issues
show
Coding Style introduced by
As per coding-style, case should be followed by a single space.

As per the PSR-2 coding standard, there must be a space after the case keyword, instead of the test immediately following it.

switch (true) {
    case!isset($a):  //wrong
        doSomething();
        break;
    case !isset($b):  //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1012
                            $where[] = 'sc.hidemenu=0';
1013
                            break;
1014
                        case '!menu';
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1015
                        case '!show_menu':
1016
                            $where[] = 'sc.hidemenu=1';
1017
                            break;
1018
                        case  'published':
0 ignored issues
show
Coding Style introduced by
As per coding-style, case should be followed by a single space.

As per the PSR-2 coding standard, there must be a space after the case keyword, instead of the test immediately following it.

switch (true) {
    case!isset($a):  //wrong
        doSomething();
        break;
    case !isset($b):  //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1019
                            $published = 1;
1020
                            break;
1021
                        case '!published':
1022
                            $published = 0;
1023
                            break;
1024
                    }
1025
                }
1026
                $where = implode(' AND ', $where);
1027
                $children = $modx->getDocumentChildren($value, $published, '0', 'id', $where);
1028
                $result = array();
1029
                foreach ((array)$children as $child) {
1030
                    $result[] = $child['id'];
1031
                }
1032
1033
                return implode(',', $result);
1034
            case 'fullurl':
1035
                if (!is_numeric($value)) {
1036
                    return $value;
1037
                }
1038
1039
                return $modx->makeUrl($value);
1040
            case 'makeurl':
1041
                if (!is_numeric($value)) {
1042
                    return $value;
1043
                }
1044
                if (!$opt) {
1045
                    $opt = 'full';
1046
                }
1047
1048
                return $modx->makeUrl($value, '', '', $opt);
1049
1050
            #####  File system
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
1051
            case 'getimageinfo':
1052
            case 'imageinfo':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
1053
                if (!is_file($value)) {
1054
                    return '';
1055
                }
1056
                $_ = getimagesize($value);
1057
                if (!$_[0]) {
1058
                    return '';
1059
                }
1060
                $info['width'] = $_[0];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$info was never initialized. Although not strictly required by PHP, it is generally a good practice to add $info = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1061
                $info['height'] = $_[1];
1062
                if ($_[0] > $_[1]) {
1063
                    $info['aspect'] = 'landscape';
1064
                } elseif ($_[0] < $_[1]) {
1065
                    $info['aspect'] = 'portrait';
1066
                } else {
1067
                    $info['aspect'] = 'square';
1068
                }
1069
                switch ($_[2]) {
1070
                    case IMAGETYPE_GIF  :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1071
                        $info['type'] = 'gif';
1072
                        break;
1073
                    case IMAGETYPE_JPEG :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1074
                        $info['type'] = 'jpg';
1075
                        break;
1076
                    case IMAGETYPE_PNG  :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1077
                        $info['type'] = 'png';
1078
                        break;
1079
                    default             :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1080
                        $info['type'] = 'unknown';
1081
                }
1082
                $info['attrib'] = $_[3];
1083
                switch ($opt) {
1084
                    case 'width' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1085
                        return $info['width'];
1086
                    case 'height':
1087
                        return $info['height'];
1088
                    case 'aspect':
1089
                        return $info['aspect'];
1090
                    case 'type'  :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1091
                        return $info['type'];
1092
                    case 'attrib':
1093
                        return $info['attrib'];
1094
                    default      :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1095
                        return print_r($info, true);
1096
                }
1097
1098
            case 'file_get_contents':
1099
            case 'readfile':
1100
                if (!is_file($value)) {
1101
                    return $value;
1102
                }
1103
                $value = realpath($value);
1104
                if (strpos($value, MODX_MANAGER_PATH) !== false) {
1105
                    exit('Can not read core file');
0 ignored issues
show
Coding Style Compatibility introduced by
The method getValueFromPreset() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
1106
                }
1107
                $ext = strtolower(substr($value, -4));
1108
                if ($ext === '.php') {
1109
                    exit('Can not read php file');
0 ignored issues
show
Coding Style Compatibility introduced by
The method getValueFromPreset() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
1110
                }
1111
                if ($ext === '.cgi') {
1112
                    exit('Can not read cgi file');
0 ignored issues
show
Coding Style Compatibility introduced by
The method getValueFromPreset() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
1113
                }
1114
1115
                return file_get_contents($value);
1116
            case 'filesize':
1117
                if ($value == '') {
1118
                    return '';
1119
                }
1120
                $filename = $value;
1121
1122
                $site_url = $modx->config['site_url'];
1123
                if (strpos($filename, $site_url) === 0) {
1124
                    $filename = substr($filename, 0, strlen($site_url));
1125
                }
1126
                $filename = trim($filename, '/');
1127
1128
                $opt = trim($opt, '/');
1129
                if ($opt !== '') {
1130
                    $opt .= '/';
1131
                }
1132
1133
                $filename = MODX_BASE_PATH . $opt . $filename;
1134
1135
                if (is_file($filename)) {
1136
                    clearstatcache();
1137
                    $size = filesize($filename);
1138
1139
                    return $size;
1140
                } else {
1141
                    return '';
1142
                }
1143
            #####  User info
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
1144
            case 'username':
1145
            case 'fullname':
1146
            case 'role':
1147
            case 'email':
1148
            case 'phone':
1149
            case 'mobilephone':
1150
            case 'blocked':
1151
            case 'blockeduntil':
1152
            case 'blockedafter':
1153
            case 'logincount':
1154
            case 'lastlogin':
1155
            case 'thislogin':
1156
            case 'failedlogincount':
1157
            case 'dob':
1158
            case 'gender':
1159
            case 'country':
1160
            case 'street':
1161
            case 'city':
1162
            case 'state':
1163
            case 'zip':
1164
            case 'fax':
1165
            case 'photo':
1166
            case 'comment':
1167
                $this->opt = $cmd;
1168
1169
                return $this->includeMdfFile('moduser');
1170
            case 'userinfo':
1171
                if (empty($opt)) {
1172
                    $this->opt = 'username';
1173
                }
1174
1175
                return $this->includeMdfFile('moduser');
1176
            case 'webuserinfo':
1177
                if (empty($opt)) {
1178
                    $this->opt = 'username';
1179
                }
1180
                $this->value = -$value;
1181
1182
                return $this->includeMdfFile('moduser');
1183
            #####  Special functions
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
1184
            case 'ifempty':
1185
            case '_default':
1186
            case 'default':
1187
                if (empty($value)) {
1188
                    return $opt;
1189
                }
1190
                break;
1191
            case 'ifnotempty':
1192
                if (!empty($value)) {
1193
                    return $opt;
1194
                }
1195
                break;
1196
            case 'datagrid':
1197
                $grd = new DataGrid(null, trim($value));
1198
                $grd->itemStyle = '';
1199
                $grd->altItemStyle = '';
1200
                $pos = strpos($value, "\n");
1201
                if ($pos) {
1202
                    $_ = substr($value, 0, $pos);
1203
                } else {
1204
                    $_ = $pos;
1205
                }
1206
                $grd->cdelim = strpos($_, "\t") !== false ? 'tab' : ',';
1207
1208
                return $grd->render();
1209
            case 'rotate':
1210
            case 'evenodd':
1211
                if (strpos($opt, ',') === false) {
1212
                    $opt = 'odd,even';
1213
                }
1214
                $_ = explode(',', $opt);
1215
                $c = count($_);
1216
                $i = $value + $c;
1217
                $i = $i % $c;
1218
1219
                return $_[$i];
1220
            case 'takeval':
1221
                $arr = explode(",", $opt);
1222
                $idx = $value;
1223
                if (!is_numeric($idx)) {
1224
                    return $value;
1225
                }
1226
1227
                return $arr[$idx];
1228
            case 'getimage':
1229
                return $this->includeMdfFile('getimage');
1230
            case 'nicesize':
1231
                return $modx->nicesize($value);
1232
            case 'googlemap':
1233
            case 'googlemaps':
1234
                if (empty($opt)) {
1235
                    $opt = 'border:none;width:500px;height:350px;';
1236
                }
1237
                $tpl = '<iframe style="[+style+]" src="https://maps.google.co.jp/maps?ll=[+value+]&output=embed&z=15"></iframe>';
1238
                $ph['style'] = $opt;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$ph was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ph = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $ph. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1239
                $ph['value'] = $value;
1240
1241
                return $modx->parseText($tpl, $ph);
1242
            case 'youtube':
1243
            case 'youtube16x9':
1244
                if (empty($opt)) {
1245
                    $opt = 560;
1246
                }
1247
                $h = round($opt * 0.5625);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $h. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1248
                $tpl = '<iframe width="%s" height="%s" src="https://www.youtube.com/embed/%s" frameborder="0" allowfullscreen></iframe>';
1249
1250
                return sprintf($tpl, $opt, $h, $value);
1251
            //case 'youtube4x3':%s*0.75+25
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1252
            case 'setvar':
1253
                $modx->placeholders[$opt] = $value;
1254
1255
                return '';
1256
            case 'csstohead':
1257
                $modx->regClientCSS($value);
1258
1259
                return '';
1260
            case 'htmltohead':
1261
                $modx->regClientStartupHTMLBlock($value);
1262
1263
                return '';
1264
            case 'htmltobottom':
1265
                $modx->regClientHTMLBlock($value);
1266
1267
                return '';
1268
            case 'jstohead':
1269
                $modx->regClientStartupScript($value);
1270
1271
                return '';
1272
            case 'jstobottom':
1273
                $modx->regClientScript($value);
1274
1275
                return '';
1276
            case 'dummy':
1277
                return $value;
1278
1279
            // If we haven't yet found the modifier, let's look elsewhere
1280
            default:
1281
                $value = $this->getValueFromElement($key, $value, $cmd, $opt);
1282
        }
1283
1284
        return $value;
1285
    }
1286
1287
    public function includeMdfFile($cmd)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1288
    {
1289
        $modx = evolutionCMS();
1290
        $key = $this->key;
1291
        $value = $this->value;
1292
        $opt = $this->opt;
1293
1294
        return include(MODX_MANAGER_PATH . "includes/extenders/modifiers/mdf_{$cmd}.inc.php");
1295
    }
1296
1297
    public function getValueFromElement($key, $value, $cmd, $opt)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1298
    {
1299
        $modx = evolutionCMS();
1300
        if (isset($modx->snippetCache[$this->elmName])) {
1301
            $php = $modx->snippetCache[$this->elmName];
1302
        } else {
1303
            $esc_elmName = $modx->getDatabase()->escape($this->elmName);
1304
            $result = $modx->getDatabase()->select('snippet', '[+prefix+]site_snippets', "name='{$esc_elmName}'");
1305
            $total = $modx->getDatabase()->getRecordCount($result);
0 ignored issues
show
Bug introduced by
It seems like $result defined by $modx->getDatabase()->se...name='{$esc_elmName}'") on line 1304 can also be of type boolean; however, EvolutionCMS\Database::getRecordCount() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1306
            if ($total == 1) {
1307
                $row = $modx->getDatabase()->getRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result defined by $modx->getDatabase()->se...name='{$esc_elmName}'") on line 1304 can also be of type boolean; however, EvolutionCMS\Database::getRow() does only seem to accept object<mysqli_result>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1308
                $php = $row['snippet'];
1309
            } elseif ($total == 0) {
1310
                $assets_path = MODX_BASE_PATH . 'assets/';
1311
                if (is_file($assets_path . "modifiers/mdf_{$cmd}.inc.php")) {
1312
                    $modifiers_path = $assets_path . "modifiers/mdf_{$cmd}.inc.php";
1313
                } elseif (is_file($assets_path . "plugins/phx/modifiers/{$cmd}.phx.php")) {
1314
                    $modifiers_path = $assets_path . "plugins/phx/modifiers/{$cmd}.phx.php";
1315
                } elseif (is_file(MODX_MANAGER_PATH . "includes/extenders/modifiers/mdf_{$cmd}.inc.php")) {
1316
                    $modifiers_path = MODX_MANAGER_PATH . "includes/extenders/modifiers/mdf_{$cmd}.inc.php";
1317
                } else {
1318
                    $modifiers_path = false;
1319
                }
1320
1321
                if ($modifiers_path !== false) {
1322
                    $php = @file_get_contents($modifiers_path);
1323
                    $php = trim($php);
1324
                    if (substr($php, 0, 5) === '<?php') {
1325
                        $php = substr($php, 6);
1326
                    }
1327
                    if (substr($php, 0, 2) === '<?') {
1328
                        $php = substr($php, 3);
1329
                    }
1330
                    if (substr($php, -2) === '?>') {
1331
                        $php = substr($php, 0, -2);
1332
                    }
1333
                    if ($this->elmName !== '') {
1334
                        $modx->snippetCache[$this->elmName . 'Props'] = '';
1335
                    }
1336
                } else {
1337
                    $php = false;
1338
                }
1339
            } else {
1340
                $php = false;
1341
            }
1342
            if ($this->elmName !== '') {
1343
                $modx->snippetCache[$this->elmName] = $php;
1344
            }
1345
        }
1346
        if ($php === '') {
1347
            $php = false;
1348
        }
1349
1350
        if ($php === false) {
1351
            $html = $modx->getChunk($this->elmName);
1352
        } else {
1353
            $html = false;
1354
        }
1355
1356
        $self = '[+output+]';
1357
1358
        if ($php !== false) {
1359
            ob_start();
1360
            $options = $opt;
0 ignored issues
show
Unused Code introduced by
$options is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1361
            $output = $value;
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1362
            $name = $key;
0 ignored issues
show
Unused Code introduced by
$name is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1363
            $this->bt = $value;
1364
            $this->vars['value'] = &$value;
1365
            $this->vars['input'] = &$value;
1366
            $this->vars['option'] = &$opt;
1367
            $this->vars['options'] = &$opt;
1368
            $custom = eval($php);
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
1369
            $msg = ob_get_contents();
1370
            if ($value === $this->bt) {
1371
                $value = $msg . $custom;
1372
            }
1373
            ob_end_clean();
1374
        } elseif ($html !== false && isset($value) && $value !== '') {
1375
            $html = str_replace(array($self, '[+value+]'), $value, $html);
1376
            $value = str_replace(array('[+options+]', '[+param+]'), $opt, $html);
1377
        } else {
1378
            return false;
1379
        }
1380
1381
        if ($php === false && $html === false && $value !== ''
1382
            && (strpos($cmd, '[+value+]') !== false || strpos($cmd, $self) !== false)) {
1383
            $value = str_replace(array('[+value+]', $self), $value, $cmd);
1384
        }
1385
1386
        return $value;
1387
    }
1388
1389
    public function parseDocumentSource($content = '')
1390
    {
1391
        $modx = evolutionCMS();
1392
1393
        if (strpos($content, '[') === false && strpos($content, '{') === false) {
1394
            return $content;
1395
        }
1396
1397
        if (!$modx->maxParserPasses) {
1398
            $modx->maxParserPasses = 10;
1399
        }
1400
        $bt = '';
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $bt. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1401
        $i = 0;
1402
        while ($bt !== $content) {
1403
            $bt = $content;
1404
            if (strpos($content, '[*') !== false && $modx->documentIdentifier) {
1405
                $content = $modx->mergeDocumentContent($content);
1406
            }
1407
            if (strpos($content, '[(') !== false) {
1408
                $content = $modx->mergeSettingsContent($content);
1409
            }
1410
            if (strpos($content, '{{') !== false) {
1411
                $content = $modx->mergeChunkContent($content);
1412
            }
1413
            if (strpos($content, '[!') !== false) {
1414
                $content = str_replace(array('[!', '!]'), array('[[', ']]'), $content);
1415
            }
1416
            if (strpos($content, '[[') !== false) {
1417
                $content = $modx->evalSnippets($content);
1418
            }
1419
1420
            if ($content === $bt) {
1421
                break;
1422
            }
1423
            if ($modx->maxParserPasses < $i) {
1424
                break;
1425
            }
1426
            $i++;
1427
        }
1428
1429
        return $content;
1430
    }
1431
1432
    public function getDocumentObject($target = '', $field = 'pagetitle')
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1433
    {
1434
        $modx = evolutionCMS();
1435
1436
        $target = trim($target);
1437
        if (empty($target)) {
1438
            $target = $modx->config['site_start'];
1439
        }
1440
        if (preg_match('@^[1-9][0-9]*$@', $target)) {
1441
            $method = 'id';
1442
        } else {
1443
            $method = 'alias';
1444
        }
1445
1446
        if (!isset($this->documentObject[$target])) {
1447
            $this->documentObject[$target] = $modx->getDocumentObject($method, $target, 'direct');
1448
        }
1449
1450
        if ($this->documentObject[$target]['publishedon'] === '0') {
1451
            return '';
1452
        } elseif (isset($this->documentObject[$target][$field])) {
1453
            if (is_array($this->documentObject[$target][$field])) {
1454
                $a = $modx->getTemplateVarOutput($field, $target);
0 ignored issues
show
Documentation introduced by
$field is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Comprehensibility introduced by
Avoid variables with short names like $a. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1455
                $this->documentObject[$target][$field] = $a[$field];
1456
            }
1457
        } else {
1458
            $this->documentObject[$target][$field] = false;
1459
        }
1460
1461
        return $this->documentObject[$target][$field];
1462
    }
1463
1464
    public function setPlaceholders($value = '', $key = '', $path = '')
1465
    {
1466
        if ($path !== '') {
1467
            $key = "{$path}.{$key}";
1468
        }
1469
        if (is_array($value)) {
1470
            foreach ($value as $subkey => $subval) {
1471
                $this->setPlaceholders($subval, $subkey, $key);
1472
            }
1473
        } else {
1474
            $this->setModifiersVariable($key, $value);
1475
        }
1476
    }
1477
1478
    // Sets a placeholder variable which can only be access by Modifiers
1479
    public function setModifiersVariable($key, $value)
1480
    {
1481
        if ($key != 'phx' && $key != 'dummy') {
1482
            $this->placeholders[$key] = $value;
1483
        }
1484
    }
1485
1486
    //mbstring
1487
    public function substr($str, $s, $l = null)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $s. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $l. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1488
    {
1489
        $modx = evolutionCMS();
1490
        if (is_null($l)) {
1491
            $l = $this->strlen($str);
1492
        }
1493
        if (function_exists('mb_substr')) {
1494
            if (strpos($str, "\r") !== false) {
1495
                $str = str_replace(array("\r\n", "\r"), "\n", $str);
1496
            }
1497
1498
            return mb_substr($str, $s, $l, $modx->config['modx_charset']);
1499
        }
1500
1501
        return substr($str, $s, $l);
1502
    }
1503
1504
    public function strpos($haystack, $needle, $offset = 0)
1505
    {
1506
        $modx = evolutionCMS();
1507
        if (function_exists('mb_strpos')) {
1508
            return mb_strpos($haystack, $needle, $offset, $modx->config['modx_charset']);
1509
        }
1510
1511
        return strpos($haystack, $needle, $offset);
1512
    }
1513
1514
    public function strlen($str)
1515
    {
1516
        $modx = evolutionCMS();
1517
        if (function_exists('mb_strlen')) {
1518
            return mb_strlen(str_replace("\r\n", "\n", $str), $modx->config['modx_charset']);
1519
        }
1520
1521
        return strlen($str);
1522
    }
1523
1524
    public function strtolower($str)
1525
    {
1526
        if (function_exists('mb_strtolower')) {
1527
            return mb_strtolower($str);
1528
        }
1529
1530
        return strtolower($str);
1531
    }
1532
1533
    public function strtoupper($str)
1534
    {
1535
        if (function_exists('mb_strtoupper')) {
1536
            return mb_strtoupper($str);
1537
        }
1538
1539
        return strtoupper($str);
1540
    }
1541
1542 View Code Duplication
    public function ucfirst($str)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1543
    {
1544
        if (function_exists('mb_strtoupper')) {
1545
            return mb_strtoupper($this->substr($str, 0, 1)) . $this->substr($str, 1, $this->strlen($str));
1546
        }
1547
1548
        return ucfirst($str);
1549
    }
1550
1551 View Code Duplication
    public function lcfirst($str)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1552
    {
1553
        if (function_exists('mb_strtolower')) {
1554
            return mb_strtolower($this->substr($str, 0, 1)) . $this->substr($str, 1, $this->strlen($str));
1555
        }
1556
1557
        return lcfirst($str);
1558
    }
1559
1560
    public function ucwords($str)
1561
    {
1562
        if (function_exists('mb_convert_case')) {
1563
            return mb_convert_case($str, MB_CASE_TITLE);
1564
        }
1565
1566
        return ucwords($str);
1567
    }
1568
1569
    public function strrev($str)
1570
    {
1571
        preg_match_all('/./us', $str, $ar);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ar. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1572
1573
        return implode(array_reverse($ar[0]));
1574
    }
1575
1576
    public function str_shuffle($str)
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
1577
    {
1578
        preg_match_all('/./us', $str, $ar);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ar. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1579
        shuffle($ar[0]);
1580
1581
        return implode($ar[0]);
1582
    }
1583
1584
    public function str_word_count($str)
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
1585
    {
1586
        return count(preg_split('~[^\p{L}\p{N}\']+~u', $str));
1587
    }
1588
1589
    public function strip_tags($value, $params = '')
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
1590
    {
1591
        $modx = evolutionCMS();
0 ignored issues
show
Unused Code introduced by
$modx is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1592
1593 View Code Duplication
        if (stripos($params, 'style') === false && stripos($value, '</style>') !== false) {
1594
            $value = preg_replace('@<style.*?>.*?</style>@is', '', $value);
1595
        }
1596 View Code Duplication
        if (stripos($params, 'script') === false && stripos($value, '</script>') !== false) {
1597
            $value = preg_replace('@<script.*?>.*?</script>@is', '', $value);
1598
        }
1599
1600
        return trim(strip_tags($value, $params));
1601
    }
1602
}
1603