SquareResizer::resize()   B
last analyzed

Complexity

Conditions 8
Paths 15

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 39
rs 8.0515
c 0
b 0
f 0
cc 8
nc 15
nop 5
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\MediaBundle\Resizer;
15
16
use Gaufrette\File;
17
use Imagine\Image\Box;
18
use Imagine\Image\ImagineInterface;
19
use Imagine\Image\Point;
20
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
21
use Sonata\MediaBundle\Model\MediaInterface;
22
23
/**
24
 * This reziser crop the image when the width and height are specified.
25
 * Every time you specify the W and H, the script generate a square with the
26
 * smaller size. For example, if width is 100 and height 80; the generated image
27
 * will be 80x80.
28
 *
29
 * @final since sonata-project/media-bundle 3.21.0
30
 *
31
 * @author Edwin Ibarra <[email protected]>
32
 */
33
class SquareResizer implements ResizerInterface
34
{
35
    use ImagineCompatibleResizerTrait;
36
37
    /**
38
     * @var ImagineInterface
39
     */
40
    protected $adapter;
41
42
    /**
43
     * @var string
44
     */
45
    protected $mode;
46
47
    /**
48
     * @var MetadataBuilderInterface
49
     */
50
    protected $metadata;
51
52
    /**
53
     * @param string $mode
54
     */
55
    public function __construct(ImagineInterface $adapter, $mode, MetadataBuilderInterface $metadata)
56
    {
57
        $this->adapter = $adapter;
58
        $this->mode = $this->convertMode($mode);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->convertMode($mode) can also be of type integer. However, the property $mode is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
59
        $this->metadata = $metadata;
60
    }
61
62
    public function getAdapter()
63
    {
64
        return $this->adapter;
65
    }
66
67
    public function setAdapter(ImagineInterface $adapter): void
68
    {
69
        $this->adapter = $adapter;
70
    }
71
72
    public function resize(MediaInterface $media, File $in, File $out, $format, array $settings): void
73
    {
74
        if (!isset($settings['width'])) {
75
            throw new \RuntimeException(sprintf('Width parameter is missing in context "%s" for provider "%s"', $media->getContext(), $media->getProviderName()));
76
        }
77
78
        $image = $this->adapter->load($in->getContent());
79
        $size = $media->getBox();
80
81
        if (null !== $settings['height']) {
82
            if ($size->getHeight() > $size->getWidth()) {
83
                $higher = $size->getHeight();
84
                $lower = $size->getWidth();
85
            } else {
86
                $higher = $size->getWidth();
87
                $lower = $size->getHeight();
88
            }
89
90
            $crop = $higher - $lower;
91
92
            if ($crop > 0) {
93
                $point = $higher === $size->getHeight() ? new Point(0, 0) : new Point($crop / 2, 0);
94
                $image->crop($point, new Box($lower, $lower));
95
                $size = $image->getSize();
96
            }
97
        }
98
99
        $settings['height'] = (int) ($settings['width'] * $size->getHeight() / $size->getWidth());
100
101
        if ($settings['height'] < $size->getHeight() && $settings['width'] < $size->getWidth()) {
102
            $content = $image
103
                ->thumbnail(new Box($settings['width'], $settings['height']), $this->mode)
104
                ->get($format, ['quality' => $settings['quality']]);
105
        } else {
106
            $content = $image->get($format, ['quality' => $settings['quality']]);
107
        }
108
109
        $out->setContent($content, $this->metadata->get($media, $out->getName()));
110
    }
111
112
    public function getBox(MediaInterface $media, array $settings)
113
    {
114
        $size = $media->getBox();
115
116
        if (null !== $settings['height']) {
117
            if ($size->getHeight() > $size->getWidth()) {
118
                $higher = $size->getHeight();
119
                $lower = $size->getWidth();
120
            } else {
121
                $higher = $size->getWidth();
122
                $lower = $size->getHeight();
123
            }
124
125
            if ($higher - $lower > 0) {
126
                $size = new Box($lower, $lower);
127
            }
128
        }
129
130
        $settings['height'] = (int) ($settings['width'] * $size->getHeight() / $size->getWidth());
131
132
        if ($settings['height'] < $size->getHeight() && $settings['width'] < $size->getWidth()) {
133
            return new Box($settings['width'], $settings['height']);
134
        }
135
136
        return $size;
137
    }
138
}
139