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 / Imagifybeat / Actions.php

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

383 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 final 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 = get_imagify_option( 'optimization_format' );
186
187 if ( 'off' === $format ) {
188 return $response;
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 [
263 'screen' => 'imagify-files',
264 ]
265 );
266
267 // Sanitize received data and grab some other info.
268 foreach ( $response[ $imagifybeat_id ] as $context_id => $media_atts ) {
269 $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] );
270
271 $response[ $imagifybeat_id ][ $context_id ] = $admin_ajax_post->get_media_columns( $process, $list_table );
272 }
273
274 return $response;
275 }
276
277
278 /** ----------------------------------------------------------------------------------------- */
279 /** TOOLS =================================================================================== */
280 /** ----------------------------------------------------------------------------------------- */
281
282 /**
283 * Look for media where status has changed, compared to what Imagifybeat sends.
284 *
285 * @since 1.9.3
286 *
287 * @param array $data The data received.
288 * @return array
289 */
290 private function get_modified_optimization_statuses( $data ) {
291 if ( ! $data ) {
292 return [];
293 }
294
295 $output = [];
296
297 // Sanitize received data and grab some other info.
298 foreach ( $data as $context => $media_statuses ) {
299 if ( ! $context || ! $media_statuses || ! is_array( $media_statuses ) ) {
300 continue;
301 }
302
303 // Sanitize the IDs: IDs come as strings, prefixed with an undescore character (to prevent JavaScript from screwing everything).
304 $media_ids = array_keys( $media_statuses );
305 $media_ids = array_map(
306 function ( $media_id ) {
307 return substr( $media_id, 1 );
308 },
309 $media_ids
310 );
311 $media_ids = array_filter( $media_ids );
312
313 if ( ! $media_ids ) {
314 continue;
315 }
316
317 // Sanitize the context.
318 $context_instance = imagify_get_context( $context );
319 $context = $context_instance->get_name();
320 $process_class_name = imagify_get_optimization_process_class_name( $context );
321 $transient_name = sprintf( $process_class_name::LOCK_NAME, $context, '%' );
322 $is_network_wide = $context_instance->is_network_wide();
323
324 \Imagify_DB::cache_process_locks( $context, $media_ids );
325
326 // Now that everything is cached for this context, we can get the transients without hitting the DB.
327 foreach ( $media_ids as $id ) {
328 $is_locked = (bool) $media_statuses[ '_' . $id ];
329 $option_name = str_replace( '%', $id, $transient_name );
330
331 if ( $is_network_wide ) {
332 $in_db = (bool) get_site_transient( $option_name );
333 } else {
334 $in_db = (bool) get_transient( $option_name );
335 }
336
337 if ( $is_locked === $in_db ) {
338 continue;
339 }
340
341 $output[ $context . '_' . $id ] = [
342 'media_id' => $id,
343 'context' => $context,
344 ];
345 }
346 }
347
348 return $output;
349 }
350
351 /**
352 * Get an Imagifybeat ID, given an action.
353 *
354 * @since 1.9.3
355 *
356 * @param string $action An action corresponding to the ID we want.
357 * @return string|bool The ID. False on failure.
358 */
359 public function get_imagifybeat_id( $action ) {
360 if ( ! empty( $this->imagifybeat_ids[ $action ] ) ) {
361 return $this->imagifybeat_ids[ $action ];
362 }
363
364 return false;
365 }
366
367 /**
368 * Get an Imagifybeat ID, given a callback name.
369 *
370 * @since 1.9.3
371 *
372 * @param string $callback A method’s name.
373 * @return string|bool The ID. False on failure.
374 */
375 private function get_imagifybeat_id_for_callback( $callback ) {
376 if ( preg_match( '@^add_(?<id>.+)_to_response$@', $callback, $matches ) ) {
377 return $this->get_imagifybeat_id( $matches['id'] );
378 }
379
380 return false;
381 }
382 }
383