PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 1.9.8
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v1.9.8
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.8, at classes/Media/AbstractMedia.php

553 lines 12.2 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 $original_path = $this->get_raw_original_path();
241
242 if ( ! $original_path || ! $this->filesystem->exists( $original_path ) ) {
243 return false;
244 }
245
246 return $original_path;
247 }
248
249
250 /** ----------------------------------------------------------------------------------------- */
251 /** FULL SIZE FILE ========================================================================== */
252 /** ----------------------------------------------------------------------------------------- */
253
254 /**
255 * Get the path to the media’s full size file if the file exists.
256 *
257 * @since 1.9.8
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_fullsize_path() {
264 if ( ! $this->is_valid() ) {
265 return false;
266 }
267
268 $original_path = $this->get_raw_fullsize_path();
269
270 if ( ! $original_path || ! $this->filesystem->exists( $original_path ) ) {
271 return false;
272 }
273
274 return $original_path;
275 }
276
277
278 /** ----------------------------------------------------------------------------------------- */
279 /** BACKUP FILE ============================================================================= */
280 /** ----------------------------------------------------------------------------------------- */
281
282 /**
283 * Get the backup file path if the file exists.
284 *
285 * @since 1.9
286 * @access public
287 * @author Grégory Viguier
288 *
289 * @return string|bool The file path. False if it doesn't exist.
290 */
291 public function get_backup_path() {
292 if ( ! $this->is_valid() ) {
293 return false;
294 }
295
296 $backup_path = $this->get_raw_backup_path();
297
298 if ( ! $backup_path || ! $this->filesystem->exists( $backup_path ) ) {
299 return false;
300 }
301
302 return $backup_path;
303 }
304
305 /**
306 * Check if the media has a backup of the original file.
307 *
308 * @since 1.9
309 * @access public
310 * @author Grégory Viguier
311 *
312 * @return bool True if the media has a backup.
313 */
314 public function has_backup() {
315 return (bool) $this->get_backup_path();
316 }
317
318
319 /** ----------------------------------------------------------------------------------------- */
320 /** MEDIA DATA ============================================================================== */
321 /** ----------------------------------------------------------------------------------------- */
322
323 /**
324 * Tell if the current media type is supported.
325 *
326 * @since 1.9
327 * @access public
328 * @author Grégory Viguier
329 *
330 * @return bool
331 */
332 public function is_supported() {
333 return (bool) $this->get_mime_type();
334 }
335
336 /**
337 * Tell if the current media refers to an image, based on file extension.
338 *
339 * @since 1.9
340 * @access public
341 * @author Grégory Viguier
342 *
343 * @return bool Returns false in case it's an image but not in a supported format (bmp for example).
344 */
345 public function is_image() {
346 if ( isset( $this->is_image ) ) {
347 return $this->is_image;
348 }
349
350 $this->is_image = strpos( (string) $this->get_mime_type(), 'image/' ) === 0;
351
352 return $this->is_image;
353 }
354
355 /**
356 * Tell if the current media refers to a pdf, based on file extension.
357 *
358 * @since 1.9
359 * @access public
360 * @author Grégory Viguier
361 *
362 * @return bool
363 */
364 public function is_pdf() {
365 if ( isset( $this->is_pdf ) ) {
366 return $this->is_pdf;
367 }
368
369 $this->is_pdf = 'application/pdf' === $this->get_mime_type();
370
371 return $this->is_pdf;
372 }
373
374 /**
375 * Get the original file extension (if supported by Imagify).
376 *
377 * @since 1.9
378 * @access public
379 * @author Grégory Viguier
380 *
381 * @return string|null
382 */
383 public function get_extension() {
384 return $this->get_file_type()->ext;
385 }
386
387 /**
388 * Get the original file mime type (if supported by Imagify).
389 *
390 * @since 1.9
391 * @access public
392 * @author Grégory Viguier
393 *
394 * @return string
395 */
396 public function get_mime_type() {
397 return $this->get_file_type()->type;
398 }
399
400 /**
401 * Get the file mime type + file extension (if the file is supported by Imagify).
402 * This test is ran against the original file.
403 *
404 * @since 1.9
405 * @access public
406 * @author Grégory Viguier
407 *
408 * @return array
409 */
410 public function get_allowed_mime_types() {
411 return imagify_get_mime_types( $this->get_context_instance()->get_allowed_mime_types() );
412 }
413
414 /**
415 * If the media is an image, update the dimensions in the database with the current file dimensions.
416 *
417 * @since 1.9
418 * @access public
419 * @author Grégory Viguier
420 *
421 * @return bool True on success. False on failure.
422 */
423 public function update_dimensions() {
424 if ( ! $this->is_image() ) {
425 // The media is not a supported image.
426 return false;
427 }
428
429 $dimensions = $this->filesystem->get_image_size( $this->get_raw_fullsize_path() );
430
431 if ( ! $dimensions ) {
432 // Could not get the new dimensions.
433 return false;
434 }
435
436 $context = $this->get_context();
437
438 /**
439 * Triggered before updating an image width and height into its metadata.
440 *
441 * @since 1.9
442 * @see Imagify_Filesystem->get_image_size()
443 * @author Grégory Viguier
444 *
445 * @param int $media_id The media ID.
446 * @param array $dimensions {
447 * An array with, among other data:
448 *
449 * @type int $width The image width.
450 * @type int $height The image height.
451 * }
452 */
453 do_action( "imagify_before_update_{$context}_media_data_dimensions", $this->get_id(), $dimensions );
454
455 $this->update_media_data_dimensions( $dimensions );
456
457 /**
458 * Triggered after updating an image width and height into its metadata.
459 *
460 * @since 1.9
461 * @see Imagify_Filesystem->get_image_size()
462 * @author Grégory Viguier
463 *
464 * @param int $media_id The media ID.
465 * @param array $dimensions {
466 * An array with, among other data:
467 *
468 * @type int $width The image width.
469 * @type int $height The image height.
470 * }
471 */
472 do_action( "imagify_after_update_{$context}_media_data_dimensions", $this->get_id(), $dimensions );
473
474 return true;
475 }
476
477 /**
478 * Update the media data dimensions.
479 *
480 * @since 1.9
481 * @access public
482 * @author Grégory Viguier
483 *
484 * @param array $dimensions {
485 * An array containing width and height.
486 *
487 * @type int $width The image width.
488 * @type int $height The image height.
489 * }
490 */
491 abstract protected function update_media_data_dimensions( $dimensions );
492
493 /**
494 * Get the file mime type + file extension (if the file is supported by Imagify).
495 * This test is ran against the original file.
496 *
497 * @since 1.9
498 * @access protected
499 * @see wp_check_filetype()
500 * @author Grégory Viguier
501 *
502 * @return object
503 */
504 protected function get_file_type() {
505 if ( isset( $this->file_type ) ) {
506 return $this->file_type;
507 }
508
509 $this->file_type = (object) [
510 'ext' => '',
511 'type' => '',
512 ];
513
514 if ( ! $this->is_valid() ) {
515 return $this->file_type;
516 }
517
518 $path = $this->get_raw_fullsize_path();
519
520 if ( ! $path ) {
521 return $this->file_type;
522 }
523
524 $this->file_type = (object) wp_check_filetype( $path, $this->get_allowed_mime_types() );
525
526 return $this->file_type;
527 }
528
529 /**
530 * Filter the result of $this->get_media_files().
531 *
532 * @since 1.9
533 * @access protected
534 * @see $this->get_media_files()
535 * @author Grégory Viguier
536 *
537 * @param array $files An array with the size names as keys ('full' is used for the full size file), and arrays of data as values.
538 * @return array
539 */
540 protected function filter_media_files( $files ) {
541 /**
542 * Filter the media files.
543 *
544 * @since 1.9
545 * @author Grégory Viguier
546 *
547 * @param array $files An array with the size names as keys ('full' is used for the full size file), and arrays of data as values.
548 * @param MediaInterface $media This instance.
549 */
550 return (array) apply_filters( 'imagify_media_files', $files, $this );
551 }
552 }
553