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 / process.php

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

274 lines 8.7 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 * Process an image with Imagify.
6 *
7 * @since 1.0
8 *
9 * @param string $file_path Absolute path to the image file.
10 * @param array $args An array that can contain:
11 * bool $backup Force a backup of the original file.
12 * int $optimization_level The optimization level (2=ultra, 1=aggressive, 0=normal).
13 * bool $keep_exif To keep exif data or not.
14 * @return obj|array Error message | Optimized image data.
15 */
16 function do_imagify( $file_path, $args = array() ) {
17 $errors = new WP_Error();
18 $args = array_merge( array(
19 'backup' => get_imagify_option( 'backup' ),
20 'optimization_level' => get_imagify_option( 'optimization_level' ),
21 'keep_exif' => get_imagify_option( 'exif' ),
22 'context' => 'wp',
23 'resized' => false,
24 'original_size' => 0,
25 'backup_path' => null,
26 ), $args );
27
28 /**
29 * Filter the attachment path.
30 *
31 * @since 1.2
32 *
33 * @param string $file_path The attachment path.
34 */
35 $file_path = apply_filters( 'imagify_file_path', $file_path );
36
37 // Check if the Imagify servers & the API are accessible.
38 if ( ! is_imagify_servers_up() ) {
39 $errors->add( 'api_server_down', __( 'Sorry, our servers are temporarily unaccessible. Please, try again in a couple of minutes.', 'imagify' ) );
40 return $errors;
41 }
42
43 // Check if external HTTP requests are blocked.
44 if ( is_imagify_blocked() ) {
45 $errors->add( 'http_block_external', __( 'External HTTP requests are blocked', 'imagify' ) );
46 return $errors;
47 }
48
49 // Check that file path isn't empty.
50 if ( empty( $file_path ) ) {
51 $errors->add( 'empty_path', __( 'File path is empty', 'imagify' ) );
52 return $errors;
53 }
54
55 $filesystem = imagify_get_filesystem();
56
57 // Check that the file exists.
58 if ( ! $filesystem->exists( $file_path ) || ! $filesystem->is_file( $file_path ) ) {
59 /* translators: %s is a file path. */
60 $errors->add( 'file_not_found', sprintf( __( 'Could not find %s', 'imagify' ), $file_path ) );
61 return $errors;
62 }
63
64 // Check that the file is writable.
65 if ( ! wp_is_writable( dirname( $file_path ) ) ) {
66 /* translators: %s is a file path. */
67 $errors->add( 'not_writable', sprintf( __( '%s is not writable', 'imagify' ), dirname( $file_path ) ) );
68 return $errors;
69 }
70
71 // Get file size.
72 $file_size = $filesystem->size( $file_path );
73
74 // Check that file exists.
75 if ( 0 === $file_size ) {
76 /* translators: %s is a file path. */
77 $errors->add( 'image_not_found', sprintf( __( 'Skipped (%s), image not found.', 'imagify' ), '<code>' . imagify_make_file_path_relative( $file_path ) . '</code>' ) );
78 return $errors;
79 }
80
81 /**
82 * Fires before to optimize the Image with Imagify.
83 *
84 * @since 1.0
85 *
86 * @param string $file_path Absolute path to the image file.
87 * @param bool $backup Force a backup of the original file.
88 */
89 do_action( 'before_do_imagify', $file_path, $args['backup'] );
90
91 // Send image for optimization and fetch the response.
92 $response = upload_imagify_image( array(
93 'image' => $file_path,
94 'data' => wp_json_encode( array(
95 'aggressive' => ( 1 === (int) $args['optimization_level'] ),
96 'ultra' => ( 2 === (int) $args['optimization_level'] ),
97 'keep_exif' => $args['keep_exif'],
98 'context' => $args['context'],
99 'original_size' => $args['original_size'],
100 ) ),
101 ) );
102
103 // Check status code.
104 if ( is_wp_error( $response ) ) {
105 $errors->add( 'api_error', $response->get_error_message() );
106 return $errors;
107 }
108
109 // Create a backup file.
110 if ( $args['backup'] && ! $args['resized'] ) {
111 // TODO (@Greg): Send an error message if the backup fails.
112 imagify_backup_file( $file_path, $args['backup_path'] );
113 }
114
115 if ( ! function_exists( 'download_url' ) ) {
116 require_once ABSPATH . 'wp-admin/includes/file.php';
117 }
118
119 $temp_file = download_url( $response->image );
120
121 if ( is_wp_error( $temp_file ) ) {
122 $errors->add( 'temp_file_not_found', $temp_file->get_error_message() );
123 return $errors;
124 }
125
126 $filesystem->move( $temp_file, $file_path, true );
127 imagify_chmod_file( $file_path );
128
129 // If temp file still exists, delete it.
130 if ( $filesystem->exists( $temp_file ) ) {
131 $filesystem->delete( $temp_file );
132 }
133
134 /**
135 * Fires after to optimize the Image with Imagify.
136 *
137 * @since 1.0
138 *
139 * @param string $file_path Absolute path to the image file.
140 * @param bool $backup Force a backup of the original file.
141 */
142 do_action( 'after_do_imagify', $file_path, $args['backup'] );
143
144 return $response;
145 }
146
147 /**
148 * Run an async job to optimize images in background.
149 *
150 * @param array $body Contains the usual $_POST.
151 *
152 * @since 1.4
153 */
154 function imagify_do_async_job( $body ) {
155 $args = array(
156 'timeout' => 0.01,
157 'blocking' => false,
158 'body' => $body,
159 'cookies' => isset( $_COOKIE ) && is_array( $_COOKIE ) ? $_COOKIE : array(),
160 'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
161 );
162
163 /**
164 * Filter the arguments used to launch an async job.
165 *
166 * @since 1.6.6
167 * @author Grégory Viguier
168 *
169 * @param array $args An array of arguments passed to wp_remote_post().
170 */
171 $args = apply_filters( 'imagify_do_async_job_args', $args );
172
173 /**
174 * It can be a XML-RPC request. The problem is that XML-RPC doesn't use cookies.
175 */
176 if ( defined( 'XMLRPC_REQUEST' ) && get_current_user_id() ) {
177 /**
178 * In old WP versions, the field "option_name" in the wp_options table was limited to 64 characters.
179 * From 64, remove 19 characters for "_transient_timeout_" = 45.
180 * Then remove 12 characters for "imagify_rpc_" (transient name) = 33.
181 * Hopefully, a md5 is 32 characters long.
182 */
183 $rpc_id = md5( maybe_serialize( $body ) );
184
185 // Send the request to our RPC bridge instead.
186 $args['body']['imagify_rpc_action'] = $args['body']['action'];
187 $args['body']['action'] = 'imagify_rpc';
188 $args['body']['imagify_rpc_id'] = $rpc_id;
189 $args['body']['imagify_rpc_nonce'] = wp_create_nonce( 'imagify_rpc_' . $rpc_id );
190
191 // Since we can't send cookies to keep the user logged in, store the user ID in a transient.
192 set_transient( 'imagify_rpc_' . $rpc_id, get_current_user_id(), 30 );
193 }
194
195 wp_remote_post( admin_url( 'admin-ajax.php' ), $args );
196 }
197
198 /**
199 * Backup a file.
200 *
201 * @since 1.6.8
202 * @author Grégory Viguier
203 *
204 * @param string $file_path The file path.
205 * @param string $backup_path The backup path. This is useful for NGG for example, who doesn't store the backups in our backup folder.
206 * @return bool|object True on success. False if the backup option is not enabled. A WP_Error object on failure.
207 */
208 function imagify_backup_file( $file_path, $backup_path = null ) {
209 if ( ! get_imagify_option( 'backup' ) ) {
210 return false;
211 }
212
213 // Make sure the source path is not empty.
214 if ( ! $file_path ) {
215 return new WP_Error( 'empty_path', __( 'The file path is empty.', 'imagify' ) );
216 }
217
218 $filesystem = imagify_get_filesystem();
219
220 // Make sure the filesystem has no errors.
221 if ( ! empty( $filesystem->errors->errors ) ) {
222 return new WP_Error( 'filesystem_error', __( 'Filesystem error.', 'imagify' ), $filesystem->errors );
223 }
224
225 // Make sure the source file exists.
226 if ( ! $filesystem->exists( $file_path ) ) {
227 return new WP_Error( 'source_doesnt_exist', __( 'The file to backup does not exist.', 'imagify' ), array(
228 'file_path' => imagify_make_file_path_relative( $file_path ),
229 ) );
230 }
231
232 if ( ! isset( $backup_path ) ) {
233 // Make sure the backup directory is writable.
234 if ( ! imagify_backup_dir_is_writable() ) {
235 return new WP_Error( 'backup_dir_not_writable', __( 'The backup directory is not writable.', 'imagify' ) );
236 }
237
238 $backup_path = get_imagify_attachment_backup_path( $file_path );
239 }
240
241 // Make sure the uploads directory has no errors.
242 if ( ! $backup_path ) {
243 return new WP_Error( 'wp_upload_error', __( 'Error while retrieving the uploads directory path.', 'imagify' ) );
244 }
245
246 // Create sub-directories.
247 wp_mkdir_p( dirname( $backup_path ) );
248
249 /**
250 * Allow to overwrite the backup file if it already exists.
251 *
252 * @since 1.6.9
253 * @author Grégory Viguier
254 *
255 * @param bool $overwrite Whether to overwrite the backup file.
256 * @param string $file_path The file path.
257 * @param string $backup_path The backup path.
258 */
259 $overwrite = apply_filters( 'imagify_backup_overwrite_backup', false, $file_path, $backup_path );
260
261 // Copy the file.
262 $filesystem->copy( $file_path, $backup_path, $overwrite, FS_CHMOD_FILE );
263
264 // Make sure the backup copy exists.
265 if ( ! $filesystem->exists( $backup_path ) ) {
266 return new WP_Error( 'backup_doesnt_exist', __( 'The file could not be saved.', 'imagify' ), array(
267 'file_path' => imagify_make_file_path_relative( $file_path ),
268 'backup_path' => imagify_make_file_path_relative( $backup_path ),
269 ) );
270 }
271
272 return true;
273 }
274