PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.2.2
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.2.2
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 / WP.php

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

431 lines 11.3 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 defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
5
6 /**
7 * Media class for the medias in the WP library.
8 *
9 * @since 1.9
10 * @author Grégory Viguier
11 */
12 class WP extends AbstractMedia {
13 use \Imagify\Deprecated\Traits\Media\WPDeprecatedTrait;
14
15 /**
16 * Tell if we’re playing in WP 5.3’s garden.
17 *
18 * @var bool
19 * @since 1.9.8
20 * @access protected
21 * @author Grégory Viguier
22 */
23 protected $is_wp53;
24
25 /**
26 * The constructor.
27 *
28 * @since 1.9
29 * @access public
30 * @author Grégory Viguier
31 *
32 * @param int|\WP_Post $id The attachment ID, or \WP_Post object.
33 */
34 public function __construct( $id ) {
35 if ( ! static::constructor_accepts( $id ) ) {
36 parent::__construct( 0 );
37 return;
38 }
39
40 if ( is_numeric( $id ) ) {
41 $id = get_post( (int) $id );
42 }
43
44 if ( ! $id || 'attachment' !== $id->post_type ) {
45 parent::__construct( 0 );
46 return;
47 }
48
49 parent::__construct( $id->ID );
50 }
51
52 /**
53 * Tell if the given entry can be accepted in the constructor.
54 *
55 * @since 1.9
56 * @access public
57 * @author Grégory Viguier
58 *
59 * @param mixed $id Whatever.
60 * @return bool
61 */
62 public static function constructor_accepts( $id ) {
63 return $id && ( is_numeric( $id ) || $id instanceof \WP_Post );
64 }
65
66
67 /** ----------------------------------------------------------------------------------------- */
68 /** ORIGINAL FILE =========================================================================== */
69 /** ----------------------------------------------------------------------------------------- */
70
71 /**
72 * Get the original file path, even if the file doesn't exist.
73 *
74 * @since 1.9
75 * @access public
76 * @author Grégory Viguier
77 *
78 * @return string|bool The file path. False on failure.
79 */
80 public function get_raw_original_path() {
81 if ( ! $this->is_valid() ) {
82 return false;
83 }
84
85 if ( $this->get_cdn() ) {
86 return $this->get_cdn()->get_file_path( 'original' );
87 }
88
89 if ( $this->is_wp_53() ) {
90 // `wp_get_original_image_path()` may return false.
91 $path = wp_get_original_image_path( $this->id );
92 } else {
93 $path = false;
94 }
95
96 if ( ! $path ) {
97 $path = get_attached_file( $this->id );
98 }
99
100 return $path ? $path : false;
101 }
102
103
104 /** ----------------------------------------------------------------------------------------- */
105 /** FULL SIZE FILE ========================================================================== */
106 /** ----------------------------------------------------------------------------------------- */
107
108 /**
109 * Get the URL of the media’s full size file.
110 *
111 * @since 1.9.8
112 * @access public
113 * @author Grégory Viguier
114 *
115 * @return string|bool The file URL. False on failure.
116 */
117 public function get_fullsize_url() {
118 if ( ! $this->is_valid() ) {
119 return false;
120 }
121
122 if ( $this->get_cdn() ) {
123 return $this->get_cdn()->get_file_url();
124 }
125
126 $url = wp_get_attachment_url( $this->id );
127
128 return $url ? $url : false;
129 }
130
131 /**
132 * Get the path to the media’s full size file, even if the file doesn't exist.
133 *
134 * @since 1.9.8
135 * @access public
136 * @author Grégory Viguier
137 *
138 * @return string|bool The file path. False on failure.
139 */
140 public function get_raw_fullsize_path() {
141 if ( ! $this->is_valid() ) {
142 return false;
143 }
144
145 if ( $this->get_cdn() ) {
146 return $this->get_cdn()->get_file_path();
147 }
148
149 $path = get_attached_file( $this->id );
150
151 return $path ? $path : false;
152 }
153
154
155 /** ----------------------------------------------------------------------------------------- */
156 /** BACKUP FILE ============================================================================= */
157 /** ----------------------------------------------------------------------------------------- */
158
159 /**
160 * Get the backup URL, even if the file doesn't exist.
161 *
162 * @since 1.9
163 * @access public
164 * @author Grégory Viguier
165 *
166 * @return string|bool The file URL. False on failure.
167 */
168 public function get_backup_url() {
169 if ( ! $this->is_valid() ) {
170 return false;
171 }
172
173 return get_imagify_attachment_url( $this->get_raw_backup_path() );
174 }
175
176 /**
177 * Get the backup file path, even if the file doesn't exist.
178 *
179 * @since 1.9
180 * @access public
181 * @author Grégory Viguier
182 *
183 * @return string|bool The file path. False on failure.
184 */
185 public function get_raw_backup_path() {
186 if ( ! $this->is_valid() ) {
187 return false;
188 }
189
190 return get_imagify_attachment_backup_path( $this->get_raw_original_path() );
191 }
192
193
194 /** ----------------------------------------------------------------------------------------- */
195 /** THUMBNAILS ============================================================================== */
196 /** ----------------------------------------------------------------------------------------- */
197
198 /**
199 * Create the media thumbnails.
200 * With WP 5.3+, this will also generate a new full size file if the original file is wider or taller than a defined threshold.
201 *
202 * @since 1.9
203 * @access public
204 * @author Grégory Viguier
205 *
206 * @return bool|WP_Error True on success. A \WP_Error instance on failure.
207 */
208 public function generate_thumbnails() {
209 if ( ! $this->is_valid() ) {
210 return new \WP_Error( 'invalid_media', __( 'This media is not valid.', 'imagify' ) );
211 }
212
213 if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
214 require_once ABSPATH . 'wp-admin/includes/image.php';
215 }
216
217 // Store the path to the current full size file before generating the thumbnails.
218 $old_full_size_path = $this->get_raw_fullsize_path();
219 $metadata = wp_generate_attachment_metadata( $this->get_id(), $this->get_raw_original_path() );
220
221 if ( empty( $metadata['file'] ) ) {
222 // Σ(゚Д゚).
223 update_post_meta( $this->get_id(), '_wp_attachment_metadata', $metadata );
224
225 return true;
226 }
227
228 /**
229 * Don't change the full size file name.
230 * WP 5.3+ will rename the full size file if the resizing threshold has changed (not the same as the one used to generate it previously).
231 * This will force WP to keep the previous file name.
232 */
233 $old_full_size_file_name = $this->filesystem->file_name( $old_full_size_path );
234 $new_full_size_file_name = $this->filesystem->file_name( $metadata['file'] );
235
236 if ( $new_full_size_file_name !== $old_full_size_file_name ) {
237 $new_full_size_path = $this->filesystem->dir_path( $old_full_size_path ) . $new_full_size_file_name;
238
239 $moved = $this->filesystem->move( $new_full_size_path, $old_full_size_path, true );
240
241 if ( $moved ) {
242 $metadata['file'] = $this->filesystem->dir_path( $metadata['file'] ) . $old_full_size_file_name;
243 update_post_meta( $this->get_id(), '_wp_attached_file', $metadata['file'] );
244 }
245 }
246
247 update_post_meta( $this->get_id(), '_wp_attachment_metadata', $metadata );
248
249 return true;
250 }
251
252
253 /** ----------------------------------------------------------------------------------------- */
254 /** MEDIA DATA ============================================================================== */
255 /** ----------------------------------------------------------------------------------------- */
256
257 /**
258 * Tell if the current media has the required data (the data containing the file paths and thumbnails).
259 *
260 * @since 1.9
261 * @access public
262 * @author Grégory Viguier
263 *
264 * @return bool
265 */
266 public function has_required_media_data() {
267 if ( ! $this->is_valid() ) {
268 return false;
269 }
270
271 $file = get_post_meta( $this->id, '_wp_attached_file', true );
272
273 if ( ! $file || preg_match( '@://@', $file ) || preg_match( '@^.:\\\@', $file ) ) {
274 return false;
275 }
276
277 return (bool) wp_get_attachment_metadata( $this->id, true );
278 }
279
280 /**
281 * Get the list of the files of this media, including the full size file.
282 *
283 * @since 1.9
284 * @access public
285 * @author Grégory Viguier
286 *
287 * @return array {
288 * An array with the size names as keys ('full' is used for the full size file), and arrays of data as values:
289 *
290 * @type string $size The size name.
291 * @type string $path Absolute path to the file.
292 * @type int $width The file width.
293 * @type int $height The file height.
294 * @type string $mime-type The file mime type.
295 * @type bool $disabled True if the size is disabled in the plugin’s settings.
296 * }
297 */
298 public function get_media_files() {
299 if ( ! $this->is_valid() ) {
300 return [];
301 }
302
303 $fullsize_path = $this->get_raw_fullsize_path();
304
305 if ( ! $fullsize_path ) {
306 return [];
307 }
308
309 $dimensions = $this->get_dimensions();
310 $all_sizes = [
311 'full' => [
312 'size' => 'full',
313 'path' => $fullsize_path,
314 'width' => $dimensions['width'],
315 'height' => $dimensions['height'],
316 'mime-type' => $this->get_mime_type(),
317 'disabled' => false,
318 ],
319 ];
320
321 if ( $this->is_image() ) {
322 $sizes = wp_get_attachment_metadata( $this->id, true );
323 $sizes = ! empty( $sizes['sizes'] ) && is_array( $sizes['sizes'] ) ? $sizes['sizes'] : [];
324 $sizes = array_intersect_key( $sizes, $this->get_context_instance()->get_thumbnail_sizes() );
325 } else {
326 $sizes = [];
327 }
328
329 if ( ! $sizes ) {
330 return $all_sizes;
331 }
332
333 $dir_path = $this->filesystem->dir_path( $fullsize_path );
334 $disallowed_sizes = get_imagify_option( 'disallowed-sizes' );
335 $is_active_for_network = imagify_is_active_for_network();
336
337 foreach ( $sizes as $size => $size_data ) {
338 $all_sizes[ $size ] = [
339 'size' => $size,
340 'path' => $dir_path . $size_data['file'],
341 'width' => $size_data['width'],
342 'height' => $size_data['height'],
343 'mime-type' => $size_data['mime-type'],
344 'disabled' => ! $is_active_for_network && isset( $disallowed_sizes[ $size ] ),
345 ];
346 }
347
348 return $this->filter_media_files( $all_sizes );
349 }
350
351 /**
352 * If the media is an image, get its width and height.
353 *
354 * @since 1.9
355 * @access public
356 * @author Grégory Viguier
357 *
358 * @return array
359 */
360 public function get_dimensions() {
361 if ( ! $this->is_image() ) {
362 return [
363 'width' => 0,
364 'height' => 0,
365 ];
366 }
367
368 $values = wp_get_attachment_image_src( $this->id, 'full' );
369
370 return [
371 'width' => $values[1],
372 'height' => $values[2],
373 ];
374 }
375
376 /**
377 * Update the media data dimensions.
378 *
379 * @since 1.9
380 * @access protected
381 * @author Grégory Viguier
382 *
383 * @param array $dimensions {
384 * An array containing width and height.
385 *
386 * @type int $width The image width.
387 * @type int $height The image height.
388 * }
389 */
390 protected function update_media_data_dimensions( $dimensions ) {
391 $metadata = wp_get_attachment_metadata( $this->id );
392
393 if ( ! is_array( $metadata ) ) {
394 $row = [];
395 }
396
397 if ( isset( $metadata['width'], $metadata['height'] ) && $metadata['width'] === $dimensions['width'] && $metadata['height'] === $dimensions['height'] ) {
398 return;
399 }
400
401 $metadata['width'] = $dimensions['width'];
402 $metadata['height'] = $dimensions['height'];
403
404 update_post_meta( $this->get_id(), '_wp_attachment_metadata', $metadata );
405 }
406
407
408 /** ----------------------------------------------------------------------------------------- */
409 /** INTERNAL TOOLS ========================================================================== */
410 /** ----------------------------------------------------------------------------------------- */
411
412 /**
413 * Tell if we’re playing in WP 5.3’s garden.
414 *
415 * @since 1.9.8
416 * @access protected
417 * @author Grégory Viguier
418 *
419 * @return bool
420 */
421 protected function is_wp_53() {
422 if ( isset( $this->is_wp53 ) ) {
423 return $this->is_wp53;
424 }
425
426 $this->is_wp53 = function_exists( 'wp_get_original_image_path' );
427
428 return $this->is_wp53;
429 }
430 }
431