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

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