Test Failed
Push — master ( 6548d1...8173f8 )
by Alexey
05:06
created

Tools::addWatermark()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 19
nc 3
nop 2
dl 0
loc 28
ccs 0
cts 17
cp 0
crap 42
rs 8.439
c 0
b 0
f 0
1
<?php
2
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['res']}";
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
            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
    /**
456
     * Translit function
457
     *
458
     * @param string $str
459
     * @return string
460
     */
461
    public static function translit($str) {
462
        $rus = array('А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я', 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я');
463
        $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');
464
        return str_replace($rus, $lat, $str);
465
    }
466
467
    /**
468
     * get youtube video ID from URL
469
     *
470
     * @author http://stackoverflow.com/a/6556662
471
     * @param string $url
472
     * @return string Youtube video id or FALSE if none found.
473
     */
474
    public static function youtubeIdFromUrl($url) {
475
        $pattern = '%^# Match any youtube URL
476
        (?:https?://)?  # Optional scheme. Either http or https
477
        (?:www\.)?      # Optional www subdomain
478
        (?:             # Group host alternatives
479
          youtu\.be/    # Either youtu.be,
480
        | youtube\.com  # or youtube.com
481
          (?:           # Group path alternatives
482
            /embed/     # Either /embed/
483
          | /v/         # or /v/
484
          | /watch\?v=  # or /watch\?v=
485
          )             # End path alternatives.
486
        )               # End host alternatives.
487
        ([\w-]{10,12})  # Allow 10-12 for 11 char youtube id.
488
        $%x';
489
        $result = preg_match($pattern, $url, $matches);
490
        if (false !== $result) {
491
            return $matches[1];
492
        }
493
        return false;
494
    }
495
496
    /**
497
     * check array is associative
498
     *
499
     * @author http://stackoverflow.com/a/173479
500
     * @param array $arr
501
     * @return boolean
502
     */
503
    public static function isAssoc(&$arr) {
504
        return array_keys($arr) !== range(0, count($arr) - 1);
505
    }
506
507
    public static function defValue(&$link, $defValue = '') {
508
        return isset($link) ? $link : $defValue;
509
    }
510
511
    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...
512
        $afterDot = $price == (int) $price ? 0 : 2;
513
        return number_format($price, $afterDot, '.', ' ');
514
    }
515
}