Test Failed
Branch v5 (12d602)
by Alexey
04:51
created

Tools::header()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 6
nop 2
dl 0
loc 14
rs 9.2
c 0
b 0
f 0
1
<?php
2
namespace Inji;
3
/**
4
 * Tools object
5
 *
6
 * Toolkit with most needed functions
7
 *
8
 * @author Alexey Krupskiy <[email protected]>
9
 * @link http://inji.ru/
10
 * @copyright 2015 Alexey Krupskiy
11
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
12
 */
13
class Tools extends Model {
14
15
    /**
16
     * Return random string
17
     *
18
     * @param int $length
19
     * @param string $characters
20
     * @return string
21
     */
22
    public static function randomString($length = 20, $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
23
        $charactersLength = strlen($characters);
24
        $randomString = '';
25
        for ($i = 0; $i < $length; $i++) {
26
            $randomString .= $characters[rand(0, $charactersLength - 1)];
27
        }
28
        return $randomString;
29
    }
30
31
    /**
32
     * Clean and return user query params
33
     *
34
     * @param string $uri
35
     * @return array
36
     */
37
    public static function uriParse($uri) {
38
        $answerPos = strpos($uri, '?');
39
        $params = array_slice(explode('/', substr($uri, 0, $answerPos ? $answerPos : strlen($uri))), 1);
40
41
        foreach ($params as $key => $param) {
42
            if ($param != '') {
43
                $params[$key] = urldecode($param);
44
            } else {
45
                unset($params[$key]);
46
            }
47
        }
48
        return $params;
49
    }
50
51
    /**
52
     * Recursive create dir
53
     *
54
     * @param string $path
55
     * @return boolean
56
     */
57
    public static function createDir($path) {
58
        if (file_exists($path)) {
59
            return true;
60
        }
61
        $root = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $_SERVER['DOCUMENT_ROOT']), '/') . '/';
62
        if (strpos($path, $root) === 0) {
63
            $path = str_replace($root, '', $path);
64
        }
65
        $path = explode('/', $path);
66
        $cur = '';
67
        foreach ($path as $item) {
68
            $cur .= $item . '/';
69
            if (!file_exists($cur)) {
70
                mkdir($cur);
71
            }
72
        }
73
        return true;
74
    }
75
76
    public static function delDir($dir) {
77
        if (!file_exists($dir)) {
78
            return true;
79
        }
80
        $files = array_diff(scandir($dir), array('.', '..'));
81
        foreach ($files as $file) {
82
            is_dir("$dir/$file") ? self::delDir("$dir/$file") : unlink("$dir/$file");
83
        }
84
        return rmdir($dir);
85
    }
86
87
    /**
88
     * Resize image in path
89
     *
90
     * @param string $img_path
91
     * @param int $max_width
92
     * @param int $max_height
93
     * @param string|false $crop
94
     * @param string $pos
95
     * @return string
96
     */
97
    public static function resizeImage($img_path, $max_width = 1000, $max_height = 1000, $crop = false, $pos = 'center') {
98
        ini_set("gd.jpeg_ignore_warning", 1);
99
        if (!getimagesize($img_path)) {
100
            return false;
101
        }
102
        list($img_width, $img_height, $img_type, $img_tag) = getimagesize($img_path);
103
        switch ($img_type) {
104
            case 1:
105
                $img_type = 'gif';
106
                break;
107
            case 3:
108
                $img_type = 'png';
109
                break;
110
            case 2:
111
            default:
112
                $img_type = 'jpeg';
113
                break;
114
        }
115
        $imagecreatefromX = "imagecreatefrom{$img_type}";
116
        $src_res = @$imagecreatefromX($img_path);
117
        if (!$src_res) {
118
            return false;
119
        }
120
121
        if ($img_width / $max_width > $img_height / $max_height) {
122
            $separator = $img_width / $max_width;
123
        } else {
124
            $separator = $img_height / $max_height;
125
        }
126
127
        if ($crop === true || $crop == 'q') {
128
            if ($img_width > $img_height) {
129
                $imgX = floor(($img_width - $img_height) / 2);
130
                $imgY = 0;
131
                $img_width = $img_height;
132
                $new_width = $max_width;
133
                $new_height = $max_height;
134 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
135
                $imgX = 0;
136
                $imgY = floor(($img_height - $img_width) / 2);
137
                $img_height = $img_width;
138
                $new_width = $max_width;
139
                $new_height = $max_height;
140
            }
141
            if ($pos == 'top') {
142
                $imgY = 0;
143
            }
144
        } elseif ($crop == 'c') {
145
//Вычисляем некий коэффициент масштабирования
146
            $k1 = $img_width / $max_width;
147
            $k2 = $img_height / $max_height;
148
            $k = $k1 > $k2 ? $k2 : $k1;
149
            $ow = $img_width;
150
            $oh = $img_height;
151
//Вычисляем размеры области для нового изображения
152
            $img_width = intval($max_width * $k);
153
            $img_height = intval($max_height * $k);
154
            $new_width = $max_width;
155
            $new_height = $max_height;
156
//Находим начальные координаты (центрируем новое изображение)
157
            $imgX = (int) (($ow / 2) - ($img_width / 2));
158
            if ($pos == 'center') {
159
                $imgY = (int) (($oh / 2) - ($img_height / 2));
160
            } else {
161
                $imgY = 0;
162
            }
163 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
164
            $imgX = 0;
165
            $imgY = 0;
166
            $new_width = floor($img_width / $separator);
167
            $new_height = floor($img_height / $separator);
168
        }
169
170
        $new_res = imagecreatetruecolor($new_width, $new_height);
171
        imageAlphaBlending($new_res, false);
172
        imagesavealpha($new_res, true);
173
        imagecopyresampled($new_res, $src_res, 0, 0, $imgX, $imgY, $new_width, $new_height, $img_width, $img_height);
174
175
        if ($img_type == 'jpeg') {
176
            imageinterlace($new_res, 1); // чересстрочное формирование изображение
177
            imagejpeg($new_res, $img_path, 85);
178
        } else {
179
            $imageX = "image{$img_type}";
180
            $imageX($new_res, $img_path);
181
        }
182
183
        imagedestroy($new_res);
184
        imagedestroy($src_res);
185
        return $img_type;
186
    }
187
188
    public static function imgToResource($path) {
189
        ini_set("gd.jpeg_ignore_warning", 1);
190
        if (!getimagesize($path)) {
191
            return false;
192
        }
193
        list($img_width, $img_height, $imgType, $img_tag) = getimagesize($path);
0 ignored issues
show
Unused Code introduced by
The assignment to $img_width is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $img_height is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $img_tag is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
194
        switch ($imgType) {
195
            case 1:
196
                $imgType = 'gif';
197
                break;
198
            case 3:
199
                $imgType = 'png';
200
                break;
201
            case 2:
202
            default:
203
                $imgType = 'jpeg';
204
                break;
205
        }
206
207
        $imagecreatefromX = "imagecreatefrom{$imgType}";
208
        $src_res = @$imagecreatefromX($path);
209
        return [
210
            'res' => $src_res,
211
            'type' => $imgType
212
        ];
213
    }
214
215
    public static function addWatermark($imagePath, $watermarkPath) {
216
217
        $image = self::imgToResource($imagePath);
218
        $watermark = self::imgToResource($watermarkPath);
219
        if (!$image || !$watermark || !$image['res'] || !$watermark['res']) {
220
            return false;
221
        }
222
223
        $marge_right = 10;
224
        $marge_bottom = 10;
225
        $sx = imagesx($watermark['res']);
226
        $sy = imagesy($watermark['res']);
227
228
        imagecopy($image['res'], $watermark['res'], imagesx($image['res']) - $sx - $marge_right, imagesy($image['res']) - $sy - $marge_bottom, 0, 0, imagesx($watermark['res']), imagesy($watermark['res']));
229
230
        if ($image['type'] == 'jpeg') {
231
            imageinterlace($image['res'], 1); // чересстрочное формирование изображение
232
            imagejpeg($image['res'], $imagePath, 85);
233
        } else {
234
            $imageX = "image{$image['type']}";
235
            $imageX($image['res'], $imagePath);
236
        }
237
238
        imagedestroy($watermark['res']);
239
        imagedestroy($image['res']);
240
241
        return true;
242
    }
243
244
    /**
245
     * Send mail
246
     *
247
     * @param string $from
248
     * @param string $to
249
     * @param string $subject
250
     * @param string $text
251
     * @param string $charset
252
     * @param string $ctype
253
     * @return boolean
254
     */
255
    public static function sendMail($from, $to, $subject, $text, $charset = 'utf-8', $ctype = 'text/html') {
256
        $msg = compact('from', 'to', 'subject', 'text', 'charset', 'ctype');
257
        $msg = Inji::$inst->event('sendMail', $msg);
258
        if (is_array($msg)) {
259
            $headers = "From: {$msg['from']}\r\n";
260
            $headers .= "Content-type: {$msg['ctype']}; charset={$msg['charset']}\r\n";
261
            $headers .= "Mime-Version: 1.0\r\n";
262
            return mail($msg['to'], $msg['subject'], $msg['text'], $headers);
263
        }
264
        return $msg;
265
    }
266
267
    /**
268
     * Redirect user from any place of code
269
     *
270
     * Also add message to message query for view
271
     *
272
     * @param string $href
273
     * @param string $text
274
     * @param string $status
275
     */
276
    public static function redirect($href = null, $text = false, $status = 'info') {
277
        if ($href === null) {
278
            $href = $_SERVER['REQUEST_URI'];
279
        }
280
        if ($text !== false) {
281
            \Inji\Msg::add($text, $status);
282
        }
283
        if (!headers_sent()) {
284
            header("Location: {$href}");
285
        } else {
286
            echo '\'"><script>window.location="' . $href . '";</script>';
287
        }
288
        exit("Перенаправление на: <a href = '{$href}'>{$href}</a>");
289
    }
290
291
    /**
292
     * Функция возвращает окончание для множественного числа слова на основании числа и массива окончаний
293
     * @param  Integer $number Число на основе которого нужно сформировать окончание
294
     * @param  String[] $endingArray Массив слов или окончаний для чисел (1, 4, 5),
295
     *         например ['яблоко', 'яблока', 'яблок']
296
     * @return String
297
     */
298
    public static function getNumEnding($number, $endingArray) {
299
        $number = $number % 100;
300
        if ($number >= 11 && $number <= 19) {
301
            $ending = $endingArray[2];
302
        } else {
303
            $i = $number % 10;
304
            switch ($i) {
305
                case (1):
306
                    $ending = $endingArray[0];
307
                    break;
308
                case (2):
309
                case (3):
310
                case (4):
311
                    $ending = $endingArray[1];
312
                    break;
313
                default:
314
                    $ending = $endingArray[2];
315
            }
316
        }
317
        return $ending;
318
    }
319
320
    /**
321
     * Clean request path
322
     *
323
     * @param string $path
324
     * @return string
325
     */
326
    public static function parsePath($path) {
327
        $path = str_replace('\\', '/', $path);
328
        $pathArray = explode('/', $path);
329
        $cleanPathArray = [];
330
        do {
331
            $changes = 0;
332
            foreach ($pathArray as $pathItem) {
333
                if (trim($pathItem) === '' || $pathItem == '.') {
334
                    $changes++;
335
                    continue;
336
                }
337
                if ($pathItem == '..') {
338
                    array_pop($cleanPathArray);
339
                    $changes++;
340
                    continue;
341
                }
342
                $cleanPathArray[] = $pathItem;
343
            }
344
            $pathArray = $cleanPathArray;
345
            $cleanPathArray = [];
346
        } while ($changes);
347
        return (strpos($path, '/') === 0 ? '/' : '') . implode('/', $pathArray);
348
    }
349
350
    /**
351
     * Show date in rus
352
     *
353
     * @param string $date
354
     * @return string
355
     */
356
    public static function toRusDate($date) {
357
        $yy = (int) substr($date, 0, 4);
358
        $mm = (int) substr($date, 5, 2);
359
        $dd = (int) substr($date, 8, 2);
360
361
        $hours = substr($date, 11, 5);
362
363
        $month = array('января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря');
364
        if (empty($month[$mm - 1])) {
365
            return 'Не указано';
366
        }
367
        return ($dd > 0 ? $dd . " " : '') . $month[$mm - 1] . " " . $yy . " " . $hours;
368
    }
369
370
    /**
371
     * Set header
372
     *
373
     * @param string $code
374
     * @param boolean $exit
375
     */
376
    public static function header($code, $exit = false) {
377
        if (!headers_sent()) {
378
            switch ($code) {
379
                case '404':
380
                    header('HTTP/1.1 404 Not Found');
381
                    break;
382
                default:
383
                    header($code);
384
            }
385
        }
386
        if ($exit) {
387
            exit;
388
        }
389
    }
390
391
    /**
392
     * Return exist path from array
393
     *
394
     * If no exist path in array - return default
395
     *
396
     * @param array $paths
397
     * @param string|boolean $default
398
     * @return string|boolean
399
     */
400
    public static function pathsResolve($paths = [], $default = false) {
401
        foreach ($paths as $path) {
402
            if (file_exists($path)) {
403
                return $path;
404
            }
405
        }
406
        return $default;
407
    }
408
409
    /**
410
     * Convert acronyms to bites
411
     *
412
     * @param string $val
413
     * @return int
414
     */
415
    public static function toBytes($val) {
416
        $val = trim($val);
417
        $last = strtolower($val[strlen($val) - 1]);
418
        switch ($last) {
419
            case 'g':
420
                $val *= 1024;
421
            // no break
422
            case 'm':
423
                $val *= 1024;
424
            // no break
425
            case 'k':
426
                $val *= 1024;
427
        }
428
429
        return $val;
430
    }
431
432
    /**
433
     * Recursive copy directories and files
434
     *
435
     * @param string $from
436
     * @param string $to
437
     */
438
    public static function copyFiles($from, $to) {
439
        $from = rtrim($from, '/');
440
        $to = rtrim($to, '/');
441
        self::createDir($to);
442
        $files = scandir($from);
443
        foreach ($files as $file) {
444
            if (in_array($file, ['.', '..'])) {
445
                continue;
446
            }
447
            if (is_dir($from . '/' . $file)) {
448
                self::copyFiles($from . '/' . $file, $to . '/' . $file);
449
            } else {
450
                copy($from . '/' . $file, $to . '/' . $file);
451
            }
452
        }
453
    }
454
455
    public static function getDirContents($dir, &$results = array(), $curPath = '') {
456
        $files = scandir($dir);
457
        foreach ($files as $key => $value) {
458
            $path = realpath($dir . '/' . $value);
459
            if (!is_dir($path)) {
460
                $results[$path] = $curPath . '/' . $value;
461
            } else if ($value != "." && $value != "..") {
462
                self::getDirContents($path, $results, $curPath . '/' . $value);
463
            }
464
        }
465
466
        return $results;
467
    }
468
469
    /**
470
     * Translit function
471
     *
472
     * @param string $str
473
     * @return string
474
     */
475
    public static function translit($str) {
476
        $rus = array('А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я', 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я');
477
        $lat = array('A', 'B', 'V', 'G', 'D', 'E', 'E', 'Gh', 'Z', 'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', 'C', 'Ch', 'Sh', 'Sch', 'Y', 'Y', 'Y', 'E', 'Yu', 'Ya', 'a', 'b', 'v', 'g', 'd', 'e', 'e', 'gh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sh', 'sch', 'y', 'y', 'y', 'e', 'yu', 'ya');
478
        return str_replace($rus, $lat, $str);
479
    }
480
481
    /**
482
     * get youtube video ID from URL
483
     *
484
     * @author http://stackoverflow.com/a/6556662
485
     * @param string $url
486
     * @return string Youtube video id or FALSE if none found.
487
     */
488
    public static function youtubeIdFromUrl($url) {
489
        $pattern = '%^# Match any youtube URL
490
        (?:https?://)?  # Optional scheme. Either http or https
491
        (?:www\.)?      # Optional www subdomain
492
        (?:             # Group host alternatives
493
          youtu\.be/    # Either youtu.be,
494
        | youtube\.com  # or youtube.com
495
          (?:           # Group path alternatives
496
            /embed/     # Either /embed/
497
          | /v/         # or /v/
498
          | /watch\?v=  # or /watch\?v=
499
          )             # End path alternatives.
500
        )               # End host alternatives.
501
        ([\w-]{10,12})  # Allow 10-12 for 11 char youtube id.
502
        $%x';
503
        $result = preg_match($pattern, $url, $matches);
504
        if (false !== $result) {
505
            return $matches[1];
506
        }
507
        return false;
508
    }
509
510
    /**
511
     * check array is associative
512
     *
513
     * @author http://stackoverflow.com/a/173479
514
     * @param array $arr
515
     * @return boolean
516
     */
517
    public static function isAssoc(&$arr) {
518
        return array_keys($arr) !== range(0, count($arr) - 1);
519
    }
520
521
    public static function defValue(&$link, $defValue = '') {
522
        return isset($link) ? $link : $defValue;
523
    }
524
525
    public static function rusPrice($price, $zeroEnding = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $zeroEnding is not used and could be removed.

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

Loading history...
526
        $afterDot = $price == (int) $price ? 0 : 2;
527
        return number_format($price, $afterDot, '.', ' ');
528
    }
529
}