PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.2.1
GiveWP – Donation Plugin and Fundraising Platform v2.2.1
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / class-give-background-updater.php
give / includes Last commit date
admin 7 years ago api 7 years ago deprecated 7 years ago donors 7 years ago emails 7 years ago forms 7 years ago gateways 7 years ago libraries 7 years ago payments 7 years ago actions.php 7 years ago ajax-functions.php 7 years ago class-give-async-process.php 8 years ago class-give-background-updater.php 7 years ago class-give-cache.php 7 years ago class-give-cli-commands.php 8 years ago class-give-comment.php 7 years ago class-give-cron.php 8 years ago class-give-db-donor-meta.php 8 years ago class-give-db-donors.php 7 years ago class-give-db-form-meta.php 8 years ago class-give-db-logs-meta.php 8 years ago class-give-db-logs.php 7 years ago class-give-db-meta.php 7 years ago class-give-db-payment-meta.php 7 years ago class-give-db-sequential-ordering.php 7 years ago class-give-db-sessions.php 7 years ago class-give-db.php 8 years ago class-give-donate-form.php 8 years ago class-give-donor-wall-widget.php 7 years ago class-give-donor.php 7 years ago class-give-email-access.php 8 years ago class-give-html-elements.php 7 years ago class-give-license-handler.php 7 years ago class-give-logging.php 8 years ago class-give-readme-parser.php 8 years ago class-give-roles.php 8 years ago class-give-scripts.php 7 years ago class-give-session.php 7 years ago class-give-stats.php 8 years ago class-give-template-loader.php 8 years ago class-give-tooltips.php 8 years ago class-give-translation.php 8 years ago class-notices.php 7 years ago country-functions.php 8 years ago currency-functions.php 7 years ago error-tracking.php 8 years ago filters.php 7 years ago formatting.php 7 years ago import-functions.php 7 years ago install.php 7 years ago login-register.php 8 years ago misc-functions.php 7 years ago plugin-compatibility.php 8 years ago post-types.php 8 years ago price-functions.php 7 years ago process-donation.php 7 years ago shortcodes.php 7 years ago template-functions.php 8 years ago user-functions.php 7 years ago
class-give-background-updater.php
468 lines
1 <?php
2 /**
3 * Background Updater
4 *
5 * Uses https://github.com/A5hleyRich/wp-background-processing to handle DB
6 * updates in the background.
7 *
8 * @class Give_Background_Updater
9 * @version 2.0.0
10 * @package Give/Classes
11 * @category Class
12 * @author WordImpress
13 */
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 /**
19 * Give_Background_Updater Class.
20 */
21 class Give_Background_Updater extends WP_Background_Process {
22
23 /**
24 * @var string
25 */
26 protected $action = 'give_db_updater';
27
28 /**
29 * Dispatch updater.
30 *
31 * Updater will still run via cron job if this fails for any reason.
32 */
33 public function dispatch() {
34 if ( give_test_ajax_works() ) {
35 parent::dispatch();
36 } elseif ( wp_doing_ajax() ) {
37 $this->maybe_handle();
38 }
39 }
40
41
42 /**
43 * Get all batches.
44 *
45 * @since 2.0
46 * @access public
47 * @return stdClass
48 */
49 public function get_all_batch() {
50 return parent::get_batch();
51 }
52
53 /**
54 * Is queue empty
55 *
56 * @since 2.0.3
57 *
58 * @return bool
59 */
60 public function has_queue() {
61 return ( ! parent::is_queue_empty() );
62 }
63
64
65 /**
66 * Lock process
67 *
68 * Lock the process so that multiple instances can't run simultaneously.
69 * Override if applicable, but the duration should be greater than that
70 * defined in the time_exceeded() method.
71 *
72 *
73 * @since 2.0.3
74 */
75 protected function lock_process() {
76 // Check if admin want to pause upgrade.
77 if( get_option('give_pause_upgrade') ) {
78 self::flush_cache();
79
80 delete_option( 'give_paused_batches' );
81
82 Give_Updates::get_instance()->__pause_db_update( true );
83
84 delete_option('give_pause_upgrade');
85
86 /**
87 * Fire action when pause db updates
88 *
89 * @since 2.0.1
90 */
91 do_action( 'give_pause_db_upgrade', Give_Updates::get_instance() );
92
93 wp_die();
94 }
95
96
97 $this->start_time = time(); // Set start time of current process.
98
99 $lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute
100 $lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration );
101
102 set_site_transient( $this->identifier . '_process_lock', microtime(), $lock_duration );
103 }
104
105 /**
106 * Handle cron healthcheck
107 *
108 * Restart the background process if not already running
109 * and data exists in the queue.
110 */
111 public function handle_cron_healthcheck() {
112 if ( $this->is_process_running() || $this->is_paused_process() ) {
113 // Background process already running.
114 return;
115 }
116
117 if ( $this->is_queue_empty() ) {
118 // No data to process.
119 $this->clear_scheduled_event();
120
121 return;
122 }
123
124 $this->handle();
125 }
126
127 /**
128 * Schedule fallback event.
129 */
130 protected function schedule_event() {
131 if ( ! wp_next_scheduled( $this->cron_hook_identifier ) && ! $this->is_paused_process() ) {
132 wp_schedule_event( time() + 10, $this->cron_interval_identifier, $this->cron_hook_identifier );
133 }
134 }
135
136 /**
137 * Task
138 *
139 * Override this method to perform any actions required on each
140 * queue item. Return the modified item for further processing
141 * in the next pass through. Or, return false to remove the
142 * item from the queue.
143 *
144 * @param array $update Update info
145 *
146 * @return mixed
147 */
148 protected function task( $update ) {
149 // Pause upgrade immediately if admin pausing upgrades.
150 if( $this->is_paused_process() ) {
151 wp_die();
152 }
153
154 if ( empty( $update ) ) {
155 return false;
156 }
157
158 // Delete cache.
159 self::flush_cache();
160
161 /* @var Give_Updates $give_updates */
162 $give_updates = Give_Updates::get_instance();
163 $resume_update = get_option(
164 'give_doing_upgrade',
165
166 // Default update.
167 array(
168 'update_info' => $update,
169 'step' => 1,
170 'update' => 1,
171 'heading' => sprintf( 'Update %s of {update_count}', 1 ),
172 'percentage' => $give_updates->percentage,
173 'total_percentage' => 0,
174 )
175 );
176
177 // Continuously skip update if previous update does not complete yet.
178 if (
179 $resume_update['update_info']['id'] !== $update['id'] &&
180 ! give_has_upgrade_completed( $resume_update['update_info']['id'] )
181 ) {
182 return $update;
183 }
184
185 // Set params.
186 $resume_update['update_info'] = $update;
187 $give_updates->step = absint( $resume_update['step'] );
188 $give_updates->update = absint( $resume_update['update'] );
189 $is_parent_update_completed = $give_updates->is_parent_updates_completed( $update );
190
191
192 // Skip update if dependency update does not complete yet.
193 if ( empty( $is_parent_update_completed ) ) {
194 // @todo: set error when you have only one update with invalid dependency
195 if ( ! is_null( $is_parent_update_completed ) ) {
196 return $update;
197 }
198
199 return false;
200 }
201
202
203 // Pause upgrade immediately if found following:
204 // 1. Running update number greater then total update count
205 // 2. Processing percentage greater then 100%
206 if( (
207 101 < $resume_update['total_percentage'] ) ||
208 ( $give_updates->get_total_db_update_count() < $resume_update['update'] ) ||
209 ! in_array( $resume_update['update_info']['id'], $give_updates->get_update_ids() )
210 ) {
211 if( ! $this->is_paused_process() ){
212 $give_updates->__pause_db_update(true);
213 }
214
215 update_option( 'give_upgrade_error', 1, false );
216
217 $log_data = 'Update Task' . "\n";
218 $log_data .= "Total update count: {$give_updates->get_total_db_update_count()}\n";
219 $log_data .= 'Update IDs: ' . print_r( $give_updates->get_update_ids() , true );
220 $log_data .= 'Update: ' . print_r( $resume_update , true );
221
222 Give()->logs->add( 'Update Error', $log_data, 0, 'update' );
223
224 wp_die();
225 }
226
227 // Disable cache.
228 Give_Cache::disable();
229
230 try{
231 // Run update.
232 if ( is_array( $update['callback'] ) ) {
233 $update['callback'][0]->$update['callback'][1]();
234 } else {
235 $update['callback']();
236 }
237 } catch ( Exception $e ){
238
239 if( ! $this->is_paused_process() ){
240 $give_updates->__pause_db_update(true);
241 }
242
243 $log_data = 'Update Task' . "\n";
244 $log_data .= print_r( $resume_update, true ) . "\n\n";
245 $log_data .= "Error\n {$e->getMessage()}";
246
247 Give()->logs->add( 'Update Error', $log_data, 0, 'update' );
248 update_option( 'give_upgrade_error', 1, false );
249
250 wp_die();
251 }
252
253 // Set update info.
254 $doing_upgrade_args = array(
255 'update_info' => $update,
256 'step' => ++ $give_updates->step,
257 'update' => $give_updates->update,
258 'heading' => sprintf( 'Update %s of %s', $give_updates->update, get_option( 'give_db_update_count' ) ),
259 'percentage' => $give_updates->percentage,
260 'total_percentage' => $give_updates->get_db_update_processing_percentage(),
261 );
262
263 // Cache upgrade.
264 update_option( 'give_doing_upgrade', $doing_upgrade_args, false );
265
266 // Enable cache.
267 Give_Cache::enable();
268
269 // Check if current update completed or not.
270 if ( give_has_upgrade_completed( $update['id'] ) ) {
271 return false;
272 }
273
274 return $update;
275 }
276
277 /**
278 * Complete
279 *
280 * Override if applicable, but ensure that the below actions are
281 * performed, or, call parent::complete().
282 */
283 public function complete() {
284 if ( $this->is_paused_process() ) {
285 return false;
286 }
287
288 parent::complete();
289
290 delete_option( 'give_pause_upgrade' );
291 delete_option( 'give_upgrade_error' );
292 delete_option( 'give_db_update_count' );
293 delete_option( 'give_doing_upgrade' );
294 add_option( 'give_show_db_upgrade_complete_notice', 1, '', false );
295
296 // Flush cache.
297 Give_Cache::flush_cache( true );
298
299 if ( $cache_keys = Give_Cache::get_options_like( '' ) ) {
300 Give_Cache::delete( $cache_keys );
301 }
302 }
303
304 /**
305 * Get memory limit
306 *
307 * @return int
308 */
309 protected function get_memory_limit() {
310 if ( function_exists( 'ini_get' ) ) {
311 $memory_limit = ini_get( 'memory_limit' );
312 } else {
313 // Sensible default.
314 $memory_limit = '128M';
315 }
316
317 if ( ! $memory_limit || '-1' === $memory_limit ) {
318 // Unlimited, set to 32GB.
319 $memory_limit = '32000M';
320 }
321
322 return intval( $memory_limit ) * 1024 * 1024;
323 }
324
325 /**
326 * Maybe process queue
327 *
328 * Checks whether data exists within the queue and that
329 * the process is not already running.
330 */
331 public function maybe_handle() {
332 // Don't lock up other requests while processing
333 session_write_close();
334
335 if ( $this->is_process_running() || $this->is_paused_process() ) {
336 // Background process already running.
337 wp_die();
338 }
339
340 if ( $this->is_queue_empty() ) {
341 // No data to process.
342 wp_die();
343 }
344
345 check_ajax_referer( $this->identifier, 'nonce' );
346
347 $this->handle();
348
349 wp_die();
350 }
351
352 /**
353 * Handle
354 *
355 * Pass each queue item to the task handler, while remaining
356 * within server memory and time limit constraints.
357 */
358 protected function handle() {
359 $this->lock_process();
360
361 do {
362 $batch = $this->get_batch();
363
364 foreach ( $batch->data as $key => $value ) {
365 $task = $this->task( $value );
366
367 if ( false !== $task ) {
368 $batch->data[ $key ] = $task;
369 } else {
370 unset( $batch->data[ $key ] );
371 }
372
373 if ( $this->time_exceeded() || $this->memory_exceeded() ) {
374 // Batch limits reached.
375 break;
376 }
377 }
378
379 // Update or delete current batch.
380 if ( ! empty( $batch->data ) ) {
381 $this->update( $batch->key, $batch->data );
382 } else {
383 $this->delete( $batch->key );
384 }
385 } while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
386
387 $this->unlock_process();
388
389 // Start next batch or complete process.
390 if ( ! $this->is_queue_empty() ) {
391
392 // Dispatch only if ajax works.
393 if( give_test_ajax_works() ) {
394 $this->dispatch();
395 }
396 } else {
397 $this->complete();
398 }
399
400 wp_die();
401 }
402
403
404 /**
405 * Check if backgound upgrade paused or not.
406 *
407 * @since 2.0
408 * @access public
409 * @return bool
410 */
411 public function is_paused_process(){
412 // Delete cache.
413 wp_cache_delete( 'give_paused_batches', 'options' );
414
415 $paused_batches = get_option('give_paused_batches');
416
417 return ! empty( $paused_batches );
418 }
419
420
421 /**
422 * Get identifier
423 *
424 * @since 2.0
425 * @access public
426 * @return mixed|string
427 */
428 public function get_identifier() {
429 return $this->identifier;
430 }
431
432 /**
433 * Get cron identifier
434 *
435 * @since 2.0
436 * @access public
437 * @return mixed|string
438 */
439 public function get_cron_identifier() {
440 return $this->cron_hook_identifier;
441 }
442
443
444 /**
445 * Flush background update related cache to prevent task to go to stalled state.
446 *
447 * @since 2.0.3
448 */
449 public static function flush_cache() {
450
451 $options = array(
452 'give_completed_upgrades',
453 'give_doing_upgrade',
454 'give_paused_batches',
455 'give_upgrade_error',
456 'give_db_update_count',
457 'give_doing_upgrade',
458 'give_pause_upgrade',
459 'give_show_db_upgrade_complete_notice',
460 );
461
462
463 foreach ( $options as $option ) {
464 wp_cache_delete( $option, 'options' );
465 }
466 }
467 }
468