PluginProbe
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress / trunk
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress vtrunk
4.1.2 4.1.1 4.1.0 4.0.1 4.0.0 3.3.1 3.3.0 trunk 1.0.0 2.0.0 2.1.0 3.0.0 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8
quickwebp / admin / class-cron-job.php

class-cron-job.php in QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress trunk, at admin/class-cron-job.php

321 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The admin-specific functionality of the plugin.
4 *
5 * @link http://webdeclic.com
6 * @since 1.0.0
7 *
8 * @package Quickwebp
9 * @subpackage Quickwebp/admin
10 */
11 class Quickwebp_Cron_Job {
12
13 /**
14 * The ID of this plugin.
15 *
16 * @since 1.0.0
17 * @access private
18 * @var string $plugin_name The ID of this plugin.
19 */
20 private $plugin_name;
21
22 /**
23 * The version of this plugin.
24 *
25 * @since 1.0.0
26 * @access private
27 * @var string $version The current version of this plugin.
28 */
29 private $version;
30
31 /**
32 * Initialize the class and set its properties.
33 *
34 * @since 1.0.0
35 * @param string $plugin_name The name of this plugin.
36 * @param string $version The version of this plugin.
37 */
38 public function __construct( $plugin_name, $version ) {
39 $this->plugin_name = $plugin_name;
40 $this->version = $version;
41 }
42
43 /**
44 * Register cron jobs
45 */
46 public function crons_registrations( $schedules ) {
47
48 $schedules['bulk_optimization'] = array(
49 'interval' => MINUTE_IN_SECONDS,
50 'display' => __( 'Every minute', 'quickwebp' )
51 );
52
53 return $schedules;
54 }
55
56 /**
57 * excute bulk optimization
58 */
59 public function excute_bulk_optimization() {
60 $lock_token = $this->acquire_bulk_optimization_lock();
61 if ( ! $lock_token ) {
62 return;
63 }
64
65 $time_start = microtime( true );
66
67 $quickwebp_image_optimizer = new Quickwebp_Image_Optimizer( QUICKWEBP_TEXT_DOMAIN, QUICKWEBP_VERSION );
68 $settings = $quickwebp_image_optimizer->get_settings();
69
70 $mode_enabled = $settings['quickwebp_settings_conversion'];
71 if ( '0' === $mode_enabled ) {
72 $this->end_cron_job();
73 $this->release_bulk_optimization_lock( $lock_token );
74 return;
75 }
76
77 $media_ids = $quickwebp_image_optimizer->get_unoptimized_media_ids( 5 );
78 if ( empty( $media_ids ) ) {
79 $this->end_cron_job();
80 $this->release_bulk_optimization_lock( $lock_token );
81 return;
82 }
83
84 $status = get_option( 'quickwebp_bulk_optimize_status', 'finish' );
85 if ( $status != 'running' ) {
86 $this->end_cron_job();
87 $this->release_bulk_optimization_lock( $lock_token );
88 return;
89 }
90
91 $current = (int) get_option( 'quickwebp_bulk_optimize_current', 0 );
92 $batch_stats = array(
93 'images_optimized' => 0,
94 'bytes_before' => 0,
95 'bytes_after' => 0,
96 );
97
98 foreach ( $media_ids as $id ) {
99 if ( $time_start + 55 < microtime( true ) ) {
100 break;
101 }
102
103 $sizes = $quickwebp_image_optimizer->get_media_files( $id );
104 $new_sizes = array();
105
106 foreach ( $sizes as $key => $size ) {
107 $result = $quickwebp_image_optimizer->optimize_local_file( $size );
108
109 if ( $result ) {
110 $new_sizes[$key] = $result;
111 }
112 }
113
114 if ( ! empty( $new_sizes ) ) {
115 $attachment_stats = $quickwebp_image_optimizer->get_attachment_optimization_stats( $new_sizes );
116 $batch_stats['images_optimized'] += $attachment_stats['images_optimized'];
117 $batch_stats['bytes_before'] += $attachment_stats['bytes_before'];
118 $batch_stats['bytes_after'] += $attachment_stats['bytes_after'];
119
120 $data = get_post_meta( $id, 'quickwebp_data', true );
121 if ( ! empty( $data ) ) {
122 $quickwebp_image_optimizer->remove_related_files( $data );
123 }
124
125 if ( '1' == $mode_enabled ) {
126 update_post_meta( $id, 'quickwebp_already_optimized', '1' );
127 } elseif ( '2' == $mode_enabled ) {
128 update_post_meta( $id, 'quickwebp_already_optimized', '2' );
129 }
130
131 update_post_meta( $id, 'quickwebp_data', $new_sizes );
132 delete_post_meta( $id, 'quickwebp_has_error' );
133 } else {
134 update_post_meta( $id, 'quickwebp_has_error', '1' );
135 delete_post_meta( $id, 'quickwebp_already_optimized' );
136 delete_post_meta( $id, 'quickwebp_data' );
137 }
138
139 $current++;
140 }
141
142 if ( $batch_stats['images_optimized'] ) {
143 $quickwebp_image_optimizer->record_optimization_stats(
144 $batch_stats['bytes_before'],
145 $batch_stats['bytes_after'],
146 $batch_stats['images_optimized']
147 );
148 }
149
150 update_option( 'quickwebp_bulk_optimize_current', $current );
151
152 if ( empty( $quickwebp_image_optimizer->get_unoptimized_media_ids( 1 ) ) ) {
153 $this->end_cron_job();
154 }
155
156 $this->release_bulk_optimization_lock( $lock_token );
157 }
158
159 /**
160 * Acquire an expiring lock for the bulk optimization worker.
161 *
162 * @return string|false
163 */
164 private function acquire_bulk_optimization_lock() {
165 $lock_token = wp_generate_uuid4();
166 $lock = array(
167 'token' => $lock_token,
168 'expires' => time() + ( 2 * MINUTE_IN_SECONDS ),
169 );
170
171 if ( add_option( 'quickwebp_bulk_optimization_lock', $lock, '', false ) ) {
172 return $lock_token;
173 }
174
175 $existing_lock = get_option( 'quickwebp_bulk_optimization_lock', array() );
176 if ( is_array( $existing_lock ) && absint( $existing_lock['expires'] ?? 0 ) < time() ) {
177 delete_option( 'quickwebp_bulk_optimization_lock' );
178 if ( add_option( 'quickwebp_bulk_optimization_lock', $lock, '', false ) ) {
179 return $lock_token;
180 }
181 }
182
183 return false;
184 }
185
186 /**
187 * Release the bulk optimization lock owned by this process.
188 *
189 * @param string $lock_token Lock ownership token.
190 */
191 private function release_bulk_optimization_lock( $lock_token ) {
192 $lock = get_option( 'quickwebp_bulk_optimization_lock', array() );
193 if ( is_array( $lock ) && hash_equals( (string) ( $lock['token'] ?? '' ), $lock_token ) ) {
194 delete_option( 'quickwebp_bulk_optimization_lock' );
195 }
196 }
197
198 /**
199 * Start bulk optimization
200 */
201 public function start_bulk_optimization() {
202
203 if ( ! current_user_can( 'manage_options' ) ) {
204 wp_send_json_error( __( 'You are not allowed to manage plugin settings.', 'quickwebp' ), 403 );
205 }
206
207 // verify the nonce.
208 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
209 if( !wp_verify_nonce( $nonce, 'image_optimize_nonce' ) ) {
210 wp_send_json_error( __( 'Refresh the page and try again.', 'quickwebp' ) );
211 }
212
213 $quickwebp_image_optimizer = new Quickwebp_Image_Optimizer( QUICKWEBP_TEXT_DOMAIN, QUICKWEBP_VERSION );
214 $settings = $quickwebp_image_optimizer->get_settings();
215
216 $mode_enabled = $settings['quickwebp_settings_conversion'];
217 if ( '0' === $mode_enabled ) {
218 wp_send_json_error( __( 'Choose an image format and save the settings.', 'quickwebp' ) );
219 }
220
221 $total = $quickwebp_image_optimizer->get_unoptimized_media_count();
222 if ( ! $total ) {
223 wp_send_json_error( __( 'No images to optimize.', 'quickwebp' ) );
224 }
225
226 $status = get_option( 'quickwebp_bulk_optimize_status', 'finish' );
227 if ( $status != 'finish' ) {
228 wp_send_json_error( __( 'Bulk optimization is already running.', 'quickwebp' ) );
229 }
230
231 if ( ! wp_next_scheduled( 'quickwebp_bulk_optimization_hook' ) ) {
232 wp_schedule_event( time(), 'bulk_optimization', 'quickwebp_bulk_optimization_hook' );
233
234 $current = 0;
235
236 update_option( 'quickwebp_bulk_optimize_total', $total );
237 update_option( 'quickwebp_bulk_optimize_current', $current );
238 update_option( 'quickwebp_bulk_optimize_status', 'running' );
239
240 $data = array(
241 'progress' => $current . '/' . $total,
242 'percent' => $total ? round( abs( ( $current / $total ) ) * 100 ) . '%' : '0%'
243 );
244 wp_send_json_success( $data );
245 }
246
247 wp_send_json_error( __( 'Refresh the page and try again.', 'quickwebp' ) );
248 }
249
250 /**
251 * Stop bulk optimization
252 */
253 public function stop_bulk_optimization() {
254
255 if ( ! current_user_can( 'manage_options' ) ) {
256 wp_send_json_error( __( 'You are not allowed to manage plugin settings.', 'quickwebp' ), 403 );
257 }
258
259 // verify the nonce.
260 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
261 if( !wp_verify_nonce( $nonce, 'image_optimize_nonce' ) ) {
262 wp_send_json_error( __( 'Refresh the page and try again.', 'quickwebp' ) );
263 }
264
265 if ( $this->clear_bulk_optimization() ) {
266 wp_send_json_success( __( 'Bulk optimization stopped.', 'quickwebp' ) );
267 }
268
269 wp_send_json_error( __( 'Refresh the page and try again.', 'quickwebp' ) );
270 }
271
272 /**
273 * Check bulk optimization progress
274 */
275 public function check_bulk_optimization_progress() {
276
277 if ( ! current_user_can( 'manage_options' ) ) {
278 wp_send_json_error( __( 'You are not allowed to manage plugin settings.', 'quickwebp' ), 403 );
279 }
280
281 // verify the nonce.
282 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
283 if( !wp_verify_nonce( $nonce, 'image_optimize_nonce' ) ) {
284 wp_send_json_error( __( 'Refresh the page and try again.', 'quickwebp' ) );
285 }
286
287 $status = get_option( 'quickwebp_bulk_optimize_status', '' );
288 $total = (int)get_option( 'quickwebp_bulk_optimize_total', 0 );
289 $current = (int)get_option( 'quickwebp_bulk_optimize_current', 0 );
290 $is_running = $status == 'running' ? true : false;
291
292 $data = array(
293 'running' => $is_running,
294 'progress' => $current . '/' . $total,
295 'percent' => $total ? round( abs( ( $current / $total ) ) * 100 ) . '%' : '0%'
296 );
297 wp_send_json_success( $data );
298 }
299
300 /**
301 * Clear bulk optimization
302 */
303 private function clear_bulk_optimization() {
304 update_option( 'quickwebp_bulk_optimize_status', 'finish' );
305
306 if ( wp_next_scheduled( 'quickwebp_bulk_optimization_hook' ) ) {
307 wp_clear_scheduled_hook( 'quickwebp_bulk_optimization_hook' );
308 return true;
309 }
310
311 return false;
312 }
313
314 /**
315 * End cron job
316 */
317 private function end_cron_job() {
318 $this->clear_bulk_optimization();
319 }
320 }
321