Storyblok   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 212
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 72
c 2
b 1
f 0
dl 0
loc 212
rs 9.76
wmc 33

9 Methods

Rating   Name   Duplication   Size   Complexity  
A extractMetaDetails() 0 20 3
B buildUrl() 0 24 7
A init() 0 5 1
B applyFilters() 0 25 8
A hasFilters() 0 3 5
A assetDomain() 0 5 1
A resize() 0 22 4
A format() 0 14 2
A fitIn() 0 15 2
1
<?php
2
3
namespace Riclep\Storyblok\Support\ImageTransformers;
4
5
use Illuminate\Support\Str;
6
7
class Storyblok extends BaseTransformer
8
{
9
10
	/**
11
	 * Performs any actions needed once the object is created
12
	 * and any preprocessing is completed
13
	 *
14
	 * @return $this
15
	 */
16
	public function init(): self
17
	{
18
		$this->extractMetaDetails();
19
20
		return $this;
21
	}
22
23
	/**
24
	 * Resizes the image and sets the focal point
25
	 *
26
	 * @param int $width
27
	 * @param int $height
28
	 * @param string|null $focus
29
	 * @return $this
30
	 */
31
	public function resize(int $width = 0, int $height = 0, string $focus = null): self
32
	{
33
		$this->transformations = array_merge($this->transformations, [
34
			'width' => $width,
35
			'height' => $height,
36
		]);
37
38
		if ($focus) {
39
			if ($focus === 'auto') {
40
				if ($this->image->focus) {
41
					$focus = 'focal-point';
42
				} else {
43
					$focus = 'smart';
44
				}
45
			}
46
47
			$this->transformations = array_merge($this->transformations, [
48
				'focus' => $focus,
49
			]);
50
		}
51
52
		return $this;
53
	}
54
55
	/**
56
	 * Fits the image in the given width and height
57
	 *
58
	 * @param int $width
59
	 * @param int $height
60
	 * @param string $fill
61
	 * @return $this
62
	 */
63
	public function fitIn(int $width = 0, int $height = 0, string $fill = 'transparent'): self
64
	{
65
		$this->transformations = array_merge($this->transformations, [
66
			'width' => $width,
67
			'height' => $height,
68
			'fill' => $fill,
69
			'fit-in' => true,
70
		]);
71
72
		// has to be an image that supports transparency
73
		if ($fill === 'transparent') {
74
			$this->format('webp');
75
		}
76
77
		return $this;
78
	}
79
80
	/**
81
	 * Set the image format you want returned
82
	 *
83
	 * @param string $format
84
	 * @param int|null $quality
85
	 * @return $this
86
	 */
87
	public function format(string $format, int $quality = null): self
88
	{
89
		$this->transformations = array_merge($this->transformations, [
90
			'format' => $format,
91
			'mime' => $this->setMime($format),
92
		]);
93
94
		if ($quality !== null) {
95
			$this->transformations = array_merge($this->transformations, [
96
				'quality' => $quality,
97
			]);
98
		}
99
100
		return $this;
101
	}
102
103
104
	/**
105
	 * Creates the Storyblok image service URL
106
	 *
107
	 * @return string
108
	 */
109
	public function buildUrl(): string
110
	{
111
		if ($this->transformations === 'svg') {
0 ignored issues
show
introduced by
The condition $this->transformations === 'svg' is always false.
Loading history...
112
			return $this->image->content()['filename'];
113
		}
114
115
		$transforms = '';
116
117
		if (array_key_exists('fit-in', $this->transformations)) {
118
			$transforms .= '/fit-in';
119
		}
120
121
		if (array_key_exists('width', $this->transformations)) {
122
			$transforms .= '/' . $this->transformations['width'] . 'x' . $this->transformations['height'];
123
		}
124
125
		if (array_key_exists('focus', $this->transformations) && $this->transformations['focus'] === 'smart') {
126
			$transforms .= '/smart';
127
		}
128
		if ($this->hasFilters()) {
129
			$transforms .= $this->applyFilters();
130
		}
131
132
		return $this->assetDomain($transforms);
133
	}
134
135
	/**
136
	 * Applies the filters to the image service URL
137
	 *
138
	 * @return string
139
	 */
140
	private function applyFilters(): string
141
	{
142
		$filters = '';
143
144
		if (array_key_exists('format', $this->transformations)) {
145
			$filters .= ':format(' . $this->transformations['format'] . ')';
146
		}
147
148
		if (array_key_exists('quality', $this->transformations)) {
149
			$filters .= ':quality(' . $this->transformations['quality'] . ')';
150
		}
151
152
		if (array_key_exists('fill', $this->transformations)) {
153
			$filters .= ':fill(' . $this->transformations['fill'] . ')';
154
		}
155
156
		if (array_key_exists('focus', $this->transformations) && $this->transformations['focus'] === 'focal-point' && $this->image->content()['focus']) {
157
			$filters .= ':focal(' . $this->image->content()['focus'] . ')';
158
		}
159
160
		if ($filters) {
161
			$filters = '/filters' . $filters;
162
		}
163
164
		return $filters;
165
	}
166
167
	/**
168
	 * Extracts meta details from the image. With Storyblok we can get a
169
	 * few things from the URL
170
	 *
171
	 * @return void
172
	 */
173
	protected function extractMetaDetails(): void
174
	{
175
		$path = $this->image->content()['filename'];
176
177
		preg_match_all('/(?<width>\d+)x(?<height>\d+).+\.(?<extension>[a-z]{3,4})/mi', $path, $dimensions, PREG_SET_ORDER, 0);
178
179
		if ($dimensions) {
180
			if (Str::endsWith(strtolower($this->image->content()['filename']), '.svg')) {
181
				$this->meta = [
182
					'height' => null,
183
					'width' => null,
184
					'extension' => 'svg',
185
					'mime' => 'image/svg+xml',
186
				];
187
			} else {
188
				$this->meta = [
189
					'height' => $dimensions[0]['height'],
190
					'width' => $dimensions[0]['width'],
191
					'extension' => strtolower($dimensions[0]['extension']),
192
					'mime' => $this->setMime(strtolower($dimensions[0]['extension'])),
193
				];
194
			}
195
		}
196
	}
197
198
	/**
199
	 * Checks if any filters were applied to the transformation
200
	 *
201
	 * @return bool
202
	 */
203
	private function hasFilters(): bool
204
	{
205
		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');
206
	}
207
208
	/**
209
	 * Sets the asset domain
210
	 *
211
	 * @param $options
212
	 * @return string
213
	 */
214
	protected function assetDomain($options = null): string
215
	{
216
		$resource = str_replace(config('storyblok.asset_domain'), config('storyblok.image_service_domain'), $this->image->content()['filename']);
217
218
		return $resource . '/m' . $options;
219
	}
220
}