MyTextSanitizer::htmlSpecialChars()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 8
c 0
b 0
f 0
nc 4
nop 4
dl 0
loc 13
rs 9.6111
1
<?php
2
/**
3
 * XOOPS TextSanitizer extension
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2021 XOOPS Project (https://xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             class
15
 * @since               2.0.0
16
 * @author              Kazumi Ono (http://www.myweb.ne.jp/, http://jp.xoops.org/)
17
 * @author              Goghs Cheng (http://www.eqiao.com, http://www.devbeez.com/)
18
 * @author              Taiwen Jiang <[email protected]>
19
 */
20
21
/**
22
 * Abstract class for extensions
23
 *
24
 * @author              Taiwen Jiang <[email protected]>
25
 * @copyright       (c) 2000-2021 XOOPS Project (https://xoops.org)
26
 */
27
class MyTextSanitizerExtension
28
{
29
    public $instance;
30
    public $myts;
31
    public $config;
32
    public $image_path;
33
34
    /**
35
     * Constructor
36
     *
37
     * @param MyTextSanitizer $myts
38
     */
39
    public function __construct(MyTextSanitizer $myts)
40
    {
41
        $this->myts         = $myts;
42
        $this->image_path = XOOPS_URL . '/images/form';
43
    }
44
45
    /**
46
     * loadConfig
47
     *
48
     * @param  string $path
49
     * @return string|array
50
     */
51
    public static function loadConfig($path = null)
52
    {
53
        $myts   = \MyTextSanitizer::getInstance();
54
        $extensionName = (null === $path) ? '' : basename($path);
55
        $pathDist = $myts->path_basic;
56
        $pathConfig = $myts->path_config;
57
58
        if ('' !== $extensionName) {
59
            $configFileName = $pathConfig . '/config.' . $extensionName . '.php';
60
            $distFileName = $pathDist . '/' . $extensionName . '/config.' . $extensionName . '.dist.php';
61
        } else {
62
            $configFileName = $pathConfig . '/config.php';
63
            $distFileName = $pathDist . '/config.dist.php';
64
        }
65
        if (!file_exists($configFileName)) {
66
            if (false === copy($distFileName, $configFileName)) {
67
                trigger_error('Could not create textsanitizer config file ' . basename($configFileName));
68
                return $a = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $a is dead and can be removed.
Loading history...
69
            }
70
        }
71
        $configs = include $configFileName;
72
        return $configs;
73
    }
74
75
    /**
76
     * Merge Config
77
     *
78
     * @param  array $config_default
79
     * @param  array $config_custom
80
     * @return array
81
     */
82
    public static function mergeConfig($config_default, $config_custom)
83
    {
84
        if (is_array($config_custom)) {
0 ignored issues
show
introduced by
The condition is_array($config_custom) is always true.
Loading history...
85
            foreach ($config_custom as $key => $val) {
86
                if (is_array($config_default[$key])) {
87
                    $config_default[$key] = self::mergeConfig($config_default[$key], $config_custom[$key]);
88
                } else {
89
                    $config_default[$key] = $val;
90
                }
91
            }
92
        }
93
94
        return $config_default;
95
    }
96
97
    /**
98
     * encode
99
     *
100
     * @param string $textarea_id id attribute of text area
101
     *
102
     * @return array
103
     */
104
    public function encode($textarea_id)
0 ignored issues
show
Unused Code introduced by
The parameter $textarea_id is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

104
    public function encode(/** @scrutinizer ignore-unused */ $textarea_id)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
    {
106
        return array(array(), array());
107
    }
108
109
    /**
110
     * decode
111
     *
112
     * @param string $url
113
     * @param string|integer $width
114
     * @param string|integer $height
115
     *
116
     * @return Null
117
     */
118
    public static function decode($url, $width, $height)
0 ignored issues
show
Unused Code introduced by
The parameter $height is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

118
    public static function decode($url, $width, /** @scrutinizer ignore-unused */ $height)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $width is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

118
    public static function decode($url, /** @scrutinizer ignore-unused */ $width, $height)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
119
    {
120
        return null;
121
    }
122
}
123
124
/**
125
 * Class to "clean up" text for various uses
126
 *
127
 * <strong>Singleton</strong>
128
 *
129
 * @package       kernel
130
 * @subpackage    core
131
 * @author        Kazumi Ono <[email protected]>
132
 * @author        Taiwen Jiang <[email protected]>
133
 * @author        Goghs Cheng
134
 * @copyright (c) 2000-2021 XOOPS Project (https://xoops.org)
135
 */
136
class MyTextSanitizer
137
{
138
    /**
139
     *
140
     * @var array
141
     */
142
    public $smileys = array();
143
144
    /**
145
     */
146
    public $censorConf;
147
148
    /**
149
     *
150
     * @var string holding reference to text
151
     */
152
    public $text         = '';
153
    public $patterns     = array();
154
    public $replacements = array();
155
    public $callbackPatterns = array();
156
    public $callbacks        = array();
157
158
    public $path_basic;
159
    public $path_config;
160
    public $path_plugin;
161
162
    public $config;
163
164
    /**
165
     * Constructor of this class
166
     *
167
     * Gets allowed html tags from admin config settings
168
     * <br> should not be allowed since nl2br will be used
169
     * when storing data.
170
     *
171
     * @access private
172
     */
173
174
    public function __construct()
175
    {
176
        $this->path_basic  = XOOPS_ROOT_PATH . '/class/textsanitizer';
177
        $this->path_config = XOOPS_VAR_PATH . '/configs/textsanitizer';
178
        $this->path_plugin = XOOPS_ROOT_PATH . '/Frameworks/textsanitizer';
179
        $this->config      = $this->loadConfig();
180
    }
181
182
    /**
183
     * Enter description here...
184
     *
185
     * @param  string $name
186
     * @return array|string
187
     */
188
    public function loadConfig($name = null)
189
    {
190
        // NB: sending a null name results in an infinite loop
191
        if (!empty($name)) {
192
            return MyTextSanitizerExtension::loadConfig($name);
193
        }
194
195
        $configFileName = $this->path_config . '/config.php';
196
        $distFileName = $this->path_basic . '/config.dist.php';
197
198
        if (!file_exists($configFileName)) {
199
            if (false===copy($distFileName, $configFileName)) {
200
                trigger_error('Could not create textsanitizer config file ' . basename($configFileName));
201
                return array();
202
            }
203
        }
204
        return include $configFileName;
205
    }
206
207
    /**
208
     * Enter description here...
209
     *
210
     * @param  array $config_default
211
     * @param  array $config_custom
212
     * @return mixed
213
     */
214
    public function mergeConfig($config_default, $config_custom)
215
    {
216
        if (is_array($config_custom)) {
0 ignored issues
show
introduced by
The condition is_array($config_custom) is always true.
Loading history...
217
            foreach ($config_custom as $key => $val) {
218
                if (isset($config_default[$key]) && \is_array($config_default[$key])) {
219
                    $config_default[$key] = $this->mergeConfig($config_default[$key], $config_custom[$key]);
220
                } else {
221
                    $config_default[$key] = $val;
222
                }
223
            }
224
        }
225
226
        return $config_default;
227
    }
228
229
    /**
230
     * Access the only instance of this class
231
     *
232
     * @return MyTextSanitizer
233
     */
234
    public static function getInstance()
235
    {
236
        static $instance;
237
        if (!isset($instance)) {
238
            $instance = new MyTextSanitizer();
239
        }
240
241
        return $instance;
242
    }
243
244
    /**
245
     * Get the smileys
246
     *
247
     * @param bool $isAll TRUE for all smileys, FALSE for smileys with display = 1
248
     *
249
     * @return array
250
     */
251
    public function getSmileys($isAll = true)
252
    {
253
        if (count($this->smileys) == 0) {
254
            /** @var XoopsMySQLDatabase $xoopsDB */
255
            $xoopsDB = XoopsDatabaseFactory::getDatabaseConnection();
256
            $sql     = 'SELECT * FROM ' . $xoopsDB->prefix('smiles');
257
            $result  = $xoopsDB->query($sql);
258
            if ($xoopsDB->isResultSet($result)) {
259
                while (false !== ($smiles = $xoopsDB->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

259
                while (false !== ($smiles = $xoopsDB->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
260
                    $this->smileys[] = $smiles;
261
                }
262
            }
263
        }
264
        if ($isAll) {
265
            return $this->smileys;
266
        }
267
268
        $smileys = array();
269
        foreach ($this->smileys as $smile) {
270
            if (empty($smile['display'])) {
271
                continue;
272
            }
273
            $smileys[] = $smile;
274
        }
275
276
        return $smileys;
277
    }
278
279
    /**
280
     * Replace emoticons in the message with smiley images
281
     *
282
     * @param  string $message
283
     * @return string
284
     */
285
    public function smiley($message)
286
    {
287
        $smileys = $this->getSmileys();
288
        foreach ($smileys as $smile) {
289
            $message = str_replace($smile['code'], '<img class="imgsmile" src="' . XOOPS_UPLOAD_URL . '/' . htmlspecialchars($smile['smile_url'], ENT_QUOTES | ENT_HTML5) . '" alt="" />', $message);
290
        }
291
292
        return $message;
293
    }
294
295
    /**
296
     * Callback to process email address match
297
     *
298
     * @param array $match array of matched elements
299
     *
300
     * @return string
301
     */
302
    protected function makeClickableCallbackEmailAddress($match)
303
    {
304
        $email = trim($match[0]);
305
        return '<a href="mailto:' . $email . '" title="' . $email . '">' . $email . '</a>';
306
    }
307
308
    /**
309
     * Make links in the text clickable
310
     * Presently handles email addresses and http, https, ftp and sftp urls
311
     * (Note: at this time, major browsers no longer directly handle ftp/sftp urls.)
312
     *
313
     * @param  string $text
314
     * @return string
315
     */
316
    public function makeClickable($text)
317
    {
318
        $pattern = "/(^|\s)([-_a-z0-9\'+*$^&%=~!?{}]+(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@[-a-z0-9.]+\.[a-z]{2,6})/i";
319
        $text = preg_replace_callback($pattern, function($matches) { return $matches[1] .$this->makeClickableCallbackEmailAddress(array($matches[2])); }, $text);
320
321
        $pattern = "/(?:\s+|^)(https?:\/\/)([-A-Z0-9.\_*?&:;=#\/\[\]\%@]+)/i";
322
        $replacement = '<a href="$1$2" target="_blank" rel="external noopener nofollow">$1$2</a>';
323
        $text = preg_replace($pattern, $replacement, $text);
324
325
        $pattern = "%(?:\s+|^)(s?ftp://)([-A-Z0-9./_*?&:;=#\[\]\%@]+)%i";
326
        $replacement = '<a href="$1$2" target="_blank" rel="external">$1$2</a>';
327
        $text = preg_replace($pattern, $replacement, $text);
328
329
        return $text;
330
    }
331
332
    /**
333
     * MyTextSanitizer::truncate()
334
     *
335
     * @param  mixed $text
336
     * @return mixed|string
337
     */
338
    public function truncate($text)
339
    {
340
        $instance = \MyTextSanitizer::getInstance();
341
        if (empty($text) || empty($instance->config['truncate_length']) || strlen($text) < $instance->config['truncate_length']) {
342
            return $text;
343
        }
344
        $len = floor($instance->config['truncate_length'] / 2);
345
        $ret = substr($text, 0, $len) . ' ... ' . substr($text, 5 - $len);
0 ignored issues
show
Bug introduced by
$len of type double is incompatible with the type integer|null expected by parameter $length of substr(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

345
        $ret = substr($text, 0, /** @scrutinizer ignore-type */ $len) . ' ... ' . substr($text, 5 - $len);
Loading history...
Bug introduced by
5 - $len of type double is incompatible with the type integer expected by parameter $offset of substr(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

345
        $ret = substr($text, 0, $len) . ' ... ' . substr($text, /** @scrutinizer ignore-type */ 5 - $len);
Loading history...
346
347
        return $ret;
348
    }
349
350
    /**
351
     * Replace XoopsCodes with their equivalent HTML formatting
352
     *
353
     * @param  string   $text
354
     * @param  bool|int $allowimage Allow images in the text?
355
     *                              On FALSE, uses links to the images.
356
     * @return string
357
     */
358
    public function &xoopsCodeDecode(&$text, $allowimage = 1)
359
    {
360
        $patterns       = array();
361
        $replacements   = array();
362
        $patterns[]     = "/\[siteurl=(['\"]?)([^\"'<>]*)\\1](.*)\[\/siteurl\]/sU";
363
        $replacements[] = '<a href="' . XOOPS_URL . '/\\2" title="">\\3</a>';
364
        $patterns[]     = "/\[url=(['\"]?)(http[s]?:\/\/[^\"'<>]*)\\1](.*)\[\/url\]/sU";
365
        $replacements[] = '<a href="\\2" rel="noopener external" title="">\\3</a>';
366
        $patterns[]     = "/\[url=(['\"]?)(ftp?:\/\/[^\"'<>]*)\\1](.*)\[\/url\]/sU";
367
        $replacements[] = '<a href="\\2" rel="external" title="">\\3</a>';
368
        $patterns[]     = "/\[url=(['\"]?)([^'\"<>]*)\\1](.*)\[\/url\]/sU";
369
        $replacements[] = '<a href="http://\\2" rel="noopener external" title="">\\3</a>';
370
        $patterns[]     = "/\[color=(['\"]?)([a-zA-Z0-9#]*)\\1](.*)\[\/color\]/sU";
371
        $replacements[] = '<span style="color: \\2;">\\3</span>';
372
        $patterns[]     = "/\[size=(['\"]?)([a-zA-Z0-9.#]*)\\1](.*)\[\/size\]/sU";
373
        $replacements[] = '<span style="font-size: \\2;">\\3</span>';
374
        $patterns[]     = "/\[font=(['\"]?)([^;<>\*\(\)\"']*)\\1](.*)\[\/font\]/sU";
375
        $replacements[] = '<span style="font-family: \\2;">\\3</span>';
376
        $patterns[]     = "/\[email]([^;<>\*\(\)\"']*)\[\/email\]/sU";
377
        $replacements[] = '<a href="mailto:\\1" title="">\\1</a>';
378
379
        $patterns[]     = "/\[b](.*)\[\/b\]/sU";
380
        $replacements[] = '<strong>\\1</strong>';
381
        $patterns[]     = "/\[i](.*)\[\/i\]/sU";
382
        $replacements[] = '<em>\\1</em>';
383
        $patterns[]     = "/\[u](.*)\[\/u\]/sU";
384
        $replacements[] = '<span style="text-decoration: underline;">\\1</span>';
385
        $patterns[]     = "/\[d](.*)\[\/d\]/sU";
386
        $replacements[] = '<del>\\1</del>';
387
        $patterns[]     = "/\[center](.*)\[\/center\]/sU";
388
        $replacements[] = '<div style="text-align: center;">\\1</div>';
389
        $patterns[]     = "/\[left](.*)\[\/left\]/sU";
390
        $replacements[] = '<div style="text-align: left;">\\1</div>';
391
        $patterns[]     = "/\[right](.*)\[\/right\]/sU";
392
        $replacements[] = '<div style="text-align: right;">\\1</div>';
393
394
        $this->text         = $text;
395
        $this->patterns     = $patterns;
396
        $this->replacements = $replacements;
397
398
        $this->config['allowimage'] = $allowimage;
399
        $this->executeExtensions();
400
401
        $text = preg_replace($this->patterns, $this->replacements, $this->text);
402
        //-------------------------------------------------------------------------------
403
        $count = count($this->callbackPatterns);
404
405
        for ($i = 0; $i < $count; ++$i) {
406
            $text = preg_replace_callback($this->callbackPatterns[$i], $this->callbacks[$i], $text);
407
        }
408
        //------------------------------------------------------------------------------
409
        $text = $this->quoteConv($text);
410
411
        return $text;
412
    }
413
414
    /**
415
     * Convert quote tags
416
     *
417
     * @param  string $text
418
     * @return string
419
     */
420
    public function quoteConv($text)
421
    {
422
        //look for both open and closing tags in the correct order
423
        $pattern     = "/\[quote](.*)\[\/quote\]/sU";
424
        $replacement = _QUOTEC . '<div class="xoopsQuote"><blockquote>\\1</blockquote></div>';
425
426
        $text = preg_replace($pattern, $replacement, $text, -1, $count);
427
        //no more matches, return now
428
        if (!$count) {
429
            return $text;
430
        }
431
432
        //new matches could have been created, keep doing it until we have no matches
433
        return $this->quoteConv($text);
434
    }
435
436
    /**
437
     * A quick solution for filtering XSS scripts
438
     *
439
     * @TODO : To be improved
440
     * @param $text
441
     * @return mixed
442
     */
443
    public function filterXss($text)
444
    {
445
        $patterns       = array();
446
        $replacements   = array();
447
        $text           = str_replace("\x00", '', $text);
448
        $c              = "[\x01-\x1f]*";
449
        $patterns[]     = "/\bj{$c}a{$c}v{$c}a{$c}s{$c}c{$c}r{$c}i{$c}p{$c}t{$c}[\s]*:/si";
450
        $replacements[] = 'javascript;';
451
        $patterns[]     = "/\ba{$c}b{$c}o{$c}u{$c}t{$c}[\s]*:/si";
452
        $replacements[] = 'about;';
453
        $patterns[]     = "/\bx{$c}s{$c}s{$c}[\s]*:/si";
454
        $replacements[] = 'xss;';
455
        $text           = preg_replace($patterns, $replacements, $text);
456
457
        return $text;
458
    }
459
460
    /**
461
     * Convert linebreaks to <br> tags
462
     *
463
     * @param  string $text
464
     * @return string
465
     */
466
    public function nl2Br($text)
467
    {
468
        return preg_replace('/(\015\012)|(\015)|(\012)/', '<br>', $text);
469
    }
470
471
    /**
472
     * Add slashes to the text if magic_quotes_gpc is turned off.
473
     *
474
     * @param  string $text
475
     * @return string
476
     */
477
    public function addSlashes($text)
478
    {
479
        if (PHP_VERSION_ID < 50400) {
480
            if (!get_magic_quotes_gpc()) {
481
                $text = addslashes($text);
482
            }
483
        }
484
485
        return $text;
486
    }
487
488
    /**
489
     * Convert special characters to HTML entities
490
     *
491
     * @param  string $text    string being converted
492
     * @param  int|null    $quote_style
493
     * @param  string $charset character set used in conversion
494
     * @param  bool   $double_encode
495
     * @return string
496
     */
497
    public function htmlSpecialChars($text, $quote_style = NULL, $charset = null, $double_encode = true)
498
    {
499
        if ($quote_style === NULL) {
500
            $quote_style = ENT_QUOTES;
501
        }
502
        $text = (string) $text;
503
        if (version_compare(phpversion(), '5.2.3', '>=')) {
504
            $text = htmlspecialchars($text, $quote_style, $charset ?: (defined('_CHARSET') ? _CHARSET : 'UTF-8'), $double_encode);
505
        } else {
506
            $text = htmlspecialchars($text, $quote_style);
507
        }
508
509
        return preg_replace(array('/&amp;/i', '/&nbsp;/i'), array('&', '&amp;nbsp;'), $text);
510
    }
511
512
    /**
513
     * Reverses {@link htmlSpecialChars()}
514
     *
515
     * @param  string $text
516
     * @return string
517
     */
518
    public function undoHtmlSpecialChars($text)
519
    {
520
        return preg_replace(array('/&gt;/i', '/&lt;/i', '/&quot;/i', '/&#039;/i', '/&amp;nbsp;/i'), array('>', '<', '"', '\'', '&nbsp;'), $text);
521
    }
522
523
    /**
524
     * Filters textarea form data in DB for display
525
     *
526
     * @param  string   $text
527
     * @param  bool|int $html   allow html?
528
     * @param  bool|int $smiley allow smileys?
529
     * @param  bool|int $xcode  allow xoopscode?
530
     * @param  bool|int $image  allow inline images?
531
     * @param  bool|int $br     convert linebreaks?
532
     * @return string
533
     */
534
    public function &displayTarea($text, $html = 0, $smiley = 1, $xcode = 1, $image = 1, $br = 1)
535
    {
536
        $text = (string) $text;
537
        $charset = (defined('_CHARSET') ? _CHARSET : 'UTF-8');
538
        if (function_exists('mb_convert_encoding')) {
539
            $text = mb_convert_encoding($text, $charset, mb_detect_encoding($text, mb_detect_order(), true));
0 ignored issues
show
Bug introduced by
It seems like mb_detect_order() can also be of type true; however, parameter $encodings of mb_detect_encoding() does only seem to accept array|null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

539
            $text = mb_convert_encoding($text, $charset, mb_detect_encoding($text, /** @scrutinizer ignore-type */ mb_detect_order(), true));
Loading history...
540
        }
541
        if ($html && $br) {
542
            $testText = strip_tags($text);
0 ignored issues
show
Bug introduced by
It seems like $text can also be of type array; however, parameter $string of strip_tags() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

542
            $testText = strip_tags(/** @scrutinizer ignore-type */ $text);
Loading history...
543
            if (mb_strlen($text) != mb_strlen($testText)) {
0 ignored issues
show
Bug introduced by
It seems like $text can also be of type array; however, parameter $string of mb_strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

543
            if (mb_strlen(/** @scrutinizer ignore-type */ $text) != mb_strlen($testText)) {
Loading history...
544
                $br = 0;
545
            }
546
            unset($testText);
547
        }
548
        if ($html != 1) {
549
            // html not allowed
550
            $text = $this->htmlSpecialChars($text, ENT_COMPAT, $charset);
0 ignored issues
show
Bug introduced by
It seems like $text can also be of type array; however, parameter $text of MyTextSanitizer::htmlSpecialChars() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

550
            $text = $this->htmlSpecialChars(/** @scrutinizer ignore-type */ $text, ENT_COMPAT, $charset);
Loading history...
551
        }
552
        $text = $this->codePreConv($text, $xcode); // Ryuji_edit(2003-11-18)
553
        if ($smiley != 0) {
554
            // process smiley
555
            $text = $this->smiley($text);
0 ignored issues
show
Bug introduced by
It seems like $text can also be of type array; however, parameter $message of MyTextSanitizer::smiley() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

555
            $text = $this->smiley(/** @scrutinizer ignore-type */ $text);
Loading history...
556
        }
557
        if ($xcode != 0) {
558
            // decode xcode
559
            if ($image != 0) {
560
                // image allowed
561
                $text =& $this->xoopsCodeDecode($text);
0 ignored issues
show
Bug introduced by
It seems like $text can also be of type array; however, parameter $text of MyTextSanitizer::xoopsCodeDecode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

561
                $text =& $this->xoopsCodeDecode(/** @scrutinizer ignore-type */ $text);
Loading history...
562
            } else {
563
                // image not allowed
564
                $text =& $this->xoopsCodeDecode($text, 0);
565
            }
566
        }
567
        if ($br != 0) {
568
            $text = $this->nl2Br($text);
0 ignored issues
show
Bug introduced by
It seems like $text can also be of type array; however, parameter $text of MyTextSanitizer::nl2Br() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

568
            $text = $this->nl2Br(/** @scrutinizer ignore-type */ $text);
Loading history...
569
        }
570
        $text = $this->codeConv($text, $xcode);
571
        $text = $this->makeClickable($text);
0 ignored issues
show
Bug introduced by
It seems like $text can also be of type array; however, parameter $text of MyTextSanitizer::makeClickable() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

571
        $text = $this->makeClickable(/** @scrutinizer ignore-type */ $text);
Loading history...
572
        if (!empty($this->config['filterxss_on_display'])) {
573
            $text = $this->filterXss($text);
574
        }
575
576
        return $text;
577
    }
578
579
    /**
580
     * Filters textarea form data submitted for preview
581
     *
582
     * @param  string   $text
583
     * @param  bool|int $html   allow html?
584
     * @param  bool|int $smiley allow smileys?
585
     * @param  bool|int $xcode  allow xoopscode?
586
     * @param  bool|int $image  allow inline images?
587
     * @param  bool|int $br     convert linebreaks?
588
     * @return string
589
     */
590
    public function &previewTarea($text, $html = 0, $smiley = 1, $xcode = 1, $image = 1, $br = 1)
591
    {
592
        $text = $this->stripSlashesGPC($text);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

592
        $text = /** @scrutinizer ignore-deprecated */ $this->stripSlashesGPC($text);

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

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

Loading history...
593
        $text =& $this->displayTarea($text, $html, $smiley, $xcode, $image, $br);
594
595
        return $text;
596
    }
597
598
    /**
599
     * Replaces banned words in a string with their replacements
600
     *
601
     * @param  string $text
602
     * @return string
603
     */
604
    public function &censorString(&$text)
605
    {
606
        $ret = $this->executeExtension('censor', $text);
607
        if ($ret === false) {
608
            return $text;
609
        }
610
611
        return $ret;
612
    }
613
614
    /**
615
     * MyTextSanitizer::codePreConv()
616
     *
617
     * @param  mixed $text
618
     * @param  mixed $xcode
619
     * @return mixed
620
     */
621
    public function codePreConv($text, $xcode = 1)
622
    {
623
        if ($xcode != 0) {
624
            //            $patterns = "/\[code([^\]]*?)\](.*)\[\/code\]/esU";
625
            //            $replacements = "'[code\\1]'.base64_encode('\\2').'[/code]'";
626
627
            $patterns = "/\[code([^\]]*?)\](.*)\[\/code\]/sU";
628
            $text = preg_replace_callback(
629
                $patterns,
630
                function ($matches) {
631
                    return '[code'. $matches[1] . ']' . base64_encode($matches[2]) . '[/code]';
632
                },
633
                $text
634
            );
635
        }
636
637
        return $text;
638
    }
639
640
    /**
641
     * @param $match
642
     *
643
     * @return string
644
     */
645
    public function codeConvCallback($match)
646
    {
647
        return '<div class="xoopsCode">' . $this->executeExtension('syntaxhighlight', str_replace('\\\"', '\"', base64_decode($match[2])), $match[1]) . '</div>';
648
    }
649
650
    /**
651
     * MyTextSanitizer::codeConv()
652
     *
653
     * @param  mixed $text
654
     * @param  mixed $xcode
655
     * @return mixed
656
     */
657
    public function codeConv($text, $xcode = 1)
658
    {
659
        if (empty($xcode)) {
660
            return $text;
661
        }
662
        $patterns = "/\[code([^\]]*?)\](.*)\[\/code\]/sU";
663
        $text1    = preg_replace_callback($patterns, array($this, 'codeConvCallback'), $text);
664
665
        return $text1;
666
    }
667
668
    /**
669
     * MyTextSanitizer::executeExtensions()
670
     *
671
     * @return bool
672
     */
673
    public function executeExtensions()
674
    {
675
        $extensions = array_filter($this->config['extensions']);
676
        if (empty($extensions)) {
677
            return true;
678
        }
679
        foreach (array_keys($extensions) as $extension) {
680
            $this->executeExtension($extension);
681
        }
682
        return null;
683
    }
684
685
    /**
686
     * MyTextSanitizer::loadExtension()
687
     *
688
     * @param  mixed $name
689
     * @return MyTextSanitizerExtension|false
690
     */
691
    public function loadExtension($name)
692
    {
693
        if (file_exists($file = $this->path_basic . '/' . $name . '/' . $name . '.php')) {
694
            include_once $file;
695
        } elseif (file_exists($file = $this->path_plugin . '/' . $name . '/' . $name . '.php')) {
696
            include_once $file;
697
        } else {
698
            return false;
699
        }
700
        $class = 'Myts' . ucfirst($name);
701
        if (!class_exists($class)) {
702
            trigger_error("Extension '{$name}' does not exist", E_USER_WARNING);
703
704
            return false;
705
        }
706
        return new $class($this);
707
    }
708
709
    /**
710
     * MyTextSanitizer::executeExtension()
711
     *
712
     * @param  mixed $name
713
     * @return mixed
714
     */
715
    public function executeExtension($name)
716
    {
717
        $extension = $this->loadExtension($name);
718
        $args      = array_slice(func_get_args(), 1);
719
        array_unshift($args, $this);
720
721
        return call_user_func_array(array($extension, 'load'), $args);
722
    }
723
724
    /**
725
     * Filter out possible malicious text
726
     * kses project at SF could be a good solution to check
727
     *
728
     * @param  string $text  text to filter
729
     * @param  bool   $force force filtering
730
     * @return string filtered text
731
     */
732
    public function textFilter($text, $force = false)
733
    {
734
        $ret = $this->executeExtension('textfilter', $text, $force);
735
        if ($ret === false) {
736
            return $text;
737
        }
738
739
        return $ret;
740
    }
741
742
    // #################### Deprecated Methods ######################
743
744
    /**
745
     * if magic_quotes_gpc is on, strip back slashes
746
     *
747
     * @param  string $text
748
     * @return string
749
     * @deprecated as of XOOPS 2.5.11 and will be removed in next XOOPS version
750
     *
751
     * This remains here until we officially drop support for PHP 5.3 in next release
752
     */
753
    public function stripSlashesGPC($text)
754
    {
755
        if (PHP_VERSION_ID < 50400) {
756
            if (get_magic_quotes_gpc()) {
757
                $text = stripslashes($text);
758
            }
759
        }
760
761
        return $text;
762
    }
763
764
    /**
765
     * MyTextSanitizer::codeSanitizer()
766
     *
767
     * @param  mixed $str
768
     * @param  mixed $image
769
     * @return mixed|string
770
     * @deprecated will be removed in next XOOPS version
771
     */
772
    public function codeSanitizer($str, $image = 1)
773
    {
774
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
775
        $str = $this->htmlSpecialChars(str_replace('\"', '"', base64_decode($str)));
776
        $str =& $this->xoopsCodeDecode($str, $image);
777
778
        return $str;
779
    }
780
781
    /**
782
     * MyTextSanitizer::sanitizeForDisplay()
783
     *
784
     * @param  mixed   $text
785
     * @param  integer $allowhtml
786
     * @param  integer $smiley
787
     * @param  mixed   $bbcode
788
     * @return mixed|string
789
     * @deprecated will be removed in next XOOPS version
790
     */
791
    public function sanitizeForDisplay($text, $allowhtml = 0, $smiley = 1, $bbcode = 1)
792
    {
793
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
794
        if ($allowhtml == 0) {
795
            $text = $this->htmlSpecialChars($text);
796
        } else {
797
            // $config =& $GLOBALS['xoopsConfig'];
798
            // $allowed = $config['allowed_html'];
799
            // $text = strip_tags($text, $allowed);
800
            $text = $this->makeClickable($text);
801
        }
802
        if ($smiley == 1) {
803
            $text = $this->smiley($text);
804
        }
805
        if ($bbcode == 1) {
806
            $text =& $this->xoopsCodeDecode($text);
807
        }
808
        $text = $this->nl2Br($text);
809
810
        return $text;
811
    }
812
813
    /**
814
     * MyTextSanitizer::sanitizeForPreview()
815
     *
816
     * @param  mixed   $text
817
     * @param  integer $allowhtml
818
     * @param  integer $smiley
819
     * @param  mixed   $bbcode
820
     * @return mixed|string
821
     * @deprecated will be removed in next XOOPS version
822
     */
823
    public function sanitizeForPreview($text, $allowhtml = 0, $smiley = 1, $bbcode = 1)
824
    {
825
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
826
        $text = $this->oopsStripSlashesGPC($text);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::oopsStripSlashesGPC() has been deprecated: will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

826
        $text = /** @scrutinizer ignore-deprecated */ $this->oopsStripSlashesGPC($text);

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

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

Loading history...
827
        if ($allowhtml == 0) {
828
            $text = $this->htmlSpecialChars($text);
829
        } else {
830
            // $config =& $GLOBALS['xoopsConfig'];
831
            // $allowed = $config['allowed_html'];
832
            // $text = strip_tags($text, $allowed);
833
            $text = $this->makeClickable($text);
834
        }
835
        if ($smiley == 1) {
836
            $text = $this->smiley($text);
837
        }
838
        if ($bbcode == 1) {
839
            $text =& $this->xoopsCodeDecode($text);
840
        }
841
        $text = $this->nl2Br($text);
842
843
        return $text;
844
    }
845
846
    /**
847
     * MyTextSanitizer::makeTboxData4Save()
848
     *
849
     * @param  mixed $text
850
     * @return string
851
     * @deprecated will be removed in next XOOPS version
852
     */
853
    public function makeTboxData4Save($text)
854
    {
855
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
856
857
        // $text = $this->undoHtmlSpecialChars($text);
858
        return $this->addSlashes($text);
859
    }
860
861
    /**
862
     * MyTextSanitizer::makeTboxData4Show()
863
     *
864
     * @param  mixed $text
865
     * @param  mixed $smiley
866
     * @return mixed|string
867
     * @deprecated will be removed in next XOOPS version
868
     */
869
    public function makeTboxData4Show($text, $smiley = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $smiley is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

869
    public function makeTboxData4Show($text, /** @scrutinizer ignore-unused */ $smiley = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
870
    {
871
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
872
        $text = $this->htmlSpecialChars($text);
873
874
        return $text;
875
    }
876
877
    /**
878
     * MyTextSanitizer::makeTboxData4Edit()
879
     *
880
     * @param  mixed $text
881
     * @return string
882
     * @deprecated will be removed in next XOOPS version
883
     */
884
    public function makeTboxData4Edit($text)
885
    {
886
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
887
888
        return $this->htmlSpecialChars($text);
889
    }
890
891
    /**
892
     * MyTextSanitizer::makeTboxData4Preview()
893
     *
894
     * @param  mixed $text
895
     * @param  mixed $smiley
896
     * @return mixed|string
897
     * @deprecated will be removed in next XOOPS version
898
     */
899
    public function makeTboxData4Preview($text, $smiley = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $smiley is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

899
    public function makeTboxData4Preview($text, /** @scrutinizer ignore-unused */ $smiley = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
900
    {
901
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
902
        $text = $this->stripSlashesGPC($text);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

902
        $text = /** @scrutinizer ignore-deprecated */ $this->stripSlashesGPC($text);

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

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

Loading history...
903
        $text = $this->htmlSpecialChars($text);
904
905
        return $text;
906
    }
907
908
    /**
909
     * MyTextSanitizer::makeTboxData4PreviewInForm()
910
     *
911
     * @param  mixed $text
912
     * @return string
913
     * @deprecated will be removed in next XOOPS version
914
     */
915
    public function makeTboxData4PreviewInForm($text)
916
    {
917
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
918
        $text = $this->stripSlashesGPC($text);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

918
        $text = /** @scrutinizer ignore-deprecated */ $this->stripSlashesGPC($text);

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

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

Loading history...
919
920
        return $this->htmlSpecialChars($text);
921
    }
922
923
    /**
924
     * MyTextSanitizer::makeTareaData4Save()
925
     *
926
     * @param  mixed $text
927
     * @return string
928
     * @deprecated will be removed in next XOOPS version
929
     */
930
    public function makeTareaData4Save($text)
931
    {
932
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
933
934
        return $this->addSlashes($text);
935
    }
936
937
    /**
938
     * MyTextSanitizer::makeTareaData4Show()
939
     *
940
     * @param  mixed   $text
941
     * @param  integer $html
942
     * @param  integer $smiley
943
     * @param  mixed   $xcode
944
     * @return mixed|string
945
     * @deprecated will be removed in next XOOPS version
946
     */
947
    public function &makeTareaData4Show(&$text, $html = 1, $smiley = 1, $xcode = 1)
948
    {
949
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
950
        $text =& $this->displayTarea($text, $html, $smiley, $xcode);
951
952
        return $text;
953
    }
954
955
    /**
956
     * MyTextSanitizer::makeTareaData4Edit()
957
     *
958
     * @param  mixed $text
959
     * @return string
960
     * @deprecated will be removed in next XOOPS version
961
     */
962
    public function makeTareaData4Edit($text)
963
    {
964
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
965
966
        return $this->htmlSpecialChars($text);
967
    }
968
969
    /**
970
     * MyTextSanitizer::makeTareaData4Preview()
971
     *
972
     * @param  mixed   $text
973
     * @param  integer $html
974
     * @param  integer $smiley
975
     * @param  mixed   $xcode
976
     * @return mixed|string
977
     * @deprecated will be removed in next XOOPS version
978
     */
979
    public function &makeTareaData4Preview(&$text, $html = 1, $smiley = 1, $xcode = 1)
980
    {
981
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
982
        $text =& $this->previewTarea($text, $html, $smiley, $xcode);
983
984
        return $text;
985
    }
986
987
    /**
988
     * MyTextSanitizer::makeTareaData4PreviewInForm()
989
     *
990
     * @param  mixed $text
991
     * @return string
992
     * @deprecated will be removed in next XOOPS version
993
     */
994
    public function makeTareaData4PreviewInForm($text)
995
    {
996
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
997
        // if magic_quotes_gpc is on, do stipslashes
998
        $text = $this->stripSlashesGPC($text);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

998
        $text = /** @scrutinizer ignore-deprecated */ $this->stripSlashesGPC($text);

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

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

Loading history...
999
1000
        return $this->htmlSpecialChars($text);
1001
    }
1002
1003
    /**
1004
     * MyTextSanitizer::makeTareaData4InsideQuotes()
1005
     *
1006
     * @param  mixed $text
1007
     * @return string
1008
     * @deprecated will be removed in next XOOPS version
1009
     */
1010
    public function makeTareaData4InsideQuotes($text)
1011
    {
1012
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
1013
1014
        return $this->htmlSpecialChars($text);
1015
    }
1016
1017
    /**
1018
     * MyTextSanitizer::oopsStripSlashesGPC()
1019
     *
1020
     * @param  mixed $text
1021
     * @return string
1022
     * @deprecated will be removed in next XOOPS version
1023
     */
1024
    public function oopsStripSlashesGPC($text)
1025
    {
1026
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
1027
1028
        return $this->stripSlashesGPC($text);
0 ignored issues
show
Deprecated Code introduced by
The function MyTextSanitizer::stripSlashesGPC() has been deprecated: as of XOOPS 2.5.11 and will be removed in next XOOPS version ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1028
        return /** @scrutinizer ignore-deprecated */ $this->stripSlashesGPC($text);

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

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

Loading history...
1029
    }
1030
1031
    /**
1032
     * MyTextSanitizer::oopsStripSlashesRT()
1033
     *
1034
     * @param  mixed $text
1035
     * @return mixed|string
1036
     * @deprecated will be removed in next XOOPS version
1037
     */
1038
    public function oopsStripSlashesRT($text)
1039
    {
1040
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
1041
        if (PHP_VERSION_ID < 50400) {
1042
            if (get_magic_quotes_runtime()) {
1043
                $text = stripslashes($text);
1044
            }
1045
        }
1046
1047
        return $text;
1048
    }
1049
1050
    /**
1051
     * MyTextSanitizer::oopsAddSlashes()
1052
     *
1053
     * @param  mixed $text
1054
     * @return string
1055
     * @deprecated will be removed in next XOOPS version
1056
     */
1057
    public function oopsAddSlashes($text)
1058
    {
1059
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
1060
1061
        return $this->addSlashes($text);
1062
    }
1063
1064
    /**
1065
     * MyTextSanitizer::oopsHtmlSpecialChars()
1066
     *
1067
     * @param  mixed $text
1068
     * @return string
1069
     * @deprecated will be removed in next XOOPS version
1070
     */
1071
    public function oopsHtmlSpecialChars($text)
1072
    {
1073
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
1074
1075
        return $this->htmlSpecialChars($text);
1076
    }
1077
1078
    /**
1079
     * MyTextSanitizer::oopsNl2Br()
1080
     *
1081
     * @param  mixed $text
1082
     * @return string
1083
     * @deprecated will be removed in next XOOPS version
1084
     */
1085
    public function oopsNl2Br($text)
1086
    {
1087
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
1088
1089
        return $this->nl2Br($text);
1090
    }
1091
}
1092