Passed
Push — master ( 02cf08...5790a7 )
by kicaj
07:32
created

FileBehavior::createThumbs()   F

Complexity

Conditions 50
Paths 3135

Size

Total Lines 181
Code Lines 111

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 111
c 0
b 0
f 0
dl 0
loc 181
rs 0
cc 50
nc 3135
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace File\Model\Behavior;
3
4
use Cake\Datasource\EntityInterface;
5
use Cake\Event\Event;
6
use Cake\Event\EventInterface;
7
use Cake\ORM\Behavior;
8
use Cake\Utility\Text;
9
use File\Exception\LibraryException;
10
use File\Exception\PathException;
11
use File\Exception\ThumbsException;
12
use Laminas\Diactoros\UploadedFile;
13
use ArrayObject;
14
15
class FileBehavior extends Behavior
16
{
17
18
    /**
19
     * Default config.
20
     *
21
     * @var array
22
     */
23
    public $defaultConfig = [
24
        'library' => 'gd',
25
        'types' => [ // Default allowed types.
26
            'image/bmp',
27
            'image/gif',
28
            'image/jpeg',
29
            'image/jpg',
30
            'image/pjpeg',
31
            'image/pjpg',
32
            'image/png',
33
            'image/x-png',
34
            'image/webp',
35
        ],
36
        'extensions' => [ // Default allowed extensions.
37
            'bmp',
38
            'gif',
39
            'jpeg',
40
            'jpg',
41
            'pjpg',
42
            'pjpeg',
43
            'png',
44
            'webp',
45
        ],
46
        'path' => 'files',
47
        'background' => [255, 255, 255, 127],
48
        'watermark' => '',
49
        'thumbs' => [],
50
    ];
51
52
    /**
53
     * Array of files to upload.
54
     *
55
     * @var array
56
     */
57
    protected $files = [];
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function initialize(array $config): void
63
    {
64
        parent::initialize($config);
65
66
        foreach ($this->getConfig() as $file => $fileConfig) {
67
            $this->_configDelete($file);
68
69
            if (!is_array($fileConfig)) {
70
                $file = $fileConfig;
71
72
                $this->setConfig($file, $this->defaultConfig);
73
            } else {
74
                $this->setConfig($file, $config[$file] += $this->defaultConfig);
75
            }
76
        }
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82
    public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
83
    {
84
        $config = $this->getConfig();
85
86
        if (!empty($config)) {
87
            foreach (array_keys($config) as $file) {
88
                $this->setFile($file, $data[$file]);
89
90
                $data[$file] = $this->createName($data[$file]->getClientFilename());
91
            }
92
        }
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98
    public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options)
99
    {
100
        $files = $this->getFiles();
101
102
        if (!empty($files)) {
103
            foreach ($files as $file => $fileObject) {
104
                if ($fileObject->getError() === 0) {
105
                    $fileConfig = $this->getConfig($file);
106
107
                    // Move original file
108
                    $fileObject->moveTo($this->getPath($fileConfig['path']) . DS . $entity->{$file});
109
110
                    // Prepare thumb files
111
                    if (!empty($fileConfig['thumbs'])) {
112
                        $this->createThumbs($entity->{$file}, $fileConfig);
113
                    }
114
                }
115
            }
116
        }
117
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122
    public function beforeDelete(Event $event, EntityInterface $entity, ArrayObject $options)
123
    {
124
        $entity = $this->getTable()->find()->select(
125
            array_merge(
126
                [$this->getTable()->getPrimaryKey()],
127
                array_keys($this->getConfig())
128
            )
129
        )->where([
130
            $this->getTable()->getAlias() . '.' . $this->getTable()->getPrimaryKey() => $entity->{$this->getTable()->getPrimaryKey()},
131
        ])->first();
132
133
        return $this->deleteFiles($entity);
134
    }
135
136
    /**
137
     * {@inheritDoc}
138
     */
139
    public function afterDelete(Event $event, EntityInterface $entity, ArrayObject $options)
140
    {
141
        return $this->deleteFiles($entity);
142
    }
143
144
    protected function createThumbs(string $file, array $fileConfig): void
145
    {
146
        $filePath = $fileConfig['path'] . DS . $file;
147
148
        if (is_file($filePath)) {
149
            // Check installed image library
150
            if (!extension_loaded($fileConfig['library'])) {
151
                throw new LibraryException(__d('file', 'The library identified by {0} is not loaded!', $fileConfig['library']));
152
            }
153
154
            // Get extension from original file
155
            $fileExtension = $this->getExtension($file);
156
157
            $fileConfig['library'] = mb_strtolower($fileConfig['library']);
158
159
            switch ($fileConfig['library']) {
160
                // Get image resource
161
                case 'gd':
162
                    switch ($fileExtension) {
163
                        case 'bmp':
164
                            $sourceImage = imagecreatefrombmp($filePath);
165
166
                            break;
167
                        case 'gif':
168
                            $sourceImage = imagecreatefromgif($filePath);
169
170
                            break;
171
                        case 'png':
172
                            $sourceImage = imagecreatefrompng($filePath);
173
174
                            break;
175
                        case 'webp':
176
                            $sourceImage = imagecreatefromwebp($filePath);
177
178
                            break;
179
                        default:
180
                            ini_set('gd.jpeg_ignore_warning', 1);
181
182
                            $sourceImage = imagecreatefromjpeg($filePath);
183
184
                            break;
185
                    }
186
187
                    // Get original width and height
188
                    $originalWidth = imagesx($sourceImage);
189
                    $originalHeight = imagesy($sourceImage);
190
191
                    break;
192
                case 'imagick':
193
                    $sourceImage = new \Imagick($originalFile);
194
195
                    // Get original width and height
196
                    $originalWidth = $sourceImage->getimagewidth();
197
                    $originalHeight = $sourceImage->getimageheight();
198
199
                    break;
200
                default:
201
                    throw new LibraryException(__d('file', 'The library identified by {0} it is not known as image processing!', $fileConfig['library']));
202
            }
203
204
            $offsetX = 0;
205
            $offsetY = 0;
206
207
            $cropX = 0;
208
            $cropY = 0;
209
210
            foreach ($fileConfig['thumbs'] as $thumbName => $thumbConfig) {
211
                if (isset($thumbConfig['width'])) {
212
                    list($newWidth, $newHeight) = $this->getDimensionsByNewWidth($originalWidth, $originalHeight, $thumbConfig['width']);
213
                } elseif (isset($thumbConfig['height'])) {
214
                    list($newWidth, $newHeight) = $this->getDimensionsByNewHeight($originalWidth, $originalHeight, $thumbConfig['height']);
215
                } elseif (isset($thumbConfig['shorter']) && is_array($thumbConfig['shorter']) && count($thumbConfig['shorter']) === 2) {
216
                    list($newWidth, $newHeight) = $this->getDimensionsByShorterSide($originalWidth, $originalHeight, $thumbConfig['shorter'][0], $thumbConfig['shorter'][1]);
217
                } elseif (isset($thumbConfig['longer']) && is_array($thumbConfig['longer']) && count($thumbConfig['longer']) === 2) {
218
                    list($newWidth, $newHeight) = $this->getDimensionsByLongerSide($originalWidth, $originalHeight, $thumbConfig['longer'][0], $thumbConfig['longer'][1]);
219
                } elseif (isset($thumbConfig['fit']) && is_array($thumbConfig['fit']) && count($thumbConfig['fit']) === 2) {
220
                    list($newWidth, $newHeight, $offsetX, $offsetY, $cropX, $cropY) = $this->getDimensionsByFit($originalWidth, $originalHeight, $thumbConfig['fit'][0], $thumbConfig['fit'][1]);
221
                } elseif (isset($thumbConfig['fit']) && is_array($thumbConfig['fit']) && count($thumbConfig['fit']) === 3) {
222
                    list($newWidth, $newHeight, $offsetX, $offsetY, $cropX, $cropY) = $this->getDimensionsByFit($originalWidth, $originalHeight, $thumbConfig['fit'][0], $thumbConfig['fit'][1], $thumbConfig['fit'][2]);
223
                } elseif (isset($thumbConfig['square']) && is_array($thumbConfig['square']) && count($thumbConfig['square']) === 1) {
224
                    list($newWidth, $newHeight, $offsetX, $offsetY, $cropX, $cropY) = $this->getDimensionsByFitToSquare($originalWidth, $originalHeight, $thumbConfig['square'][0]);
225
                } elseif (isset($thumbConfig['square']) && is_array($thumbConfig['square']) && count($thumbConfig['square']) === 2) {
226
                    list($newWidth, $newHeight, $offsetX, $offsetY, $cropX, $cropY) = $this->getDimensionsByFitToSquare($originalWidth, $originalHeight, $thumbConfig['square'][0], $thumbConfig['square'][1]);
227
                } else {
228
                    throw new ThumbsException(__d('file', 'Unknown type or incorrect parameters of creating thumbnails!'));
229
                }
230
231
                $thumbFile = str_replace('default', $thumbName, $filePath);
232
233
                switch ($fileConfig['library']) {
234
                    // Get image resource
235
                    case 'gd':
236
                        $newImage = imagecreatetruecolor($newWidth, $newHeight);
237
238
                        if (is_array($fileConfig['background'])) {
239
                            // Set background color and transparent indicates
240
                            imagefill($newImage, 0, 0, imagecolorallocatealpha($newImage, $fileConfig['background'][0], $fileConfig['background'][1], $fileConfig['background'][2], $fileConfig['background'][3]));
241
                        }
242
243
                        imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $originalWidth, $originalHeight);
244
245
                        if ((isset($thumbConfig['square']) && is_array($thumbConfig['square'])) || (isset($thumbConfig['fit']) && is_array($thumbConfig['fit']))) {
246
                            $fitImage = imagecreatetruecolor($newWidth + (2 * $offsetX) - (2 * $cropX), $newHeight + (2 * $offsetY) - (2 * $cropY));
247
248
                            if (is_array($fileConfig['background'])) {
249
                                // Set background color and transparent indicates
250
                                imagefill($fitImage, 0, 0, imagecolorallocatealpha($fitImage, $fileConfig['background'][0], $fileConfig['background'][1], $fileConfig['background'][2], $fileConfig['background'][3]));
251
                            }
252
253
                            imagecopyresampled($fitImage, $newImage, $offsetX, $offsetY, $cropX, $cropY, $newWidth, $newHeight, $newWidth, $newHeight);
254
255
                            $newImage = $fitImage;
256
                        }
257
258
                        imagealphablending($newImage, false);
259
                        imagesavealpha($newImage, true);
260
261
                        // Watermark
262
                        if (isset($thumbConfig['watermark']) && ($watermarkSource = file_get_contents($fileConfig['watermark'])) !== false) {
263
                            $watermarkImage = imagecreatefromstring($watermarkSource);
264
265
                            list($watermarkPositionX, $watermarkPositionY) = $this->getPosition(imagesx($newImage), imagesy($newImage), imagesx($watermarkImage), imagesy($watermarkImage), $offsetX, $offsetY, $thumbConfig['watermark']);
266
267
                            // Set transparent
268
                            imagealphablending($newImage, true);
269
                            imagecopy($newImage, $watermarkImage, $watermarkPositionX, $watermarkPositionY, 0, 0, imagesx($watermarkImage), imagesy($watermarkImage));
270
                        }
271
272
                        // Set resource file type
273
                        switch ($fileExtension) {
274
                            case 'bmp':
275
                                imagebmp($newImage, $thumbFile);
276
277
                                break;
278
                            case 'gif':
279
                                imagegif($newImage, $thumbFile);
280
281
                                break;
282
                            case 'png':
283
                                imagepng($newImage, $thumbFile);
284
285
                                break;
286
                            case 'webp':
287
                                imagewebp($newImage, $thumbFile);
288
289
                                break;
290
                            default:
291
                                imagejpeg($newImage, $thumbFile, 100);
292
293
                                break;
294
                        }
295
296
                        break;
297
                    case 'imagick':
298
                        $newImage = $sourceImage->clone();
299
300
                        $newImage->scaleimage($newWidth, $newHeight);
301
                        $newImage->setimagebackgroundcolor('transparent');
302
                        $newImage->extentimage($newWidth + (2 * $offsetX), $newHeight + (2 * $offsetY), -$offsetX, -$offsetY);
303
304
                        if ((isset($thumbConfig['square']) && is_array($thumbConfig['square'])) || (isset($thumbConfig['fit']) && is_array($thumbConfig['fit']))) {
305
                            $newImage->cropimage($newWidth + (2 * $offsetX) - (2 * $cropX), $newHeight + (2 * $offsetY) - (2 * $cropY), $cropX, $cropY);
306
                        }
307
308
                        // Watermark
309
                        if (isset($thumbConfig['watermark']) && ($watermarkSource = file_get_contents($fileConfig['watermark'])) !== false) {
310
                            $watermarkImage = new \Imagick();
311
                            $watermarkImage->readimageblob($watermarkSource);
312
313
                            list($watermarkPositionX, $watermarkPositionY) = $this->getPosition($newWidth, $newHeight, $watermarkImage->getimagewidth(), $watermarkImage->getimageheight(), $offsetX, $offsetY, $thumbConfig['watermark']);
314
315
                            $newImage->compositeimage($watermarkImage, \Imagick::COMPOSITE_OVER, $watermarkPositionX, $watermarkPositionY);
316
                        }
317
318
                        // Set object file type
319
                        $newImage->setImageFormat($fileExtension);
320
321
                        $newImage->writeimage($thumbFile);
322
                        $newImage->clear();
323
324
                        break;
325
                }
326
            }
327
        }
328
    }
329
330
    /**
331
     * Delete files with created thumbs.
332
     *
333
     * @param EntityInterface $entity Entity
334
     * @return boolean True if is successful.
335
     */
336
    protected function deleteFiles(EntityInterface $entity)
337
    {
338
        $config = $this->getConfig();
339
340
        if (!empty($config)) {
341
            foreach ($config as $file => $fileConfig) {
342
                if (isset($entity[$file])) {
343
                    $path = $fileConfig['path'] . DS . substr($entity[$file], 0, 37);
344
345
                    foreach (glob($path . '*') as $file) {
346
                        if (file_exists($file)) {
347
                            unlink($file);
348
                        }
349
                    }
350
                }
351
            }
352
        }
353
354
        return true;
355
    }
356
357
    /**
358
     * Get files fields with config.
359
     *
360
     * @return array Files fields with config.
361
     */
362
    protected function getFiles(): array
363
    {
364
        return $this->files;
365
    }
366
367
    /**
368
     * Set file fields config.
369
     *
370
     * @param string $file File name.
371
     * @param UploadedFile $data Uploaded data.
372
     */
373
    protected function setFile(string $file, UploadedFile $data): void
374
    {
375
        $this->files[$file] = $data;
376
    }
377
378
    /**
379
     * Get file path.
380
     *
381
     * @param string $path Path.
382
     * @return string Path.
383
     */
384
    protected function getPath(string $path): string
385
    {
386
        if (!is_dir($path)) {
387
            $this->setPath($path);
388
        }
389
390
        return $path;
391
    }
392
393
    /**
394
     * Set file path.
395
     *
396
     * @param string $path Path.
397
     * @return string Path.
398
     */
399
    protected function setPath(string $path): string
400
    {
401
        if (mkdir($path, 0777, true)) {
402
            return $path;
403
        }
404
405
        throw new PathException(__d('file', 'Could not set path'));
406
    }
407
408
    /**
409
     * Create file name.
410
     *
411
     * @param string $name Uploaded file name.
412
     * @return string Unique file name.
413
     */
414
    protected function createName(string $name): string
415
    {
416
        return Text::uuid() . '_default.' . $this->getExtension($name);
417
    }
418
419
    /**
420
     * Get extension from file name.
421
     *
422
     * @param string $name File name.
423
     * @return string Extension of uploaded file.
424
     */
425
    protected function getExtension(string $name): string
426
    {
427
        $fileExtension = pathinfo(mb_strtolower($name), PATHINFO_EXTENSION);
428
429
        switch ($fileExtension) {
430
            case 'jpg':
431
            case 'jpeg':
432
            case 'pjpg':
433
            case 'pjpeg':
434
                // Standarize JPEG image file extension
435
                return 'jpg';
436
437
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
438
            default:
439
                return $fileExtension;
440
441
                break;
442
        }
443
    }
444
445
    /**
446
     * Get position of watermark image.
447
     *
448
     * @param integer $newWidth New width of uploaded image.
449
     * @param integer $newHeight New height of uploaded image.
450
     * @param integer $watermarkWidth Original width of watermark image.
451
     * @param integer $watermarkHeight Original height of watermark image.
452
     * @param integer $offsetX Horizontal offset.
453
     * @param integer $offsetY Vertical offset.
454
     * @param integer $positionValue Value for position watermark, value between 1 and 9.
455
     * @return array Coordinates of position watermark.
456
     */
457
    protected function getPosition(int $newWidth, int $newHeight, int $watermarkWidth, int $watermarkHeight, int $offsetX = 0, int $offsetY = 0, int $positionValue = 1): array
458
    {
459
        switch ($positionValue) {
460
            case 1: // Top left
461
                return [$offsetX, $offsetY];
462
463
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
464
            case 2: // Top center
465
                return [($newWidth / 2) - ($watermarkWidth / 2), $offsetY];
466
467
                break;
468
            case 3: // Top right
469
                return [($newWidth - $watermarkWidth - $offsetX), $offsetY];
470
471
                break;
472
            case 4: // Middle left
473
                return [$offsetX, intval(($newHeight / 2) - ($watermarkHeight / 2))];
474
475
                break;
476
            case 5: // Middle center
477
                return [intval(($newWidth / 2) - ($watermarkWidth / 2)), intval(($newHeight / 2) - ($watermarkHeight / 2))];
478
479
                break;
480
            case 6: // Middle right
481
                return [($newWidth - $watermarkWidth) - $offsetX, intval(($newHeight / 2) - ($watermarkHeight / 2))];
482
483
                break;
484
            case 7: // Bottom left
485
                return [$offsetX, ($newHeight - $watermarkHeight) - $offsetY];
486
487
                break;
488
            case 8: // Bottom center
489
                return [intval(($newWidth / 2) - ($watermarkWidth / 2)), ($newHeight - $watermarkHeight) - $offsetY];
490
491
                break;
492
            case 9: // Bottom right
493
                return [($newWidth - $watermarkWidth) - $offsetX, ($newHeight - $watermarkHeight) - $offsetY];
494
495
                break;
496
            default:
497
                return [$offsetX, $offsetY];
498
499
                break;
500
        }
501
    }
502
503
    /**
504
     * Get dimension by new width.
505
     *
506
     * @param integer $originalWidth Original width of uploaded image.
507
     * @param integer $originalHeight Original height of uploaded image.
508
     * @param integer $newWidth Set new image width.
509
     * @return array New width and height.
510
     */
511
    public static function getDimensionsByNewWidth(int $originalWidth, int $originalHeight, int $newWidth): array
512
    {
513
        if ($newWidth > $originalWidth) {
514
            $newWidth = $originalWidth;
515
            $newHeight = $originalHeight;
516
        } else {
517
            $newHeight = intval($newWidth * ($originalHeight / $originalWidth));
518
        }
519
520
        return [$newWidth, $newHeight];
521
    }
522
523
    /**
524
     * Get dimension by new height.
525
     *
526
     * @param integer $originalWidth Original width of uploaded image.
527
     * @param integer $originalHeight Original height of uploaded image.
528
     * @param integer $newHeight Set new image height.
529
     * @return array New width and height.
530
     */
531
    public static function getDimensionsByNewHeight(int $originalWidth, int $originalHeight, int $newHeight): array
532
    {
533
        if ($newHeight > $originalHeight) {
534
            $newHeight = $originalHeight;
535
            $newWidth = $originalWidth;
536
        } else {
537
            $newWidth = intval($newHeight * ($originalWidth / $originalHeight));
538
        }
539
540
        return [$newWidth, $newHeight];
541
    }
542
543
    /**
544
     * Get dimension by shorter side.
545
     *
546
     * @param integer $originalWidth Original width of uploaded image.
547
     * @param integer $originalHeight Original height of uploaded image.
548
     * @param integer $newWidth Set new image min width.
549
     * @param integer $newHeight Set new image min height.
550
     * @return array New width and height.
551
     */
552
    public static function getDimensionsByShorterSide(int $originalWidth, int $originalHeight, int $newWidth, int $newHeight): array
553
    {
554
        if ($originalWidth < $originalHeight) {
555
            list($newWidth, $newHeight) = self::getDimensionsByNewWidth($originalWidth, $originalHeight, $newWidth);
556
        } else {
557
            list($newWidth, $newHeight) = self::getDimensionsByNewHeight($originalWidth, $originalHeight, $newHeight);
558
        }
559
560
        return [$newWidth, $newHeight];
561
    }
562
563
    /**
564
     * Get dimension by longer side.
565
     *
566
     * @param integer $originalWidth Original width of uploaded image.
567
     * @param integer $originalHeight Original height of uploaded image.
568
     * @param integer $newWidth Set new image max width.
569
     * @param integer $newHeight Set new image max height.
570
     * @return array New width and height.
571
     */
572
    public static function getDimensionsByLongerSide(int $originalWidth, int $originalHeight, int $newWidth, int $newHeight): array
573
    {
574
        if ($originalWidth > $originalHeight) {
575
            list($newWidth, $newHeight) = self::getDimensionsByNewWidth($originalWidth, $originalHeight, $newWidth);
576
        } else {
577
            list($newWidth, $newHeight) = self::getDimensionsByNewHeight($originalWidth, $originalHeight, $newHeight);
578
        }
579
580
        return [$newWidth, $newHeight];
581
    }
582
583
    /**
584
     * Get dimension by fit.
585
     *
586
     * @param integer $originalWidth Original width of uploaded image.
587
     * @param integer $originalHeight Original height of uploaded image.
588
     * @param integer $newWidth Set new image width.
589
     * @param integer $newHeight Set new image height.
590
     * @param boolean $originalKeep Save original shape.
591
     * @return array New width and height and offsets of position with keeping original shape.
592
     */
593
    public static function getDimensionsByFit(int $originalWidth, int $originalHeight, int $newWidth, int $newHeight, bool $originalKeep = false): array
594
    {
595
        $offsetX = 0;
596
        $offsetY = 0;
597
        $cropX = 0;
598
        $cropY = 0;
599
600
        if ($originalKeep === true) {
601
            if ($originalWidth == $originalHeight) {
602
                $newSizes = self::getDimensionsByLongerSide($originalWidth, $originalHeight, min($newWidth, $newHeight), min($newWidth, $newHeight));
603
            } else {
604
                $newSizes = self::getDimensionsByLongerSide($originalWidth, $originalHeight, $newWidth, $newHeight);
605
606
                if ($newWidth < $newSizes[0] || $newHeight < $newSizes[1]) {
607
                    $newSizes = self::getDimensionsByShorterSide($originalWidth, $originalHeight, $newWidth, $newHeight);
608
                }
609
            }
610
        } else {
611
            if ($originalWidth == $originalHeight) {
612
                $newSizes = self::getDimensionsByShorterSide($originalWidth, $originalHeight, max($newWidth, $newHeight), max($newWidth, $newHeight));
613
            } else {
614
                $newSizes = self::getDimensionsByShorterSide($originalWidth, $originalHeight, $newWidth, $newHeight);
615
616
                if ($newWidth > $newSizes[0] || $newHeight > $newSizes[1]) {
617
                    $newSizes = self::getDimensionsByLongerSide($originalWidth, $originalHeight, $newWidth, $newHeight);
618
                }
619
            }
620
        }
621
622
        if ($newWidth < $newSizes[0]) {
623
            $cropX = ($newSizes[0] - $newWidth) / 2;
624
        } else {
625
            $offsetX = ($newWidth - $newSizes[0]) / 2;
626
        }
627
628
        if ($newHeight < $newSizes[1]) {
629
            $cropY = ($newSizes[1] - $newHeight) / 2;
630
        } else {
631
            $offsetY = ($newHeight - $newSizes[1]) / 2;
632
        }
633
634
        return [$newSizes[0], $newSizes[1], intval($offsetX), intval($offsetY), intval($cropX), intval($cropY)];
635
    }
636
637
    /**
638
     * Get dimension to square.
639
     *
640
     * @param integer $originalWidth Original width of uploaded image.
641
     * @param integer $originalHeight Original height of uploaded image.
642
     * @param integer $newSide Set new image side.
643
     * @param boolean $originalKeep Save original shape.
644
     * @return array New width and height with coordinates of crop or offsets of position.
645
     */
646
    public static function getDimensionsByFitToSquare(int $originalWidth, int $originalHeight, int $newSide, bool $originalKeep = false): array
647
    {
648
        $offsetX = 0;
649
        $offsetY = 0;
650
        $cropX = 0;
651
        $cropY = 0;
652
653
        if ($originalKeep === true) {
654
            list($newWidth, $newHeight) = self::getDimensionsByLongerSide($originalWidth, $originalHeight, $newSide, $newSide);
655
656
            if ($newSide > $newWidth) {
657
                $offsetX = ($newSide - $newWidth) / 2;
658
            }
659
660
            if ($newSide > $newHeight) {
661
                $offsetY = ($newSide - $newHeight) / 2;
662
            }
663
        } else {
664
            list($newWidth, $newHeight) = self::getDimensionsByShorterSide($originalWidth, $originalHeight, $newSide, $newSide);
665
666
            if ($newSide < $newWidth) {
667
                $cropX = ($newWidth - $newSide) / 2;
668
            } else {
669
                $offsetX = ($newSide - $newWidth) / 2;
670
            }
671
672
            if ($newSide < $newHeight) {
673
                $cropY = ($newHeight - $newSide) / 2;
674
            } else {
675
                $offsetY = ($newSide - $newHeight) / 2;
676
            }
677
        }
678
679
        return [$newWidth, $newHeight, intval($offsetX), intval($offsetY), intval($cropX), intval($cropY)];
680
    }
681
}