|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Created by PhpStorm. |
|
5
|
|
|
* User: ravinderkumar |
|
6
|
|
|
* Date: 14/07/17 |
|
7
|
|
|
* Time: 3:27 PM |
|
8
|
|
|
*/ |
|
9
|
|
|
class Give_Updates { |
|
|
|
|
|
|
10
|
|
|
/** |
|
11
|
|
|
* Instance. |
|
12
|
|
|
* |
|
13
|
|
|
* @since |
|
14
|
|
|
* @access static |
|
15
|
|
|
* @var |
|
16
|
|
|
*/ |
|
17
|
|
|
static private $instance; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* Updates |
|
21
|
|
|
* |
|
22
|
|
|
* @since 1.8.12 |
|
23
|
|
|
* @access private |
|
24
|
|
|
* @var array |
|
25
|
|
|
*/ |
|
26
|
|
|
static private $updates = array(); |
|
27
|
|
|
|
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Current update percentage number |
|
31
|
|
|
* |
|
32
|
|
|
* @since 1.8.12 |
|
33
|
|
|
* @access private |
|
34
|
|
|
* @var array |
|
35
|
|
|
*/ |
|
36
|
|
|
static public $percentage = 0; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* Current update step number |
|
40
|
|
|
* |
|
41
|
|
|
* @since 1.8.12 |
|
42
|
|
|
* @access private |
|
43
|
|
|
* @var array |
|
44
|
|
|
*/ |
|
45
|
|
|
static public $step = 1; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* Current update number |
|
49
|
|
|
* |
|
50
|
|
|
* @since 1.8.12 |
|
51
|
|
|
* @access private |
|
52
|
|
|
* @var array |
|
53
|
|
|
*/ |
|
54
|
|
|
static public $update = 1; |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* Singleton pattern. |
|
58
|
|
|
* |
|
59
|
|
|
* @since 1.8.12 |
|
60
|
|
|
* @access private |
|
61
|
|
|
* |
|
62
|
|
|
* @param Give_Updates . |
|
63
|
|
|
*/ |
|
64
|
|
|
private function __construct() { |
|
65
|
|
|
} |
|
66
|
|
|
|
|
67
|
|
|
/** |
|
68
|
|
|
* Register updates |
|
69
|
|
|
* |
|
70
|
|
|
* @since 1.8.12 |
|
71
|
|
|
* @access public |
|
72
|
|
|
* |
|
73
|
|
|
* @param array $args |
|
74
|
|
|
*/ |
|
75
|
|
|
public function register( $args ) { |
|
76
|
|
|
$args_default = array( |
|
77
|
|
|
'id' => '', |
|
78
|
|
|
'version' => '', |
|
79
|
|
|
'callback' => '', |
|
80
|
|
|
); |
|
81
|
|
|
|
|
82
|
|
|
$args = wp_parse_args( $args, $args_default ); |
|
83
|
|
|
|
|
84
|
|
|
// You can only register database upgrade. |
|
85
|
|
|
$args['type'] = 'database'; |
|
86
|
|
|
|
|
87
|
|
|
// Bailout. |
|
88
|
|
|
if ( empty( $args['id'] ) || empty( $args['version'] ) || empty( $args['callback'] ) || ! is_callable( $args['callback'] ) ) { |
|
89
|
|
|
return; |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
self::$updates[ $args['type'] ][] = $args; |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* Get updates. |
|
98
|
|
|
* |
|
99
|
|
|
* @since 1.8.12 |
|
100
|
|
|
* @access public |
|
101
|
|
|
* |
|
102
|
|
|
* @param string $update_type Tye of update. |
|
103
|
|
|
* @param string $status Tye of update. |
|
104
|
|
|
* |
|
105
|
|
|
* @return array |
|
106
|
|
|
*/ |
|
107
|
|
|
public function get_updates( $update_type = '', $status = 'all' ) { |
|
108
|
|
|
// return all updates. |
|
109
|
|
|
if ( empty( $update_type ) ) { |
|
110
|
|
|
return self::$updates; |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
// Get specific update. |
|
114
|
|
|
$updates = ! empty( self::$updates[ $update_type ] ) ? self::$updates[ $update_type ] : array(); |
|
115
|
|
|
|
|
116
|
|
|
// Bailout. |
|
117
|
|
|
if ( empty( $updates ) ) { |
|
118
|
|
|
return $updates; |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
|
switch ( $status ) { |
|
122
|
|
|
case 'new': |
|
123
|
|
|
// Remove already completed updates. |
|
124
|
|
|
|
|
125
|
|
|
$completed_updates = give_get_completed_upgrades(); |
|
126
|
|
|
|
|
127
|
|
|
if ( ! empty( $completed_updates ) ) { |
|
128
|
|
|
foreach ( $updates as $index => $update ) { |
|
129
|
|
|
if ( in_array( $update['id'], $completed_updates ) ) { |
|
130
|
|
|
unset( $updates[ $index ] ); |
|
131
|
|
|
} |
|
132
|
|
|
} |
|
133
|
|
|
$updates = array_values( $updates ); |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
break; |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
return $updates; |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
|
|
143
|
|
|
/** |
|
144
|
|
|
* Get instance. |
|
145
|
|
|
* |
|
146
|
|
|
* @since |
|
147
|
|
|
* @access static |
|
148
|
|
|
* @return static |
|
149
|
|
|
*/ |
|
150
|
|
|
static function get_instance() { |
|
|
|
|
|
|
151
|
|
|
if ( null === static::$instance ) { |
|
|
|
|
|
|
152
|
|
|
self::$instance = new static(); |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
return self::$instance; |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* |
|
160
|
|
|
* Setup hook |
|
161
|
|
|
* |
|
162
|
|
|
* @since 1.8.12 |
|
163
|
|
|
* @access public |
|
164
|
|
|
* |
|
165
|
|
|
*/ |
|
166
|
|
|
public function setup() { |
|
167
|
|
|
/** |
|
168
|
|
|
* Setup hooks. |
|
169
|
|
|
*/ |
|
170
|
|
|
add_action( 'init', array( $this, '__register_upgrade' ), 9999 ); |
|
171
|
|
|
add_action( 'admin_init', array( $this, '__change_donations_label' ), 9999 ); |
|
172
|
|
|
add_action( 'admin_menu', array( $this, '__register_menu' ), 9999 ); |
|
173
|
|
|
add_action( 'give_set_upgrade_completed', array( $this, '__flush_resume_updates' ), 9999 ); |
|
174
|
|
|
add_action( 'wp_ajax_give_do_ajax_updates', array( $this, '__give_ajax_updates' ) ); |
|
175
|
|
|
|
|
176
|
|
|
/** |
|
177
|
|
|
* Load file |
|
178
|
|
|
*/ |
|
179
|
|
|
require_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/upgrade-functions.php'; |
|
180
|
|
|
} |
|
181
|
|
|
|
|
182
|
|
|
/** |
|
183
|
|
|
* Register plugin addon updates |
|
184
|
|
|
* |
|
185
|
|
|
* @since 1.8.12 |
|
186
|
|
|
* @access public |
|
187
|
|
|
*/ |
|
188
|
|
|
public function __register_plugin_addon_updates() { |
|
189
|
|
|
$addons = give_get_plugins(); |
|
190
|
|
|
$plugin_updates = get_plugin_updates(); |
|
191
|
|
|
|
|
192
|
|
|
foreach ( $addons as $key => $info ) { |
|
193
|
|
|
if ( 'active' != $info['Status'] || 'add-on' != $info['Type'] || empty( $plugin_updates[ $key ] ) ) { |
|
194
|
|
|
continue; |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
self::$updates['plugin'][] = array_merge( $info, (array) $plugin_updates[ $key ] ); |
|
198
|
|
|
} |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
|
|
202
|
|
|
/** |
|
203
|
|
|
* Fire custom aciton hook to register updates |
|
204
|
|
|
* |
|
205
|
|
|
* @since 1.8.12 |
|
206
|
|
|
* @access public |
|
207
|
|
|
*/ |
|
208
|
|
|
public function __register_upgrade() { |
|
209
|
|
|
if ( ! is_admin() ) { |
|
210
|
|
|
return; |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
/** |
|
214
|
|
|
* Fire the hook |
|
215
|
|
|
* |
|
216
|
|
|
* @since 1.8.12 |
|
217
|
|
|
*/ |
|
218
|
|
|
do_action( 'give_register_updates', $this ); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
/** |
|
222
|
|
|
* Rename `Donations` menu title if updates exists |
|
223
|
|
|
* |
|
224
|
|
|
* @since 1.8.12 |
|
225
|
|
|
* @access public |
|
226
|
|
|
*/ |
|
227
|
|
|
function __change_donations_label() { |
|
|
|
|
|
|
228
|
|
|
global $menu; |
|
|
|
|
|
|
229
|
|
|
global $submenu; |
|
|
|
|
|
|
230
|
|
|
|
|
231
|
|
|
// Bailout. |
|
232
|
|
|
if ( empty( $menu ) || ! $this->get_update_count() ) { |
|
233
|
|
|
return; |
|
234
|
|
|
} |
|
235
|
|
|
|
|
236
|
|
|
foreach ( $menu as $index => $menu_item ) { |
|
237
|
|
|
if ( 'edit.php?post_type=give_forms' !== $menu_item[2] ) { |
|
238
|
|
|
continue; |
|
239
|
|
|
} |
|
240
|
|
|
|
|
241
|
|
|
$menu[ $index ][0] = sprintf( |
|
242
|
|
|
__( 'Donations <span class="update-plugins count-%1$d"><span class="plugin-count">%1$d</span></span>', 'give' ), |
|
243
|
|
|
$this->get_update_count() |
|
244
|
|
|
); |
|
245
|
|
|
|
|
246
|
|
|
break; |
|
247
|
|
|
} |
|
248
|
|
|
} |
|
249
|
|
|
|
|
250
|
|
|
/** |
|
251
|
|
|
* Register updates menu |
|
252
|
|
|
* |
|
253
|
|
|
* @since 1.8.12 |
|
254
|
|
|
* @access public |
|
255
|
|
|
*/ |
|
256
|
|
|
public function __register_menu() { |
|
257
|
|
|
// Load plugin updates. |
|
258
|
|
|
$this->__register_plugin_addon_updates(); |
|
259
|
|
|
|
|
260
|
|
|
// Bailout. |
|
261
|
|
|
if ( ! $this->get_update_count() ) { |
|
262
|
|
|
return; |
|
263
|
|
|
} |
|
264
|
|
|
|
|
265
|
|
|
//Upgrades |
|
266
|
|
|
add_submenu_page( |
|
267
|
|
|
'edit.php?post_type=give_forms', |
|
268
|
|
|
esc_html__( 'Give Updates', 'give' ), |
|
269
|
|
|
sprintf( |
|
270
|
|
|
'%1$s <span class="update-plugins count-%2$d"><span class="plugin-count">%2$d</span></span>', |
|
271
|
|
|
__( 'Updates', 'give' ), |
|
272
|
|
|
$this->get_update_count() |
|
273
|
|
|
), |
|
274
|
|
|
'manage_give_settings', |
|
275
|
|
|
'give-updates', |
|
276
|
|
|
array( $this, 'render_page' ) |
|
277
|
|
|
); |
|
278
|
|
|
} |
|
279
|
|
|
|
|
280
|
|
|
/** |
|
281
|
|
|
* Get tottal updates count |
|
282
|
|
|
* |
|
283
|
|
|
* @since 1.8.12 |
|
284
|
|
|
* @access public |
|
285
|
|
|
* @return int |
|
286
|
|
|
*/ |
|
287
|
|
|
public function get_db_update_count() { |
|
288
|
|
|
return count( $this->get_updates( 'database', 'new' ) ); |
|
289
|
|
|
} |
|
290
|
|
|
|
|
291
|
|
|
|
|
292
|
|
|
/** |
|
293
|
|
|
* Render Give Updates page |
|
294
|
|
|
* |
|
295
|
|
|
* @since 1.8.12 |
|
296
|
|
|
* @access public |
|
297
|
|
|
*/ |
|
298
|
|
|
public function render_page() { |
|
299
|
|
|
include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php'; |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
/** |
|
303
|
|
|
* Get addon update count. |
|
304
|
|
|
* |
|
305
|
|
|
* @since 1.8.12 |
|
306
|
|
|
* @access public |
|
307
|
|
|
* @return int |
|
308
|
|
|
*/ |
|
309
|
|
|
public function get_plugin_update_count() { |
|
310
|
|
|
return count( $this->get_updates( 'plugin' ) ); |
|
311
|
|
|
} |
|
312
|
|
|
|
|
313
|
|
|
/** |
|
314
|
|
|
* Get total update count |
|
315
|
|
|
* |
|
316
|
|
|
* @since 1.8.12 |
|
317
|
|
|
* @access public |
|
318
|
|
|
* |
|
319
|
|
|
* @return int |
|
320
|
|
|
*/ |
|
321
|
|
|
public function get_update_count() { |
|
322
|
|
|
$db_update_count = $this->get_db_update_count(); |
|
323
|
|
|
$plugin_update_count = $this->get_plugin_update_count(); |
|
324
|
|
|
|
|
325
|
|
|
return ( $db_update_count + $plugin_update_count ); |
|
326
|
|
|
} |
|
327
|
|
|
|
|
328
|
|
|
|
|
329
|
|
|
/** |
|
330
|
|
|
* Delete resume updates |
|
331
|
|
|
* |
|
332
|
|
|
* @since 1.8.12 |
|
333
|
|
|
* @access public |
|
334
|
|
|
*/ |
|
335
|
|
|
public function __flush_resume_updates() { |
|
336
|
|
|
delete_option( 'give_doing_upgrade' ); |
|
337
|
|
|
update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) ); |
|
338
|
|
|
|
|
339
|
|
|
// Reset counter. |
|
340
|
|
|
self::$step = self::$percentage = 0; |
|
341
|
|
|
++ self::$update; |
|
342
|
|
|
} |
|
343
|
|
|
|
|
344
|
|
|
/** |
|
345
|
|
|
* Process give updates. |
|
346
|
|
|
* |
|
347
|
|
|
* @since 1.8.12 |
|
348
|
|
|
* @access public |
|
349
|
|
|
*/ |
|
350
|
|
|
public function __give_ajax_updates() { |
|
351
|
|
|
// Check permission. |
|
352
|
|
|
if ( ! current_user_can( 'manage_give_settings' ) ) { |
|
353
|
|
|
$this->send_ajax_response( |
|
354
|
|
|
array( |
|
355
|
|
|
'message' => esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), |
|
356
|
|
|
), |
|
357
|
|
|
'error' |
|
358
|
|
|
); |
|
359
|
|
|
} |
|
360
|
|
|
|
|
361
|
|
|
// Update timeout error. |
|
362
|
|
|
ignore_user_abort( true ); |
|
363
|
|
|
if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { |
|
364
|
|
|
@set_time_limit( 0 ); |
|
365
|
|
|
} |
|
366
|
|
|
|
|
367
|
|
|
// Set params. |
|
368
|
|
|
self::$step = absint( $_POST['step'] ); |
|
369
|
|
|
self::$update = absint( $_POST['update'] ); |
|
370
|
|
|
|
|
371
|
|
|
// Bailout: step and update must be positive and greater then zero. |
|
372
|
|
|
if ( ! self::$step ) { |
|
373
|
|
|
$this->send_ajax_response( |
|
374
|
|
|
array( |
|
375
|
|
|
'message' => __( 'Error: please reload this page and try again', 'give' ), |
|
376
|
|
|
'heading' => '', |
|
377
|
|
|
'percentage' => 0, |
|
378
|
|
|
), |
|
379
|
|
|
'error' |
|
380
|
|
|
); |
|
381
|
|
|
} |
|
382
|
|
|
|
|
383
|
|
|
// Get updates. |
|
384
|
|
|
// $all_updates = $this->get_updates( 'database' ); |
|
|
|
|
|
|
385
|
|
|
$updates = $this->get_updates( 'database', 'new' ); |
|
386
|
|
|
|
|
387
|
|
|
|
|
388
|
|
|
// Bailout if we do not have nay updates. |
|
389
|
|
|
if ( empty( $updates ) ) { |
|
390
|
|
|
$this->send_ajax_response( |
|
391
|
|
|
array( |
|
392
|
|
|
'message' => __( 'Database already up to date.', 'give' ), |
|
393
|
|
|
'heading' => '', |
|
394
|
|
|
'percentage' => 0, |
|
395
|
|
|
), |
|
396
|
|
|
'success' |
|
397
|
|
|
); |
|
398
|
|
|
} |
|
399
|
|
|
|
|
400
|
|
|
// Process update. |
|
401
|
|
|
foreach ( $updates as $index => $update ) { |
|
402
|
|
|
// Check if update depend upon any other update. |
|
403
|
|
|
if ( ! empty( $update['depend'] ) && ! give_has_upgrade_completed( $update['depend'] ) ) { |
|
404
|
|
|
continue; |
|
405
|
|
|
} |
|
406
|
|
|
|
|
407
|
|
|
// Run update. |
|
408
|
|
|
if ( is_array( $update['callback'] ) ) { |
|
409
|
|
|
$update['callback'][0]->$update['callback'][1](); |
|
410
|
|
|
} else { |
|
411
|
|
|
$update['callback'](); |
|
412
|
|
|
} |
|
413
|
|
|
|
|
414
|
|
|
// Check if current update completed or not. |
|
415
|
|
|
if ( give_has_upgrade_completed( $update['id'] ) ) { |
|
416
|
|
|
if ( 1 === count( $updates ) ) { |
|
417
|
|
|
$this->send_ajax_response( |
|
418
|
|
|
array( |
|
419
|
|
|
'message' => __( 'Database updated successfully.', 'give' ), |
|
420
|
|
|
'heading' => '', |
|
421
|
|
|
'percentage' => 0, |
|
422
|
|
|
), |
|
423
|
|
|
'success' |
|
424
|
|
|
); |
|
425
|
|
|
} |
|
426
|
|
|
} |
|
427
|
|
|
|
|
428
|
|
|
// Verify percentage. |
|
429
|
|
|
self::$percentage = ( 100 < self::$percentage ) ? 100 : self::$percentage; |
|
430
|
|
|
|
|
431
|
|
|
$doing_upgrade_args = array( |
|
432
|
|
|
'update_info' => $update, |
|
433
|
|
|
'step' => ++ self::$step, |
|
434
|
|
|
'update' => self::$update, |
|
435
|
|
|
'heading' => sprintf( 'Update %s of {update_count}', self::$update ), |
|
436
|
|
|
'percentage' => self::$percentage, |
|
437
|
|
|
); |
|
438
|
|
|
|
|
439
|
|
|
// Cache upgrade. |
|
440
|
|
|
update_option( 'give_doing_upgrade', $doing_upgrade_args ); |
|
441
|
|
|
|
|
442
|
|
|
$this->send_ajax_response( $doing_upgrade_args ); |
|
443
|
|
|
} |
|
444
|
|
|
} |
|
445
|
|
|
|
|
446
|
|
|
/** |
|
447
|
|
|
* Send ajax response |
|
448
|
|
|
* |
|
449
|
|
|
* @since 1.8.12 |
|
450
|
|
|
* @access public |
|
451
|
|
|
* |
|
452
|
|
|
* @param $data |
|
453
|
|
|
* @param string $type |
|
454
|
|
|
*/ |
|
455
|
|
|
public function send_ajax_response( $data, $type = '' ) { |
|
456
|
|
|
$default = array( |
|
457
|
|
|
'message' => '', |
|
458
|
|
|
'heading' => '', |
|
459
|
|
|
'percentage' => 0, |
|
460
|
|
|
'step' => 0, |
|
461
|
|
|
'update' => 0, |
|
462
|
|
|
); |
|
463
|
|
|
|
|
464
|
|
|
// Set data. |
|
465
|
|
|
$data = wp_parse_args( $data, $default ); |
|
466
|
|
|
|
|
467
|
|
|
switch ( $type ) { |
|
468
|
|
|
case 'success': |
|
469
|
|
|
wp_send_json_success( $data ); |
|
470
|
|
|
break; |
|
471
|
|
|
|
|
472
|
|
|
case 'error': |
|
473
|
|
|
wp_send_json_success( $data ); |
|
474
|
|
|
break; |
|
475
|
|
|
|
|
476
|
|
|
default: |
|
477
|
|
|
wp_send_json( array( 'data' => $data ) ); |
|
478
|
|
|
break; |
|
479
|
|
|
} |
|
480
|
|
|
} |
|
481
|
|
|
|
|
482
|
|
|
|
|
483
|
|
|
/** |
|
484
|
|
|
* Resume updates |
|
485
|
|
|
* @since 1.8.12 |
|
486
|
|
|
* @access public |
|
487
|
|
|
* |
|
488
|
|
|
* @return bool|int |
|
489
|
|
|
*/ |
|
490
|
|
|
public function resume_updates() { |
|
491
|
|
|
$status = false; |
|
492
|
|
|
|
|
493
|
|
|
if ( $update = get_option( 'give_doing_upgrade' ) ) { |
|
494
|
|
|
$status = ! empty( $update['step'] ) ? $update['step'] : $status; |
|
495
|
|
|
} |
|
496
|
|
|
|
|
497
|
|
|
return $status; |
|
498
|
|
|
} |
|
499
|
|
|
} |
|
500
|
|
|
|
|
501
|
|
|
Give_Updates::get_instance()->setup(); |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.