Passed
Push — master ( f972f5...70a01b )
by Kanstantsin
02:50
created

Image::format()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 5
nop 1
dl 0
loc 16
ccs 0
cts 11
cp 0
crap 30
rs 8.8571
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace tkanstantsin\fileupload\formatter;
5
6
use Imagine\Image\Box;
7
use Imagine\Image\BoxInterface;
8
use Imagine\Image\ImageInterface;
9
use Imagine\Imagick\Imagine;
10
11
/**
12
 * Class ImageProcessor
13
 */
14
class Image extends File
15
{
16
    /**
17
     * Like background `cover` in css.
18
     */
19
    public const RESIZE_OUTBOUND = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
20
    /**
21
     * Like background `contain` in css.
22
     */
23
    public const RESIZE_INSET = \Imagine\Image\ImageInterface::THUMBNAIL_INSET;
24
    /**
25
     * Means that image may be smaller than defined in config, never bigger.
26
     */
27
    public const RESIZE_INSET_KEEP_RATIO = 'inset_keep_ratio';
28
29
    public const DEFAULT_EXTENSION = 'jpg';
30
31
    /**
32
     * @var int
33
     */
34
    public $width;
35
    /**
36
     * @var int
37
     */
38
    public $height;
39
    /**
40
     * @var string
41
     */
42
    public $mode = self::RESIZE_INSET;
43
    /**
44
     * Whether image must keep aspect ration when used inset mote.
45
     * Means that image would may be smaller than smaller
46
     * @var bool
47
     */
48
    public $keepRatio = true;
49
50
    /**
51
     * @var Imagine
52
     */
53
    protected $imagine;
54
55
    /**
56
     * @inheritdoc
57
     * @throws \UnexpectedValueException
58
     * @throws \Imagine\Exception\InvalidArgumentException
59
     * @throws \Imagine\Exception\RuntimeException
60
     */
61
    protected function getContentInternal()
62
    {
63
        $this->imagine = new Imagine();
64
        $image = $this->imagine->read(parent::getContentInternal());
65
        $image = $this->format($image);
66
67
        return $image->get($this->file->getExtension() ?? self::DEFAULT_EXTENSION);
68
    }
69
70
    /**
71
     * @param ImageInterface $image
72
     * @return ImageInterface
73
     * @throws \UnexpectedValueException
74
     * @throws \Imagine\Exception\RuntimeException
75
     * @throws \Imagine\Exception\InvalidArgumentException
76
     */
77
    protected function format(ImageInterface $image): ImageInterface
78
    {
79
        $box = $this->createBox($image);
80
        if ($box === null) {
81
            return $image;
82
        }
83
84
        switch ($this->mode) {
85
            case self::RESIZE_OUTBOUND:
86
            case self::RESIZE_INSET:
87
                return $image->thumbnail($box, $this->mode);
88
            case self::RESIZE_INSET_KEEP_RATIO:
89
                // TODO: implement new resize mode.
90
                throw new \UnexpectedValueException(sprintf('Resize mode `%s` not supported yet', $this->mode));
91
            default:
92
                throw new \UnexpectedValueException(sprintf('Image resize mode `%s` not defined', $this->mode));
93
        }
94
    }
95
96
    /**
97
     * @param ImageInterface $image
98
     * @return BoxInterface|null
99
     * @throws \Imagine\Exception\InvalidArgumentException
100
     */
101
    protected function createBox(ImageInterface $image): ?BoxInterface
102
    {
103
        if ($this->width !== null
104
            && $this->height !== null
105
        ) {
106
            return new Box($this->width, $this->height);
107
        }
108
109
        $actualBox = $image->getSize();
110
        if ($this->width !== null) {
111
            return $actualBox->widen($this->width);
112
        }
113
        if ($this->height !== null
114
        ) {
115
            return $actualBox->heighten($this->height);
116
        }
117
118
        // both are null
119
        return null;
120
    }
121
}