PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 1.9.4
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v1.9.4
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / classes / Media / AbstractMedia.php

AbstractMedia.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 1.9.4, at classes/Media/AbstractMedia.php

525 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Imagify\Media;
3
4 use Imagify\CDN\PushCDNInterface;
5 use Imagify\Context\ContextInterface;
6
7 defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
8
9 /**
10 * Abstract used for "media groups" (aka attachments).
11 *
12 * @since 1.9
13 * @author Grégory Viguier
14 */
15 abstract class AbstractMedia implements MediaInterface {
16
17 /**
18 * The media ID.
19 *
20 * @var int
21 * @since 1.9
22 * @access protected
23 * @author Grégory Viguier
24 */
25 protected $id;
26
27 /**
28 * Context (where the media "comes from").
29 *
30 * @var ContextInterface
31 * @since 1.9
32 * @access protected
33 * @author Grégory Viguier
34 */
35 protected $context;
36
37 /**
38 * CDN to use.
39 *
40 * @var PushCDNInterface
41 * @since 1.9
42 * @access protected
43 * @author Grégory Viguier
44 */
45 protected $cdn;
46
47 /**
48 * Tell if the media/context is network-wide.
49 *
50 * @var bool
51 * @since 1.9
52 * @access protected
53 * @author Grégory Viguier
54 */
55 protected $is_network_wide = false;
56
57 /**
58 * Tell if the file is an image.
59 *
60 * @var bool
61 * @since 1.9
62 * @access protected
63 * @see $this->is_image()
64 * @author Grégory Viguier
65 */
66 protected $is_image;
67
68 /**
69 * Tell if the file is a pdf.
70 *
71 * @var bool
72 * @since 1.9
73 * @access protected
74 * @see $this->is_pdf()
75 * @author Grégory Viguier
76 */
77 protected $is_pdf;
78
79 /**
80 * Store the file mime type + file extension (if the file is supported).
81 *
82 * @var array
83 * @since 1.9
84 * @access protected
85 * @see $this->get_file_type()
86 * @author Grégory Viguier
87 */
88 protected $file_type;
89
90 /**
91 * Filesystem object.
92 *
93 * @var object Imagify_Filesystem
94 * @since 1.9
95 * @access protected
96 * @author Grégory Viguier
97 */
98 protected $filesystem;
99
100 /**
101 * The constructor.
102 *
103 * @since 1.9
104 * @access public
105 * @author Grégory Viguier
106 *
107 * @param int $id The media ID.
108 */
109 public function __construct( $id ) {
110 $this->id = (int) $id;
111 $this->filesystem = \Imagify_Filesystem::get_instance();
112 }
113
114 /**
115 * Get the media ID.
116 *
117 * @since 1.9
118 * @access public
119 * @author Grégory Viguier
120 *
121 * @return int
122 */
123 public function get_id() {
124 return $this->id;
125 }
126
127 /**
128 * Tell if the current media is valid.
129 *
130 * @since 1.9
131 * @access public
132 * @author Grégory Viguier
133 *
134 * @return bool
135 */
136 public function is_valid() {
137 return $this->get_id() > 0;
138 }
139
140 /**
141 * Get the media context name.
142 *
143 * @since 1.9
144 * @access public
145 * @author Grégory Viguier
146 *
147 * @return string
148 */
149 public function get_context() {
150 return $this->get_context_instance()->get_name();
151 }
152
153 /**
154 * Get the media context instance.
155 *
156 * @since 1.9
157 * @access public
158 * @author Grégory Viguier
159 *
160 * @return ContextInterface
161 */
162 public function get_context_instance() {
163 if ( $this->context ) {
164 if ( is_string( $this->context ) ) {
165 $this->context = imagify_get_context( $this->context );
166 }
167
168 return $this->context;
169 }
170
171 $class_name = get_class( $this );
172 $class_name = '\\' . trim( $class_name, '\\' );
173 $class_name = str_replace( '\\Media\\', '\\Context\\', $class_name );
174 $this->context = new $class_name();
175
176 return $this->context;
177 }
178
179 /**
180 * Get the CDN instance.
181 *
182 * @since 1.9
183 * @access public
184 * @author Grégory Viguier
185 *
186 * @return bool|PushCDNInterface A PushCDNInterface instance. False if no CDN is used.
187 */
188 public function get_cdn() {
189 if ( isset( $this->cdn ) ) {
190 return $this->cdn;
191 }
192
193 if ( ! $this->is_valid() ) {
194 $this->cdn = false;
195 return $this->cdn;
196 }
197
198 $media_id = $this->get_id();
199 $context = $this->get_context_instance();
200
201 /**
202 * The CDN to use for this media.
203 *
204 * @since 1.9
205 * @author Grégory Viguier
206 *
207 * @param bool|PushCDNInterface $cdn A PushCDNInterface instance. False if no CDN is used.
208 * @param int $media_id The media ID.
209 * @param ContextInterface $context The context object.
210 */
211 $this->cdn = apply_filters( 'imagify_cdn', false, $media_id, $context );
212
213 if ( ! $this->cdn || ! $this->cdn instanceof PushCDNInterface ) {
214 $this->cdn = false;
215 return $this->cdn;
216 }
217
218 return $this->cdn;
219 }
220
221
222 /** ----------------------------------------------------------------------------------------- */
223 /** ORIGINAL FILE =========================================================================== */
224 /** ----------------------------------------------------------------------------------------- */
225
226 /**
227 * Get the original media's path if the file exists.
228 *
229 * @since 1.9
230 * @access public
231 * @author Grégory Viguier
232 *
233 * @return string|bool The file path. False if it doesn't exist.
234 */
235 public function get_original_path() {
236 if ( ! $this->is_valid() ) {
237 return false;
238 }
239
240 $backup_path = $this->get_raw_original_path();
241
242 if ( ! $backup_path || ! $this->filesystem->exists( $backup_path ) ) {
243 return false;
244 }
245
246 return $backup_path;
247 }
248
249
250 /** ----------------------------------------------------------------------------------------- */
251 /** BACKUP FILE ============================================================================= */
252 /** ----------------------------------------------------------------------------------------- */
253
254 /**
255 * Get the backup file path if the file exists.
256 *
257 * @since 1.9
258 * @access public
259 * @author Grégory Viguier
260 *
261 * @return string|bool The file path. False if it doesn't exist.
262 */
263 public function get_backup_path() {
264 if ( ! $this->is_valid() ) {
265 return false;
266 }
267
268 $backup_path = $this->get_raw_backup_path();
269
270 if ( ! $backup_path || ! $this->filesystem->exists( $backup_path ) ) {
271 return false;
272 }
273
274 return $backup_path;
275 }
276
277 /**
278 * Check if the media has a backup of the original file.
279 *
280 * @since 1.9
281 * @access public
282 * @author Grégory Viguier
283 *
284 * @return bool True if the media has a backup.
285 */
286 public function has_backup() {
287 return (bool) $this->get_backup_path();
288 }
289
290
291 /** ----------------------------------------------------------------------------------------- */
292 /** MEDIA DATA ============================================================================== */
293 /** ----------------------------------------------------------------------------------------- */
294
295 /**
296 * Tell if the current media type is supported.
297 *
298 * @since 1.9
299 * @access public
300 * @author Grégory Viguier
301 *
302 * @return bool
303 */
304 public function is_supported() {
305 return (bool) $this->get_mime_type();
306 }
307
308 /**
309 * Tell if the current media refers to an image, based on file extension.
310 *
311 * @since 1.9
312 * @access public
313 * @author Grégory Viguier
314 *
315 * @return bool Returns false in case it's an image but not in a supported format (bmp for example).
316 */
317 public function is_image() {
318 if ( isset( $this->is_image ) ) {
319 return $this->is_image;
320 }
321
322 $this->is_image = strpos( (string) $this->get_mime_type(), 'image/' ) === 0;
323
324 return $this->is_image;
325 }
326
327 /**
328 * Tell if the current media refers to a pdf, based on file extension.
329 *
330 * @since 1.9
331 * @access public
332 * @author Grégory Viguier
333 *
334 * @return bool
335 */
336 public function is_pdf() {
337 if ( isset( $this->is_pdf ) ) {
338 return $this->is_pdf;
339 }
340
341 $this->is_pdf = 'application/pdf' === $this->get_mime_type();
342
343 return $this->is_pdf;
344 }
345
346 /**
347 * Get the original file extension (if supported by Imagify).
348 *
349 * @since 1.9
350 * @access public
351 * @author Grégory Viguier
352 *
353 * @return string|null
354 */
355 public function get_extension() {
356 return $this->get_file_type()->ext;
357 }
358
359 /**
360 * Get the original file mime type (if supported by Imagify).
361 *
362 * @since 1.9
363 * @access public
364 * @author Grégory Viguier
365 *
366 * @return string
367 */
368 public function get_mime_type() {
369 return $this->get_file_type()->type;
370 }
371
372 /**
373 * Get the file mime type + file extension (if the file is supported by Imagify).
374 * This test is ran against the original file.
375 *
376 * @since 1.9
377 * @access public
378 * @author Grégory Viguier
379 *
380 * @return array
381 */
382 public function get_allowed_mime_types() {
383 return imagify_get_mime_types( $this->get_context_instance()->get_allowed_mime_types() );
384 }
385
386 /**
387 * If the media is an image, update the dimensions in the database with the current file dimensions.
388 *
389 * @since 1.9
390 * @access public
391 * @author Grégory Viguier
392 *
393 * @return bool True on success. False on failure.
394 */
395 public function update_dimensions() {
396 if ( ! $this->is_image() ) {
397 // The media is not a supported image.
398 return false;
399 }
400
401 $dimensions = $this->filesystem->get_image_size( $this->get_raw_original_path() );
402
403 if ( ! $dimensions ) {
404 // Could not get the new dimensions.
405 return false;
406 }
407
408 $context = $this->get_context();
409
410 /**
411 * Triggered before updating an image width and height into its metadata.
412 *
413 * @since 1.9
414 * @see Imagify_Filesystem->get_image_size()
415 * @author Grégory Viguier
416 *
417 * @param int $media_id The media ID.
418 * @param array $dimensions {
419 * An array with, among other data:
420 *
421 * @type int $width The image width.
422 * @type int $height The image height.
423 * }
424 */
425 do_action( "imagify_before_update_{$context}_media_data_dimensions", $this->get_id(), $dimensions );
426
427 $this->update_media_data_dimensions( $dimensions );
428
429 /**
430 * Triggered after updating an image width and height into its metadata.
431 *
432 * @since 1.9
433 * @see Imagify_Filesystem->get_image_size()
434 * @author Grégory Viguier
435 *
436 * @param int $media_id The media ID.
437 * @param array $dimensions {
438 * An array with, among other data:
439 *
440 * @type int $width The image width.
441 * @type int $height The image height.
442 * }
443 */
444 do_action( "imagify_after_update_{$context}_media_data_dimensions", $this->get_id(), $dimensions );
445
446 return true;
447 }
448
449 /**
450 * Update the media data dimensions.
451 *
452 * @since 1.9
453 * @access public
454 * @author Grégory Viguier
455 *
456 * @param array $dimensions {
457 * An array containing width and height.
458 *
459 * @type int $width The image width.
460 * @type int $height The image height.
461 * }
462 */
463 abstract protected function update_media_data_dimensions( $dimensions );
464
465 /**
466 * Get the file mime type + file extension (if the file is supported by Imagify).
467 * This test is ran against the original file.
468 *
469 * @since 1.9
470 * @access protected
471 * @see wp_check_filetype()
472 * @author Grégory Viguier
473 *
474 * @return object
475 */
476 protected function get_file_type() {
477 if ( isset( $this->file_type ) ) {
478 return $this->file_type;
479 }
480
481 $this->file_type = (object) [
482 'ext' => '',
483 'type' => '',
484 ];
485
486 if ( ! $this->is_valid() ) {
487 return $this->file_type;
488 }
489
490 $path = $this->get_raw_original_path();
491
492 if ( ! $path ) {
493 return $this->file_type;
494 }
495
496 $this->file_type = (object) wp_check_filetype( $path, $this->get_allowed_mime_types() );
497
498 return $this->file_type;
499 }
500
501 /**
502 * Filter the result of $this->get_media_files().
503 *
504 * @since 1.9
505 * @access protected
506 * @see $this->get_media_files()
507 * @author Grégory Viguier
508 *
509 * @param array $files An array with the size names as keys ('full' is used for the original file), and arrays of data as values.
510 * @return array
511 */
512 protected function filter_media_files( $files ) {
513 /**
514 * Filter the media files.
515 *
516 * @since 1.9
517 * @author Grégory Viguier
518 *
519 * @param array $files An array with the size names as keys ('full' is used for the original file), and arrays of data as values.
520 * @param MediaInterface $media This instance.
521 */
522 return (array) apply_filters( 'imagify_media_files', $files, $this );
523 }
524 }
525