PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.3.0
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.3.0
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.3.0, at classes/Media/WP.php

426 lines 11.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 WP_Error;
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 = false;
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 update_post_meta( $this->get_id(), '_wp_attachment_metadata', $metadata );
223
224 return true;
225 }
226
227 /**
228 * Don't change the full size file name.
229 * 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).
230 * This will force WP to keep the previous file name.
231 */
232 $old_full_size_file_name = $this->filesystem->file_name( $old_full_size_path );
233 $new_full_size_file_name = $this->filesystem->file_name( $metadata['file'] );
234
235 if ( $new_full_size_file_name !== $old_full_size_file_name ) {
236 $new_full_size_path = $this->filesystem->dir_path( $old_full_size_path ) . $new_full_size_file_name;
237
238 $moved = $this->filesystem->move( $new_full_size_path, $old_full_size_path, true );
239
240 if ( $moved ) {
241 $metadata['file'] = $this->filesystem->dir_path( $metadata['file'] ) . $old_full_size_file_name;
242 update_post_meta( $this->get_id(), '_wp_attached_file', $metadata['file'] );
243 }
244 }
245
246 update_post_meta( $this->get_id(), '_wp_attachment_metadata', $metadata );
247
248 return true;
249 }
250
251
252 /** ----------------------------------------------------------------------------------------- */
253 /** MEDIA DATA ============================================================================== */
254 /** ----------------------------------------------------------------------------------------- */
255
256 /**
257 * Tell if the current media has the required data (the data containing the file paths and thumbnails).
258 *
259 * @since 1.9
260 * @access public
261 * @author Grégory Viguier
262 *
263 * @return bool
264 */
265 public function has_required_media_data() {
266 if ( ! $this->is_valid() ) {
267 return false;
268 }
269
270 $file = get_post_meta( $this->id, '_wp_attached_file', true );
271
272 if ( ! $file || preg_match( '@://@', $file ) || preg_match( '@^.:\\\@', $file ) ) {
273 return false;
274 }
275
276 return (bool) wp_get_attachment_metadata( $this->id, true );
277 }
278
279 /**
280 * Get the list of the files of this media, including the full size file.
281 *
282 * @since 1.9
283 * @access public
284 * @author Grégory Viguier
285 *
286 * @return array {
287 * An array with the size names as keys ('full' is used for the full size file), and arrays of data as values:
288 *
289 * @type string $size The size name.
290 * @type string $path Absolute path to the file.
291 * @type int $width The file width.
292 * @type int $height The file height.
293 * @type string $mime-type The file mime type.
294 * @type bool $disabled True if the size is disabled in the plugin’s settings.
295 * }
296 */
297 public function get_media_files() {
298 if ( ! $this->is_valid() ) {
299 return [];
300 }
301
302 $fullsize_path = $this->get_raw_fullsize_path();
303
304 if ( ! $fullsize_path ) {
305 return [];
306 }
307
308 $dimensions = $this->get_dimensions();
309 $all_sizes = [
310 'full' => [
311 'size' => 'full',
312 'path' => $fullsize_path,
313 'width' => $dimensions['width'],
314 'height' => $dimensions['height'],
315 'mime-type' => $this->get_mime_type(),
316 'disabled' => false,
317 ],
318 ];
319
320 if ( $this->is_image() ) {
321 $sizes = wp_get_attachment_metadata( $this->id, true );
322 $sizes = ! empty( $sizes['sizes'] ) && is_array( $sizes['sizes'] ) ? $sizes['sizes'] : [];
323 $sizes = array_intersect_key( $sizes, $this->get_context_instance()->get_thumbnail_sizes() );
324 } else {
325 $sizes = [];
326 }
327
328 if ( ! $sizes ) {
329 return $all_sizes;
330 }
331
332 $dir_path = $this->filesystem->dir_path( $fullsize_path );
333 $disallowed_sizes = get_imagify_option( 'disallowed-sizes' );
334 $is_active_for_network = imagify_is_active_for_network();
335
336 foreach ( $sizes as $size => $size_data ) {
337 $all_sizes[ $size ] = [
338 'size' => $size,
339 'path' => $dir_path . $size_data['file'],
340 'width' => $size_data['width'],
341 'height' => $size_data['height'],
342 'mime-type' => $size_data['mime-type'],
343 'disabled' => ! $is_active_for_network && isset( $disallowed_sizes[ $size ] ),
344 ];
345 }
346
347 return $this->filter_media_files( $all_sizes );
348 }
349
350 /**
351 * If the media is an image, get its width and height.
352 *
353 * @since 1.9
354 * @access public
355 * @author Grégory Viguier
356 *
357 * @return array
358 */
359 public function get_dimensions() {
360 if ( ! $this->is_image() ) {
361 return [
362 'width' => 0,
363 'height' => 0,
364 ];
365 }
366
367 $values = wp_get_attachment_image_src( $this->id, 'full' );
368
369 return [
370 'width' => $values[1],
371 'height' => $values[2],
372 ];
373 }
374
375 /**
376 * Update the media data dimensions.
377 *
378 * @since 1.9
379 * @access protected
380 * @author Grégory Viguier
381 *
382 * @param array $dimensions {
383 * An array containing width and height.
384 *
385 * @type int $width The image width.
386 * @type int $height The image height.
387 * }
388 */
389 protected function update_media_data_dimensions( $dimensions ) {
390 $metadata = wp_get_attachment_metadata( $this->id );
391
392 if ( ! is_array( $metadata ) ) {
393 $row = [];
394 }
395
396 if ( isset( $metadata['width'], $metadata['height'] ) && $metadata['width'] === $dimensions['width'] && $metadata['height'] === $dimensions['height'] ) {
397 return;
398 }
399
400 $metadata['width'] = $dimensions['width'];
401 $metadata['height'] = $dimensions['height'];
402
403 update_post_meta( $this->get_id(), '_wp_attachment_metadata', $metadata );
404 }
405
406
407 /** ----------------------------------------------------------------------------------------- */
408 /** INTERNAL TOOLS ========================================================================== */
409 /** ----------------------------------------------------------------------------------------- */
410
411 /**
412 * Tell if we’re playing in WP 5.3’s garden.
413 *
414 * @since 1.9.8
415 * @access protected
416 * @author Grégory Viguier
417 *
418 * @return bool
419 */
420 protected function is_wp_53() {
421 $this->is_wp53 = function_exists( 'wp_get_original_image_path' );
422
423 return $this->is_wp53;
424 }
425 }
426