GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#936)
by Tom
02:44
created

Scheduled_Backup::get_schedule_start_time()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 21
rs 9.0534
cc 4
eloc 11
nc 5
nop 1
1
<?php
2
3
namespace HM\BackUpWordPress;
4
5
/**
6
 * The Backup Scheduler
7
 *
8
 * Handles everything related to managing and running a backup schedule
9
 *
10
 * @uses Backup
11
 * @uses
12
 */
13
class Scheduled_Backup {
14
15
	/**
16
	 * The unique schedule id
17
	 *
18
	 * @var string
19
	 * @access private
20
	 */
21
	private $id = '';
22
23
	/**
24
	 * The slugified version of the schedule name
25
	 *
26
	 * @var string
27
	 * @access private
28
	 */
29
	private $slug = '';
30
31
	/**
32
	 * The raw schedule options from the database
33
	 *
34
	 * @var array
35
	 * @access private
36
	 */
37
	private $options = array(
38
		'max_backups'   => 3,
39
		'excludes'      => array(),
40
		'type'          => 'complete',
41
		'reoccurrence'  => 'manually'
42
	);
43
44
	/**
45
	 * Setup the schedule object
46
	 * Loads the options from the database and populates properties
47
	 *
48
	 * @param string $id
49
	 *
50
	 * @throws Exception
51
	 */
52
53
	public function __construct( $id ) {
54
55
		// Verify the schedule id
56
		if ( ! is_string( $id ) || ! trim( $id ) ) {
57
			throw new \Exception( 'Argument 1 for ' . __METHOD__ . ' must be a non-empty string' );
58
		}
59
60
		// Store id for later
61
		$this->id = $id;
62
63
		// Load the options
64
		$this->options = array_merge( $this->options, array_filter( (array) get_option( 'hmbkp_schedule_' . $this->get_id() ) ) );
65
66
		if ( defined( 'HMBKP_SCHEDULE_START_TIME' ) && strtotime( 'HMBKP_SCHEDULE_START_TIME' ) ) {
67
			$this->set_schedule_start_time( strtotime( 'HMBKP_SCHEDULE_START_TIME' ) );
0 ignored issues
show
Documentation introduced by
strtotime('HMBKP_SCHEDULE_START_TIME') is of type integer, but the function expects a object<HM\BackUpWordPress\timestamp>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
68
		}
69
70
		// Setup the schedule if it isn't set
71
		if ( ( ! $this->is_cron_scheduled() && $this->get_reoccurrence() !== 'manually' ) ) {
72
			$this->schedule();
73
		}
74
75
		$this->backup_filename = implode( '-', array(
0 ignored issues
show
Bug introduced by
The property backup_filename does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
76
			sanitize_title( str_ireplace( array(
77
				'http://',
78
				'https://',
79
				'www'
80
			), '', home_url() ) ),
81
			$this->get_id(),
82
			$this->get_type(),
83
			current_time( 'Y-m-d-H-i-s' )
84
		) ) . '.zip';
85
86
		$this->database_dump_filename = implode( '-', array(
0 ignored issues
show
Bug introduced by
The property database_dump_filename does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
87
			'database',
88
			sanitize_title( str_ireplace( array( 'http://', 'https://', 'www' ), '', home_url() ) ),
89
			$this->get_id()
90
		) ) . '.sql';
91
92
		$this->status = new Backup_Status( $this->get_id() );
0 ignored issues
show
Bug introduced by
The property status does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
93
94
	}
95
96
	/**
97
	 * Get the id for this schedule
98
	 */
99
	public function get_id() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
100
		return esc_attr( $this->id );
101
	}
102
103
	/**
104
	 * Get a slugified version of name
105
	 */
106
	public function get_slug() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
107
108
		// We cache slug in $this to save expensive calls to sanitize_title
109
		if ( ! empty( $this->slug ) ) {
110
			return $this->slug;
111
		}
112
113
		return $this->slug = sanitize_title( $this->get_name() );
114
115
	}
116
117
	/**
118
	 * Returns the given option value
119
	 *
120
	 * @param $option_name
121
	 * @return mixed The option value
122
	 */
123
	public function get_schedule_option( $option_name ) {
124
		if ( isset( $this->options[ $option_name ] ) ) {
125
			return $this->options[ $option_name ];
126
		}
127
	}
128
129
	/**
130
	 * Get the name of this backup schedule
131
	 *
132
	 * @return string
133
	 */
134
	public function get_name() {
135
		return ucwords( $this->get_type() ) . ' ' . $this->get_reoccurrence();
136
	}
137
138
	/**
139
	 * Get the type of backup
140
	 *
141
	 * @return string
142
	 */
143
	public function get_type() {
144
		return $this->options['type'];
145
	}
146
147
	/**
148
	 * Set the type of backup
149
	 *
150
	 * @param string $type
151
	 */
152
	public function set_type( $type ) {
153
		if ( ! isset( $this->options['type'] ) || $this->options['type'] !== $type ) {
154
			$this->options['type'] = $type;
155
		}
156
	}
157
158
	/**
159
	 * Get the exclude rules
160
	 *
161
	 * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be Excludes?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
162
	 */
163
	public function get_excludes() {
164
		return new Excludes( $this->options['excludes'] );
165
	}
166
167
	/**
168
	 * Set the exclude rules
169
	 *
170
	 * @param mixed $excludes A comma separated list or array of exclude rules
0 ignored issues
show
Bug introduced by
There is no parameter named $excludes. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
171
	 * @param bool $append Whether to replace or append to existing rules
172
	 *
173
	 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
174
	 */
175
	public function set_excludes( $exclude_rules, $append = false ) {
176
177
		// Normalize the exclude rules before we save them
178
		$excludes = new Excludes;
179
		$excludes = $excludes->normalize( (array) $exclude_rules );
180
181
		// If these are valid excludes and they are different save them
182
		if ( empty( $this->options['excludes'] ) || $this->options['excludes'] !== $excludes ) {
183
			$this->options['excludes'] = $append && ! empty( $this->options['excludes'] ) ? array_merge( (array) $this->options['excludes'], (array) $excludes ) : (array) $excludes;
184
		}
185
186
	}
187
188
	/**
189
	 * Get the maximum number of backups to keep
190
	 *
191
	 * @return int
192
	 */
193
	public function get_max_backups() {
194
		return (int) $this->options['max_backups'];
195
	}
196
197
	/**
198
	 * Set the maximum number of backups to keep
199
	 *
200
	 * @param int $max
201
	 *
202
	 * @return WP_Error|boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be WP_Error|boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
203
	 */
204
	public function set_max_backups( $max ) {
205
		$this->options['max_backups'] = $max;
206
	}
207
208
	public function get_status() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
209
		return $this->status;
210
	}
211
212
	/**
213
	 * Get the array of services options for this schedule
214
	 *
215
	 * @param      $service
216
	 * @param null $option
217
	 *
218
	 * @return array
219
	 */
220
	public function get_service_options( $service, $option = null ) {
221
222
		if ( ! is_null( $option ) ) {
223
224
			if ( isset( $this->options[ $service ][ $option ] ) ) {
225
				return $this->options[ $service ][ $option ];
226
			}
227
228
			return array();
229
230
		}
231
232
		if ( isset( $this->options[ $service ] ) ) {
233
			return $this->options[ $service ];
234
		}
235
236
		return array();
237
238
	}
239
240
	/**
241
	 * Set the service options for this schedule
242
	 *
243
	 * @param $service
244
	 * @param array $options
245
	 */
246
	public function set_service_options( $service, Array $options ) {
247
		$this->options[ $service ] = $options;
248
	}
249
250
	/**
251
	 * Get the start time for the schedule
252
	 *
253
	 * @return int timestamp || 0 for manual only schedules
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
254
	 */
255
	public function get_schedule_start_time( $gmt = true ) {
256
257
		if ( 'manually' === $this->get_reoccurrence() ) {
258
			return 0;
259
		}
260
261
		if ( ! $gmt ) {
262
			$offset = get_option( 'gmt_offset' ) * 3600;
263
		} else {
264
			$offset = 0;
265
		}
266
267
		if ( ! empty( $this->options['schedule_start_time'] ) ) {
268
			return $this->options['schedule_start_time'] + $offset;
269
		}
270
271
		$this->set_schedule_start_time( time() );
0 ignored issues
show
Documentation introduced by
time() is of type integer, but the function expects a object<HM\BackUpWordPress\timestamp>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
272
273
		return time() + $offset;
274
275
	}
276
277
	/**
278
	 * Set the schedule start time.
279
	 *
280
	 * @param timestamp $time
281
	 */
282
	public function set_schedule_start_time( $time ) {
283
284
		$this->options['schedule_start_time'] = $time;
285
286
		$this->schedule();
287
288
	}
289
290
	/**
291
	 * Get the schedule reoccurrence
292
	 *
293
	 */
294
	public function get_reoccurrence() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
295
		return $this->options['reoccurrence'];
296
	}
297
298
	/**
299
	 * Set the schedule reoccurrence
300
	 *
301
	 * @param string $reoccurrence
302
	 *
303
	 * @return \WP_Error|null|boolean
304
	 */
305
	public function set_reoccurrence( $reoccurrence ) {
306
307
		$hmbkp_schedules = cron_schedules();
308
309
		// Check it's valid
310
		if ( ! is_string( $reoccurrence ) || ! trim( $reoccurrence ) || ( ! in_array( $reoccurrence, array_keys( $hmbkp_schedules ) ) ) && 'manually' !== $reoccurrence ) {
311
			return new \WP_Error( 'hmbkp_invalid_argument_error', sprintf( __( 'Argument 1 for %s must be a valid cron recurrence or "manually"', 'backupwordpress' ), __METHOD__ ) );
312
		}
313
314
		// If the recurrence is already set to the same thing then there's no need to continue
315
		if ( isset( $this->options['reoccurrence'] ) && $this->options['reoccurrence'] === $reoccurrence && $this->is_cron_scheduled() ) {
316
			return;
317
		}
318
319
320
		$this->options['reoccurrence'] = $reoccurrence;
321
322
		if ( 'manually' === $reoccurrence ) {
323
			$this->unschedule();
324
325
		} else {
326
			$this->schedule();
327
		}
328
329
		return true;
330
331
	}
332
333
	/**
334
	 * Get the interval between backups
335
	 *
336
	 * @return int
337
	 */
338
	public function get_interval() {
339
340
		$hmbkp_schedules = cron_schedules();
341
342
		if ( 'manually' === $this->get_reoccurrence() ) {
343
			return 0;
344
		}
345
346
		return $hmbkp_schedules[ $this->get_reoccurrence() ]['interval'];
347
348
	}
349
350
	/**
351
	 * Get the next occurrence of this scheduled backup
352
	 *
353
	 */
354
	public function get_next_occurrence( $gmt = true ) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
355
356
		$time = wp_next_scheduled( 'hmbkp_schedule_hook', array( 'id' => $this->get_id() ) );
357
358
		if ( ! $time ) {
359
			$time = 0;
360
		}
361
362
		if ( ! $gmt ) {
363
			$time += get_option( 'gmt_offset' ) * 3600;
364
		}
365
366
		return $time;
367
368
	}
369
370
	public function is_cron_scheduled() {
371
		return (bool) $this->get_next_occurrence();
372
	}
373
374
	/**
375
	 * Schedule the backup cron
376
	 *
377
	 */
378
	public function schedule() {
379
380
		// Clear any existing hooks
381
		$this->unschedule();
382
383
		$schedule_timestamp = $this->get_schedule_start_time();
384
385
		wp_schedule_event( $schedule_timestamp, $this->get_reoccurrence(), 'hmbkp_schedule_hook', array( 'id' => $this->get_id() ) );
386
387
	}
388
389
390
	/**
391
	 * Unschedule the backup cron.
392
	 *
393
	 * @return void
394
	 */
395
	public function unschedule() {
396
		wp_clear_scheduled_hook( 'hmbkp_schedule_hook', array( 'id' => $this->get_id() ) );
397
	}
398
399
	/**
400
	 * Run the backup
401
	 *
402
	 */
403
	public function run() {
404
405
		// Don't run if this schedule is already running
406
		if ( $this->status->is_started() ) {
407
			return;
408
		}
409
410
		// Setup our Site Backup Object
411
		$backup = new Site_Backup( $this->get_backup_filename(), $this->get_database_dump_filename() );
412
		$backup->set_type( $this->get_type() );
413
		$backup->set_excludes( $this->get_excludes() );
414
		$backup->set_status( $this->status );
415
416
		$this->do_action( 'hmbkp_backup_started', $backup );
417
418
		$this->status->start( $this->get_backup_filename(), __( 'Starting backup...', 'backupwordpress' ) );
419
420
		$this->status->set_status( __( 'Deleting old backups...', 'backupwordpress' ) );
421
422
		// Delete old backups now in-case we fatal error during the backup process
423
		$this->delete_old_backups();
424
425
		$backup->run();
426
427
		$errors = array_merge( $backup->errors, $backup->warnings );
428
		$notices = array();
429
		foreach ( $errors as $key => $error ) {
430
			$key = str_replace( array( __NAMESPACE__ . '\\', '_File_Backup_Engine', '_Database_Backup_Engine' ), array( '', '', '' ), $key );
431
			$notices[] = $key . ': ' . implode( ', ', $error );
432
		}
433
		Notices::get_instance()->set_notices( 'backup_errors', $notices );
434
435
		$this->status->set_status( __( 'Deleting old backups...', 'backupwordpress' ) );
436
437
		// Delete old backups again
438
		$this->delete_old_backups();
439
440
		$this->do_action( 'hmbkp_backup_complete', $backup );
441
442
		$this->status->finish();
443
		$this->update_average_schedule_run_time( $this->status->get_start_time(), time() );
444
445
	}
446
447
	public function get_backup_filename() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
448
449
		if ( $this->status->is_started() ) {
450
			$this->backup_filename = $this->status->get_backup_filename();
451
		}
452
453
		return $this->backup_filename;
454
	}
455
456
	public function get_database_dump_filename() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
457
		return $this->database_dump_filename;
458
	}
459
460
	/**
461
	 * Hook into the actions fired in the Backup class and set the status
462
	 *
463
	 * @param $action
464
	 */
465
	public function do_action( $action, Site_Backup $backup ) {
466
467
		// Pass the actions to all the services
468
		// Todo should be decoupled into the service class
469
		foreach ( Services::get_services( $this ) as $service ) {
470
			if ( is_wp_error( $service ) ) {
471
				return $service;
472
			}
473
			$service->action( $action, $backup );
474
		}
475
476
	}
477
478
	/**
479
	 * Calculate schedule run time.
480
	 *
481
	 * @param int Timestamp $end
482
	 */
483
	public function update_average_schedule_run_time( $start, $end ) {
484
485
		if ( $end <= $start ) {
486
			// Something went wrong, ignore.
487
			return;
488
		}
489
490
		$diff = (int) abs( $end - $start );
491
492
		if ( isset( $this->options['duration_total'] ) && isset( $this->options['backup_run_count'] ) ) {
493
494
			$this->options['duration_total'] += $diff;
495
			$this->options['backup_run_count'] ++;
496
497
		} else {
498
499
			$this->options['duration_total'] = $diff;
500
			$this->options['backup_run_count'] = 1;
501
502
		}
503
504
		$this->save();
505
	}
506
507
	/**
508
	 * Calculates the average run time for this schedule.
509
	 *
510
	 * @return string
511
	 */
512
	public function get_schedule_average_duration() {
513
514
		$duration = 'Unknown';
515
516
		if ( ! isset( $this->options['duration_total'] ) || ! isset( $this->options['backup_run_count'] ) ) {
517
			return $duration;
518
		}
519
520
		if ( 0 === (int) $this->options['backup_run_count'] ) {
521
			return $duration;
522
		}
523
524
		$average_run_time = (int) $this->options['duration_total'] / (int) $this->options['backup_run_count'];
525
526
		if ( $average_run_time < HOUR_IN_SECONDS ) {
527
528
			$mins = round( $average_run_time / MINUTE_IN_SECONDS );
529
530
			if ( $mins <= 1 ) {
531
				$mins = 1;
532
			}
533
534
			/* translators: min=minute */
535
			$duration = sprintf( _n( '%s min', '%s mins', $mins, 'backupwordpress' ), $mins );
536
537
		} elseif ( $average_run_time < DAY_IN_SECONDS && $average_run_time >= HOUR_IN_SECONDS ) {
538
539
			$hours = round( $average_run_time / HOUR_IN_SECONDS );
540
541
			if ( $hours <= 1 ) {
542
				$hours = 1;
543
			}
544
545
			$duration = sprintf( _n( '%s hour', '%s hours', $hours, 'backupwordpress' ), $hours );
546
		}
547
548
		return $duration;
549
	}
550
551
	/**
552
	 * Get the backups created by this schedule
553
	 *
554
	 * @todo   look into using recursiveDirectoryIterator and recursiveRegexIterator
555
	 * @return string[] - file paths of the backups
556
	 */
557
	public function get_backups() {
558
559
		$files = array();
560
561
		if ( $handle = @opendir( Path::get_path() ) ) {
562
563
			while ( false !== ( $file = readdir( $handle ) ) ) {
564
565
				if ( pathinfo( $file, PATHINFO_EXTENSION ) === 'zip' && strpos( $file, $this->get_id() ) !== false && ( isset( $this->status ) && $this->get_backup_filename() !== $file ) ) {
566
					$files[ @filemtime( trailingslashit( Path::get_path() ) . $file ) ] = trailingslashit( Path::get_path() ) . $file;
567
				}
568
569
			}
570
571
			closedir( $handle );
572
573
		}
574
575
		krsort( $files );
576
577
		return $files;
578
579
	}
580
581
	/**
582
	 * Delete old backups
583
	 *
584
	 * @access private
585
	 */
586
	public function delete_old_backups() {
587
588
		if ( count( $this->get_backups() ) <= $this->get_max_backups() ) {
589
			return;
590
		}
591
592
		array_map( array( $this, 'delete_backup' ), array_slice( $this->get_backups(), $this->get_max_backups() ) );
593
594
	}
595
596
	/**
597
	 * Delete a specific back up file created by this schedule
598
	 *
599
	 * @param string $filepath
600
	 *
601
	 * @return \WP_Error|boolean
602
	 */
603
	public function delete_backup( $filepath ) {
604
605
		// Check that it's a valid filepath
606
		if ( empty( $filepath ) || ! is_string( $filepath ) ) {
607
			return new \WP_Error( 'hmbkp_empty_string_error', sprintf( __( 'Argument 1 for %s must be a non-empty string', 'backupwordpress' ), __METHOD__ ) );
608
		}
609
610
		// Make sure it exists
611
		if ( ! file_exists( $filepath ) ) {
612
			return new \WP_Error( 'hmbkp_file_error', sprintf( __( '%s doesn\'t exist', 'backupwordpress' ), $filepath ) );
613
		}
614
615
		// Make sure it was created by this schedule
616
		if ( strpos( $filepath, $this->get_id() ) === false ) {
617
			return new \WP_Error( 'hmbkp_backup_error', __( 'That backup wasn\'t created by this schedule', 'backupwordpress' ) );
618
		}
619
620
		unlink( $filepath );
621
622
		return true;
623
624
	}
625
626
	/**
627
	 * Delete all back up files created by this schedule
628
	 *
629
	 */
630
	public function delete_backups() {
631
		array_map( array( $this, 'delete_backup' ), $this->get_backups() );
632
	}
633
634
	/**
635
	 * Save the schedules options.
636
	 *
637
	 */
638
	public function save() {
639
640
		// Only save them if they have changed
641
		if ( $this->options !== get_option( 'hmbkp_schedule_' . $this->get_id() ) ) {
642
			update_option( 'hmbkp_schedule_' . $this->get_id(), $this->options );
643
		}
644
645
	}
646
647
	/**
648
	 * Cancel this schedule
649
	 *
650
	 * Cancels the cron job, removes the schedules options
651
	 * and optionally deletes all backups created by
652
	 * this schedule.
653
	 *
654
	 */
655
	public function cancel( $delete_backups = false ) {
656
657
		// Delete the schedule options
658
		delete_option( 'hmbkp_schedule_' . $this->get_id() );
659
660
		// Clear any existing schedules
661
		$this->unschedule();
662
663
		// Delete it's backups
664
		if ( $delete_backups ) {
665
			$this->delete_backups();
666
		}
667
668
	}
669
670
}
671