Completed
Push — master ( 0ea243...da58d4 )
by Henry
10:25 queued 33s
created

modules/Gallery/Gallery.php (2 issues)

lazy-initialization of arrays.

Coding Style Comprehensibility Informational

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Redaxscript\Modules\Gallery;
3
4
use Redaxscript\Filesystem;
5
use Redaxscript\Head;
6
use Redaxscript\Html;
7
use Redaxscript\Module;
8
use function array_key_exists;
9
use function array_reverse;
10
use function chmod;
11
use function getimagesize;
12
use function imagecopyresampled;
13
use function imagecreatefromgif;
14
use function imagecreatefromjpeg;
15
use function imagecreatefrompng;
16
use function imagecreatetruecolor;
17
use function imagedestroy;
18
use function imagejpeg;
19
use function is_array;
20
use function is_dir;
21
use function pathinfo;
22
use function round;
23
use function strtolower;
24
25
/**
26
 * javascript powered gallery
27
 *
28
 * @since 3.0.0
29
 *
30
 * @package Redaxscript
31
 * @category Modules
32
 * @author Henry Ruhs
33
 */
34
35
class Gallery extends Module\Notification
36
{
37
	/**
38
	 * array of the module
39
	 *
40
	 * @var array
41
	 */
42
43
	protected static $_moduleArray =
44
	[
45
		'name' => 'Gallery',
46
		'alias' => 'Gallery',
47
		'author' => 'Redaxmedia',
48
		'description' => 'JavaScript powered gallery',
49
		'version' => '4.0.0'
50
	];
51
52
	/**
53
	 * array of the option
54
	 *
55
	 * @var array
56
	 */
57
58
	protected $_optionArray =
59
	[
60
		'className' =>
61
		[
62
			'image' => 'rs-image-gallery',
63
			'list' => 'rs-js-gallery rs-list-gallery'
64
		],
65
		'allowedCommands' =>
66
		[
67
			'create',
68
			'remove'
69
		],
70
		'height' => 200,
71
		'quality' => 80,
72
		'thumbDirectory' => 'thumbs'
73
	];
74
75
	/**
76
	 * adminNotification
77
	 *
78
	 * @since 3.0.0
79
	 *
80
	 * @return array|null
81
	 */
82
83
	public function adminNotification() : ?array
84
	{
85
		return $this->getNotification();
86
	}
87
88
	/**
89
	 * renderStart
90
	 *
91
	 * @since 3.0.0
92
	 */
93
94
	public function renderStart() : void
95
	{
96
		/* link */
97
98
		$link = Head\Link::getInstance();
99
		$link
100
			->init()
101
			->appendFile(
102
			[
103
				'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe.min.css',
104
				'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/default-skin/default-skin.min.css',
105
				'modules/Gallery/dist/styles/gallery.min.css'
106
			]);
107
108
		/* script */
109
110
		$script = Head\Script::getInstance();
111
		$script
112
			->init('foot')
113
			->appendFile(
114
			[
115
				'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe.min.js',
116
				'https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe-ui-default.min.js',
117
				'modules/Gallery/assets/scripts/init.js',
118
				'modules/Gallery/dist/scripts/gallery.min.js'
119
			]);
120
	}
121
122
	/**
123
	 * renderEnd
124
	 *
125
	 * @since 4.0.0
126
	 */
127
128
	public function renderEnd() : void
129
	{
130
		include_once('modules/Gallery/templates/gallery.phtml');
131
	}
132
133
	/**
134
	 * render
135
	 *
136
	 * @since 3.0.0
137
	 *
138
	 * @param string $directory
139
	 * @param array $optionArray
140
	 *
141
	 * @return string|null
142
	 */
143
144
	public function render(string $directory = null, array $optionArray = []) : ?string
145
	{
146
		$output = null;
147
		$outputItem = null;
148
149
		/* html element */
150
151
		$listElement = new Html\Element();
152
		$listElement->init('ul',
153
		[
154
			'class' => $this->_optionArray['className']['list']
155
		]);
156
157
		/* handle notification */
158
159
		if (!is_dir($directory))
160
		{
161
			$this->setNotification('error', $this->_language->get('directory_not_found') . $this->_language->get('colon') . ' ' . $directory . $this->_language->get('point'));
162
		}
163
164
		/* else collect item */
165
166
		else
167
		{
168
			/* remove as needed */
169
170
			if ($optionArray['command'] === 'remove')
171
			{
172
				$this->_removeThumb($directory);
173
			}
174
175
			/* create as needed */
176
177
			if ($optionArray['command'] === 'create' || !is_dir($directory . DIRECTORY_SEPARATOR . $this->_optionArray['thumbDirectory']))
178
			{
179
				$this->_createThumb($directory, $optionArray);
180
			}
181
			$outputItem .= $this->_renderItem($directory, $optionArray);
182
183
			/* collect list output */
184
185
			if ($outputItem)
186
			{
187
				$output = $listElement->html($outputItem);
188
			}
189
		}
190
		return $output;
191
	}
192
193
	/**
194
	 * renderItem
195
	 *
196
	 * @since 2.6.0
197
	 *
198
	 * @param string $directory
199
	 * @param array $optionArray
200
	 *
201
	 * @return string|null
202
	 */
203
204
	protected function _renderItem(string $directory = null, array $optionArray = []) : ?string
205
	{
206
		$outputItem = null;
207
		$itemCounter = 0;
208
209
		/* html element */
210
211
		$element = new Html\Element();
212
		$itemElement = $element->copy()->init('li');
213
		$linkElement = $element->copy()->init('a');
214
		$imageElement = $element
215
			->copy()
216
			->init('img',
217
			[
218
				'class' => $this->_optionArray['className']['image']
219
			]);
220
221
		/* gallery filesystem */
222
223
		$galleryFilesystem = new Filesystem\Filesystem();
224
		$galleryFilesystem->init($directory, false,
225
		[
226
			$this->_optionArray['thumbDirectory']
227
		]);
228
		$galleryFilesystemArray = $galleryFilesystem->getSortArray();
229
230
		/* adjust order */
231
232
		if ($optionArray['order'] === 'desc')
233
		{
234
			$galleryFilesystemArray = array_reverse($galleryFilesystemArray);
235
		}
236
237
		/* process filesystem */
238
239
		foreach ($galleryFilesystemArray as $value)
240
		{
241
			$imagePath = $directory . DIRECTORY_SEPARATOR . $value;
242
			$thumbPath = $directory . DIRECTORY_SEPARATOR . $this->_optionArray['thumbDirectory'] . DIRECTORY_SEPARATOR . $value;
243
			$imageSize = getimagesize($imagePath);
244
245
			/* collect item output */
246
247
			$outputItem .= $itemElement
248
				->clear()
249
				->html(
250
					$linkElement
251
						->copy()
252
						->attr(
253
						[
254
							'href' => $imagePath,
255
							'data-index' => $itemCounter++,
256
							'data-height' => $imageSize[1],
257
							'data-width' => $imageSize[0]
258
						])
259
						->html(
260
							$imageElement
261
								->copy()
262
								->attr(
263
								[
264
									'src' => $thumbPath,
265
									'alt' => $value
266
								])
267
						)
268
				);
269
		}
270
		return $outputItem;
271
	}
272
273
	/**
274
	 * removeThumb
275
	 *
276
	 * @since 3.0.0
277
	 *
278
	 * @param string $directory
279
	 */
280
281
	protected function _removeThumb(string $directory = null) : void
282
	{
283
		$galleryFilesystem = new Filesystem\Directory();
284
		$galleryFilesystem->init($directory, true);
285
		$galleryFilesystem->removeDirectory($this->_optionArray['thumbDirectory']);
286
	}
287
288
	/**
289
	 * createThumb
290
	 *
291
	 * @since 3.0.0
292
	 *
293
	 * @param string $directory
294
	 * @param array $optionArray
295
	 */
296
297
	protected function _createThumb(string $directory = null, array $optionArray = []) : void
298
	{
299
		/* gallery filesystem */
300
301
		$galleryFilesystem = new Filesystem\Directory();
302
		$galleryFilesystem->init($directory, false,
303
		[
304
			$this->_optionArray['thumbDirectory']
305
		]);
306
		$galleryFilesystem->createDirectory($this->_optionArray['thumbDirectory']);
307
		$galleryFilesystemArray = $galleryFilesystem->getSortArray();
308
309
		/* handle notification */
310
311
		if (!chmod($directory . DIRECTORY_SEPARATOR . $this->_optionArray['thumbDirectory'], 0777))
312
		{
313
			$this->setNotification('error', $this->_language->get('directory_permission_grant') . $this->_language->get('colon') . ' ' . $directory . DIRECTORY_SEPARATOR . $this->_optionArray['thumbDirectory'] . $this->_language->get('point'));
314
		}
315
316
		/* else process filesystem */
317
318
		else
319
		{
320
			foreach ($galleryFilesystemArray as $value)
321
			{
322
				$imagePath = $directory . DIRECTORY_SEPARATOR . $value;
323
				$imageExtension = strtolower(pathinfo($value, PATHINFO_EXTENSION));
324
				$thumbPath = $directory . DIRECTORY_SEPARATOR . $this->_optionArray['thumbDirectory'] . DIRECTORY_SEPARATOR . $value;
325
				$image = null;
326
327
				/* handle extension */
328
329
				if ($imageExtension === 'gif')
330
				{
331
					$image = imagecreatefromgif($imagePath);
332
				}
333
				if ($imageExtension === 'jpg')
334
				{
335
					$image = imagecreatefromjpeg($imagePath);
336
				}
337
				if ($imageExtension === 'png')
338
				{
339
					$image = imagecreatefrompng($imagePath);
340
				}
341
342
				/* source and dist */
343
344
				$sourceArray = $this->_calcSource($imagePath);
345
				$distArray = $this->_calcDist($sourceArray, $optionArray);
346
347
				/* create thumb files */
348
349
				$thumb = imagecreatetruecolor($distArray['width'], $distArray['height']);
350
				imagecopyresampled($thumb, $image, 0, 0, 0, 0, $distArray['width'], $distArray['height'], $sourceArray['width'], $sourceArray['height']);
351
				imagejpeg($thumb, $thumbPath, $distArray['quality']);
352
353
				/* destroy image */
354
355
				imagedestroy($thumb);
356
				imagedestroy($image);
357
			}
358
		}
359
	}
360
361
	/**
362
	 * calcSource
363
	 *
364
	 * @param string $imagePath
365
	 *
366
	 * @return array
367
	 */
368
369
	protected function _calcSource(string $imagePath = null) : array
370
	{
371
		$sourceArray['size'] = getimagesize($imagePath);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$sourceArray was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sourceArray = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
372
		$sourceArray['height'] = $sourceArray['size'][1];
373
		$sourceArray['width'] = $sourceArray['size'][0];
374
		return $sourceArray;
375
	}
376
377
	/**
378
	 * calcDist
379
	 *
380
	 * @param array $sourceArray
381
	 * @param array $optionArray
382
	 *
383
	 * @return array
384
	 */
385
386
	protected function _calcDist(array $sourceArray = [], array $optionArray = []) : array
387
	{
388
		$distArray['height'] = is_array($optionArray) && array_key_exists('height', $optionArray) ? $optionArray['height'] : $this->_optionArray['height'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$distArray was never initialized. Although not strictly required by PHP, it is generally a good practice to add $distArray = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
389
		$distArray['quality'] = is_array($optionArray) && array_key_exists('quality', $optionArray) ? $optionArray['quality'] : $this->_optionArray['quality'];
390
391
		/* calculate */
392
393
		if ($distArray['height'])
394
		{
395
			$distArray['scaling'] = $distArray['height'] / $sourceArray['height'] * 100;
396
		}
397
		else
398
		{
399
			$distArray['height'] = round($distArray['scaling'] / 100 * $sourceArray['height']);
400
		}
401
		$distArray['width'] = round($distArray['scaling'] / 100 * $sourceArray['width']);
402
		return $distArray;
403
	}
404
}
405