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

modules/Gallery/Gallery.php (2 issues)

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