Modifiers::getValueFromElement()   F
last analyzed

Complexity

Conditions 25
Paths 3948

Size

Total Lines 95

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 25
nc 3948
nop 4
dl 0
loc 95
rs 0
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;
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->getConfig('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);
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 = '';
196
        $result = array();
197
        while ($bt !== $modifiers) {
198
            $bt = $modifiers;
199
            $c = substr($modifiers, 0, 1);
200
            $modifiers = substr($modifiers, 1);
201
202
            if ($c === ':' && preg_match('@^(!?[<>=]{1,2})@', $modifiers, $match)) { // :=, :!=, :<=, :>=, :!<=, :!>=
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 ...
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);
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);
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 = '')
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(',',
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
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');
442
                }
443
                if (strpos($path, MODX_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);
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});"));
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});");
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});");
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);
508
                for ($m = 0; $m < $c; $m++) {
509
                    $mi = explode('=', $raw[$m], 2);
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
518
519
            #####  Encode / Decode / Hash / Escape
520
            case 'htmlent':
521
            case 'htmlentities':
522
                return htmlentities($value, ENT_QUOTES, $modx->getConfig('modx_charset'));
523
            case 'html_entity_decode':
524
            case 'decode_html':
525
            case 'html_decode':
526
                return html_entity_decode($value, ENT_QUOTES, $modx->getConfig('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->getConfig('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->getConfig('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':
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
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->getConfig('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->getConfig('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':
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':
664
                $width = preg_match('/^[1-9][0-9]*$/', $opt) ? $opt : 70;
665
                if ($modx->getConfig('manager_language') === 'japanese-utf8') {
666
                    $chunk = array();
667
                    $bt = '';
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':
683
                if (empty($opt)) {
684
                    break;
685
                }
686
                if (strpos($opt, ',') !== false) {
687
                    list($b, $e) = explode(',', $opt, 2);
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);
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->getConfig('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
841
            case 'strftime':
842
            case 'date':
843
            case 'dateformat':
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
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};");
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
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', $modx->getDatabase()->getFullTableName('site_templates'), "id='{$value}'");
979
                $templateName = $modx->getDatabase()->getValue($rs);
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';
1002
                        case '!folder';
1003
                        case '!isfolder':
1004
                            $where[] = 'sc.isfolder=0';
1005
                            break;
1006
                        case 'folder';
1007
                        case 'isfolder':
1008
                            $where[] = 'sc.isfolder=1';
1009
                            break;
1010
                        case  'menu';
1011
                        case  'show_menu':
1012
                            $where[] = 'sc.hidemenu=0';
1013
                            break;
1014
                        case '!menu';
1015
                        case '!show_menu':
1016
                            $where[] = 'sc.hidemenu=1';
1017
                            break;
1018
                        case  'published':
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);
0 ignored issues
show
Deprecated Code introduced by
The method EvolutionCMS\Core::makeUrl() has been deprecated with message: use UrlProcessor::makeUrl()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
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);
0 ignored issues
show
Deprecated Code introduced by
The method EvolutionCMS\Core::makeUrl() has been deprecated with message: use UrlProcessor::makeUrl()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1049
1050
            #####  File system
1051
            case 'getimageinfo':
1052
            case 'imageinfo':
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  :
1071
                        $info['type'] = 'gif';
1072
                        break;
1073
                    case IMAGETYPE_JPEG :
1074
                        $info['type'] = 'jpg';
1075
                        break;
1076
                    case IMAGETYPE_PNG  :
1077
                        $info['type'] = 'png';
1078
                        break;
1079
                    default             :
1080
                        $info['type'] = 'unknown';
1081
                }
1082
                $info['attrib'] = $_[3];
1083
                switch ($opt) {
1084
                    case 'width' :
1085
                        return $info['width'];
1086
                    case 'height':
1087
                        return $info['height'];
1088
                    case 'aspect':
1089
                        return $info['aspect'];
1090
                    case 'type'  :
1091
                        return $info['type'];
1092
                    case 'attrib':
1093
                        return $info['attrib'];
1094
                    default      :
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');
1106
                }
1107
                $ext = strtolower(substr($value, -4));
1108
                if ($ext === '.php') {
1109
                    exit('Can not read php file');
1110
                }
1111
                if ($ext === '.cgi') {
1112
                    exit('Can not read cgi file');
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_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
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
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 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...
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);
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
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(
1305
                'snippet',
1306
                $modx->getDatabase()->getFullTableName('site_snippets'),
1307
                "name='{$esc_elmName}'"
1308
            );
1309
            $total = $modx->getDatabase()->getRecordCount($result);
1310
            if ($total == 1) {
1311
                $row = $modx->getDatabase()->getRow($result);
1312
                $php = $row['snippet'];
1313
            } elseif ($total == 0) {
1314
                $assets_path = MODX_BASE_PATH . 'assets/';
1315
                if (is_file($assets_path . "modifiers/mdf_{$cmd}.inc.php")) {
1316
                    $modifiers_path = $assets_path . "modifiers/mdf_{$cmd}.inc.php";
1317
                } elseif (is_file($assets_path . "plugins/phx/modifiers/{$cmd}.phx.php")) {
1318
                    $modifiers_path = $assets_path . "plugins/phx/modifiers/{$cmd}.phx.php";
1319
                } elseif (is_file(MODX_MANAGER_PATH . "includes/extenders/modifiers/mdf_{$cmd}.inc.php")) {
1320
                    $modifiers_path = MODX_MANAGER_PATH . "includes/extenders/modifiers/mdf_{$cmd}.inc.php";
1321
                } else {
1322
                    $modifiers_path = false;
1323
                }
1324
1325
                if ($modifiers_path !== false) {
1326
                    $php = @file_get_contents($modifiers_path);
1327
                    $php = trim($php);
1328
                    if (substr($php, 0, 5) === '<?php') {
1329
                        $php = substr($php, 6);
1330
                    }
1331
                    if (substr($php, 0, 2) === '<?') {
1332
                        $php = substr($php, 3);
1333
                    }
1334
                    if (substr($php, -2) === '?>') {
1335
                        $php = substr($php, 0, -2);
1336
                    }
1337
                    if ($this->elmName !== '') {
1338
                        $modx->snippetCache[$this->elmName . 'Props'] = '';
1339
                    }
1340
                } else {
1341
                    $php = false;
1342
                }
1343
            } else {
1344
                $php = false;
1345
            }
1346
            if ($this->elmName !== '') {
1347
                $modx->snippetCache[$this->elmName] = $php;
1348
            }
1349
        }
1350
        if ($php === '') {
1351
            $php = false;
1352
        }
1353
1354
        if ($php === false) {
1355
            $html = $modx->getChunk($this->elmName);
1356
        } else {
1357
            $html = false;
1358
        }
1359
1360
        $self = '[+output+]';
1361
1362
        if ($php !== false) {
1363
            ob_start();
1364
            $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...
1365
            $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...
1366
            $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...
1367
            $this->bt = $value;
1368
            $this->vars['value'] = &$value;
1369
            $this->vars['input'] = &$value;
1370
            $this->vars['option'] = &$opt;
1371
            $this->vars['options'] = &$opt;
1372
            $custom = eval($php);
1373
            $msg = ob_get_contents();
1374
            if ($value === $this->bt) {
1375
                $value = $msg . $custom;
1376
            }
1377
            ob_end_clean();
1378
        } elseif ($html !== false && isset($value) && $value !== '') {
1379
            $html = str_replace(array($self, '[+value+]'), $value, $html);
1380
            $value = str_replace(array('[+options+]', '[+param+]'), $opt, $html);
1381
        } else {
1382
            return false;
1383
        }
1384
1385
        if ($php === false && $html === false && $value !== ''
1386
            && (strpos($cmd, '[+value+]') !== false || strpos($cmd, $self) !== false)) {
1387
            $value = str_replace(array('[+value+]', $self), $value, $cmd);
1388
        }
1389
1390
        return $value;
1391
    }
1392
1393
    public function parseDocumentSource($content = '')
1394
    {
1395
        $modx = evolutionCMS();
1396
1397
        if (strpos($content, '[') === false && strpos($content, '{') === false) {
1398
            return $content;
1399
        }
1400
1401
        if (!$modx->maxParserPasses) {
1402
            $modx->maxParserPasses = 10;
1403
        }
1404
        $bt = '';
1405
        $i = 0;
1406
        while ($bt !== $content) {
1407
            $bt = $content;
1408
            if (strpos($content, '[*') !== false && $modx->documentIdentifier) {
1409
                $content = $modx->mergeDocumentContent($content);
1410
            }
1411
            if (strpos($content, '[(') !== false) {
1412
                $content = $modx->mergeSettingsContent($content);
1413
            }
1414
            if (strpos($content, '{{') !== false) {
1415
                $content = $modx->mergeChunkContent($content);
1416
            }
1417
            if (strpos($content, '[!') !== false) {
1418
                $content = str_replace(array('[!', '!]'), array('[[', ']]'), $content);
1419
            }
1420
            if (strpos($content, '[[') !== false) {
1421
                $content = $modx->evalSnippets($content);
1422
            }
1423
1424
            if ($content === $bt) {
1425
                break;
1426
            }
1427
            if ($modx->maxParserPasses < $i) {
1428
                break;
1429
            }
1430
            $i++;
1431
        }
1432
1433
        return $content;
1434
    }
1435
1436
    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...
1437
    {
1438
        $modx = evolutionCMS();
1439
1440
        $target = trim($target);
1441
        if (empty($target)) {
1442
            $target = $modx->getConfig('site_start');
1443
        }
1444
        if (preg_match('@^[1-9][0-9]*$@', $target)) {
1445
            $method = 'id';
1446
        } else {
1447
            $method = 'alias';
1448
        }
1449
1450
        if (!isset($this->documentObject[$target])) {
1451
            $this->documentObject[$target] = $modx->getDocumentObject($method, $target, 'direct');
1452
        }
1453
1454
        if ($this->documentObject[$target]['publishedon'] === '0') {
1455
            return '';
1456
        } elseif (isset($this->documentObject[$target][$field])) {
1457
            if (is_array($this->documentObject[$target][$field])) {
1458
                $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...
1459
                $this->documentObject[$target][$field] = $a[$field];
1460
            }
1461
        } else {
1462
            $this->documentObject[$target][$field] = false;
1463
        }
1464
1465
        return $this->documentObject[$target][$field];
1466
    }
1467
1468
    public function setPlaceholders($value = '', $key = '', $path = '')
1469
    {
1470
        if ($path !== '') {
1471
            $key = "{$path}.{$key}";
1472
        }
1473
        if (is_array($value)) {
1474
            foreach ($value as $subkey => $subval) {
1475
                $this->setPlaceholders($subval, $subkey, $key);
1476
            }
1477
        } else {
1478
            $this->setModifiersVariable($key, $value);
1479
        }
1480
    }
1481
1482
    // Sets a placeholder variable which can only be access by Modifiers
1483
    public function setModifiersVariable($key, $value)
1484
    {
1485
        if ($key != 'phx' && $key != 'dummy') {
1486
            $this->placeholders[$key] = $value;
1487
        }
1488
    }
1489
1490
    //mbstring
1491
    public function substr($str, $s, $l = null)
1492
    {
1493
        $modx = evolutionCMS();
1494
        if (is_null($l)) {
1495
            $l = $this->strlen($str);
1496
        }
1497
        if (function_exists('mb_substr')) {
1498
            if (strpos($str, "\r") !== false) {
1499
                $str = str_replace(array("\r\n", "\r"), "\n", $str);
1500
            }
1501
1502
            return mb_substr($str, $s, $l, $modx->getConfig('modx_charset'));
1503
        }
1504
1505
        return substr($str, $s, $l);
1506
    }
1507
1508
    public function strpos($haystack, $needle, $offset = 0)
1509
    {
1510
        $modx = evolutionCMS();
1511
        if (function_exists('mb_strpos')) {
1512
            return mb_strpos($haystack, $needle, $offset, $modx->getConfig('modx_charset'));
1513
        }
1514
1515
        return strpos($haystack, $needle, $offset);
1516
    }
1517
1518
    public function strlen($str)
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...
1519
    {
1520
        $modx = evolutionCMS();
1521
        if (function_exists('mb_strlen')) {
1522
            return mb_strlen(str_replace("\r\n", "\n", $str), $modx->getConfig('modx_charset'));
1523
        }
1524
1525
        return strlen($str);
1526
    }
1527
1528
    public function strtolower($str)
1529
    {
1530
        if (function_exists('mb_strtolower')) {
1531
            return mb_strtolower($str);
1532
        }
1533
1534
        return strtolower($str);
1535
    }
1536
1537
    public function strtoupper($str)
1538
    {
1539
        if (function_exists('mb_strtoupper')) {
1540
            return mb_strtoupper($str);
1541
        }
1542
1543
        return strtoupper($str);
1544
    }
1545
1546 View Code Duplication
    public function ucfirst($str)
1547
    {
1548
        if (function_exists('mb_strtoupper')) {
1549
            return mb_strtoupper($this->substr($str, 0, 1)) . $this->substr($str, 1, $this->strlen($str));
1550
        }
1551
1552
        return ucfirst($str);
1553
    }
1554
1555 View Code Duplication
    public function lcfirst($str)
1556
    {
1557
        if (function_exists('mb_strtolower')) {
1558
            return mb_strtolower($this->substr($str, 0, 1)) . $this->substr($str, 1, $this->strlen($str));
1559
        }
1560
1561
        return lcfirst($str);
1562
    }
1563
1564
    public function ucwords($str)
1565
    {
1566
        if (function_exists('mb_convert_case')) {
1567
            return mb_convert_case($str, MB_CASE_TITLE);
1568
        }
1569
1570
        return ucwords($str);
1571
    }
1572
1573
    public function strrev($str)
1574
    {
1575
        preg_match_all('/./us', $str, $ar);
1576
1577
        return implode(array_reverse($ar[0]));
1578
    }
1579
1580
    public function str_shuffle($str)
1581
    {
1582
        preg_match_all('/./us', $str, $ar);
1583
        shuffle($ar[0]);
1584
1585
        return implode($ar[0]);
1586
    }
1587
1588
    public function str_word_count($str)
1589
    {
1590
        return count(preg_split('~[^\p{L}\p{N}\']+~u', $str));
1591
    }
1592
1593
    public function strip_tags($value, $params = '')
1594
    {
1595
        $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...
1596
1597 View Code Duplication
        if (stripos($params, 'style') === false && stripos($value, '</style>') !== false) {
1598
            $value = preg_replace('@<style.*?>.*?</style>@is', '', $value);
1599
        }
1600 View Code Duplication
        if (stripos($params, 'script') === false && stripos($value, '</script>') !== false) {
1601
            $value = preg_replace('@<script.*?>.*?</script>@is', '', $value);
1602
        }
1603
1604
        return trim(strip_tags($value, $params));
1605
    }
1606
}
1607