Issues (3083)

htdocs/class/module.textsanitizer.php (2 issues)

php_analyzer.type_inference.infeasible_condition.generic

Unknown
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();
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
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)
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)
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
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))) {
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);
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));
540
        }
541
        if ($html && $br) {
542
            $testText = strip_tags($text);
543
            if (mb_strlen($text) != mb_strlen($testText)) {
544
                $br = 0;
545
            }
546
            unset($testText);
547
        }
548
        if ($html != 1) {
549
            // html not allowed
550
            $text = $this->htmlSpecialChars($text, ENT_COMPAT, $charset);
551
        }
552
        $text = $this->codePreConv($text, $xcode); // Ryuji_edit(2003-11-18)
553
        if ($smiley != 0) {
554
            // process smiley
555
            $text = $this->smiley($text);
556
        }
557
        if ($xcode != 0) {
558
            // decode xcode
559
            if ($image != 0) {
560
                // image allowed
561
                $text =& $this->xoopsCodeDecode($text);
562
            } else {
563
                // image not allowed
564
                $text =& $this->xoopsCodeDecode($text, 0);
565
            }
566
        }
567
        if ($br != 0) {
568
            $text = $this->nl2Br($text);
569
        }
570
        $text = $this->codeConv($text, $xcode);
571
        $text = $this->makeClickable($text);
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);
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);
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)
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)
900
    {
901
        $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated');
902
        $text = $this->stripSlashesGPC($text);
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);
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);
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);
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