PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / 1.0.2
Image Optimizer – Compress Images and Convert to WebP or AVIF v1.0.2
1.7.7 1.7.6 1.7.5 1.7.4 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 All 33 releases
image-optimization / modules / optimization / components / media-control.php

media-control.php in Image Optimizer – Compress Images and Convert to WebP or AVIF 1.0.2, at modules/optimization/components/media-control.php

277 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ImageOptimizer\Modules\Optimization\Components;
4
5 use ImageOptimizer\Classes\Image\{
6 Exceptions\Invalid_Image_Exception,
7 Image,
8 Image_Meta,
9 Image_Optimization_Error_Type,
10 Image_Status
11 };
12 use ImageOptimizer\Modules\Oauth\Components\{
13 Connect,
14 Exceptions\Auth_Exception,
15 };
16 use ImageOptimizer\Modules\Optimization\{
17 Classes\Exceptions\Image_Validation_Error,
18 Classes\Validate_Image,
19 Module,
20 };
21 use ImageOptimizer\Modules\Oauth\Classes\Data;
22 use ImageOptimizer\Modules\Settings\Classes\Settings;
23 use ImageOptimizer\Modules\Stats\Classes\Optimization_Stats;
24 use Throwable;
25
26 /**
27 * The class is responsible for rendering optimization control in all views.
28 */
29 class Media_Control {
30 const COLUMN_ID = 'image_optimization';
31 const META_BOX_ID = 'image_optimization_meta_box';
32 const DETAILS_MODAL_FIELD_ID = 'image_optimization_modal';
33
34 /**
35 * Adds a new optimization column to the library list view.
36 *
37 * @param array $columns
38 * @return array
39 */
40 public function add_optimization_column( array $columns ): array {
41 if ( empty( $columns ) ) {
42 return $columns;
43 }
44
45 $columns[ self::COLUMN_ID ] = esc_html__( 'Image optimization', 'image-optimizer' );
46
47 return $columns;
48 }
49
50 /**
51 * Renders optimization controls in the library list view.
52 *
53 * @param string $column_name
54 * @param int $attachment_id
55 * @return void
56 */
57 public function render_optimization_column( string $column_name, int $attachment_id ) {
58 if ( self::COLUMN_ID !== $column_name ) {
59 return;
60 }
61
62 $this->render_optimization_control( 'list-view', $attachment_id );
63 }
64
65 /**
66 * Adds optimization control as media meta box.
67 *
68 * @return void
69 */
70 public function add_optimization_meta_box() {
71 add_meta_box(
72 self::META_BOX_ID,
73 __( 'Image optimization', 'image-optimizer' ),
74 function( $post ) {
75 $this->render_optimization_control( 'meta-box', $post->ID );
76 },
77 'attachment',
78 'side',
79 );
80 }
81
82 /**
83 * Adds optimization control to media modals.
84 *
85 * @param array $form_fields
86 * @param \WP_Post $post
87 *
88 * @return array
89 */
90 public function add_media_modal_details( array $form_fields, \WP_Post $post ): array {
91 $form_fields[ self::DETAILS_MODAL_FIELD_ID ] = [
92 'label' => '',
93 'input' => 'hidden',
94 'value' => $this->get_optimization_control_html( 'details-view', $post->ID ),
95 'required' => false,
96 ];
97
98 return $form_fields;
99 }
100
101 /**
102 * Returns optimization control as an HTML string.
103 *
104 * @param string $context Control placement context. One of ['list-view', 'meta-box', 'details-view'].
105 * @param int $image_id Attachment id.
106 * @return false|string
107 */
108 public function get_optimization_control_html( string $context, int $image_id ) {
109 ob_start();
110
111 $this->render_optimization_control( $context, $image_id );
112
113 $html = ob_get_contents();
114 ob_end_clean();
115
116 return $html;
117 }
118
119 /**
120 * Renders the optimization control for the current image in the current context.
121 *
122 * @param string $context Control placement context. One of ['list-view', 'meta-box', 'details-view'].
123 * @param int $image_id Attachment id.
124 * @return void Renders the control.
125 */
126 public function render_optimization_control( string $context, int $image_id ) {
127 $global_context = [
128 'image_id' => $image_id,
129 'can_be_restored' => false,
130 ];
131
132 try {
133 if ( ! Connect::is_connected() || ! Connect::is_activated() ) {
134 throw new Auth_Exception( 'You have to activate your license to use Image Optimizer' );
135 }
136
137 Validate_Image::is_valid( $image_id );
138
139 $image = new Image( $image_id );
140 $meta = new Image_Meta( $image->get_id() );
141
142 $global_context['can_be_restored'] = Image_Status::OPTIMIZED === $meta->get_status()
143 ? $image->can_be_restored()
144 : Settings::get( Settings::BACKUP_ORIGINAL_IMAGES_OPTION_NAME );
145
146 switch ( $meta->get_status() ) {
147 case Image_Status::OPTIMIZATION_IN_PROGRESS:
148 Module::load_template( $context, 'loading', array_merge(
149 $global_context, [
150 'action' => 'optimize',
151 ]
152 ) );
153
154 break;
155
156 case Image_Status::REOPTIMIZING_IN_PROGRESS:
157 Module::load_template( $context, 'loading', array_merge(
158 $global_context, [
159 'action' => 'reoptimize',
160 ]
161 ) );
162
163 break;
164
165 case Image_Status::RESTORING_IN_PROGRESS:
166 Module::load_template( $context, 'loading', array_merge(
167 $global_context, [
168 'action' => 'restore',
169 ]
170 ) );
171
172 break;
173
174 case Image_Status::OPTIMIZED:
175 $stats = Optimization_Stats::get_image_stats( $image_id );
176 $saved = [
177 'relative' => round( $stats['current_image_size'] / $stats['initial_image_size'] * 100 ),
178 'absolute' => $stats['initial_image_size'] - $stats['current_image_size'],
179 ];
180
181 Module::load_template( $context, 'optimized', array_merge(
182 $global_context, [
183 'sizes_optimized_count' => $stats['optimized_image_count'],
184 'saved' => $saved,
185 ]
186 ) );
187
188 break;
189
190 case Image_Status::OPTIMIZATION_FAILED:
191 $error_type = $meta->get_error_type() ?? Image_Optimization_Error_Type::GENERIC;
192 $error_message = Image_Optimization_Error_Type::QUOTA_EXCEEDED === $error_type
193 ? esc_html__( 'Plan quota reached', 'image-optimizer' )
194 : esc_html__( 'Optimization error', 'image-optimizer' );
195 $images_left = Data::images_left();
196
197 Module::load_template( $context, 'error', array_merge(
198 $global_context, [
199 'message' => $error_message,
200 'optimization_error_type' => $error_type,
201 'images_left' => $images_left,
202 'allow_retry' => true,
203 'action' => 'optimize',
204 ]
205 ) );
206
207 break;
208
209 case Image_Status::REOPTIMIZING_FAILED:
210 $error_type = $meta->get_error_type() ?? Image_Optimization_Error_Type::GENERIC;
211 $error_message = Image_Optimization_Error_Type::QUOTA_EXCEEDED === $error_type
212 ? esc_html__( 'Plan quota reached', 'image-optimizer' )
213 : esc_html__( 'Image reoptimizing failed', 'image-optimizer' );
214 $images_left = Data::images_left();
215
216 Module::load_template( $context, 'error', array_merge(
217 $global_context, [
218 'message' => $error_message,
219 'optimization_error_type' => $error_type,
220 'images_left' => $images_left,
221 'allow_retry' => true,
222 'action' => 'reoptimize',
223 ]
224 ) );
225
226 break;
227
228 case Image_Status::RESTORING_FAILED:
229 Module::load_template( $context, 'error', array_merge(
230 $global_context, [
231 'message' => esc_html__( 'Image restoring error', 'image-optimizer' ),
232 'allow_retry' => true,
233 'action' => 'restore',
234 ]
235 ) );
236
237 break;
238
239 default:
240 Module::load_template( $context, 'not-optimized', $global_context );
241 }
242 } catch ( Invalid_Image_Exception |Image_Validation_Error $iie ) {
243 Module::load_template( $context, 'error', array_merge(
244 $global_context, [
245 'action' => 'error',
246 'message' => $iie->getMessage(),
247 'allow_retry' => false,
248 ]
249 ) );
250 } catch ( Auth_Exception $ae ) {
251 Module::load_template( $context, 'error', array_merge(
252 $global_context, [
253 'action' => 'error',
254 'message' => esc_html__( 'N/A', 'image-optimizer' ),
255 'allow_retry' => false,
256 ]
257 ) );
258 } catch ( Throwable $t ) {
259 Module::load_template( $context, 'error', array_merge(
260 $global_context, [
261 'action' => 'error',
262 'message' => esc_html__( 'Internal server error', 'image-optimizer' ),
263 'allow_retry' => false,
264 ]
265 ) );
266 }
267 }
268
269 public function __construct() {
270 add_filter( 'manage_upload_columns', [ $this, 'add_optimization_column' ] );
271 add_action( 'manage_media_custom_column', [ $this, 'render_optimization_column' ], 10, 2 );
272
273 add_action( 'add_meta_boxes_attachment', [ $this, 'add_optimization_meta_box' ] );
274 add_filter( 'attachment_fields_to_edit', [ $this, 'add_media_modal_details' ], 10, 2 );
275 }
276 }
277