Util::_process_selector_pattern()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace EMT;
4
5
class Util
6
{
7
    const LAYOUT_STYLE = 1;
8
    const LAYOUT_CLASS = 2;
9
10
    const INTERNAL_BLOCK_OPEN = '%%%INTBLOCKO235978%%%';
11
    const INTERNAL_BLOCK_CLOSE = '%%%INTBLOCKC235978%%%';
12
    /**
13
     * Таблица символов
14
     *
15
     * @var array
16
     */
17
    public static $_charsTable = array(
18
        '"' => array('html' => array('&laquo;', '&raquo;', '&ldquo;', '&lsquo;', '&bdquo;', '&ldquo;', '&quot;', '&#171;', '&#187;'),
19
            'utf8' => array(0x201E, 0x201C, 0x201F, 0x201D, 0x00AB, 0x00BB)),
20
        ' ' => array('html' => array('&nbsp;', '&thinsp;', '&#160;'),
21
            'utf8' => array(0x00A0, 0x2002, 0x2003, 0x2008, 0x2009)),
22
        '-' => array('html' => array( /*'&mdash;',*/
23
            '&ndash;', '&minus;', '&#151;', '&#8212;', '&#8211;'),
24
            'utf8' => array(0x002D, /*0x2014,*/
25
                0x2010, 0x2012, 0x2013)),
26
        '—' => array('html' => array('&mdash;'),
27
            'utf8' => array(0x2014)),
28
        '==' => array('html' => array('&equiv;'),
29
            'utf8' => array(0x2261)),
30
        '...' => array('html' => array('&hellip;', '&#0133;'),
31
            'utf8' => array(0x2026)),
32
        '!=' => array('html' => array('&ne;', '&#8800;'),
33
            'utf8' => array(0x2260)),
34
        '<=' => array('html' => array('&le;', '&#8804;'),
35
            'utf8' => array(0x2264)),
36
        '>=' => array('html' => array('&ge;', '&#8805;'),
37
            'utf8' => array(0x2265)),
38
        '1/2' => array('html' => array('&frac12;', '&#189;'),
39
            'utf8' => array(0x00BD)),
40
        '1/4' => array('html' => array('&frac14;', '&#188;'),
41
            'utf8' => array(0x00BC)),
42
        '3/4' => array('html' => array('&frac34;', '&#190;'),
43
            'utf8' => array(0x00BE)),
44
        '+-' => array('html' => array('&plusmn;', '&#177;'),
45
            'utf8' => array(0x00B1)),
46
        '&' => array('html' => array('&amp;', '&#38;')),
47
        '(tm)' => array('html' => array('&trade;', '&#153;'),
48
            'utf8' => array(0x2122)),
49
        //'(r)' 	=> array('html' => array('<sup>&reg;</sup>', '&reg;', '&#174;'),
50
        '(r)' => array('html' => array('&reg;', '&#174;'),
51
            'utf8' => array(0x00AE)),
52
        '(c)' => array('html' => array('&copy;', '&#169;'),
53
            'utf8' => array(0x00A9)),
54
        '§' => array('html' => array('&sect;', '&#167;'),
55
            'utf8' => array(0x00A7)),
56
        '`' => array('html' => array('&#769;')),
57
        '\'' => array('html' => array('&rsquo;', '’')),
58
        'x' => array('html' => array('&times;', '&#215;'),
59
            'utf8' => array('×') /* какой же у него может быть код? */),
60
61
    );
62
63
    /**
64
     * Добавление к тегам атрибута 'id', благодаря которому
65
     * при повторном типографирование текста будут удалены теги,
66
     * расставленные данным типографом
67
     *
68
     * @var array
69
     */
70
    protected static $_typographSpecificTagId = false;
71
72
    /**
73
     * Костыли для работы с символами UTF-8
74
     *
75
     * @author    somebody?
76
     * @param  int $c код символа в кодировке UTF-8 (например, 0x00AB)
77
     * @return string|false
78
     */
79
    public static function _getUnicodeChar($c)
80
    {
81
        if ($c <= 0x7F) {
82
            return chr($c);
83
        } elseif ($c <= 0x7FF) {
84
            return chr(0xC0 | $c >> 6)
85
            . chr(0x80 | $c & 0x3F);
86
        } elseif ($c <= 0xFFFF) {
87
            return chr(0xE0 | $c >> 12)
88
            . chr(0x80 | $c >> 6 & 0x3F)
89
            . chr(0x80 | $c & 0x3F);
90
        } elseif ($c <= 0x10FFFF) {
91
            return chr(0xF0 | $c >> 18)
92
            . chr(0x80 | $c >> 12 & 0x3F)
93
            . chr(0x80 | $c >> 6 & 0x3F)
94
            . chr(0x80 | $c & 0x3F);
95
        } else {
96
            return false;
97
        }
98
    }
99
100
    /**
101
     * Удаление кодов HTML из текста
102
     *
103
     * <code>
104
     *  // Remove UTF-8 chars:
105
     *    $str = \EMT\Util::clear_special_chars('your text', 'utf8');
106
     *  // ... or HTML codes only:
107
     *    $str = \EMT\Util::clear_special_chars('your text', 'html');
108
     *    // ... or combo:
109
     *  $str = \EMT\Util::clear_special_chars('your text');
110
     * </code>
111
     *
112
     * @param  string $text
113
     * @param  mixed $mode
114
     * @return false|string
115
     */
116
    public static function clear_special_chars($text, $mode = null)
117
    {
118
        if (is_string($mode)) $mode = array($mode);
119
        if (is_null($mode)) $mode = array('utf8', 'html');
120
        if (!is_array($mode)) return false;
121
        $moder = array();
122
        foreach ($mode as $mod) if (in_array($mod, array('utf8', 'html'))) $moder[] = $mod;
123
        if (count($moder) == 0) return false;
124
125
        foreach (self::$_charsTable as $char => $vals) {
126
            foreach ($mode as $type) {
127
                if (isset($vals[$type])) {
128
                    foreach ($vals[$type] as $v) {
129
                        if ('utf8' === $type && is_int($v)) {
130
                            $v = self::_getUnicodeChar($v);
131
                        }
132
                        if ('html' === $type) {
133
                            if (preg_match("/<[a-z]+>/i", $v)) {
134
                                $v = self::safe_tag_chars($v, true);
135
                            }
136
                        }
137
                        $text = str_replace($v, $char, $text);
138
                    }
139
                }
140
            }
141
        }
142
143
        return $text;
144
    }
145
146
    /**
147
     * Удаление тегов HTML из текста
148
     * Тег <br /> будет преобразов в перенос строки \n, сочетание тегов </p><p> -
149
     * в двойной перенос
150
     *
151
     * @param  string $text
152
     * @param  array $allowableTag массив из тегов, которые будут проигнорированы
153
     * @return string
154
     */
155
    public static function remove_html_tags($text, $allowableTag = null)
156
    {
157
        $ignore = null;
158
159
        if (null !== $allowableTag) {
160
            if (is_string($allowableTag)) {
161
                $allowableTag = array($allowableTag);
162
            }
163
            if (is_array($allowableTag)) {
164
                $tags = array();
165
                foreach ($allowableTag as $tag) {
166
                    if ('<' !== substr($tag, 0, 1) || '>' !== substr($tag, -1, 1)) continue;
167
                    if ('/' === substr($tag, 1, 1)) continue;
168
                    $tags [] = $tag;
169
                }
170
                $ignore = implode('', $tags);
171
            }
172
        }
173
        $text = preg_replace(array('/\<br\s*\/?>/i', '/\<\/p\>\s*\<p\>/'), array("\n", "\n\n"), $text);
174
        $text = strip_tags($text, $ignore);
175
176
        return $text;
177
    }
178
179
    /**
180
     * Сохраняем содержимое тегов HTML
181
     *
182
     * Тег 'a' кодируется со специальным префиксом для дальнейшей
183
     * возможности выносить за него кавычки.
184
     *
185
     * @param  string $text
186
     * @param boolean $way
187
     * @return string
188
     */
189
    public static function safe_tag_chars($text, $way)
190
    {
191
        if ($way) {
192
            $callback = function ($m) {
193
                return $m[1]
194
                    . (substr(trim($m[2]), 0, 1) === 'a' ? '%%___' : '')
195
                    . self::encrypt_tag(trim($m[2]))
196
                    . $m[3];
197
            };
198
        } else {
199
            $callback = function ($m) {
200
                return $m[1]
201
                    . (substr(trim($m[2]), 0, 3) === '%%___'
202
                        ? self::decrypt_tag(substr(trim($m[2]), 4))
203
                        : self::decrypt_tag(trim($m[2])))
204
                    . $m[3];
205
            };
206
        }
207
208
        return preg_replace_callback('/(\<\/?)(.+?)(\>)/s', $callback, $text);
209
    }
210
211
    /**
212
     * Декодриует спец блоки
213
     *
214
     * @param  string $text
215
     * @return string
216
     */
217
    public static function decode_internal_blocks($text)
218
    {
219
        return preg_replace_callback(
220
            '/' . self::INTERNAL_BLOCK_OPEN . '([a-zA-Z0-9\/=]+?)' . \EMT\Util::INTERNAL_BLOCK_CLOSE . '/s',
221
            function ($m) {
222
                return self::decrypt_tag($m[1]);
223
            },
224
            $text
225
        );
226
    }
227
228
    /**
229
     * Кодирует спец блок
230
     *
231
     * @param  string $text
232
     * @return string
233
     */
234
    public static function iblock($text)
235
    {
236
        return \EMT\Util::INTERNAL_BLOCK_OPEN . \EMT\Util::encrypt_tag($text) . \EMT\Util::INTERNAL_BLOCK_CLOSE;
237
    }
238
239
    /**
240
     * Создание тега с защищенным содержимым
241
     *
242
     * @param  string $content текст, который будет обрамлен тегом
243
     * @param  string $tag тэг
244
     * @param  array $attribute список атрибутов, где ключ - имя атрибута, а значение - само значение данного атрибута
245
     * @return string
246
     */
247
    public static function build_safe_tag($content, $tag = 'span', $attribute = array(), $layout = \EMT\Util::LAYOUT_STYLE)
248
    {
249
        $htmlTag = $tag;
250
251
        if (self::$_typographSpecificTagId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::$_typographSpecificTagId of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
252
            if (!isset($attribute['id'])) {
253
                $attribute['id'] = 'emt-2' . mt_rand(1000, 9999);
254
            }
255
        }
256
257
        $classname = "";
258
        if (count($attribute)) {
259
260
            if ($layout & self::LAYOUT_STYLE) {
261
                if (isset($attribute['__style']) && $attribute['__style']) {
262
                    if (isset($attribute['style']) && $attribute['style']) {
263
                        $st = trim($attribute['style']);
264
                        if (mb_substr($st, -1) != ";") $st .= ";";
265
                        $st .= $attribute['__style'];
266
                        $attribute['style'] = $st;
267
                    } else {
268
                        $attribute['style'] = $attribute['__style'];
269
                    }
270
                    unset($attribute['__style']);
271
                }
272
273
            }
274
            foreach ($attribute as $attr => $value) {
275
                if ($attr == "__style") continue;
276
                if ($attr == "class") {
277
                    $classname = "$value";
278
                    continue;
279
                }
280
                $htmlTag .= " $attr=\"$value\"";
281
            }
282
283
        }
284
285
        if (($layout & self::LAYOUT_CLASS) && $classname) {
286
            $htmlTag .= " class=\"$classname\"";
287
        }
288
289
        return "<" . self::encrypt_tag($htmlTag) . ">$content</" . self::encrypt_tag($tag) . ">";
290
    }
291
292
    /**
293
     * Метод, осуществляющий кодирование (сохранение) информации
294
     * с целью невозможности типографировать ее
295
     *
296
     * @param  string $text
297
     * @return string
298
     */
299
    public static function encrypt_tag($text)
300
    {
301
        return base64_encode($text) . "=";
302
    }
303
304
    /**
305
     * Метод, осуществляющий декодирование информации
306
     *
307
     * @param  string $text
308
     * @return string
309
     */
310
    public static function decrypt_tag($text)
311
    {
312
        return base64_decode(substr($text, 0, -1));
313
    }
314
315
    /**
316
     * @param string[] $needle
317
     */
318
    public static function strpos_ex(&$haystack, $needle, $offset = null)
319
    {
320
        if (is_array($needle)) {
321
            $m = false;
322
            $w = false;
323
            foreach ($needle as $n) {
324
                $p = strpos($haystack, $n, $offset);
325
                if ($p === false) continue;
326
                if ($m === false) {
327
                    $m = $p;
328
                    $w = $n;
329
                    continue;
330
                }
331
                if ($p < $m) {
332
                    $m = $p;
333
                    $w = $n;
334
                }
335
            }
336
            if ($m === false) return false;
337
338
            return array('pos' => $m, 'str' => $w);
339
        }
340
341
        return strpos($haystack, $needle, $offset);
342
    }
343
344
    public static function _process_selector_pattern(&$pattern)
345
    {
346
        if ($pattern === false) return;
347
        $pattern = preg_quote($pattern, '/');
348
        $pattern = str_replace("\\*", "[a-z0-9_\-]*", $pattern);
349
        $pattern = "/" . $pattern . "/i";
350
    }
351
352
    public static function _test_pattern($pattern, $text)
353
    {
354
        if ($pattern === false) return true;
355
356
        return preg_match($pattern, $text);
357
    }
358
359
    public static function strtolower($string)
360
    {
361
        $convert_to = array(
362
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
363
            "v", "w", "x", "y", "z", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï",
364
            "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "ø", "ù", "ú", "û", "ü", "ý", "а", "б", "в", "г", "д", "е", "ё", "ж",
365
            "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы",
366
            "ь", "э", "ю", "я"
367
        );
368
        $convert_from = array(
369
            "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
370
            "V", "W", "X", "Y", "Z", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï",
371
            "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж",
372
            "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ъ",
373
            "Ь", "Э", "Ю", "Я"
374
        );
375
376
        return str_replace($convert_from, $convert_to, $string);
377
    }
378
379
    // взято с http://www.w3.org/TR/html4/sgml/entities.html
380
    protected static $html4_char_ents = array(
381
        'nbsp' => 160,
382
        'iexcl' => 161,
383
        'cent' => 162,
384
        'pound' => 163,
385
        'curren' => 164,
386
        'yen' => 165,
387
        'brvbar' => 166,
388
        'sect' => 167,
389
        'uml' => 168,
390
        'copy' => 169,
391
        'ordf' => 170,
392
        'laquo' => 171,
393
        'not' => 172,
394
        'shy' => 173,
395
        'reg' => 174,
396
        'macr' => 175,
397
        'deg' => 176,
398
        'plusmn' => 177,
399
        'sup2' => 178,
400
        'sup3' => 179,
401
        'acute' => 180,
402
        'micro' => 181,
403
        'para' => 182,
404
        'middot' => 183,
405
        'cedil' => 184,
406
        'sup1' => 185,
407
        'ordm' => 186,
408
        'raquo' => 187,
409
        'frac14' => 188,
410
        'frac12' => 189,
411
        'frac34' => 190,
412
        'iquest' => 191,
413
        'Agrave' => 192,
414
        'Aacute' => 193,
415
        'Acirc' => 194,
416
        'Atilde' => 195,
417
        'Auml' => 196,
418
        'Aring' => 197,
419
        'AElig' => 198,
420
        'Ccedil' => 199,
421
        'Egrave' => 200,
422
        'Eacute' => 201,
423
        'Ecirc' => 202,
424
        'Euml' => 203,
425
        'Igrave' => 204,
426
        'Iacute' => 205,
427
        'Icirc' => 206,
428
        'Iuml' => 207,
429
        'ETH' => 208,
430
        'Ntilde' => 209,
431
        'Ograve' => 210,
432
        'Oacute' => 211,
433
        'Ocirc' => 212,
434
        'Otilde' => 213,
435
        'Ouml' => 214,
436
        'times' => 215,
437
        'Oslash' => 216,
438
        'Ugrave' => 217,
439
        'Uacute' => 218,
440
        'Ucirc' => 219,
441
        'Uuml' => 220,
442
        'Yacute' => 221,
443
        'THORN' => 222,
444
        'szlig' => 223,
445
        'agrave' => 224,
446
        'aacute' => 225,
447
        'acirc' => 226,
448
        'atilde' => 227,
449
        'auml' => 228,
450
        'aring' => 229,
451
        'aelig' => 230,
452
        'ccedil' => 231,
453
        'egrave' => 232,
454
        'eacute' => 233,
455
        'ecirc' => 234,
456
        'euml' => 235,
457
        'igrave' => 236,
458
        'iacute' => 237,
459
        'icirc' => 238,
460
        'iuml' => 239,
461
        'eth' => 240,
462
        'ntilde' => 241,
463
        'ograve' => 242,
464
        'oacute' => 243,
465
        'ocirc' => 244,
466
        'otilde' => 245,
467
        'ouml' => 246,
468
        'divide' => 247,
469
        'oslash' => 248,
470
        'ugrave' => 249,
471
        'uacute' => 250,
472
        'ucirc' => 251,
473
        'uuml' => 252,
474
        'yacute' => 253,
475
        'thorn' => 254,
476
        'yuml' => 255,
477
        'fnof' => 402,
478
        'Alpha' => 913,
479
        'Beta' => 914,
480
        'Gamma' => 915,
481
        'Delta' => 916,
482
        'Epsilon' => 917,
483
        'Zeta' => 918,
484
        'Eta' => 919,
485
        'Theta' => 920,
486
        'Iota' => 921,
487
        'Kappa' => 922,
488
        'Lambda' => 923,
489
        'Mu' => 924,
490
        'Nu' => 925,
491
        'Xi' => 926,
492
        'Omicron' => 927,
493
        'Pi' => 928,
494
        'Rho' => 929,
495
        'Sigma' => 931,
496
        'Tau' => 932,
497
        'Upsilon' => 933,
498
        'Phi' => 934,
499
        'Chi' => 935,
500
        'Psi' => 936,
501
        'Omega' => 937,
502
        'alpha' => 945,
503
        'beta' => 946,
504
        'gamma' => 947,
505
        'delta' => 948,
506
        'epsilon' => 949,
507
        'zeta' => 950,
508
        'eta' => 951,
509
        'theta' => 952,
510
        'iota' => 953,
511
        'kappa' => 954,
512
        'lambda' => 955,
513
        'mu' => 956,
514
        'nu' => 957,
515
        'xi' => 958,
516
        'omicron' => 959,
517
        'pi' => 960,
518
        'rho' => 961,
519
        'sigmaf' => 962,
520
        'sigma' => 963,
521
        'tau' => 964,
522
        'upsilon' => 965,
523
        'phi' => 966,
524
        'chi' => 967,
525
        'psi' => 968,
526
        'omega' => 969,
527
        'thetasym' => 977,
528
        'upsih' => 978,
529
        'piv' => 982,
530
        'bull' => 8226,
531
        'hellip' => 8230,
532
        'prime' => 8242,
533
        'Prime' => 8243,
534
        'oline' => 8254,
535
        'frasl' => 8260,
536
        'weierp' => 8472,
537
        'image' => 8465,
538
        'real' => 8476,
539
        'trade' => 8482,
540
        'alefsym' => 8501,
541
        'larr' => 8592,
542
        'uarr' => 8593,
543
        'rarr' => 8594,
544
        'darr' => 8595,
545
        'harr' => 8596,
546
        'crarr' => 8629,
547
        'lArr' => 8656,
548
        'uArr' => 8657,
549
        'rArr' => 8658,
550
        'dArr' => 8659,
551
        'hArr' => 8660,
552
        'forall' => 8704,
553
        'part' => 8706,
554
        'exist' => 8707,
555
        'empty' => 8709,
556
        'nabla' => 8711,
557
        'isin' => 8712,
558
        'notin' => 8713,
559
        'ni' => 8715,
560
        'prod' => 8719,
561
        'sum' => 8721,
562
        'minus' => 8722,
563
        'lowast' => 8727,
564
        'radic' => 8730,
565
        'prop' => 8733,
566
        'infin' => 8734,
567
        'ang' => 8736,
568
        'and' => 8743,
569
        'or' => 8744,
570
        'cap' => 8745,
571
        'cup' => 8746,
572
        'int' => 8747,
573
        'there4' => 8756,
574
        'sim' => 8764,
575
        'cong' => 8773,
576
        'asymp' => 8776,
577
        'ne' => 8800,
578
        'equiv' => 8801,
579
        'le' => 8804,
580
        'ge' => 8805,
581
        'sub' => 8834,
582
        'sup' => 8835,
583
        'nsub' => 8836,
584
        'sube' => 8838,
585
        'supe' => 8839,
586
        'oplus' => 8853,
587
        'otimes' => 8855,
588
        'perp' => 8869,
589
        'sdot' => 8901,
590
        'lceil' => 8968,
591
        'rceil' => 8969,
592
        'lfloor' => 8970,
593
        'rfloor' => 8971,
594
        'lang' => 9001,
595
        'rang' => 9002,
596
        'loz' => 9674,
597
        'spades' => 9824,
598
        'clubs' => 9827,
599
        'hearts' => 9829,
600
        'diams' => 9830,
601
        'quot' => 34,
602
        'amp' => 38,
603
        'lt' => 60,
604
        'gt' => 62,
605
        'OElig' => 338,
606
        'oelig' => 339,
607
        'Scaron' => 352,
608
        'scaron' => 353,
609
        'Yuml' => 376,
610
        'circ' => 710,
611
        'tilde' => 732,
612
        'ensp' => 8194,
613
        'emsp' => 8195,
614
        'thinsp' => 8201,
615
        'zwnj' => 8204,
616
        'zwj' => 8205,
617
        'lrm' => 8206,
618
        'rlm' => 8207,
619
        'ndash' => 8211,
620
        'mdash' => 8212,
621
        'lsquo' => 8216,
622
        'rsquo' => 8217,
623
        'sbquo' => 8218,
624
        'ldquo' => 8220,
625
        'rdquo' => 8221,
626
        'bdquo' => 8222,
627
        'dagger' => 8224,
628
        'Dagger' => 8225,
629
        'permil' => 8240,
630
        'lsaquo' => 8249,
631
        'rsaquo' => 8250,
632
        'euro' => 8364,
633
    );
634
635
    /**
636
     * Вернуть уникод символ по html entinty
637
     *
638
     * @param  string $entity
639
     * @return string
640
     */
641
    public static function html_char_entity_to_unicode($entity)
642
    {
643
        if (isset(self::$html4_char_ents[$entity])) return self::_getUnicodeChar(self::$html4_char_ents[$entity]);
644
645
        return false;
646
    }
647
648
    /**
649
     * Сконвериторвать все html entity в соответсвующие юникод символы
650
     *
651
     * @param string $text
652
     */
653
    public static function convert_html_entities_to_unicode(&$text)
654
    {
655
        $text = preg_replace_callback('/\&#([0-9]+)\;/', function ($m) {
656
            return self::_getUnicodeChar(intval($m[1]));
657
        }, $text);
658
659
        $text = preg_replace_callback('/\&#x([0-9A-F]+)\;/', function ($m) {
660
            return self::_getUnicodeChar(hexdec($m[1]));
661
        }, $text);
662
663
        $text = preg_replace_callback('/\&([a-zA-Z0-9]+)\;/', function ($m) {
664
            $r = self::html_char_entity_to_unicode($m[1]);
665
666
            return $r ? $r : $m[0];
667
        }, $text);
668
    }
669
670
    /**
671
     * @param string $needle
672
     */
673
    public static function rstrpos($haystack, $needle, $offset = 0)
674
    {
675
        if (trim($haystack) != "" && trim($needle) != "" && $offset <= mb_strlen($haystack)) {
676
            $last_pos = $offset;
677
            $found = false;
678
            while (($curr_pos = mb_strpos($haystack, $needle, $last_pos)) !== false) {
679
                $found = true;
680
                $last_pos = $curr_pos + 1;
681
            }
682
            if ($found) {
683
                return $last_pos - 1;
684
            } else {
685
                return false;
686
            }
687
        } else {
688
            return false;
689
        }
690
    }
691
692
    public static function ifop($cond, $true, $false)
693
    {
694
        return $cond ? $true : $false;
695
    }
696
697
}
698