Completed
Push — master ( 5fd908...1b4f1b )
by Maxim
02:44
created

APIhelpers::sanitarIn()   A

Complexity

Conditions 6
Paths 24

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6.9157

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 20
ccs 12
cts 17
cp 0.7059
rs 9.2222
cc 6
nc 24
nop 3
crap 6.9157
1
<?php
2
3
/**
4
 * Class APIhelpers
5
 */
6
class APIhelpers
7
{
8
9
    /**
10
     * Преобразует первый символ в нижний регистр
11
     * @param $str
12
     * @param string $encoding - кодировка, по-умолчанию UTF-8
13
     * @return string
14
     */
15
    public static function mb_lcfirst($str, $encoding = 'UTF-8')
0 ignored issues
show
Coding Style introduced by
Method name "APIhelpers::mb_lcfirst" is not in camel caps format
Loading history...
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
16
    {
17
        return mb_strtolower(mb_substr($str, 0, 1, $encoding), $encoding) . mb_substr(
18
            $str,
19
            1,
20
            mb_strlen($str),
21
            $encoding
22
        );
23
    }
24
25
    /**
26
     * mb_ucfirst - преобразует первый символ в верхний регистр
27
     * @param string $str - строка
28
     * @param string $encoding - кодировка, по-умолчанию UTF-8
29
     * @return string
30
     */
31
    public static function mb_ucfirst($str, $encoding = 'UTF-8')
0 ignored issues
show
Coding Style introduced by
Method name "APIhelpers::mb_ucfirst" is not in camel caps format
Loading history...
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
32
    {
33
        $str = mb_ereg_replace('^[\ ]+', '', $str);
34
        $str = mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding) . mb_substr(
35
            $str,
36
            1,
37
            mb_strlen($str),
38
            $encoding
39
        );
40
41
        return $str;
42
    }
43
44
    /**
45
     * Обрезание текста по длине с поиском последнего полностью вмещающегося слова и удалением лишних крайних знаков пунктуации.
46
     *
47
     * @author Agel_Nash <[email protected]>
48
     * @version 0.1
49
     *
50
     * @param string $html HTML текст
51
     * @param integer $len максимальная длина строки
52
     * @param string $encoding кодировка
53
     * @return string
54
     */
55
    public static function mb_trim_word($html, $len, $encoding = 'UTF-8')
0 ignored issues
show
Coding Style introduced by
Method name "APIhelpers::mb_trim_word" is not in camel caps format
Loading history...
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
56
    {
57
        $text = trim(preg_replace('|\s+|', ' ', strip_tags($html)));
58
        $text = mb_substr($text, 0, $len + 1, $encoding);
59
        if (mb_substr($text, -1, null, $encoding) == ' ') {
60
            $out = trim($text);
61
        } else {
62
            $out = mb_substr($text, 0, mb_strripos($text, ' ', null, $encoding), $encoding);
63
        }
64
65
        return preg_replace("/(([\.,\-:!?;\s])|(&\w+;))+$/ui", "", $out);
66
    }
67
68
    /**
69
     * Получение значения по ключу из массива, либо возврат значения по умолчанию
70
     *
71
     * @param mixed $data массив
72
     * @param string $key ключ массива
73
     * @param mixed $default null значение по умолчанию
74
     * @param Closure $validate null функция дополнительной валидации значения (должна возвращать true или false)
75
     * @return mixed
76
     */
77 72
    public static function getkey($data, $key, $default = null, $validate = null)
78
    {
79 72
        $out = $default;
80 72
        if (is_array($data) && (is_int($key) || is_string($key)) && $key !== '' && array_key_exists($key, $data)) {
81 72
            $out = $data[$key];
82 72
        }
83 72
        if (! empty($validate) && is_callable($validate)) {
84
            $out = (($validate($out) === true) ? $out : $default);
85
        }
86 72
87
        return $out;
88
    }
89
90
    /**
91
     * Email validate
92
     *
93
     * @category   validate
94
     * @version    0.1
95
     * @license    GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html
96
     * @param string $email проверяемый email
97
     * @param boolean $dns проверять ли DNS записи
98
     * @return boolean|string Результат проверки почтового ящика
99
     * @author Anton Shevchuk
100
     */
101
    public static function emailValidate($email, $dns = true)
102
    {
103
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
104
            list(, $domain) = explode("@", $email, 2);
105
            if (! $dns || ($dns && checkdnsrr($domain, "MX") && checkdnsrr($domain, "A"))) {
106
                $error = false;
107
            } else {
108
                $error = 'dns';
109
            }
110
        } else {
111
            $error = 'format';
112
        }
113
114
        return $error;
115
    }
116
117
    /**
118
     * Password generate
119
     *
120
     * @category   generate
121
     * @version   0.1
122
     * @license    GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html
123
     * @param string $len длина пароля
124
     * @param string $data правила генерации пароля
125
     * @return string Строка с паролем
126
     * @author Agel_Nash <[email protected]>
127
     *
128
     * Расшифровка значений $data
129
     * "A": A-Z буквы
130
     * "a": a-z буквы
131
     * "0": цифры
132
     * ".": все печатные символы
133
     *
134
     * @example
135
     * $this->genPass(10,"Aa"); //nwlTVzFdIt
136
     * $this->genPass(8,"0"); //71813728
137
     * $this->genPass(11,"A"); //VOLRTMEFAEV
138
     * $this->genPass(5,"a0"); //4hqi7
139
     * $this->genPass(5,"."); //2_Vt}
140
     * $this->genPass(20,"."); //AMV,>&?J)v55,(^g}Z06
141
     * $this->genPass(20,"aaa0aaa.A"); //rtvKja5xb0\KpdiRR1if
142
     */
143
    public static function genPass($len, $data = '')
144
    {
145
        if ($data == '') {
146
            $data = 'Aa0.';
147
        }
148
        $opt = strlen($data);
149
        $pass = array();
150
151
        for ($i = $len; $i > 0; $i--) {
152
            switch ($data[rand(0, ($opt - 1))]) {
153
                case 'A':
154
                    $tmp = rand(65, 90);
155
                    break;
156
                case 'a':
157
                    $tmp = rand(97, 122);
158
                    break;
159
                case '0':
160
                    $tmp = rand(48, 57);
161
                    break;
162
                default:
163
                    $tmp = rand(33, 126);
164
            }
165
            $pass[] = chr($tmp);
166
        }
167
        $pass = implode("", $pass);
168
169
        return $pass;
170
    }
171
172
    /**
173
     * @param $data
174
     * @return bool|false|string
175
     */
176
    public static function getEnv($data)
177
    {
178
        switch (true) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $tmp = getenv($data) of type string to the boolean true. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
179
            case (isset($_SERVER[$data])):
180
                $out = $_SERVER[$data];
181
                break;
182
            case (isset($_ENV[$data])):
183
                $out = $_ENV[$data];
184
                break;
185
            case ($tmp = getenv($data)):
186
                $out = $tmp;
187
                break;
188
            case (function_exists('apache_getenv') && $tmp = apache_getenv($data, true)):
189
                $out = $tmp;
190
                break;
191
            default:
192
                $out = false;
193
        }
194
        unset($tmp);
195
196
        return $out;
197
    }
198
199
    /**
200
     * User IP
201
     *
202
     * @category   validate
203
     * @version   0.1
204
     * @license    GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html
205
     * @param string $default IP адрес который будет отдан функцией, если больше ничего не обнаружено
206
     * @return string IP пользователя
207
     * @author Agel_Nash <[email protected]>
208
     *
209
     * @see http://stackoverflow.com/questions/5036443/php-how-to-block-proxies-from-my-site
210
     */
211
    public static function getUserIP($default = '127.0.0.1')
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
212
    {
213
        //Порядок условий зависит от приоритетов
214
        switch (true) {
215
            case ($tmp = self::getEnv('HTTP_COMING_FROM')):
216
                $out = $tmp;
217
                break;
218
            case ($tmp = self::getEnv('HTTP_X_COMING_FROM')):
219
                $out = $tmp;
220
                break;
221
            case ($tmp = self::getEnv('HTTP_VIA')):
222
                $out = $tmp;
223
                break;
224
            case ($tmp = self::getEnv('HTTP_FORWARDED')):
225
                $out = $tmp;
226
                break;
227
            case ($tmp = self::getEnv('HTTP_FORWARDED_FOR')):
228
                $out = $tmp;
229
                break;
230
            case ($tmp = self::getEnv('HTTP_X_FORWARDED')):
231
                $out = $tmp;
232
                break;
233
            case ($tmp = self::getEnv('HTTP_X_FORWARDED_FOR')):
234
                $out = $tmp;
235
                break;
236
            case (! empty($_SERVER['REMOTE_ADDR'])):
237
                $out = $_SERVER['REMOTE_ADDR'];
238
                break;
239
            default:
240
                $out = false;
241
        }
242
        unset($tmp);
243
244
        return (false !== $out && preg_match('|^(?:[0-9]{1,3}\.){3,3}[0-9]{1,3}$|', $out, $matches)) ? $out : $default;
245
    }
246
247
    /**
248
     * @param $data
249
     * @param string $charset
250
     * @param array $chars
251
     * @return array|mixed|string
252 61
     */
253
    public static function sanitarTag(
254
        $data,
255
        $charset = 'UTF-8',
256
        $chars = array(
257
            '['   => '&#91;',
258
            '%5B' => '&#91;',
259
            ']'   => '&#93;',
260
            '%5D' => '&#93;',
261
            '{'   => '&#123;',
262
            '%7B' => '&#123;',
263
            '}'   => '&#125;',
264
            '%7D' => '&#125;',
265
            '`'   => '&#96;',
266
            '%60' => '&#96;'
267
        )
268
    ) {
269 61
        switch (true) {
270 61
            case is_scalar($data):
271 61
                $out = str_replace(
272 61
                    array_keys($chars),
273 61
                    array_values($chars),
274 61
                    $charset === null ? $data : self::e($data, $charset)
0 ignored issues
show
introduced by
The condition $charset === null is always false.
Loading history...
275 61
                );
276 3
                break;
277 2
            case is_array($data):
278 2
                $out = array();
279 2
                foreach ($data as $key => $val) {
280 2
                    $key = self::sanitarTag($key, $charset, $chars);
281 2
                    $out[$key] = self::sanitarTag($val, $charset, $chars);
282 2
                }
283 1
                break;
284 1
            default:
285 1
                $out = '';
286
        }
287 61
288
        return $out;
289
    }
290
291
    /**
292
     * @param $text
293
     * @param string $charset
294
     * @return string
295 58
     */
296
    public static function e($text, $charset = 'UTF-8')
297 58
    {
298
        return is_scalar($text) ? htmlspecialchars($text, ENT_QUOTES, $charset, false) : '';
299
    }
300
301
    /**
302
     * Проверка строки на наличе запрещенных символов
303
     * Проверка конечно круто, но валидация русских символов в строке порой завершается не удачей по разным причинам
304
     * (начиная от кривых настроек сервера и заканчивая кривыми настройками кодировки на сайте)
305
     *
306
     * @param string $value Проверяемая строка
307
     * @param int $minLen Минимальная длина строки
308
     * @param array $alph Разрешенные алфавиты
309
     * @param array $mixArray Примесь символов, которые так же могут использоваться в строке
310
     * @return bool
311
     */
312
    public static function checkString($value, $minLen = 1, $alph = array(), $mixArray = array())
0 ignored issues
show
Coding Style introduced by
Function's nesting level (5) exceeds 3; consider refactoring the function
Loading history...
313
    {
314
        $flag = true;
315
        $len = mb_strlen($value, 'UTF-8');
316
        $value = trim($value);
317
        if (mb_strlen($value, 'UTF-8') == $len) {
318
            $data = is_array($mixArray) ? $mixArray : array();
0 ignored issues
show
introduced by
The condition is_array($mixArray) is always true.
Loading history...
319
            $alph = is_array($alph) ? array_unique($alph) : array();
0 ignored issues
show
introduced by
The condition is_array($alph) is always true.
Loading history...
320
            foreach ($alph as $item) {
321
                $item = strtolower($item);
322
                switch ($item) {
323
                    case 'rus':
324
                        $data = array_merge($data, array(
325
                            'А',
326
                            'Б',
327
                            'В',
328
                            'Г',
329
                            'Д',
330
                            'Е',
331
                            'Ё',
332
                            'Ж',
333
                            'З',
334
                            'И',
335
                            'Й',
336
                            'К',
337
                            'Л',
338
                            'М',
339
                            'Н',
340
                            'О',
341
                            'П',
342
                            'Р',
343
                            'С',
344
                            'Т',
345
                            'У',
346
                            'Ф',
347
                            'Х',
348
                            'Ц',
349
                            'Ч',
350
                            'Ш',
351
                            'Щ',
352
                            'Ъ',
353
                            'Ы',
354
                            'Ь',
355
                            'Э',
356
                            'Ю',
357
                            'Я'
358
                        ));
359
                        break;
360
                    case 'num':
361
                        $tmp = range('0', '9');
362
                        foreach ($tmp as $t) {
363
                            $data[] = (string)$t;
364
                        }
365
                        break;
366
                    case 'eng':
367
                        $data = array_merge($data, range('A', 'Z'));
368
                        break;
369
                }
370
            }
371
            for ($i = 0; $i < $len; $i++) {
372
                $chr = mb_strtoupper(mb_substr($value, $i, 1, 'UTF-8'), 'UTF-8');
373
                if (!in_array($chr, $data, true)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
374
                    $flag = false;
375
                    break;
376
                }
377
            }
378
            $flag = ($flag && $len >= $minLen);
379
        } else {
380
            $flag = false;
381
        }
382
383
        return $flag;
384
    }
385
386
    /**
387
     * @param $IDs
388
     * @param string $sep
389
     * @param integer[] $ignore
390
     * @return array
391
     * @throws Exception
392 5
     */
393
    public static function cleanIDs($IDs, $sep = ',', $ignore = array())
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
394 5
    {
395 5
        $out = array();
396 5
        if (!is_array($IDs)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
397 4
            if (is_scalar($IDs)) {
398 4
                $IDs = explode($sep, $IDs);
399 1
            } else {
400 1
                $IDs = array();
401
                throw new Exception('Invalid IDs list <pre>' . print_r($IDs, 1) . '</pre>');
402 4
            }
403 4
        }
404 4
        foreach ($IDs as $item) {
405 4
            $item = trim($item);
406 4
            if (is_scalar($item) && (int)$item >= 0) { //Fix 0xfffffffff
407 4
                if (empty($ignore) || !\in_array((int)$item, $ignore, true)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
408 4
                    $out[] = (int)$item;
409 4
                }
410 4
            }
411 4
        }
412
        $out = array_unique($out);
413 4
414
        return $out;
415
    }
416
417
    /**
418
     * Предварительная обработка данных перед вставкой в SQL запрос вида IN
419
     * Если данные в виде строки, то происходит попытка сформировать массив из этой строки по разделителю $sep
420
     * Точно по тому, по которому потом данные будут собраны обратно
421
     *
422
     * @param integer|string|array $data данные для обработки
423
     * @param string $sep разделитель
424
     * @param boolean $quote заключать ли данные на выходе в кавычки
425
     * @return string обработанная строка
426 59
     */
427
    public static function sanitarIn($data, $sep = ',', $quote = true)
428 59
    {
429 59
        $modx = evolutionCMS();
0 ignored issues
show
Bug introduced by
The function evolutionCMS was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

429
        $modx = /** @scrutinizer ignore-call */ evolutionCMS();
Loading history...
430 1
        if (is_scalar($data)) {
431 1
            $data = explode($sep, $data);
432 58
        }
433 58
        if (!is_array($data)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
introduced by
The condition is_array($data) is always true.
Loading history...
434 58
            $data = array(); //@TODO: throw
435 58
        }
436 58
437
        $out = array();
438 58
        foreach ($data as $item) {
439 58
            if ($item !== '') {
440 58
                $out[] = $modx->db->escape($item);
441
            }
442
        }
443
        $q = $quote ? "'" : "";
444
        $out = $q . implode($q . "," . $q, $out) . $q;
445
446
        return $out;
447 58
    }
448 58
449
    /**
450
     * Переменовывание элементов массива
451 59
     *
452
     * @param array $data массив с данными
453
     * @param string $prefix префикс ключей
454
     * @param string $suffix суффикс ключей
455
     * @param string $addPS разделитель суффиксов, префиксов и ключей массива
456
     * @param string $sep разделитель ключей при склейке многомерных массивов
457
     * @return array массив с переименованными ключами
458
     */
459
    public static function renameKeyArr($data, $prefix = '', $suffix = '', $addPS = '.', $sep = '.')
0 ignored issues
show
Coding Style introduced by
Function's nesting level (4) exceeds 3; consider refactoring the function
Loading history...
460
    {
461
        $out = array();
462
        if ($prefix == '' && $suffix == '') {
463
            $out = $data;
464
        } else {
465
            $InsertPrefix = ($prefix != '') ? ($prefix . $addPS) : '';
466
            $InsertSuffix = ($suffix != '') ? ($addPS . $suffix) : '';
467
            foreach ($data as $key => $item) {
468
                $key = $InsertPrefix . $key;
469
                $val = null;
470
                switch (true) {
471
                    case is_scalar($item):
472
                        $val = $item;
473
                        break;
474
                    case is_array($item):
475
                        $val = self::renameKeyArr($item, $key . $sep, $InsertSuffix, '', $sep);
476
                        $out = array_merge($out, $val);
477
                        $val = '';
478
                        break;
479
                }
480
                $out[$key . $InsertSuffix] = $val;
481
            }
482
        }
483
484
        return $out;
485
    }
486
}
487