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

Actions.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 2.2, at classes/Imagifybeat/Actions.php

378 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Imagify\Imagifybeat;
3
4 use Imagify_Requirements;
5 use Imagify\Traits\InstanceGetterTrait;
6 use Imagify\Bulk\Bulk;
7
8 /**
9 * Imagifybeat actions.
10 *
11 * @since 1.9.3
12 */
13 class Actions {
14 use InstanceGetterTrait;
15
16 /**
17 * The list of action IDs.
18 * Keys are related to method names, values are Imagifybeat IDs.
19 *
20 * @var array
21 *
22 * @since 1.9.3
23 */
24 private $imagifybeat_ids = [
25 'requirements' => 'imagify_requirements',
26 'bulk_optimization_stats' => 'imagify_bulk_optimization_stats',
27 'bulk_optimization_status' => 'imagify_bulk_optimization_status',
28 'options_optimization_status' => 'imagify_options_optimization_status',
29 'library_optimization_status' => 'imagify_library_optimization_status',
30 'custom_folders_optimization_status' => 'imagify_custom_folders_optimization_status',
31 ];
32
33 /**
34 * Class init: launch hooks.
35 *
36 * @since 1.9.3
37 */
38 public function init() {
39 foreach ( $this->imagifybeat_ids as $action => $imagifybeat_id ) {
40 add_filter( 'imagifybeat_received', [ $this, 'add_' . $action . '_to_response' ], 10, 2 );
41 }
42 }
43
44 /** ----------------------------------------------------------------------------------------- */
45 /** IMAGIFYBEAT CALLBACKS =================================================================== */
46 /** ----------------------------------------------------------------------------------------- */
47
48 /**
49 * Add requirements to Imagifybeat data.
50 *
51 * @since 1.9.3
52 *
53 * @param array $response The Imagifybeat response.
54 * @param array $data The $_POST data sent.
55 * @return array
56 */
57 public function add_requirements_to_response( $response, $data ) {
58 $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ );
59
60 if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) ) {
61 return $response;
62 }
63
64 $response[ $imagifybeat_id ] = [
65 'curl_missing' => ! Imagify_Requirements::supports_curl(),
66 'editor_missing' => ! Imagify_Requirements::supports_image_editor(),
67 'external_http_blocked' => Imagify_Requirements::is_imagify_blocked(),
68 'api_down' => ! Imagify_Requirements::is_api_up(),
69 'key_is_valid' => Imagify_Requirements::is_api_key_valid(),
70 'is_over_quota' => Imagify_Requirements::is_over_quota(),
71 ];
72
73 return $response;
74 }
75
76 /**
77 * Add bulk stats to Imagifybeat data.
78 *
79 * @since 1.9.3
80 *
81 * @param array $response The Imagifybeat response.
82 * @param array $data The $_POST data sent.
83 * @return array
84 */
85 public function add_bulk_optimization_stats_to_response( $response, $data ) {
86 $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ );
87
88 if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) ) {
89 return $response;
90 }
91
92 $folder_types = array_flip( array_filter( $data[ $imagifybeat_id ] ) );
93
94 $response[ $imagifybeat_id ] = imagify_get_bulk_stats(
95 $folder_types,
96 [
97 'fullset' => true,
98 ]
99 );
100
101 return $response;
102 }
103
104 /**
105 * Look for media where status has changed, compared to what Imagifybeat sends.
106 * This is used in the bulk optimization page.
107 *
108 * @since 1.9.3
109 *
110 * @param array $response The Imagifybeat response.
111 * @param array $data The $_POST data sent.
112 * @return array
113 */
114 public function add_bulk_optimization_status_to_response( $response, $data ) {
115 $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ );
116
117 if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) {
118 return $response;
119 }
120
121 if ( ! isset( $data[ $imagifybeat_id ] ) ) {
122 return $response;
123 }
124
125 $bulk = Bulk::get_instance();
126 $groups_data = [];
127 $types = [];
128 $total = 0;
129 $remaining = 0;
130 $percentage = 0;
131
132 foreach ( $data[ $imagifybeat_id ] as $group ) {
133 $types[ $group['groupID'] . '|' . $group['context'] ] = true;
134
135 $transient = get_transient( "imagify_{$group['context']}_optimize_running" );
136
137 if ( false !== $transient ) {
138 $total += $transient['total'];
139 $remaining += $transient['remaining'];
140 }
141
142 $groups_data[ $group['context'] ] = $bulk->get_bulk_instance( $group['context'] )->get_context_data();
143 }
144
145 if ( 0 !== $total ) {
146 $percentage = ( $total - $remaining ) / $total * 100;
147 }
148
149 $response[ $imagifybeat_id ] = [
150 'groups_data' => $groups_data,
151 'remaining' => $remaining,
152 'percentage' => round( $percentage ),
153 'result' => get_transient( 'imagify_bulk_optimization_result' ),
154 ];
155
156 return $response;
157 }
158
159 /**
160 * Look for media where status has changed, compared to what Imagifybeat sends.
161 * This is used in the settings page.
162 *
163 * @since 1.9
164 *
165 * @param array $response The Imagifybeat response.
166 * @param array $data The $_POST data sent.
167 * @return array
168 */
169 public function add_options_optimization_status_to_response( $response, $data ) {
170 $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ );
171
172 if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) {
173 return $response;
174 }
175
176 $remaining = 0;
177 $total = get_transient( 'imagify_missing_next_gen_total' );
178
179 if ( false === $total ) {
180 return $response;
181 }
182
183 $bulk = Bulk::get_instance();
184
185 $format = 'webp';
186
187 if ( get_imagify_option( 'convert_to_avif' ) ) {
188 $format = 'avif';
189 }
190
191 foreach ( $data[ $imagifybeat_id ] as $context ) {
192 $media = $bulk->get_bulk_instance( $context )->get_optimized_media_ids_without_format( $format );
193 $remaining += count( $media['ids'] );
194 }
195
196 $response[ $imagifybeat_id ] = [
197 'remaining' => $remaining,
198 'total' => (int) $total,
199 ];
200
201 return $response;
202 }
203
204 /**
205 * Look for media where status has changed, compared to what Imagifybeat sends.
206 * This is used in the WP Media Library.
207 *
208 * @since 1.9.3
209 *
210 * @param array $response The Imagifybeat response.
211 * @param array $data The $_POST data sent.
212 * @return array
213 */
214 public function add_library_optimization_status_to_response( $response, $data ) {
215 $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ );
216
217 if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) {
218 return $response;
219 }
220
221 $response[ $imagifybeat_id ] = $this->get_modified_optimization_statuses( $data[ $imagifybeat_id ] );
222
223 if ( ! $response[ $imagifybeat_id ] ) {
224 return $response;
225 }
226
227 // Sanitize received data and grab some other info.
228 foreach ( $response[ $imagifybeat_id ] as $context_id => $media_atts ) {
229 $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] );
230
231 $response[ $imagifybeat_id ][ $context_id ] = get_imagify_media_column_content( $process, false );
232 }
233
234 return $response;
235 }
236
237 /**
238 * Look for media where status has changed, compared to what Imagifybeat sends.
239 * This is used in the custom folders list (the "Other Media" page).
240 *
241 * @since 1.9.3
242 *
243 * @param array $response The Imagifybeat response.
244 * @param array $data The $_POST data sent.
245 * @return array
246 */
247 public function add_custom_folders_optimization_status_to_response( $response, $data ) {
248 $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ );
249
250 if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) {
251 return $response;
252 }
253
254 $response[ $imagifybeat_id ] = $this->get_modified_optimization_statuses( $data[ $imagifybeat_id ] );
255
256 if ( ! $response[ $imagifybeat_id ] ) {
257 return $response;
258 }
259
260 $admin_ajax_post = \Imagify_Admin_Ajax_Post::get_instance();
261 $list_table = new \Imagify_Files_List_Table( [
262 'screen' => 'imagify-files',
263 ] );
264
265 // Sanitize received data and grab some other info.
266 foreach ( $response[ $imagifybeat_id ] as $context_id => $media_atts ) {
267 $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] );
268
269 $response[ $imagifybeat_id ][ $context_id ] = $admin_ajax_post->get_media_columns( $process, $list_table );
270 }
271
272 return $response;
273 }
274
275
276 /** ----------------------------------------------------------------------------------------- */
277 /** TOOLS =================================================================================== */
278 /** ----------------------------------------------------------------------------------------- */
279
280 /**
281 * Look for media where status has changed, compared to what Imagifybeat sends.
282 *
283 * @since 1.9.3
284 *
285 * @param array $data The data received.
286 * @return array
287 */
288 private function get_modified_optimization_statuses( $data ) {
289 if ( ! $data ) {
290 return [];
291 }
292
293 $output = [];
294
295 // Sanitize received data and grab some other info.
296 foreach ( $data as $context => $media_statuses ) {
297 if ( ! $context || ! $media_statuses || ! is_array( $media_statuses ) ) {
298 continue;
299 }
300
301 // Sanitize the IDs: IDs come as strings, prefixed with an undescore character (to prevent JavaScript from screwing everything).
302 $media_ids = array_keys( $media_statuses );
303 $media_ids = array_map( function( $media_id ) {
304 return (int) substr( $media_id, 1 );
305 }, $media_ids );
306 $media_ids = array_filter( $media_ids );
307
308 if ( ! $media_ids ) {
309 continue;
310 }
311
312 // Sanitize the context.
313 $context_instance = imagify_get_context( $context );
314 $context = $context_instance->get_name();
315 $process_class_name = imagify_get_optimization_process_class_name( $context );
316 $transient_name = sprintf( $process_class_name::LOCK_NAME, $context, '%' );
317 $is_network_wide = $context_instance->is_network_wide();
318
319 \Imagify_DB::cache_process_locks( $context, $media_ids );
320
321 // Now that everything is cached for this context, we can get the transients without hitting the DB.
322 foreach ( $media_ids as $id ) {
323 $is_locked = (bool) $media_statuses[ '_' . $id ];
324 $option_name = str_replace( '%', $id, $transient_name );
325
326 if ( $is_network_wide ) {
327 $in_db = (bool) get_site_transient( $option_name );
328 } else {
329 $in_db = (bool) get_transient( $option_name );
330 }
331
332 if ( $is_locked === $in_db ) {
333 continue;
334 }
335
336 $output[ $context . '_' . $id ] = [
337 'media_id' => $id,
338 'context' => $context,
339 ];
340 }
341 }
342
343 return $output;
344 }
345
346 /**
347 * Get an Imagifybeat ID, given an action.
348 *
349 * @since 1.9.3
350 *
351 * @param string $action An action corresponding to the ID we want.
352 * @return string|bool The ID. False on failure.
353 */
354 public function get_imagifybeat_id( $action ) {
355 if ( ! empty( $this->imagifybeat_ids[ $action ] ) ) {
356 return $this->imagifybeat_ids[ $action ];
357 }
358
359 return false;
360 }
361
362 /**
363 * Get an Imagifybeat ID, given a callback name.
364 *
365 * @since 1.9.3
366 *
367 * @param string $callback A method’s name.
368 * @return string|bool The ID. False on failure.
369 */
370 private function get_imagifybeat_id_for_callback( $callback ) {
371 if ( preg_match( '@^add_(?<id>.+)_to_response$@', $callback, $matches ) ) {
372 return $this->get_imagifybeat_id( $matches['id'] );
373 }
374
375 return false;
376 }
377 }
378