tv.php ➔ getTVDisplayFormat()   F
last analyzed

Complexity

Conditions 84
Paths 2312

Size

Total Lines 338

Duplication

Lines 12
Ratio 3.55 %

Importance

Changes 0
Metric Value
cc 84
nc 2312
nop 7
dl 12
loc 338
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
2
3
if (! function_exists('ProcessTVCommand')) {
4
    /**
5
     * @param string $value
6
     * @param string $name
7
     * @param string $docid
8
     * @param string $src
9
     * @param array $tvsArray
10
     * @return string
11
     */
12
    function ProcessTVCommand($value, $name = '', $docid = '', $src = 'docform', $tvsArray = array())
13
    {
14
        $modx = evolutionCMS();
15
        $docid = (int)$docid > 0 ? (int)$docid : $modx->documentIdentifier;
16
        $nvalue = trim($value);
17
        if (substr($nvalue, 0, 1) != '@') {
18
            return $value;
19
        } elseif (isset($modx->config['enable_bindings']) && $modx->config['enable_bindings'] != 1 && $src === 'docform') {
20
            return '@Bindings is disabled.';
21
        } else {
22
            list ($cmd, $param) = ParseCommand($nvalue);
23
            $cmd = trim($cmd);
24
            $param = parseTvValues($param, $tvsArray);
25
            switch ($cmd) {
26
                case "FILE" :
27
                    $output = $modx->atBindFileContent($nvalue);
28
                    break;
29
30
                case "CHUNK" : // retrieve a chunk and process it's content
31
                    $chunk = $modx->getChunk(trim($param));
32
                    $output = $chunk;
33
                    break;
34
35
                case "DOCUMENT" : // retrieve a document and process it's content
36
                    $rs = $modx->getDocument($param);
37
                    if (is_array($rs)) {
38
                        $output = $rs['content'];
39
                    } else {
40
                        $output = "Unable to locate document $param";
41
                    }
42
                    break;
43
44
                case "SELECT" : // selects a record from the cms database
45
                    $rt = array();
0 ignored issues
show
Unused Code introduced by
$rt 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...
46
                    $replacementVars = array(
47
                        'DBASE'  => $modx->getDatabase()->getConfig('database'),
48
                        'PREFIX' => $modx->getDatabase()->getConfig('prefix')
49
                    );
50
                    foreach ($replacementVars as $rvKey => $rvValue) {
51
                        $modx->setPlaceholder($rvKey, $rvValue);
52
                    }
53
                    $param = $modx->mergePlaceholderContent($param);
54
                    $rs = $modx->getDatabase()->query("SELECT $param;");
55
                    $output = $rs;
56
                    break;
57
58
                case "EVAL" : // evaluates text as php codes return the results
59
                    $output = eval ($param);
60
                    break;
61
62
                case "INHERIT" :
63
                    $output = $param; // Default to param value if no content from parents
64
                    $doc = $modx->getPageInfo($docid, 0, 'id,parent');
65
66
                    while ($doc['parent'] != 0) {
67
                        $parent_id = $doc['parent'];
68
69
                        // Grab document regardless of publish status
70
                        $doc = $modx->getPageInfo($parent_id, 0, 'id,parent,published');
71
                        if ($doc['parent'] != 0 && !$doc['published']) {
72
                            continue;
73
                        } // hide unpublished docs if we're not at the top
74
75
                        $tv = $modx->getTemplateVar($name, '*', $doc['id'], $doc['published']);
76
77
                        // if an inherited value is found and if there is content following the @INHERIT binding
78
                        // remove @INHERIT and output that following content. This content could contain other
79
                        // @ bindings, that are processed in the next step
80
                        if ((string)$tv['value'] !== '' && !preg_match('%^@INHERIT[\s\n\r]*$%im', $tv['value'])) {
81
                            $output = trim(str_replace('@INHERIT', '', (string)$tv['value']));
82
                            break 2;
83
                        }
84
                    }
85
                    break;
86
87
                case 'DIRECTORY' :
88
                    $files = array();
89
                    $path = MODX_BASE_PATH . $param;
90
                    if (substr($path, -1, 1) != '/') {
91
                        $path .= '/';
92
                    }
93
                    if (!is_dir($path)) {
94
                        die($path);
95
                        break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
96
                    }
97
                    $dir = dir($path);
98
                    while (($file = $dir->read()) !== false) {
99
                        if (substr($file, 0, 1) != '.') {
100
                            $files[] = "{$file}=={$param}{$file}";
101
                        }
102
                    }
103
                    asort($files);
104
                    $output = implode('||', $files);
105
                    break;
106
107
                default :
108
                    $output = $value;
109
                    break;
110
111
            }
112
113
            // support for nested bindings
114
            return is_string($output) && ($output != $value) ? ProcessTVCommand($output, $name, $docid, $src,
115
                $tvsArray) : $output;
116
        }
117
    }
118
}
119
120
if (! function_exists('ProcessFile')) {
121
    /**
122
     * @param $file
123
     * @return string
124
     */
125
    function ProcessFile($file)
126
    {
127
        // get the file
128
        $buffer = @file_get_contents($file);
129
        if ($buffer === false) {
130
            $buffer = " Could not retrieve document '$file'.";
131
        }
132
133
        return $buffer;
134
    }
135
}
136
137
if (! function_exists('ParseCommand')) {
138
    /**
139
     * ParseCommand - separate @ cmd from params
140
     *
141
     * @param string $binding_string
142
     * @return array
143
     */
144
    function ParseCommand($binding_string)
145
    {
146
        $BINDINGS = array( // Array of supported bindings. must be upper case
147
            'FILE',
148
            'CHUNK',
149
            'DOCUMENT',
150
            'SELECT',
151
            'EVAL',
152
            'INHERIT',
153
            'DIRECTORY'
154
        );
155
156
        $binding_array = array();
157
        foreach ($BINDINGS as $cmd) {
158
            if (strpos($binding_string, '@' . $cmd) === 0) {
159
                $code = substr($binding_string, strlen($cmd) + 1);
160
                $binding_array = array($cmd, trim($code));
161
                break;
162
            }
163
        }
164
165
        return $binding_array;
166
    }
167
}
168
169
if (! function_exists('parseTvValues')) {
170
    /**
171
     * Parse Evolution CMS Template-Variables
172
     *
173
     * @param string $param
174
     * @param array $tvsArray
175
     * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use 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...
176
     */
177
    function parseTvValues($param, $tvsArray)
178
    {
179
        $modx = evolutionCMS();
180
        $tvsArray = is_array($modx->documentObject) ? array_merge($tvsArray, $modx->documentObject) : $tvsArray;
181
        if (strpos($param, '[*') !== false) {
182
            $matches = $modx->getTagsFromContent($param, '[*', '*]');
183
            foreach ($matches[0] as $i => $match) {
184
                if (isset($tvsArray[$matches[1][$i]])) {
185
                    if (is_array($tvsArray[$matches[1][$i]])) {
186
                        $value = $tvsArray[$matches[1][$i]]['value'];
187
                        $value = $value === '' ? $tvsArray[$matches[1][$i]]['default_text'] : $value;
188
                    } else {
189
                        $value = $tvsArray[$matches[1][$i]];
190
                    }
191
                    $param = str_replace($match, $value, $param);
192
                }
193
            }
194
        }
195
196
        return $param;
197
    }
198
}
199
200
if (! function_exists('getTVDisplayFormat')) {
201
    /**
202
     * @param string $name
203
     * @param string $value
204
     * @param string $format
205
     * @param string $paramstring
206
     * @param string $tvtype
207
     * @param string $docid
208
     * @param string $sep
209
     * @return mixed|string
210
     */
211
    function getTVDisplayFormat($name, $value, $format, $paramstring = "", $tvtype = "", $docid = "", $sep = '')
212
    {
213
214
        $modx = evolutionCMS();
215
        $o = '';
216
217
        // process any TV commands in value
218
        $docid = (int)$docid > 0 ? (int)$docid : $modx->documentIdentifier;
219
        $value = ProcessTVCommand($value, $name, $docid);
220
221
        $params = array();
222
        if ($paramstring) {
223
            $cp = explode("&", $paramstring);
224
            foreach ($cp as $p => $v) {
225
                $v = trim($v); // trim
226
                $ar = explode("=", $v);
227
                if (is_array($ar) && count($ar) == 2) {
228
                    $params[$ar[0]] = decodeParamValue($ar[1]);
229
                }
230
            }
231
        }
232
233
        $id = "tv$name";
234
        switch ($format) {
235
            case 'image':
236
                $images = parseInput($value, '||', 'array');
237
                foreach ($images as $image) {
0 ignored issues
show
Bug introduced by
The expression $images of type array|string is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
238
                    if (!is_array($image)) {
239
                        $image = explode('==', $image);
240
                    }
241
                    $src = $image[0];
242
243
                    if ($src) {
244
                        // We have a valid source
245
                        $attributes = '';
246
                        $attr = array(
247
                            'class' => $params['class'],
248
                            'src'   => $src,
249
                            'id'    => ($params['id'] ? $params['id'] : ''),
250
                            'alt'   => $modx->getPhpCompat()->htmlspecialchars($params['alttext']),
251
                            'style' => $params['style']
252
                        );
253 View Code Duplication
                        if (isset($params['align']) && $params['align'] != 'none') {
254
                            $attr['align'] = $params['align'];
255
                        }
256 View Code Duplication
                        foreach ($attr as $k => $v) {
257
                            $attributes .= ($v ? ' ' . $k . '="' . $v . '"' : '');
258
                        }
259
                        $attributes .= ' ' . $params['attrib'];
260
261
                        // Output the image with attributes
262
                        $o .= '<img' . rtrim($attributes) . ' />';
263
                    }
264
                }
265
                break;
266
267
            case "delim":    // display as delimitted list
268
                $value = parseInput($value, "||");
269
                $p = $params['format'] ? $params['format'] : " ";
270
                if ($p == "\\n") {
271
                    $p = "\n";
272
                }
273
                $o = str_replace("||", $p, $value);
274
                break;
275
276
            case "string":
277
                $value = parseInput($value);
278
                $format = strtolower($params['format']);
279
                if ($format == 'upper case') {
280
                    $o = strtoupper($value);
281
                } else {
282
                    if ($format == 'lower case') {
283
                        $o = strtolower($value);
284
                    } else {
285
                        if ($format == 'sentence case') {
286
                            $o = ucfirst($value);
287
                        } else {
288
                            if ($format == 'capitalize') {
289
                                $o = ucwords($value);
290
                            } else {
291
                                $o = $value;
292
                            }
293
                        }
294
                    }
295
                }
296
                break;
297
298
            case "date":
299
                if ($value != '' || $params['default'] == 'Yes') {
300
                    if (empty($value)) {
301
                        $value = 'now';
302
                    }
303
                    $timestamp = getUnixtimeFromDateString($value);
304
                    $p = $params['format'] ? $params['format'] : "%A %d, %B %Y";
305
                    $o = strftime($p, $timestamp);
306
                } else {
307
                    $value = '';
0 ignored issues
show
Unused Code introduced by
$value 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...
308
                }
309
                break;
310
311
            case "hyperlink":
312
                $value = parseInput($value, "||", "array");
313
                $o = '';
314
                $countValue = count($value);
315
                for ($i = 0; $i < $countValue; $i++) {
316
                    list($name, $url) = is_array($value[$i]) ? $value[$i] : explode("==", $value[$i]);
317
                    if (!$url) {
318
                        $url = $name;
319
                    }
320
                    if ($url) {
321
                        if ($o) {
322
                            $o .= '<br />';
323
                        }
324
                        $attributes = '';
325
                        // setup the link attributes
326
                        $attr = array(
327
                            'href'   => $url,
328
                            'title'  => $params['title'] ? $modx->getPhpCompat()->htmlspecialchars($params['title']) : $name,
329
                            'class'  => $params['class'],
330
                            'style'  => $params['style'],
331
                            'target' => $params['target'],
332
                        );
333 View Code Duplication
                        foreach ($attr as $k => $v) {
334
                            $attributes .= ($v ? ' ' . $k . '="' . $v . '"' : '');
335
                        }
336
                        $attributes .= ' ' . $params['attrib']; // add extra
337
338
                        // Output the link
339
                        $o .= '<a' . rtrim($attributes) . '>' . ($params['text'] ? $modx->getPhpCompat()->htmlspecialchars($params['text']) : $name) . '</a>';
340
                    }
341
                }
342
                break;
343
344
            case "htmltag":
345
                $value = parseInput($value, "||", "array");
346
                $tagid = $params['tagid'];
347
                $tagname = ($params['tagname']) ? $params['tagname'] : 'div';
348
                $o = '';
349
                // Loop through a list of tags
350
                $countValue = count($value);
351
                for ($i = 0; $i < $countValue; $i++) {
352
                    $tagvalue = is_array($value[$i]) ? implode(' ', $value[$i]) : $value[$i];
353
                    if (!$tagvalue) {
354
                        continue;
355
                    }
356
357
                    $attributes = '';
358
                    $attr = array(
359
                        'id'    => ($tagid ? $tagid : $id),
360
                        // 'tv' already added to id
361
                        'class' => $params['class'],
362
                        'style' => $params['style'],
363
                    );
364 View Code Duplication
                    foreach ($attr as $k => $v) {
365
                        $attributes .= ($v ? ' ' . $k . '="' . $v . '"' : '');
366
                    }
367
                    $attributes .= ' ' . $params['attrib']; // add extra
368
369
                    // Output the HTML Tag
370
                    $o .= '<' . $tagname . rtrim($attributes) . '>' . $tagvalue . '</' . $tagname . '>';
371
                }
372
                break;
373
374
            case "richtext":
375
                $value = parseInput($value);
376
                $w = $params['w'] ? $params['w'] : '100%';
377
                $h = $params['h'] ? $params['h'] : '400px';
378
                $richtexteditor = $params['edt'] ? $params['edt'] : "";
379
                $o = '<div class="MODX_RichTextWidget"><textarea id="' . $id . '" name="' . $id . '" style="width:' . $w . '; height:' . $h . ';">';
380
                $o .= $modx->getPhpCompat()->htmlspecialchars($value);
381
                $o .= '</textarea></div>';
382
                $replace_richtext = array($id);
383
                // setup editors
384
                if (!empty($replace_richtext) && !empty($richtexteditor)) {
385
                    // invoke OnRichTextEditorInit event
386
                    $evtOut = $modx->invokeEvent("OnRichTextEditorInit", array(
387
                        'editor'      => $richtexteditor,
388
                        'elements'    => $replace_richtext,
389
                        'forfrontend' => 1,
390
                        'width'       => $w,
391
                        'height'      => $h
392
                    ));
393
                    if (is_array($evtOut)) {
394
                        $o .= implode("", $evtOut);
395
                    }
396
                }
397
                break;
398
399
            case "unixtime":
400
                $value = parseInput($value);
401
                $o = getUnixtimeFromDateString($value);
0 ignored issues
show
Bug introduced by
It seems like $value defined by parseInput($value) on line 400 can also be of type array; however, getUnixtimeFromDateString() does only seem to accept 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...
402
                break;
403
404
            case "viewport":
405
                $value = parseInput($value);
406
                $id = '_' . time();
407
                if (!$params['vpid']) {
408
                    $params['vpid'] = $id;
409
                }
410
                $sTag = "<iframe";
411
                $eTag = "</iframe>";
412
                $autoMode = "0";
413
                $w = $params['width'];
414
                $h = $params['height'];
415
                if ($params['stretch'] == 'Yes') {
416
                    $w = "100%";
417
                    $h = "100%";
418
                }
419
                if ($params['asize'] == 'Yes' || ($params['awidth'] == 'Yes' && $params['aheight'] == 'Yes')) {
420
                    $autoMode = "3";  //both
421
                } else {
422
                    if ($params['awidth'] == 'Yes') {
423
                        $autoMode = "1"; //width only
424
                    } else {
425
                        if ($params['aheight'] == 'Yes') {
426
                            $autoMode = "2";    //height only
427
                        }
428
                    }
429
                }
430
431
                $modx->regClientStartupScript(MODX_MANAGER_URL . "media/script/bin/viewport.js", array(
432
                    'name'      => 'viewport',
433
                    'version'   => '0',
434
                    'plaintext' => false
435
                ));
436
                $o = $sTag . " id='" . $params['vpid'] . "' name='" . $params['vpid'] . "' ";
437
                if ($params['class']) {
438
                    $o .= " class='" . $params['class'] . "' ";
439
                }
440
                if ($params['style']) {
441
                    $o .= " style='" . $params['style'] . "' ";
442
                }
443
                if ($params['attrib']) {
444
                    $o .= $params['attrib'] . " ";
445
                }
446
                $o .= "scrolling='" . ($params['sbar'] == 'No' ? "no" : ($params['sbar'] == 'Yes' ? "yes" : "auto")) . "' ";
447
                $o .= "src='" . $value . "' frameborder='" . $params['borsize'] . "' ";
448
                $o .= "onload=\"window.setTimeout('ResizeViewPort(\\'" . $params['vpid'] . "\\'," . $autoMode . ")',100);\" width='" . $w . "' height='" . $h . "' ";
449
                $o .= ">";
450
                $o .= $eTag;
451
                break;
452
453
            case "datagrid":
454
                $grd = new \EvolutionCMS\Support\DataGrid('', $value);
455
456
                $grd->noRecordMsg = $params['egmsg'];
457
458
                $grd->columnHeaderClass = $params['chdrc'];
459
                $grd->cssClass = $params['tblc'];
460
                $grd->itemClass = $params['itmc'];
461
                $grd->altItemClass = $params['aitmc'];
462
463
                $grd->columnHeaderStyle = $params['chdrs'];
464
                $grd->cssStyle = $params['tbls'];
465
                $grd->itemStyle = $params['itms'];
466
                $grd->altItemStyle = $params['aitms'];
467
468
                $grd->columns = $params['cols'];
469
                $grd->fields = $params['flds'];
470
                $grd->colWidths = $params['cwidth'];
471
                $grd->colAligns = $params['calign'];
472
                $grd->colColors = $params['ccolor'];
473
                $grd->colTypes = $params['ctype'];
474
475
                $grd->cellPadding = $params['cpad'];
476
                $grd->cellSpacing = $params['cspace'];
477
                $grd->header = $params['head'];
478
                $grd->footer = $params['foot'];
479
                $grd->pageSize = $params['psize'];
480
                $grd->pagerLocation = $params['ploc'];
481
                $grd->pagerClass = $params['pclass'];
482
                $grd->pagerStyle = $params['pstyle'];
483
                $o = $grd->render();
484
                break;
485
486
            case 'htmlentities':
487
                $value = parseInput($value);
488
                if ($tvtype == 'checkbox' || $tvtype == 'listbox-multiple') {
489
                    // remove delimiter from checkbox and listbox-multiple TVs
490
                    $value = str_replace('||', '', $value);
491
                }
492
                $o = htmlentities($value, ENT_NOQUOTES, $modx->getConfig('modx_charset'));
493
                break;
494
495
            case 'custom_widget':
496
                $widget_output = '';
497
                $o = '';
498
                /* If we are loading a file */
499
                if (substr($params['output'], 0, 5) == "@FILE") {
500
                    $file_name = MODX_BASE_PATH . trim(substr($params['output'], 6));
501
                    if (!file_exists($file_name)) {
502
                        $widget_output = $file_name . ' does not exist';
503
                    } else {
504
                        $widget_output = file_get_contents($file_name);
505
                    }
506
                } elseif (substr($params['output'], 0, 8) == '@INCLUDE') {
507
                    $file_name = MODX_BASE_PATH . trim(substr($params['output'], 9));
508
                    if (!file_exists($file_name)) {
509
                        $widget_output = $file_name . ' does not exist';
510
                    } else {
511
                        /* The included file needs to set $widget_output. Can be string, array, object */
512
                        include $file_name;
513
                    }
514
                } elseif (substr($params['output'], 0, 6) == '@CHUNK' && $value !== '') {
515
                    $chunk_name = trim(substr($params['output'], 7));
516
                    $widget_output = $modx->getChunk($chunk_name);
517
                } elseif (substr($params['output'], 0, 5) == '@EVAL' && $value !== '') {
518
                    $eval_str = trim(substr($params['output'], 6));
519
                    $widget_output = eval($eval_str);
520
                } elseif ($value !== '') {
521
                    $widget_output = $params['output'];
522
                } else {
523
                    $widget_output = '';
524
                }
525
                if (is_string($widget_output)) {
526
                    $_ = $modx->getConfig('enable_filter');
527
                    $modx->setConfig('enable_filter', 1);
528
                    $widget_output = $modx->parseText($widget_output, array('value' => $value));
529
                    $modx->setConfig('enable_filter', $_);
530
                    $o = $modx->parseDocumentSource($widget_output);
531
                } else {
532
                    $o = $widget_output;
533
                }
534
                break;
535
536
            default:
537
                $value = parseInput($value);
538
                if ($tvtype == 'checkbox' || $tvtype == 'listbox-multiple') {
539
                    // add separator
540
                    $value = explode('||', $value);
541
                    $value = implode($sep, $value);
542
                }
543
                $o = $value;
544
                break;
545
        }
546
547
        return $o;
548
    }
549
}
550
551
if (! function_exists('decodeParamValue')) {
552
    /**
553
     * @param string $s
554
     * @return string
555
     */
556
    function decodeParamValue($s)
557
    {
558
        $s = str_replace("%3D", '=', $s); // =
559
560
        return str_replace("%26", '&', $s); // &
561
    }
562
}
563
564
if (! function_exists('parseInput')) {
565
    /**
566
     * returns an array if a delimiter is present. returns array is a recordset is present
567
     *
568
     * @param $src
569
     * @param string $delim
570
     * @param string $type
571
     * @param bool $columns
572
     * @return array|string
573
     */
574
    function parseInput($src, $delim = "||", $type = "string", $columns = true)
575
    { // type can be: string, array
576
        $modx = evolutionCMS();
577
        if ($modx->getDatabase()->isResult($src)) {
578
            // must be a recordset
579
            $rows = array();
580
            while ($cols = $modx->getDatabase()->getRow($src, 'num')) {
581
                $rows[] = ($columns) ? $cols : implode(" ", $cols);
582
            }
583
584
            return ($type == "array") ? $rows : implode($delim, $rows);
585
        } else {
586
            // must be a text
587
            if ($type == "array") {
588
                return explode($delim, $src);
589
            } else {
590
                return $src;
591
            }
592
        }
593
    }
594
}
595
596
if (! function_exists('getUnixtimeFromDateString')) {
597
    /**
598
     * @param string $value
599
     * @return bool|false|int
600
     */
601
    function getUnixtimeFromDateString($value)
602
    {
603
        $timestamp = false;
604
        // Check for MySQL or legacy style date
605
        $date_match_1 = '/^([0-9]{2})-([0-9]{2})-([0-9]{4})\ ([0-9]{2}):([0-9]{2}):([0-9]{2})$/';
606
        $date_match_2 = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})\ ([0-9]{2}):([0-9]{2}):([0-9]{2})$/';
607
        $matches = array();
608
        if (strpos($value, '-') !== false) {
609
            if (preg_match($date_match_1, $value, $matches)) {
610
                $timestamp = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[1], $matches[3]);
611
            } elseif (preg_match($date_match_2, $value, $matches)) {
612
                $timestamp = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
613
            }
614
        }
615
        // If those didn't work, use strtotime to figure out the date
616
        if ($timestamp === false || $timestamp === -1) {
617
            $timestamp = strtotime($value);
618
        }
619
620
        return $timestamp;
621
    }
622
}
623
624
if (! function_exists('renderFormElement')) {
625
    /**
626
     * DISPLAY FORM ELEMENTS
627
     *
628
     * @param string $field_type
629
     * @param string $field_id
630
     * @param string $default_text
631
     * @param string $field_elements
632
     * @param string $field_value
633
     * @param string $field_style
634
     * @param array $row
635
     * @param array $tvsArray
636
     * @return string
637
     */
638
    function renderFormElement(
639
        $field_type,
640
        $field_id,
641
        $default_text = '',
642
        $field_elements = '',
643
        $field_value = '',
644
        $field_style = '',
645
        $row = array(),
646
        $tvsArray = array()
647
    ) {
648
        $modx = evolutionCMS();
649
        global $_style;
650
        global $_lang;
651
        global $content;
652
        global $which_browser;
653
654
        if (substr($default_text, 0, 6) === '@@EVAL' && $field_value === $default_text) {
655
            $eval_str = trim(substr($default_text, 7));
656
            $default_text = eval($eval_str);
657
            $field_value = $default_text;
658
        }
659
660
        $field_html = '';
661
        $cimode = strpos($field_type, ':');
662
        if ($cimode === false) {
663
            switch ($field_type) {
664
665
                case "text": // handler for regular text boxes
666 View Code Duplication
                case "rawtext"; // non-htmlentity converted text boxes
667
                    $field_html .= '<input type="text" id="tv' . $field_id . '" name="tv' . $field_id . '" value="' . $modx->getPhpCompat()->htmlspecialchars($field_value) . '" ' . $field_style . ' tvtype="' . $field_type . '" onchange="documentDirty=true;" style="width:100%" />';
668
                    break;
669 View Code Duplication
                case "email": // handles email input fields
670
                    $field_html .= '<input type="email" id="tv' . $field_id . '" name="tv' . $field_id . '" value="' . $modx->getPhpCompat()->htmlspecialchars($field_value) . '" ' . $field_style . ' tvtype="' . $field_type . '" onchange="documentDirty=true;" style="width:100%"/>';
671
                    break;
672 View Code Duplication
                case "number": // handles the input of numbers
673
                    $field_html .= '<input type="number" id="tv' . $field_id . '" name="tv' . $field_id . '" value="' . $modx->getPhpCompat()->htmlspecialchars($field_value) . '" ' . $field_style . ' tvtype="' . $field_type . '" onchange="documentDirty=true;" style="width:100%" onkeyup="this.value=this.value.replace(/[^\d-,.+]/,\'\')"/>';
674
                    break;
675 View Code Duplication
                case "textareamini": // handler for textarea mini boxes
676
                    $field_html .= '<textarea id="tv' . $field_id . '" name="tv' . $field_id . '" cols="40" rows="5" onchange="documentDirty=true;" style="width:100%">' . $modx->getPhpCompat()->htmlspecialchars($field_value) . '</textarea>';
677
                    break;
678
                case "textarea": // handler for textarea boxes
679
                case "rawtextarea": // non-htmlentity convertex textarea boxes
680
                case "htmlarea": // handler for textarea boxes (deprecated)
681 View Code Duplication
                case "richtext": // handler for textarea boxes
682
                    $field_html .= '<textarea id="tv' . $field_id . '" name="tv' . $field_id . '" cols="40" rows="15" onchange="documentDirty=true;" style="width:100%">' . $modx->getPhpCompat()->htmlspecialchars($field_value) . '</textarea>';
683
                    break;
684
                case "date":
685
                    $field_id = str_replace(array(
686
                        '-',
687
                        '.'
688
                    ), '_', urldecode($field_id));
689
                    if ($field_value == '') {
690
                        $field_value = 0;
691
                    }
692
                    $field_html .= '<input id="tv' . $field_id . '" name="tv' . $field_id . '" class="DatePicker" type="text" value="' . ($field_value == 0 || !isset($field_value) ? "" : $field_value) . '" onblur="documentDirty=true;" />';
693
                    $field_html .= ' <a onclick="document.forms[\'mutate\'].elements[\'tv' . $field_id . '\'].value=\'\';document.forms[\'mutate\'].elements[\'tv' . $field_id . '\'].onblur(); return true;" onmouseover="window.status=\'clear the date\'; return true;" onmouseout="window.status=\'\'; return true;" style="cursor:pointer; cursor:hand"><i class="' . $_style["actions_calendar_delete"] . '"></i></a>';
694
695
                    break;
696 View Code Duplication
                case "dropdown": // handler for select boxes
697
                    $field_html .= '<select id="tv' . $field_id . '" name="tv' . $field_id . '" size="1" onchange="documentDirty=true;">';
698
                    $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id, '', 'tvform',
699
                        $tvsArray));
700
                    foreach($index_list as $item => $itemvalue) {
701
                        list($item, $itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==", $itemvalue);
702
                        if (strlen($itemvalue) == 0) {
703
                            $itemvalue = $item;
704
                        }
705
                        $field_html .= '<option value="' . $modx->getPhpCompat()->htmlspecialchars($itemvalue) . '"' . ($itemvalue == $field_value ? ' selected="selected"' : '') . '>' . $modx->getPhpCompat()->htmlspecialchars($item) . '</option>';
706
                    }
707
                    $field_html .= "</select>";
708
                    break;
709 View Code Duplication
                case "listbox": // handler for select boxes
710
                    $field_html .= '<select id="tv' . $field_id . '" name="tv' . $field_id . '" onchange="documentDirty=true;" size="8">';
711
                    $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id, '', 'tvform',
712
                        $tvsArray));
713
                    foreach($index_list as $item => $itemvalue) {
714
                        list($item, $itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==", $itemvalue);
715
                        if (strlen($itemvalue) == 0) {
716
                            $itemvalue = $item;
717
                        }
718
                        $field_html .= '<option value="' . $modx->getPhpCompat()->htmlspecialchars($itemvalue) . '"' . ($itemvalue == $field_value ? ' selected="selected"' : '') . '>' . $modx->getPhpCompat()->htmlspecialchars($item) . '</option>';
719
                    }
720
                    $field_html .= "</select>";
721
                    break;
722
                case "listbox-multiple": // handler for select boxes where you can choose multiple items
723
                    $field_value = explode("||", $field_value);
724
                    $field_html .= '<select id="tv' . $field_id . '" name="tv' . $field_id . '[]" multiple="multiple" onchange="documentDirty=true;" size="8">';
725
                    $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id, '', 'tvform',
726
                        $tvsArray));
727
                    foreach($index_list as $item => $itemvalue) {
728
                        list($item, $itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==", $itemvalue);
729
                        if (strlen($itemvalue) == 0) {
730
                            $itemvalue = $item;
731
                        }
732
                        $field_html .= '<option value="' . $modx->getPhpCompat()->htmlspecialchars($itemvalue) . '"' . (in_array($itemvalue,
733
                                $field_value) ? ' selected="selected"' : '') . '>' . $modx->getPhpCompat()->htmlspecialchars($item) . '</option>';
734
                    }
735
                    $field_html .= "</select>";
736
                    break;
737
                case "url": // handles url input fields
738
                    $urls = array(
739
                        ''         => '--',
740
                        'http://'  => 'http://',
741
                        'https://' => 'https://',
742
                        'ftp://'   => 'ftp://',
743
                        'mailto:'  => 'mailto:'
744
                    );
745
                    $field_html = '<table border="0" cellspacing="0" cellpadding="0"><tr><td><select id="tv' . $field_id . '_prefix" name="tv' . $field_id . '_prefix" onchange="documentDirty=true;">';
746
                    foreach ($urls as $k => $v) {
747
                        if (strpos($field_value, $v) === false) {
748
                            $field_html .= '<option value="' . $v . '">' . $k . '</option>';
749
                        } else {
750
                            $field_value = str_replace($v, '', $field_value);
751
                            $field_html .= '<option value="' . $v . '" selected="selected">' . $k . '</option>';
752
                        }
753
                    }
754
                    $field_html .= '</select></td><td>';
755
                    $field_html .= '<input type="text" id="tv' . $field_id . '" name="tv' . $field_id . '" value="' . $modx->getPhpCompat()->htmlspecialchars($field_value) . '" width="100" ' . $field_style . ' onchange="documentDirty=true;" /></td></tr></table>';
756
                    break;
757
                case 'checkbox': // handles check boxes
758
                    $values = !is_array($field_value) ? explode('||', $field_value) : $field_value;
759
                    $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id, '', 'tvform',
760
                        $tvsArray));
761
                    $tpl = '<label class="checkbox"><input type="checkbox" value="%s" id="tv_%s" name="tv%s[]" %s onchange="documentDirty=true;" />%s</label><br />';
762
                    static $i = 0;
763
                    $_ = array();
764
                    foreach ($index_list as $c => $item) {
765
                        if (is_array($item)) {
766
                            $name = trim($item[0]);
767
                            $value = isset($item[1]) ? $item[1] : $name;
768
                        } else {
769
                            $item = trim($item);
770
                            list($name, $value) = (strpos($item, '==') !== false) ? explode('==', $item, 2) : array(
771
                                $item,
772
                                $item
773
                            );
774
                        }
775
                        $checked = in_array($value, $values) ? ' checked="checked"' : '';
776
                        $param = array(
777
                            $modx->getPhpCompat()->htmlspecialchars($value),
778
                            $i,
779
                            $field_id,
780
                            $checked,
781
                            $name
782
                        );
783
                        $_[] = vsprintf($tpl, $param);
784
                        $i++;
785
                    }
786
                    $field_html = implode("\n", $_);
787
                    break;
788
                case "option": // handles radio buttons
789
                    $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id, '', 'tvform',
790
                        $tvsArray));
791
                    static $i = 0;
792
                    foreach($index_list as $item => $itemvalue) {
793
                        list($item, $itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==", $itemvalue);
794
                        if (strlen($itemvalue) == 0) {
795
                            $itemvalue = $item;
796
                        }
797
                        $field_html .= '<input type="radio" value="' . $modx->getPhpCompat()->htmlspecialchars($itemvalue) . '" id="tv_' . $i . '" name="tv' . $field_id . '" ' . ($itemvalue == $field_value ? 'checked="checked"' : '') . ' onchange="documentDirty=true;" /><label for="tv_' . $i . '" class="radio">' . $item . '</label><br />';
798
                        $i++;
799
                    }
800
                    break;
801 View Code Duplication
                case "image": // handles image fields using htmlarea image manager
802
                    global $_lang;
803
                    global $ResourceManagerLoaded;
804
                    global $content, $use_editor, $which_editor;
805
                    if (!$ResourceManagerLoaded && !(($content['richtext'] == 1 || $modx->getManagerApi()->action == 4) && $use_editor == 1 && $which_editor == 3)) {
806
                        $field_html .= "
807
						<script type=\"text/javascript\">
808
							/* <![CDATA[ */
809
								var lastImageCtrl;
810
								var lastFileCtrl;
811
								function OpenServerBrowser(url, width, height ) {
812
									var iLeft = (screen.width  - width) / 2 ;
813
									var iTop  = (screen.height - height) / 2 ;
814
815
									var sOptions = 'toolbar=no,status=no,resizable=yes,dependent=yes' ;
816
									sOptions += ',width=' + width ;
817
									sOptions += ',height=' + height ;
818
									sOptions += ',left=' + iLeft ;
819
									sOptions += ',top=' + iTop ;
820
821
									var oWindow = window.open( url, 'FCKBrowseWindow', sOptions ) ;
822
								}			
823
								function BrowseServer(ctrl) {
824
									lastImageCtrl = ctrl;
825
									var w = screen.width * 0.5;
826
									var h = screen.height * 0.5;
827
									OpenServerBrowser('" . MODX_MANAGER_URL . "media/browser/{$which_browser}/browser.php?Type=images', w, h);
828
								}
829
								function BrowseFileServer(ctrl) {
830
									lastFileCtrl = ctrl;
831
									var w = screen.width * 0.5;
832
									var h = screen.height * 0.5;
833
									OpenServerBrowser('" . MODX_MANAGER_URL . "media/browser/{$which_browser}/browser.php?Type=files', w, h);
834
								}
835
								function SetUrlChange(el) {
836
									if ('createEvent' in document) {
837
										var evt = document.createEvent('HTMLEvents');
838
										evt.initEvent('change', false, true);
839
										el.dispatchEvent(evt);
840
									} else {
841
										el.fireEvent('onchange');
842
									}
843
								}
844
								function SetUrl(url, width, height, alt) {
845
									if(lastFileCtrl) {
846
										var c = document.getElementById(lastFileCtrl);
847
										if(c && c.value != url) {
848
										    c.value = url;
849
											SetUrlChange(c);
850
										}
851
										lastFileCtrl = '';
852
									} else if(lastImageCtrl) {
853
										var c = document.getElementById(lastImageCtrl);
854
										if(c && c.value != url) {
855
										    c.value = url;
856
											SetUrlChange(c);
857
										}
858
										lastImageCtrl = '';
859
									} else {
860
										return;
861
									}
862
								}
863
							/* ]]> */
864
						</script>";
865
                        $ResourceManagerLoaded = true;
866
                    }
867
                    $field_html .= '<input type="text" id="tv' . $field_id . '" name="tv' . $field_id . '"  value="' . $field_value . '" ' . $field_style . ' onchange="documentDirty=true;" /><input type="button" value="' . $_lang['insert'] . '" onclick="BrowseServer(\'tv' . $field_id . '\')" />';
868
                    break;
869 View Code Duplication
                case "file": // handles the input of file uploads
870
                    /* Modified by Timon for use with resource browser */
871
                    global $_lang;
872
                    global $ResourceManagerLoaded;
873
                    global $content, $use_editor, $which_editor;
874
                    if (!$ResourceManagerLoaded && !(($content['richtext'] == 1 || $modx->getManagerApi()->action == 4) && $use_editor == 1 && $which_editor == 3)) {
875
                        /* I didn't understand the meaning of the condition above, so I left it untouched ;-) */
876
                        $field_html .= "
877
						<script type=\"text/javascript\">
878
							/* <![CDATA[ */
879
								var lastImageCtrl;
880
								var lastFileCtrl;
881
								function OpenServerBrowser(url, width, height ) {
882
									var iLeft = (screen.width  - width) / 2 ;
883
									var iTop  = (screen.height - height) / 2 ;
884
885
									var sOptions = 'toolbar=no,status=no,resizable=yes,dependent=yes' ;
886
									sOptions += ',width=' + width ;
887
									sOptions += ',height=' + height ;
888
									sOptions += ',left=' + iLeft ;
889
									sOptions += ',top=' + iTop ;
890
891
									var oWindow = window.open( url, 'FCKBrowseWindow', sOptions ) ;
892
								}
893
								function BrowseServer(ctrl) {
894
									lastImageCtrl = ctrl;
895
									var w = screen.width * 0.5;
896
									var h = screen.height * 0.5;
897
									OpenServerBrowser('" . MODX_MANAGER_URL . "media/browser/{$which_browser}/browser.php?Type=images', w, h);
898
								}
899
								function BrowseFileServer(ctrl) {
900
									lastFileCtrl = ctrl;
901
									var w = screen.width * 0.5;
902
									var h = screen.height * 0.5;
903
									OpenServerBrowser('" . MODX_MANAGER_URL . "media/browser/{$which_browser}/browser.php?Type=files', w, h);
904
								}
905
								function SetUrlChange(el) {
906
									if ('createEvent' in document) {
907
										var evt = document.createEvent('HTMLEvents');
908
										evt.initEvent('change', false, true);
909
										el.dispatchEvent(evt);
910
									} else {
911
										el.fireEvent('onchange');
912
									}
913
								}
914
								function SetUrl(url, width, height, alt) {
915
									if(lastFileCtrl) {
916
										var c = document.getElementById(lastFileCtrl);
917
										if(c && c.value != url) {
918
										    c.value = url;
919
											SetUrlChange(c);
920
										}
921
										lastFileCtrl = '';
922
									} else if(lastImageCtrl) {
923
										var c = document.getElementById(lastImageCtrl);
924
										if(c && c.value != url) {
925
										    c.value = url;
926
											SetUrlChange(c);
927
										}
928
										lastImageCtrl = '';
929
									} else {
930
										return;
931
									}
932
								}
933
							/* ]]> */
934
						</script>";
935
                        $ResourceManagerLoaded = true;
936
                    }
937
                    $field_html .= '<input type="text" id="tv' . $field_id . '" name="tv' . $field_id . '"  value="' . $field_value . '" ' . $field_style . ' onchange="documentDirty=true;" /><input type="button" value="' . $_lang['insert'] . '" onclick="BrowseFileServer(\'tv' . $field_id . '\')" />';
938
939
                    break;
940
941
                case 'custom_tv':
942
                    $custom_output = '';
943
                    /* If we are loading a file */
944
                    if (substr($field_elements, 0, 5) == "@FILE") {
945
                        $file_name = MODX_BASE_PATH . trim(substr($field_elements, 6));
946
                        if (!file_exists($file_name)) {
947
                            $custom_output = $file_name . ' does not exist';
948
                        } else {
949
                            $custom_output = file_get_contents($file_name);
950
                        }
951
                    } elseif (substr($field_elements, 0, 8) == '@INCLUDE') {
952
                        $file_name = MODX_BASE_PATH . trim(substr($field_elements, 9));
953 View Code Duplication
                        if (!file_exists($file_name)) {
954
                            $custom_output = $file_name . ' does not exist';
955
                        } else {
956
                            ob_start();
957
                            include $file_name;
958
                            $custom_output = ob_get_contents();
959
                            ob_end_clean();
960
                        }
961
                    } elseif (substr($field_elements, 0, 6) == "@CHUNK") {
962
                        $chunk_name = trim(substr($field_elements, 7));
963
                        $chunk_body = $modx->getChunk($chunk_name);
964
                        if ($chunk_body == false) {
965
                            $custom_output = $_lang['chunk_no_exist'] . '(' . $_lang['htmlsnippet_name'] . ':' . $chunk_name . ')';
966
                        } else {
967
                            $custom_output = $chunk_body;
968
                        }
969
                    } elseif (substr($field_elements, 0, 5) == "@EVAL") {
970
                        $eval_str = trim(substr($field_elements, 6));
971
                        $custom_output = eval($eval_str);
972
                    } else {
973
                        $custom_output = $field_elements;
974
                    }
975
                    $replacements = array(
976
                        '[+field_type+]'   => $field_type,
977
                        '[+field_id+]'     => $field_id,
978
                        '[+default_text+]' => $default_text,
979
                        '[+field_value+]'  => $modx->getPhpCompat()->htmlspecialchars($field_value),
980
                        '[+field_style+]'  => $field_style,
981
                    );
982
                    $custom_output = str_replace(array_keys($replacements), $replacements, $custom_output);
983
                    $modx->documentObject = $content;
984
                    $modx->documentIdentifier = $content['id'];
985
                    $custom_output = $modx->parseDocumentSource($custom_output);
986
                    $field_html .= $custom_output;
987
                    break;
988
989 View Code Duplication
                default: // the default handler -- for errors, mostly
990
                    $field_html .= '<input type="text" id="tv' . $field_id . '" name="tv' . $field_id . '" value="' . $modx->getPhpCompat()->htmlspecialchars($field_value) . '" ' . $field_style . ' onchange="documentDirty=true;" />';
991
992
            } // end switch statement
993
        } else {
994
            $custom = explode(":", $field_type);
995
            $custom_output = '';
996
            $file_name = MODX_BASE_PATH . 'assets/tvs/' . $custom['1'] . '/' . $custom['1'] . '.customtv.php';
997 View Code Duplication
            if (!file_exists($file_name)) {
998
                $custom_output = $file_name . ' does not exist';
999
            } else {
1000
                ob_start();
1001
                include $file_name;
1002
                $custom_output = ob_get_contents();
1003
                ob_end_clean();
1004
            }
1005
            $replacements = array(
1006
                '[+field_type+]'   => $field_type,
1007
                '[+field_id+]'     => $field_id,
1008
                '[+default_text+]' => $default_text,
1009
                '[+field_value+]'  => $modx->getPhpCompat()->htmlspecialchars($field_value),
1010
                '[+field_style+]'  => $field_style,
1011
            );
1012
            $custom_output = str_replace(array_keys($replacements), $replacements, $custom_output);
1013
            $modx->documentObject = $content;
1014
            $custom_output = $modx->parseDocumentSource($custom_output);
1015
            $field_html .= $custom_output;
1016
        }
1017
1018
        return $field_html;
1019
    } // end renderFormElement function
1020
}
1021
1022
if (! function_exists('ParseIntputOptions')) {
1023
    /**
1024
     * @param string|array|mysqli_result $v
1025
     * @return array
1026
     */
1027
    function ParseIntputOptions($v)
1028
    {
1029
        $modx = evolutionCMS();
1030
        $a = array();
1031
        if (is_array($v)) {
1032
            return $v;
1033
        } else {
1034
            if ($modx->getDatabase()->isResult($v)) {
1035
                /**
1036
                 * @todo May be, should use DBAPI::makeArray($v);
1037
                 */
1038
                while ($cols = $modx->getDatabase()->getRow($v, 'num')) {
1039
                    $a[] = $cols;
1040
                }
1041
            } else {
1042
                $a = explode("||", $v);
1043
            }
1044
        }
1045
1046
        return $a;
1047
    }
1048
}
1049