PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 1.7
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v1.7
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 / inc / functions / attachments.php

attachments.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 1.7, at inc/functions/attachments.php

408 lines 10.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
4 /**
5 * Get all mime types which could be optimized by Imagify.
6 *
7 * @since 1.7
8 *
9 * @return array The mime types.
10 */
11 function imagify_get_mime_types() {
12 return array(
13 'jpg|jpeg|jpe' => 'image/jpeg',
14 'png' => 'image/png',
15 'gif' => 'image/gif',
16 );
17 }
18
19 /**
20 * Tell if an attachment has a supported mime type.
21 * Was previously Imagify_AS3CF::is_mime_type_supported() since 1.6.6.
22 * Ironically, this function is used in Imagify::is_mime_type_supported() since 1.6.9.
23 *
24 * @since 1.6.8
25 * @author Grégory Viguier
26 *
27 * @param int $attachment_id The attachment ID.
28 * @return bool
29 */
30 function imagify_is_attachment_mime_type_supported( $attachment_id ) {
31 static $is = array( false );
32
33 $attachment_id = absint( $attachment_id );
34
35 if ( isset( $is[ $attachment_id ] ) ) {
36 return $is[ $attachment_id ];
37 }
38
39 $mime_types = imagify_get_mime_types();
40 $mime_types = array_flip( $mime_types );
41 $mime_type = (string) get_post_mime_type( $attachment_id );
42
43 $is[ $attachment_id ] = isset( $mime_types[ $mime_type ] );
44
45 return $is[ $attachment_id ];
46 }
47
48 /**
49 * Get post statuses related to attachments.
50 *
51 * @since 1.7
52 * @author Grégory Viguier
53 *
54 * @return array
55 */
56 function imagify_get_post_statuses() {
57 static $statuses;
58
59 if ( isset( $statuses ) ) {
60 return $statuses;
61 }
62
63 $statuses = array(
64 'inherit' => 'inherit',
65 'private' => 'private',
66 );
67
68 $custom_statuses = get_post_stati( array( 'public' => true ) );
69 unset( $custom_statuses['publish'] );
70
71 if ( $custom_statuses ) {
72 $statuses = array_merge( $statuses, $custom_statuses );
73 }
74
75 /**
76 * Filter the post statuses Imagify is allowed to optimize.
77 *
78 * @since 1.7
79 * @author Grégory Viguier
80 *
81 * @param array $statuses An array of post statuses. Kays and values are set.
82 */
83 $statuses = apply_filters( 'imagify_post_statuses', $statuses );
84
85 return $statuses;
86 }
87
88 /**
89 * Tell if the attachment has the required WP metadata.
90 *
91 * @since 1.6.12
92 * @since 1.7 Also checks that the '_wp_attached_file' meta is valid (not a URL or anything funny).
93 * @author Grégory Viguier
94 *
95 * @param int $attachment_id The attachment ID.
96 * @return bool
97 */
98 function imagify_attachment_has_required_metadata( $attachment_id ) {
99 $file = get_post_meta( $attachment_id, '_wp_attached_file', true );
100
101 if ( ! $file || preg_match( '@://@', $file ) || preg_match( '@^.:\\\@', $file ) ) {
102 return false;
103 }
104
105 return (bool) wp_get_attachment_metadata( $attachment_id, true );
106 }
107
108 /**
109 * Tell if the site has attachments (only the ones Imagify would optimize) without the required WP metadata.
110 *
111 * @since 1.7
112 * @author Grégory Viguier
113 *
114 * @return bool
115 */
116 function imagify_has_attachments_without_required_metadata() {
117 global $wpdb;
118 static $has;
119
120 if ( isset( $has ) ) {
121 return $has;
122 }
123
124 $mime_types = Imagify_DB::get_mime_types();
125 $statuses = Imagify_DB::get_post_statuses();
126 $nodata_join = Imagify_DB::get_required_wp_metadata_join_clause( 'p.ID', false, false );
127 $nodata_where = Imagify_DB::get_required_wp_metadata_where_clause( array(), false, false );
128 $has = (bool) $wpdb->get_var( // WPCS: unprepared SQL ok.
129 "
130 SELECT p.ID
131 FROM $wpdb->posts AS p
132 $nodata_join
133 WHERE p.post_mime_type IN ( $mime_types )
134 AND p.post_type = 'attachment'
135 AND p.post_status IN ( $statuses )
136 $nodata_where
137 LIMIT 1"
138 );
139
140 return $has;
141 }
142
143 /**
144 * Get the path to the backups directory.
145 *
146 * @since 1.6.8
147 * @author Grégory Viguier
148 *
149 * @param bool $bypass_error True to return the path even if there is an error. This is used when we want to display this path in a message for example.
150 * @return string|bool Path to the backups directory. False on failure.
151 */
152 function get_imagify_backup_dir_path( $bypass_error = false ) {
153 static $backup_dir;
154
155 if ( isset( $backup_dir ) ) {
156 return $backup_dir;
157 }
158
159 $upload_basedir = get_imagify_upload_basedir( $bypass_error );
160
161 if ( ! $upload_basedir ) {
162 return false;
163 }
164
165 $backup_dir = $upload_basedir . 'backup/';
166
167 /**
168 * Filter the backup directory path.
169 *
170 * @since 1.0
171 *
172 * @param string $backup_dir The backup directory path.
173 */
174 $backup_dir = apply_filters( 'imagify_backup_directory', $backup_dir );
175 $backup_dir = trailingslashit( wp_normalize_path( $backup_dir ) );
176
177 return $backup_dir;
178 }
179
180 /**
181 * Tell if the folder containing the backups is writable.
182 *
183 * @since 1.6.8
184 * @author Grégory Viguier
185 *
186 * @return bool
187 */
188 function imagify_backup_dir_is_writable() {
189 if ( ! get_imagify_backup_dir_path() ) {
190 return false;
191 }
192
193 $filesystem = imagify_get_filesystem();
194 $has_backup_dir = wp_mkdir_p( get_imagify_backup_dir_path() );
195
196 return $has_backup_dir && $filesystem->is_writable( get_imagify_backup_dir_path() );
197 }
198
199 /**
200 * Get the backup path of a specific attachement.
201 *
202 * @since 1.0
203 *
204 * @param string $file_path The file path.
205 * @return string|bool The backup path. False on failure.
206 */
207 function get_imagify_attachment_backup_path( $file_path ) {
208 $file_path = wp_normalize_path( (string) $file_path );
209 $upload_basedir = get_imagify_upload_basedir();
210 $backup_dir = get_imagify_backup_dir_path();
211
212 if ( ! $file_path || ! $upload_basedir ) {
213 return false;
214 }
215
216 return str_replace( $upload_basedir, $backup_dir, $file_path );
217 }
218
219 /**
220 * Retrieve file path for an attachment based on filename.
221 *
222 * @since 1.4.5
223 *
224 * @param int $file_path The file path.
225 * @return string|false The file path to where the attached file should be, false otherwise.
226 */
227 function get_imagify_attached_file( $file_path ) {
228 $file_path = wp_normalize_path( (string) $file_path );
229 $upload_basedir = get_imagify_upload_basedir();
230
231 if ( ! $file_path || ! $upload_basedir ) {
232 return false;
233 }
234
235 // The file path is absolute.
236 if ( strpos( $file_path, '/' ) === 0 || preg_match( '|^.:\\\|', $file_path ) ) {
237 return false;
238 }
239
240 // Prepend upload dir.
241 return $upload_basedir . $file_path;
242 }
243
244 /**
245 * Retrieve the URL for an attachment based on file path.
246 *
247 * @since 1.4.5
248 *
249 * @param string $file_path A relative or absolute file path.
250 * @return string|bool File URL, otherwise false.
251 */
252 function get_imagify_attachment_url( $file_path ) {
253 $file_path = wp_normalize_path( (string) $file_path );
254 $upload_basedir = get_imagify_upload_basedir();
255
256 if ( ! $file_path || ! $upload_basedir ) {
257 return false;
258 }
259
260 $upload_baseurl = get_imagify_upload_baseurl();
261
262 // Check that the upload base exists in the (absolute) file location.
263 if ( 0 === strpos( $file_path, $upload_basedir ) ) {
264 // Replace file location with url location.
265 return str_replace( $upload_basedir, $upload_baseurl, $file_path );
266 }
267
268 if ( false !== strpos( '/' . $file_path, '/wp-content/uploads/' ) ) {
269 // Get the directory name relative to the basedir (back compat for pre-2.7 uploads).
270 return trailingslashit( $upload_baseurl . _wp_get_attachment_relative_path( $file_path ) ) . basename( $file_path );
271 }
272
273 // It's a newly-uploaded file, therefore $file is relative to the basedir.
274 return $upload_baseurl . $file_path;
275 }
276
277 /**
278 * Get size information for all currently registered thumbnail sizes.
279 *
280 * @since 1.5.10
281 * @since 1.6.10 For consistency, revamped the function like WP does with wp_generate_attachment_metadata().
282 * Removed the filter, added crop value to each size.
283 * @author Grégory Viguier
284 *
285 * @return array Data for all currently registered thumbnail sizes (width, height, crop, name).
286 */
287 function get_imagify_thumbnail_sizes() {
288 // All image size names.
289 $intermediate_image_sizes = get_intermediate_image_sizes();
290 $intermediate_image_sizes = array_flip( $intermediate_image_sizes );
291 // Additional image size attributes.
292 $additional_image_sizes = wp_get_additional_image_sizes();
293
294 // Create the full array with sizes and crop info.
295 foreach ( $intermediate_image_sizes as $size_name => $s ) {
296 $intermediate_image_sizes[ $size_name ] = array(
297 'width' => '',
298 'height' => '',
299 'crop' => false,
300 'name' => $size_name,
301 );
302
303 if ( isset( $additional_image_sizes[ $size_name ]['width'] ) ) {
304 // For theme-added sizes.
305 $intermediate_image_sizes[ $size_name ]['width'] = (int) $additional_image_sizes[ $size_name ]['width'];
306 } else {
307 // For default sizes set in options.
308 $intermediate_image_sizes[ $size_name ]['width'] = (int) get_option( "{$size_name}_size_w" );
309 }
310
311 if ( isset( $additional_image_sizes[ $size_name ]['height'] ) ) {
312 // For theme-added sizes.
313 $intermediate_image_sizes[ $size_name ]['height'] = (int) $additional_image_sizes[ $size_name ]['height'];
314 } else {
315 // For default sizes set in options.
316 $intermediate_image_sizes[ $size_name ]['height'] = (int) get_option( "{$size_name}_size_h" );
317 }
318
319 if ( isset( $additional_image_sizes[ $size_name ]['crop'] ) ) {
320 // For theme-added sizes.
321 $intermediate_image_sizes[ $size_name ]['crop'] = (int) $additional_image_sizes[ $size_name ]['crop'];
322 } else {
323 // For default sizes set in options.
324 $intermediate_image_sizes[ $size_name ]['crop'] = (int) get_option( "{$size_name}_crop" );
325 }
326 }
327
328 return $intermediate_image_sizes;
329 }
330
331 /**
332 * A simple helper to get the upload basedir.
333 *
334 * @since 1.6.7
335 * @since 1.6.8 Added the $bypass_error parameter.
336 * @author Grégory Viguier
337 *
338 * @param bool $bypass_error True to return the path even if there is an error. This is used when we want to display this path in a message for example.
339 * @return string|bool The path. False on failure.
340 */
341 function get_imagify_upload_basedir( $bypass_error = false ) {
342 static $upload_basedir;
343 static $upload_basedir_or_error;
344
345 if ( isset( $upload_basedir ) ) {
346 return $bypass_error ? $upload_basedir : $upload_basedir_or_error;
347 }
348
349 $uploads = wp_upload_dir();
350 $upload_basedir = trailingslashit( wp_normalize_path( $uploads['basedir'] ) );
351
352 if ( false !== $uploads['error'] ) {
353 $upload_basedir_or_error = false;
354 } else {
355 $upload_basedir_or_error = $upload_basedir;
356 }
357
358 return $bypass_error ? $upload_basedir : $upload_basedir_or_error;
359 }
360
361 /**
362 * A simple helper to get the upload baseurl.
363 *
364 * @since 1.6.7
365 * @author Grégory Viguier
366 *
367 * @return string|bool The path. False on failure.
368 */
369 function get_imagify_upload_baseurl() {
370 static $upload_baseurl;
371
372 if ( isset( $upload_baseurl ) ) {
373 return $upload_baseurl;
374 }
375
376 $uploads = wp_upload_dir();
377
378 if ( false !== $uploads['error'] ) {
379 $upload_baseurl = false;
380 return $upload_baseurl;
381 }
382
383 $upload_baseurl = trailingslashit( $uploads['baseurl'] );
384
385 return $upload_baseurl;
386 }
387
388 /**
389 * Get the maximal number of unoptimized attachments to fetch.
390 *
391 * @since 1.6.14
392 * @author Grégory Viguier
393 *
394 * @return int
395 */
396 function imagify_get_unoptimized_attachment_limit() {
397 /**
398 * Filter the unoptimized attachments limit query.
399 *
400 * @since 1.4.4
401 *
402 * @param int $limit The limit (-1 for unlimited).
403 */
404 $limit = (int) apply_filters( 'imagify_unoptimized_attachment_limit', 10000 );
405
406 return -1 === $limit ? PHP_INT_MAX : abs( $limit );
407 }
408