Issues (26)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/EMT/Util.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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