Passed
Push — master ( f8757e...2f0502 )
by Richard
09:51 queued 12s
created

ImageTransformation::__toString()   B

Complexity

Conditions 7
Paths 17

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 12
c 2
b 0
f 0
nc 17
nop 0
dl 0
loc 26
rs 8.8333
1
<?php
2
3
4
namespace Riclep\Storyblok\Support;
5
6
use Illuminate\Support\Str;
7
use Riclep\Storyblok\Fields\Image;
8
9
class ImageTransformation
10
{
11
	private $filename;
12
	private $focus;
13
	protected $transformations = [];
14
	private $image;
15
16
	public function __construct(Image $image)
17
	{
18
		$this->filename = $image->filename;
0 ignored issues
show
Documentation Bug introduced by
It seems like $image->filename can also be of type boolean. However, the property $filename is declared as type false|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...
19
		$this->focus = $image->focus;
0 ignored issues
show
Bug Best Practice introduced by
The property focus does not exist on Riclep\Storyblok\Fields\Image. Since you implemented __get, consider adding a @property annotation.
Loading history...
20
		$this->image = $image;
21
	}
22
23
	public function width() {
24
		return $this->transformations['width'] ?? $this->image->width();
25
	}
26
27
	public function height() {
28
		return $this->transformations['height'] ?? $this->image->height();
29
	}
30
31
	public function type() {
32
		if (array_key_exists('format', $this->transformations)) {
33
			return 'image/' . $this->transformations['format'];
34
		}
35
36
		return $this->image->type();
37
	}
38
39
	public function resize($width = 0, $height = 0, $focus = null)
40
	{
41
		$this->transformations = array_merge($this->transformations, [
42
			'width' => $width,
43
			'height' => $height,
44
		]);
45
46
		if ($focus) {
47
			$this->transformations = array_merge($this->transformations, [
48
				'focus' => $focus,
49
			]);
50
		}
51
52
		return $this;
53
	}
54
55
	public function format($format, $quality = null)
56
	{
57
		$this->transformations = array_merge($this->transformations, [
58
			'format' => $format,
59
		]);
60
61
		if ($quality) {
62
			$this->transformations = array_merge($this->transformations, [
63
				'quality' => $quality,
64
			]);
65
		}
66
67
		return $this;
68
	}
69
70
	public function fitIn($width = 0, $height = 0, $fill = 'transparent')
71
	{
72
		$this->transformations = array_merge($this->transformations, [
73
			'width' => $width,
74
			'height' => $height,
75
			'fill' => $fill,
76
			'fit-in' => true,
77
		]);
78
79
		// has to be an image that supports transparency
80
		if ($fill === 'transparent') {
81
			$this->format('png');
82
		}
83
84
		return $this;
85
	}
86
87
	/**
88
	 * Transforms the image using the Storyblok image service
89
	 * See: https://www.storyblok.com/docs/image-service
90
	 *
91
	 * @param $options
92
	 * @return string
93
	 */
94
	public function createUrl($options): string
95
	{
96
		$resource = str_replace(['https:', '//' . config('storyblok.asset_domain')], '', $this->filename);
97
		return '//' . config('storyblok.image_service_domain') . $options . $resource;
98
	}
99
100
	public function getTransformations() {
101
		return $this->transformations;
102
	}
103
104
	private function hasFilters() {
105
		return array_key_exists('format', $this->transformations) || array_key_exists('quality', $this->transformations) || array_key_exists('fill', $this->transformations) || (array_key_exists('focus', $this->transformations) && $this->transformations['focus'] === 'focal-point');
106
	}
107
108
	private function applyFilters() {
109
		$filters = '/filters';
110
111
		if (array_key_exists('format', $this->transformations)) {
112
			$filters .= ':format(' . $this->transformations['format'] . ')';
113
		}
114
115
		if (array_key_exists('quality', $this->transformations)) {
116
			$filters .= ':quality(' . $this->transformations['quality'] . ')';
117
		}
118
119
		if (array_key_exists('fill', $this->transformations)) {
120
			$filters .= ':fill(' . $this->transformations['fill'] . ')';
121
		}
122
123
		if (array_key_exists('focus', $this->transformations) && $this->transformations['focus'] === 'focal-point' && $this->focus) {
124
			$filters .= ':focal(' . $this->focus . ')';
0 ignored issues
show
Bug introduced by
Are you sure $this->focus of type mixed|string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

124
			$filters .= ':focal(' . /** @scrutinizer ignore-type */ $this->focus . ')';
Loading history...
125
		}
126
127
		return $filters;
128
	}
129
130
	public function __toString()
131
	{
132
		if (Str::endsWith($this->filename, 'svg')) {
133
			return $this->filename;
134
		}
135
136
		$transforms = '';
137
138
		if (array_key_exists('fit-in', $this->transformations)) {
139
			$transforms .= '/fit-in';
140
		}
141
142
		if (array_key_exists('width', $this->transformations)) {
143
			$transforms .= '/' . $this->transformations['width'] . 'x' . $this->transformations['height'];
144
		}
145
146
		if (array_key_exists('focus', $this->transformations) && $this->transformations['focus'] === 'smart') {
147
			$transforms .= '/smart';
148
		}
149
150
		// filters
151
		if ($this->hasFilters()) {
152
			$transforms .= $this->applyFilters();
153
		}
154
155
		return $this->createUrl($transforms);
156
	}
157
}
158