PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.2.9
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.2.9
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 / admin-ui.php

admin-ui.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 2.2.9, at inc/functions/admin-ui.php

588 lines 17.1 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 the optimization data list for a specific media.
6 *
7 * @since 1.0
8 * @since 1.9 Function signature changed.
9 * @author Jonathan Buttigieg
10 *
11 * @param ProcessInterface $process The optimization process object.
12 * @return string The output to print.
13 */
14 function get_imagify_attachment_optimization_text( $process ) {
15 if ( ! $process->is_valid() ) {
16 return '';
17 }
18
19 $is_media_page = Imagify_Views::get_instance()->is_media_page();
20 $is_library_page = Imagify_Views::get_instance()->is_wp_library_page();
21 $output = $is_media_page ? '' : '<ul class="imagify-datas-list" id="imagify_data_sum">';
22 $output_before = $is_media_page ? '' : '<li class="imagify-data-item">';
23 $output_after = $is_media_page ? '<br/>' : '</li>';
24 $reoptimize_link = get_imagify_attachment_reoptimize_link( $process );
25 $reoptimize_link .= get_imagify_attachment_optimize_missing_thumbnails_link( $process );
26 $reoptimize_link .= get_imagify_attachment_generate_nextgen_versions_link( $process );
27 $reoptimize_link .= get_imagify_attachment_delete_nextgen_versions_link( $process );
28 $reoptimize_output = $reoptimize_link ? $reoptimize_link : '';
29 $reoptimize_output_before = '<div class="imagify-datas-actions-links">';
30 $reoptimize_output_after = '</div><!-- .imagify-datas-actions-links -->';
31 $error = get_imagify_attachment_error_text( $process );
32 $media = $process->get_media();
33
34 if ( $error ) {
35 if ( ! $is_media_page && $reoptimize_link && $media->has_backup() ) {
36 $reoptimize_output .= '<span class="attachment-has-backup hidden"></span>';
37 }
38
39 $reoptimize_output = $reoptimize_output_before . $reoptimize_output . $reoptimize_output_after;
40
41 return $is_media_page ? $output_before . $error . $reoptimize_output . $output_after : $error . $reoptimize_output;
42 }
43
44 $data = $process->get_data();
45 $optimized_data = $data->get_optimization_data();
46 $attachment_id = $media->get_id();
47 $optimization_level = imagify_get_optimization_level_label( $data->get_optimization_level() );
48
49 if ( ! $is_media_page ) {
50 $output .= $output_before . '<span class="data">' . __( 'New Filesize:', 'imagify' ) . '</span> <strong class="big">' . $data->get_optimized_size() . '</strong>' . $output_after;
51 }
52
53 if ( key_exists( 'message', $optimized_data ) && $optimized_data['message'] ) {
54 $output .= $output_before . '<span class="data">' . __( 'Convert:', 'imagify' ) . '</span> <strong class="big">' . $optimized_data['message'] . '</strong>' . $output_after;
55 }
56
57 $chart = '';
58
59 if ( ! $is_media_page ) {
60 if ( ! $is_library_page ) {
61 // No need to print this on the library page, the event whould be triggered before the handler is attached (the JS file is loaded in the footer).
62 $chart = '<script type="text/javascript">jQuery( window ).trigger( "canvasprinted.imagify", [ ".imagify-consumption-chart-' . $attachment_id . '" ] ); </script>';
63 }
64
65 $chart = '<span class="imagify-chart">
66 <span class="imagify-chart-container">
67 <canvas class="imagify-consumption-chart imagify-consumption-chart-' . $attachment_id . '" width="15" height="15"></canvas>
68 ' . $chart . '
69 </span>
70 </span>';
71 }
72
73 $output .= $output_before;
74 $output .= '<span class="data">' . __( 'Original Saving:', 'imagify' ) . '</span> ';
75 $output .= '<strong>' . $chart . '<span class="imagify-chart-value">' . $data->get_saving_percent() . '</span>%</strong>';
76 $output .= $output_after;
77
78 // More details section.
79 if ( ! $is_media_page ) {
80 // New list.
81 $output .= '</ul>';
82 $output .= '<p class="imagify-datas-more-action">';
83 $output .= '<a href="#imagify-view-details-' . $attachment_id . '" data-close="' . __( 'Close details', 'imagify' ) . '" data-open="' . __( 'View details', 'imagify' ) . '">';
84 $output .= '<span class="the-text">' . __( 'View details', 'imagify' ) . '</span>';
85 $output .= '<span class="dashicons dashicons-arrow-down-alt2"></span>';
86 $output .= '</a>';
87 $output .= '</p>';
88 $output .= '<ul id="imagify-view-details-' . $attachment_id . '" class="imagify-datas-list imagify-datas-details">';
89
90 // Not in metabox.
91 $output .= $output_before . '<span class="data">' . __( 'Original Filesize:', 'imagify' ) . '</span> <strong class="original">' . $data->get_original_size() . '</strong>' . $output_after;
92 }
93
94 $output .= $output_before . '<span class="data">' . __( 'Level:', 'imagify' ) . '</span> <strong>' . $optimization_level . '</strong>' . $output_after;
95
96 if ( $media->is_image() ) {
97 $has_nextgen = $process->has_next_gen() ? __( 'Yes', 'imagify' ) : __( 'No', 'imagify' );
98
99 if ( $process->has_next_gen() ) {
100 $has_nextgen = $process->is_full_next_gen() ? __( 'Yes', 'imagify' ) : __( 'Partially', 'imagify' );
101 }
102 $output .= $output_before . '<span class="data">' . __( 'Next-Gen generated:', 'imagify' ) . '</span> <strong class="big">' . esc_html( $has_nextgen ) . '</strong>' . $output_after;
103
104 $total_optimized_thumbnails = $data->get_optimized_sizes_count();
105
106 if ( $total_optimized_thumbnails ) {
107 $output .= $output_before . '<span class="data">' . __( 'Thumbnails Optimized:', 'imagify' ) . '</span> <strong>' . $total_optimized_thumbnails . '</strong>' . $output_after;
108 $output .= $output_before . '<span class="data">' . __( 'Overall Saving:', 'imagify' ) . '</span> <strong>' . $data->get_overall_saving_percent() . '%</strong>' . $output_after;
109 }
110 }
111
112 // End of list.
113 $output .= $is_media_page ? '' : '</ul>';
114
115 // Actions section.
116 $output .= $is_media_page ? $output_before : '';
117 $output .= $reoptimize_output_before;
118 $output .= $reoptimize_output;
119
120 if ( $media->has_backup() ) {
121 $url = get_imagify_admin_url(
122 'restore',
123 [
124 'attachment_id' => $attachment_id,
125 'context' => $media->get_context(),
126 ]
127 );
128
129 $output .= Imagify_Views::get_instance()->get_template(
130 'button/restore',
131 [
132 'url' => $url,
133 'atts' => [
134 'class' => $is_media_page ? '' : null,
135 ],
136 ]
137 );
138
139 if ( ! $is_library_page ) {
140 $output .= '<input id="imagify-original-src" type="hidden" value="' . esc_url( $media->get_backup_url() ) . '">';
141 $output .= '<input id="imagify-original-size" type="hidden" value="' . $data->get_original_size() . '">';
142 $output .= '<input id="imagify-full-src" type="hidden" value="' . esc_url( $media->get_fullsize_url() ) . '">';
143
144 if ( $media->is_image() ) {
145 $dimensions = $media->get_dimensions();
146
147 $output .= '<input id="imagify-full-width" type="hidden" value="' . $dimensions['width'] . '">';
148 $output .= '<input id="imagify-full-height" type="hidden" value="' . $dimensions['height'] . '">';
149 }
150 }
151 }
152
153 $output .= $reoptimize_output_after;
154
155 return $output;
156 }
157
158 /**
159 * Get the error message for a specific attachment.
160 *
161 * @since 1.0
162 * @since 1.9 Function signature changed.
163 * @author Jonathan Buttigieg
164 *
165 * @param ProcessInterface $process The optimization process object.
166 * @return string The output to print.
167 */
168 function get_imagify_attachment_error_text( $process ) {
169 if ( ! $process->is_valid() ) {
170 return '';
171 }
172
173 $data = $process->get_data()->get_optimization_data();
174
175 if ( ! isset( $data['sizes']['full']['success'] ) || $data['sizes']['full']['success'] ) {
176 return '';
177 }
178
179 $class = 'button';
180 $media = $process->get_media();
181 $url = get_imagify_admin_url(
182 'optimize',
183 [
184 'attachment_id' => $media->get_id(),
185 'context' => $media->get_context(),
186 ]
187 );
188
189 if ( ! Imagify_Views::get_instance()->is_media_page() ) {
190 $class .= ' button-imagify-optimize';
191 }
192
193 return Imagify_Views::get_instance()->get_template(
194 'button/retry-optimize',
195 [
196 'url' => $url,
197 'error' => $data['sizes']['full']['error'],
198 'atts' => [
199 'class' => $class,
200 ],
201 ]
202 );
203 }
204
205 /**
206 * Get the re-optimize link for a specific attachment.
207 *
208 * @since 1.0
209 * @since 1.9 Function signature changed.
210 * @author Jonathan Buttigieg
211 *
212 * @param ProcessInterface $process The optimization process object.
213 * @return string The output to print.
214 */
215 function get_imagify_attachment_reoptimize_link( $process ) {
216 if ( ! $process->is_valid() ) {
217 return '';
218 }
219
220 $data = $process->get_data();
221
222 if ( ! $data->get_optimization_status() ) {
223 // Not optimized yet.
224 return '';
225 }
226
227 // Stop the process if the API key isn't valid.
228 if ( ! Imagify_Requirements::is_api_key_valid() ) {
229 return '';
230 }
231
232 $is_already_optimized = $data->is_already_optimized();
233 $media = $process->get_media();
234 $can_reoptimize = $is_already_optimized || $media->has_backup();
235
236 // Don't display anything if there is no backup or the image has been optimized.
237 if ( ! $can_reoptimize ) {
238 return '';
239 }
240
241 $output = '';
242 $views = Imagify_Views::get_instance();
243 $media_level = $data->get_optimization_level();
244 $data = [];
245 $url_args = [
246 'attachment_id' => $media->get_id(),
247 'context' => $media->get_context(),
248 ];
249
250 if ( Imagify_Views::get_instance()->is_media_page() ) {
251 $data['atts'] = [
252 'class' => '',
253 ];
254 }
255
256 if ( $media_level < 1 ) {
257 $url_args['optimization_level'] = 2;
258 $data['optimization_level'] = 2;
259 $data['url'] = get_imagify_admin_url( 'manual-reoptimize', $url_args );
260
261 $output .= $views->get_template( 'button/re-optimize', $data );
262 } elseif ( $media_level > 0 ) {
263 $url_args['optimization_level'] = 0;
264 $data['optimization_level'] = 0;
265 $data['url'] = get_imagify_admin_url( 'manual-reoptimize', $url_args );
266
267 $output .= $views->get_template( 'button/re-optimize', $data );
268 }
269
270 return $output;
271 }
272
273 /**
274 * Get the link to optimize missing thumbnail sizes for a specific attachment.
275 *
276 * @since 1.6.10
277 * @since 1.9 Function signature changed.
278 * @author Grégory Viguier
279 *
280 * @param ProcessInterface $process The optimization process object.
281 * @return string The output to print.
282 */
283 function get_imagify_attachment_optimize_missing_thumbnails_link( $process ) {
284 if ( ! $process->is_valid() ) {
285 return '';
286 }
287
288 $media = $process->get_media();
289
290 if ( ! $media->is_image() || ! Imagify_Requirements::is_api_key_valid() || ! $media->has_backup() ) {
291 return '';
292 }
293
294 $context = $media->get_context();
295
296 /**
297 * Allow to not display the "Optimize missing thumbnails" link.
298 *
299 * @since 1.6.10
300 * @since 1.9 The $attachment object is replaced by a $process object.
301 * @author Grégory Viguier
302 *
303 * @param bool $display True to display the link. False to not display it.
304 * @param ProcessInterface $process The optimization process object.
305 * @param string $context The context.
306 */
307 $display = apply_filters( 'imagify_display_missing_thumbnails_link', true, $process, $context );
308
309 // Stop the process if the filter is false.
310 if ( ! $display ) {
311 return '';
312 }
313
314 $missing_sizes = $process->get_missing_sizes();
315
316 if ( ! $missing_sizes || is_wp_error( $missing_sizes ) ) {
317 return '';
318 }
319
320 $url = get_imagify_admin_url(
321 'optimize-missing-sizes',
322 [
323 'attachment_id' => $media->get_id(),
324 'context' => $context,
325 ]
326 );
327
328 return Imagify_Views::get_instance()->get_template(
329 'button/optimize-missing-sizes',
330 [
331 'url' => $url,
332 'count' => count( $missing_sizes ),
333 ]
334 );
335 }
336
337 /**
338 * Get the link to generate next-gen versions if they are missing.
339 *
340 * @since 1.9
341 *
342 * @param ProcessInterface $process The optimization process object.
343 *
344 * @return string The output to print.
345 */
346 function get_imagify_attachment_generate_nextgen_versions_link( $process ) {
347 if ( ! $process->is_valid() ) {
348 return '';
349 }
350
351 $formats = imagify_nextgen_images_formats();
352
353 if ( empty( $formats ) ) {
354 return '';
355 }
356
357 $media = $process->get_media();
358
359 if ( ! $media->is_image() || ! Imagify_Requirements::is_api_key_valid() || ! $media->has_backup() ) {
360 return '';
361 }
362
363 $format = get_imagify_option( 'optimization_format' );
364
365 if (
366 'avif' === $format
367 &&
368 'image/avif' === $media->get_mime_type()
369 ) {
370 return '';
371 } elseif ( 'image/webp' === $media->get_mime_type() ) {
372 return '';
373 }
374
375 $data = $process->get_data();
376
377 if ( ! $data->is_optimized() && ! $data->is_already_optimized() ) {
378 return '';
379 }
380
381 if ( $process->has_next_gen() ) {
382 return '';
383 }
384
385 $context = $media->get_context();
386
387 $display = apply_filters_deprecated( 'imagify_display_generate_webp_versions_link', [ true, $process, $context ], '2.2', 'imagify_display_generate_next_gen_versions_link' );
388
389 /**
390 * Allow to not display the "Generate next-gen versions" link.
391 *
392 * @since 1.9
393 * @author Grégory Viguier
394 *
395 * @param bool $display True to display the link. False to not display it.
396 * @param ProcessInterface $process The optimization process object.
397 * @param string $context The context.
398 */
399 $display = apply_filters( 'imagify_display_generate_next_gen_versions_link', $display, $process, $context );
400
401 // Stop the process if the filter is false.
402 if ( ! $display ) {
403 return '';
404 }
405
406 $url = get_imagify_admin_url(
407 'generate-nextgen-versions',
408 [
409 'attachment_id' => $media->get_id(),
410 'context' => $context,
411 ]
412 );
413
414 $output = Imagify_Views::get_instance()->get_template(
415 'button/generate-webp',
416 [
417 'url' => $url,
418 ]
419 );
420
421 return $output . '<br/>';
422 }
423
424 /**
425 * Get the link to delete next-gen versions when the status is "already_optimized".
426 *
427 * @since 1.9.6
428 * @author Grégory Viguier
429 *
430 * @param ProcessInterface $process The optimization process object.
431 * @return string The output to print.
432 */
433 function get_imagify_attachment_delete_nextgen_versions_link( $process ) {
434 if ( ! $process->is_valid() ) {
435 return '';
436 }
437
438 $media = $process->get_media();
439 $context = $media->get_context();
440 $media_id = $media->get_id();
441
442 if ( ! imagify_get_context( $context )->current_user_can( 'manual-restore', $media_id ) ) {
443 imagify_die();
444 }
445
446 $data = $process->get_data();
447
448 if ( ! $data->is_already_optimized() || ! $process->has_next_gen() ) {
449 return '';
450 }
451
452 $class = '';
453 $url = get_imagify_admin_url(
454 'delete-nextgen-versions',
455 [
456 'attachment_id' => $media_id,
457 'context' => $context,
458 ]
459 );
460
461 if ( ! Imagify_Views::get_instance()->is_media_page() ) {
462 $class .= 'button-imagify-delete-webp';
463 }
464
465 return Imagify_Views::get_instance()->get_template(
466 'button/delete-webp',
467 [
468 'url' => $url,
469 'atts' => [
470 'class' => $class,
471 ],
472 ]
473 );
474 }
475
476 /**
477 * Get all data to diplay for a specific media.
478 *
479 * @since 1.2
480 * @since 1.9 Function signature changed.
481 * @author Jonathan Buttigieg
482 *
483 * @param \Imagify\Optimization\Process\ProcessInterface $process The optimization process object.
484 * @param bool $with_container Set to false to not return the HTML container.
485 *
486 * @return string The output to print.
487 */
488 function get_imagify_media_column_content( $process, $with_container = true ) {
489 if ( ! $process->is_valid() ) {
490 return __( 'This media is not valid.', 'imagify' );
491 }
492
493 if ( ! $process->current_user_can( 'manual-optimize' ) ) {
494 return __( 'You are not allowed to optimize this file.', 'imagify' );
495 }
496
497 $media = $process->get_media();
498
499 // Check if the media is supported.
500 if ( ! $media->is_supported() ) {
501 return __( 'This media is not supported.', 'imagify' );
502 }
503
504 // Check if the media has the required WP data.
505 if ( ! $media->has_required_media_data() ) {
506 return __( 'This media lacks the required metadata and cannot be optimized.', 'imagify' );
507 }
508
509 $data = $process->get_data();
510
511 // Check if the API key is valid.
512 if ( ! Imagify_Requirements::is_api_key_valid() && ! $data->is_optimized() ) {
513 $output = __( 'Invalid API key', 'imagify' );
514 $output .= '<br/>';
515 $output .= '<a href="' . esc_url( get_imagify_admin_url() ) . '">' . __( 'Check your Settings', 'imagify' ) . '</a>';
516 return $output;
517 }
518
519 $media_id = $media->get_id();
520 $context = $media->get_context();
521 $views = Imagify_Views::get_instance();
522 $is_locked = $process->is_locked();
523
524 if ( $is_locked ) {
525 switch ( $is_locked ) {
526 case 'optimizing':
527 $lock_label = __( 'Optimizing...', 'imagify' );
528 break;
529 case 'restoring':
530 $lock_label = __( 'Restoring...', 'imagify' );
531 break;
532 default:
533 $lock_label = __( 'Processing...', 'imagify' );
534 }
535
536 if ( ! $with_container ) {
537 return $views->get_template(
538 'button/processing',
539 [ 'label' => $lock_label ]
540 );
541 }
542
543 return $views->get_template(
544 'container/data-actions',
545 [
546 'media_id' => $media_id,
547 'context' => $context,
548 'content' => $views->get_template( 'button/processing', [ 'label' => $lock_label ] ),
549 ]
550 );
551 }
552
553 // Check if the image was optimized.
554 if ( ! $data->get_optimization_status() ) {
555 $output = Imagify_Views::get_instance()->get_template(
556 'button/optimize',
557 [
558 'url' => get_imagify_admin_url(
559 'manual-optimize',
560 [
561 'attachment_id' => $media_id,
562 'context' => $context,
563 ]
564 ),
565 ]
566 );
567
568 if ( $media->has_backup() ) {
569 $output .= '<span class="attachment-has-backup hidden"></span>';
570 }
571 } else {
572 $output = get_imagify_attachment_optimization_text( $process );
573 }
574
575 if ( ! $with_container ) {
576 return $output;
577 }
578
579 return $views->get_template(
580 'container/data-actions',
581 [
582 'media_id' => $media_id,
583 'context' => $context,
584 'content' => $output,
585 ]
586 );
587 }
588