Issues (20)

src/Fields/Image.php (1 issue)

1
<?php
2
3
4
namespace Riclep\Storyblok\Fields;
5
6
use Riclep\Storyblok\Support\ImageTransformation;
7
8
/**
9
 * @property boolean $focus
10
 */
11
class Image extends Asset
12
{
13
	/**
14
	 * Stores the transformations to be applied
15
	 *
16
	 * @var array
17
	 */
18
	public array $transformations = [];
19
20
	/**
21
	 * The transformer used for this image
22
	 *
23
	 * @var mixed
24
	 */
25
	protected mixed $transformer;
26
27
	/**
28
	 * The transformer class used for transformations
29
	 *
30
	 * @var mixed
31
	 */
32
	protected mixed $transformerClass;
33
34
	/**
35
	 * Constructs the image image field
36
	 *
37
	 * @param $content
38
	 * @param $block
39
	 */
40
	public function __construct($content, $block)
41
	{
42
		if (is_string($content)) {
43
			$this->upgradeStringFields($content);
44
			parent::__construct($this->content, $block);
45
		} else {
46
			parent::__construct($content, $block);
47
		}
48
49
		$this->transformerClass = config('storyblok.image_transformer');
50
51
		$transformerClass = $this->transformerClass;
52
		$this->transformer = new $transformerClass($this);
53
54
		if (method_exists($this->transformer, 'init')) {
55
			$this->transformer->init();
56
		}
57
58
		if (method_exists($this, 'transformations')) {
59
			$this->transformations();
60
		}
61
	}
62
63
	/**
64
	 * Get the width of the image or transformed image
65
	 *
66
	 * @param bool $original
67
	 * @return int
68
	 */
69
	public function width(bool $original = false): int
70
	{
71
		return $this->transformer->width($original);
72
	}
73
74
	/**
75
	 * Get the height of the image or transformed image
76
	 *
77
	 * @param bool $original
78
	 * @return int
79
	 */
80
	public function height(bool $original = false): int
81
	{
82
		return $this->transformer->height($original);
83
	}
84
85
	/**
86
	 * Get the mime of the image or transformed image
87
	 *
88
	 * @param bool $original
89
	 * @return string
90
	 */
91
	public function mime(bool $original = false): string
92
	{
93
		return $this->transformer->mime($original);
94
	}
95
96
	/**
97
	 * Create a new or get a transformation of the image
98
	 *
99
	 * @param $tranformation
100
	 * @return mixed
101
	 */
102
	public function transform($tranformation = null): mixed
103
	{
104
		if ($tranformation) {
105
			if (array_key_exists($tranformation, $this->transformations) ) {
106
				return new ImageTransformation($this->transformations[$tranformation]);
107
			}
108
			return false;
109
		}
110
111
		$transformerClass = $this->transformerClass;
112
		$this->transformer = new $transformerClass($this);
113
114
		if (method_exists($this->transformer, 'init')) {
115
			$this->transformer->init();
116
		}
117
118
		return $this->transformer;
119
	}
120
121
	/**
122
	 * Set the driver to use for transformations
123
	 *
124
	 * @param $transformer
125
	 * @return mixed
126
	 */
127
	public function transformer($transformer): mixed
128
	{
129
		$this->transformerClass = $transformer;
130
131
		return $this;
132
	}
133
134
135
	/**
136
	 * Returns a picture element tag for this image and
137
	 * ant transforms defined on the image class
138
	 *
139
	 * @param string $alt
140
	 * @param $default
141
	 * @param array $attributes
142
	 * @param string $view
143
	 * @param bool $reverseTagOrder
144
	 * @return string
145
	 */
146
	public function picture(string $alt = '', $default = null, array $attributes = [], string $view = 'laravel-storyblok::picture-element', bool $reverseTagOrder = false): string
147
	{
148
		if ($default) {
149
			$imgSrc = (string) $this->transformations[$default]['src'];
150
		} else {
151
			$imgSrc = $this->filename;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->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...
152
		}
153
154
		// srcset seems to work the opposite way to picture elements when working out sizes
155
		if ($reverseTagOrder) {
156
			$transformations = array_reverse($this->transformations);
157
		} else {
158
			$transformations = $this->transformations;
159
		}
160
161
		return view($view, [
162
			'alt' => $alt,
163
			'attributes' => $attributes,
164
			'default' => $default,
165
			'imgSrc' => $imgSrc,
166
			'transformations' => $transformations,
167
		])->render();
168
	}
169
170
	/**
171
	 * Returns an image tag with srcset attribute
172
	 *
173
	 * @param string $alt
174
	 * @param $default
175
	 * @param array $attributes
176
	 * @param string $view
177
	 * @return string
178
	 */
179
	public function srcset(string $alt = '', $default = null, array $attributes = [], string $view = 'laravel-storyblok::srcset'): string
180
	{
181
		return $this->picture($alt, $default, $attributes, $view ?? 'laravel-storyblok::srcset');
182
	}
183
184
	/**
185
	 * Allows setting of new transformations on this image. Optionally
186
	 * return a new image so the original is not mutated
187
	 *
188
	 * @param $transformations
189
	 * @param bool $mutate
190
	 * @return $this|Image
191
	 */
192
	public function setTransformations($transformations, bool $mutate = true): Image|self
193
	{
194
		if ($mutate) {
195
			$this->transformations = $transformations;
196
197
			return $this;
198
		}
199
200
		$class = get_class($this); // don’t mutate original object
201
		$image = new $class($this->content, $this->block);
202
		$image->transformations = $transformations;
203
204
		return $image;
205
	}
206
207
	/**
208
	 * Reads the focus property if available and returns a string that can be used for CSS
209
	 * object-position or background-position. The default should be any valid value for
210
	 * the CSS property being used. Rigid will use hard alignments to edges.
211
	 *
212
	 * @param $default
213
	 * @param $rigid
214
	 * @return string
215
	 */
216
	public function focalPointAlignment($default = 'center', $rigid = false): string
217
	{
218
		if (!$this->focus) {
219
			return $default;
220
		}
221
222
		preg_match_all('/\d+/', $this->focus, $matches);
223
224
		$leftPercent = round(($matches[0][0] / $this->width(true)) * 100);
225
		$topPercent = round(($matches[0][1] / $this->height(true)) * 100);
226
227
		if ($rigid) {
228
			if ($leftPercent > 66) {
229
				$horizontalAlignment = 'right';
230
			} else if ($leftPercent > 33) {
231
				$horizontalAlignment = 'center';
232
			} else {
233
				$horizontalAlignment = 'left';
234
			}
235
236
			if ($topPercent > 66) {
237
				$verticalAlignment = 'bottom';
238
			} else if ($topPercent > 33) {
239
				$verticalAlignment = 'center';
240
			} else {
241
				$verticalAlignment = 'top';
242
			}
243
244
			return $horizontalAlignment . ' ' . $verticalAlignment;
245
		}
246
247
		return $leftPercent . '% ' . $topPercent . '%';
248
	}
249
250
	/**
251
	 * Converts string fields into full image fields
252
	 *
253
	 * @param $content
254
	 * @return void
255
	 */
256
	protected function upgradeStringFields($content): void
257
	{
258
		$this->content = [
259
			'filename' => $content,
260
			'alt' => null,
261
			'copyright' => null,
262
			'fieldtype' => 'asset',
263
			'focus' => null,
264
			'name' => '',
265
			'title' => null,
266
		];
267
	}
268
}