Diff: STRATO-apps/wordpress_03/app/wp-includes/cron.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
/**
3
+
* WordPress Cron API
4
+
*
5
+
* @package WordPress
6
+
*/
7
+
8
+
/**
9
+
* Schedules an event to run only once.
10
+
*
11
+
* Schedules a hook which will be triggered by WordPress at the specified UTC time.
12
+
* The action will trigger when someone visits your WordPress site if the scheduled
13
+
* time has passed.
14
+
*
15
+
* Note that scheduling an event to occur within 10 minutes of an existing event
16
+
* with the same action hook will be ignored unless you pass unique `$args` values
17
+
* for each scheduled event.
18
+
*
19
+
* Use wp_next_scheduled() to prevent duplicate events.
20
+
*
21
+
* Use wp_schedule_event() to schedule a recurring event.
22
+
*
23
+
* @since 2.1.0
24
+
* @since 5.1.0 Return value modified to boolean indicating success or failure,
25
+
* {@see 'pre_schedule_event'} filter added to short-circuit the function.
26
+
* @since 5.7.0 The `$wp_error` parameter was added.
27
+
*
28
+
* @link https://developer.wordpress.org/reference/functions/wp_schedule_single_event/
29
+
*
30
+
* @param int $timestamp Unix timestamp (UTC) for when to next run the event.
31
+
* @param string $hook Action hook to execute when the event is run.
32
+
* @param array $args Optional. Array containing arguments to pass to the
33
+
* hook's callback function. Each value in the array
34
+
* is passed to the callback as an individual parameter.
35
+
* The array keys are ignored. Default empty array.
36
+
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
37
+
* @return bool|WP_Error True if event successfully scheduled. False or WP_Error on failure.
38
+
*/
39
+
function wp_schedule_single_event( $timestamp, $hook, $args = array(), $wp_error = false ) {
40
+
// Make sure timestamp is a positive integer.
41
+
if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) {
42
+
if ( $wp_error ) {
43
+
return new WP_Error(
44
+
'invalid_timestamp',
45
+
__( 'Event timestamp must be a valid Unix timestamp.' )
46
+
);
47
+
}
48
+
49
+
return false;
50
+
}
51
+
52
+
$event = (object) array(
53
+
'hook' => $hook,
54
+
'timestamp' => $timestamp,
55
+
'schedule' => false,
56
+
'args' => $args,
57
+
);
58
+
59
+
/**
60
+
* Filter to override scheduling an event.
61
+
*
62
+
* Returning a non-null value will short-circuit adding the event to the
63
+
* cron array, causing the function to return the filtered value instead.
64
+
*
65
+
* Both single events and recurring events are passed through this filter;
66
+
* single events have `$event->schedule` as false, whereas recurring events
67
+
* have this set to a recurrence from wp_get_schedules(). Recurring
68
+
* events also have the integer recurrence interval set as `$event->interval`.
69
+
*
70
+
* For plugins replacing wp-cron, it is recommended you check for an
71
+
* identical event within ten minutes and apply the {@see 'schedule_event'}
72
+
* filter to check if another plugin has disallowed the event before scheduling.
73
+
*
74
+
* Return true if the event was scheduled, false or a WP_Error if not.
75
+
*
76
+
* @since 5.1.0
77
+
* @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned.
78
+
*
79
+
* @param null|bool|WP_Error $result The value to return instead. Default null to continue adding the event.
80
+
* @param object $event {
81
+
* An object containing an event's data.
82
+
*
83
+
* @type string $hook Action hook to execute when the event is run.
84
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
85
+
* @type string|false $schedule How often the event should subsequently recur.
86
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
87
+
* @type int $interval Optional. The interval time in seconds for the schedule. Only present for recurring events.
88
+
* }
89
+
* @param bool $wp_error Whether to return a WP_Error on failure.
90
+
*/
91
+
$pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error );
92
+
93
+
if ( null !== $pre ) {
94
+
if ( $wp_error && false === $pre ) {
95
+
return new WP_Error(
96
+
'pre_schedule_event_false',
97
+
__( 'A plugin prevented the event from being scheduled.' )
98
+
);
99
+
}
100
+
101
+
if ( ! $wp_error && is_wp_error( $pre ) ) {
102
+
return false;
103
+
}
104
+
105
+
return $pre;
106
+
}
107
+
108
+
/*
109
+
* Check for a duplicated event.
110
+
*
111
+
* Don't schedule an event if there's already an identical event
112
+
* within 10 minutes.
113
+
*
114
+
* When scheduling events within ten minutes of the current time,
115
+
* all past identical events are considered duplicates.
116
+
*
117
+
* When scheduling an event with a past timestamp (ie, before the
118
+
* current time) all events scheduled within the next ten minutes
119
+
* are considered duplicates.
120
+
*/
121
+
$crons = _get_cron_array();
122
+
123
+
$key = md5( serialize( $event->args ) );
124
+
$duplicate = false;
125
+
126
+
if ( $event->timestamp < time() + 10 * MINUTE_IN_SECONDS ) {
127
+
$min_timestamp = 0;
128
+
} else {
129
+
$min_timestamp = $event->timestamp - 10 * MINUTE_IN_SECONDS;
130
+
}
131
+
132
+
if ( $event->timestamp < time() ) {
133
+
$max_timestamp = time() + 10 * MINUTE_IN_SECONDS;
134
+
} else {
135
+
$max_timestamp = $event->timestamp + 10 * MINUTE_IN_SECONDS;
136
+
}
137
+
138
+
foreach ( $crons as $event_timestamp => $cron ) {
139
+
if ( $event_timestamp < $min_timestamp ) {
140
+
continue;
141
+
}
142
+
143
+
if ( $event_timestamp > $max_timestamp ) {
144
+
break;
145
+
}
146
+
147
+
if ( isset( $cron[ $event->hook ][ $key ] ) ) {
148
+
$duplicate = true;
149
+
break;
150
+
}
151
+
}
152
+
153
+
if ( $duplicate ) {
154
+
if ( $wp_error ) {
155
+
return new WP_Error(
156
+
'duplicate_event',
157
+
__( 'A duplicate event already exists.' )
158
+
);
159
+
}
160
+
161
+
return false;
162
+
}
163
+
164
+
/**
165
+
* Modify an event before it is scheduled.
166
+
*
167
+
* @since 3.1.0
168
+
*
169
+
* @param object|false $event {
170
+
* An object containing an event's data, or boolean false to prevent the event from being scheduled.
171
+
*
172
+
* @type string $hook Action hook to execute when the event is run.
173
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
174
+
* @type string|false $schedule How often the event should subsequently recur.
175
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
176
+
* @type int $interval Optional. The interval time in seconds for the schedule. Only present for recurring events.
177
+
* }
178
+
*/
179
+
$event = apply_filters( 'schedule_event', $event );
180
+
181
+
// A plugin disallowed this event.
182
+
if ( ! $event ) {
183
+
if ( $wp_error ) {
184
+
return new WP_Error(
185
+
'schedule_event_false',
186
+
__( 'A plugin disallowed this event.' )
187
+
);
188
+
}
189
+
190
+
return false;
191
+
}
192
+
193
+
$crons[ $event->timestamp ][ $event->hook ][ $key ] = array(
194
+
'schedule' => $event->schedule,
195
+
'args' => $event->args,
196
+
);
197
+
uksort( $crons, 'strnatcasecmp' );
198
+
199
+
return _set_cron_array( $crons, $wp_error );
200
+
}
201
+
202
+
/**
203
+
* Schedules a recurring event.
204
+
*
205
+
* Schedules a hook which will be triggered by WordPress at the specified interval.
206
+
* The action will trigger when someone visits your WordPress site if the scheduled
207
+
* time has passed.
208
+
*
209
+
* Valid values for the recurrence are 'hourly', 'twicedaily', 'daily', and 'weekly'.
210
+
* These can be extended using the {@see 'cron_schedules'} filter in wp_get_schedules().
211
+
*
212
+
* Use wp_next_scheduled() to prevent duplicate events.
213
+
*
214
+
* Use wp_schedule_single_event() to schedule a non-recurring event.
215
+
*
216
+
* @since 2.1.0
217
+
* @since 5.1.0 Return value modified to boolean indicating success or failure,
218
+
* {@see 'pre_schedule_event'} filter added to short-circuit the function.
219
+
* @since 5.7.0 The `$wp_error` parameter was added.
220
+
*
221
+
* @link https://developer.wordpress.org/reference/functions/wp_schedule_event/
222
+
*
223
+
* @param int $timestamp Unix timestamp (UTC) for when to next run the event.
224
+
* @param string $recurrence How often the event should subsequently recur.
225
+
* See wp_get_schedules() for accepted values.
226
+
* @param string $hook Action hook to execute when the event is run.
227
+
* @param array $args Optional. Array containing arguments to pass to the
228
+
* hook's callback function. Each value in the array
229
+
* is passed to the callback as an individual parameter.
230
+
* The array keys are ignored. Default empty array.
231
+
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
232
+
* @return bool|WP_Error True if event successfully scheduled. False or WP_Error on failure.
233
+
*/
234
+
function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array(), $wp_error = false ) {
235
+
// Make sure timestamp is a positive integer.
236
+
if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) {
237
+
if ( $wp_error ) {
238
+
return new WP_Error(
239
+
'invalid_timestamp',
240
+
__( 'Event timestamp must be a valid Unix timestamp.' )
241
+
);
242
+
}
243
+
244
+
return false;
245
+
}
246
+
247
+
$schedules = wp_get_schedules();
248
+
249
+
if ( ! isset( $schedules[ $recurrence ] ) ) {
250
+
if ( $wp_error ) {
251
+
return new WP_Error(
252
+
'invalid_schedule',
253
+
__( 'Event schedule does not exist.' )
254
+
);
255
+
}
256
+
257
+
return false;
258
+
}
259
+
260
+
$event = (object) array(
261
+
'hook' => $hook,
262
+
'timestamp' => $timestamp,
263
+
'schedule' => $recurrence,
264
+
'args' => $args,
265
+
'interval' => $schedules[ $recurrence ]['interval'],
266
+
);
267
+
268
+
/** This filter is documented in wp-includes/cron.php */
269
+
$pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error );
270
+
271
+
if ( null !== $pre ) {
272
+
if ( $wp_error && false === $pre ) {
273
+
return new WP_Error(
274
+
'pre_schedule_event_false',
275
+
__( 'A plugin prevented the event from being scheduled.' )
276
+
);
277
+
}
278
+
279
+
if ( ! $wp_error && is_wp_error( $pre ) ) {
280
+
return false;
281
+
}
282
+
283
+
return $pre;
284
+
}
285
+
286
+
/** This filter is documented in wp-includes/cron.php */
287
+
$event = apply_filters( 'schedule_event', $event );
288
+
289
+
// A plugin disallowed this event.
290
+
if ( ! $event ) {
291
+
if ( $wp_error ) {
292
+
return new WP_Error(
293
+
'schedule_event_false',
294
+
__( 'A plugin disallowed this event.' )
295
+
);
296
+
}
297
+
298
+
return false;
299
+
}
300
+
301
+
$key = md5( serialize( $event->args ) );
302
+
303
+
$crons = _get_cron_array();
304
+
305
+
$crons[ $event->timestamp ][ $event->hook ][ $key ] = array(
306
+
'schedule' => $event->schedule,
307
+
'args' => $event->args,
308
+
'interval' => $event->interval,
309
+
);
310
+
uksort( $crons, 'strnatcasecmp' );
311
+
312
+
return _set_cron_array( $crons, $wp_error );
313
+
}
314
+
315
+
/**
316
+
* Reschedules a recurring event.
317
+
*
318
+
* Mainly for internal use, this takes the Unix timestamp (UTC) of a previously run
319
+
* recurring event and reschedules it for its next run.
320
+
*
321
+
* To change upcoming scheduled events, use wp_schedule_event() to
322
+
* change the recurrence frequency.
323
+
*
324
+
* @since 2.1.0
325
+
* @since 5.1.0 Return value modified to boolean indicating success or failure,
326
+
* {@see 'pre_reschedule_event'} filter added to short-circuit the function.
327
+
* @since 5.7.0 The `$wp_error` parameter was added.
328
+
*
329
+
* @param int $timestamp Unix timestamp (UTC) for when the event was scheduled.
330
+
* @param string $recurrence How often the event should subsequently recur.
331
+
* See wp_get_schedules() for accepted values.
332
+
* @param string $hook Action hook to execute when the event is run.
333
+
* @param array $args Optional. Array containing arguments to pass to the
334
+
* hook's callback function. Each value in the array
335
+
* is passed to the callback as an individual parameter.
336
+
* The array keys are ignored. Default empty array.
337
+
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
338
+
* @return bool|WP_Error True if event successfully rescheduled. False or WP_Error on failure.
339
+
*/
340
+
function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array(), $wp_error = false ) {
341
+
// Make sure timestamp is a positive integer.
342
+
if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) {
343
+
if ( $wp_error ) {
344
+
return new WP_Error(
345
+
'invalid_timestamp',
346
+
__( 'Event timestamp must be a valid Unix timestamp.' )
347
+
);
348
+
}
349
+
350
+
return false;
351
+
}
352
+
353
+
$schedules = wp_get_schedules();
354
+
$interval = 0;
355
+
356
+
// First we try to get the interval from the schedule.
357
+
if ( isset( $schedules[ $recurrence ] ) ) {
358
+
$interval = $schedules[ $recurrence ]['interval'];
359
+
}
360
+
361
+
// Now we try to get it from the saved interval in case the schedule disappears.
362
+
if ( 0 === $interval ) {
363
+
$scheduled_event = wp_get_scheduled_event( $hook, $args, $timestamp );
364
+
365
+
if ( $scheduled_event && isset( $scheduled_event->interval ) ) {
366
+
$interval = $scheduled_event->interval;
367
+
}
368
+
}
369
+
370
+
$event = (object) array(
371
+
'hook' => $hook,
372
+
'timestamp' => $timestamp,
373
+
'schedule' => $recurrence,
374
+
'args' => $args,
375
+
'interval' => $interval,
376
+
);
377
+
378
+
/**
379
+
* Filter to override rescheduling of a recurring event.
380
+
*
381
+
* Returning a non-null value will short-circuit the normal rescheduling
382
+
* process, causing the function to return the filtered value instead.
383
+
*
384
+
* For plugins replacing wp-cron, return true if the event was successfully
385
+
* rescheduled, false or a WP_Error if not.
386
+
*
387
+
* @since 5.1.0
388
+
* @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned.
389
+
*
390
+
* @param null|bool|WP_Error $pre Value to return instead. Default null to continue adding the event.
391
+
* @param object $event {
392
+
* An object containing an event's data.
393
+
*
394
+
* @type string $hook Action hook to execute when the event is run.
395
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
396
+
* @type string $schedule How often the event should subsequently recur.
397
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
398
+
* @type int $interval The interval time in seconds for the schedule.
399
+
* }
400
+
* @param bool $wp_error Whether to return a WP_Error on failure.
401
+
*/
402
+
$pre = apply_filters( 'pre_reschedule_event', null, $event, $wp_error );
403
+
404
+
if ( null !== $pre ) {
405
+
if ( $wp_error && false === $pre ) {
406
+
return new WP_Error(
407
+
'pre_reschedule_event_false',
408
+
__( 'A plugin prevented the event from being rescheduled.' )
409
+
);
410
+
}
411
+
412
+
if ( ! $wp_error && is_wp_error( $pre ) ) {
413
+
return false;
414
+
}
415
+
416
+
return $pre;
417
+
}
418
+
419
+
// Now we assume something is wrong and fail to schedule.
420
+
if ( 0 === $interval ) {
421
+
if ( $wp_error ) {
422
+
return new WP_Error(
423
+
'invalid_schedule',
424
+
__( 'Event schedule does not exist.' )
425
+
);
426
+
}
427
+
428
+
return false;
429
+
}
430
+
431
+
$now = time();
432
+
433
+
if ( $timestamp >= $now ) {
434
+
$timestamp = $now + $interval;
435
+
} else {
436
+
$timestamp = $now + ( $interval - ( ( $now - $timestamp ) % $interval ) );
437
+
}
438
+
439
+
return wp_schedule_event( $timestamp, $recurrence, $hook, $args, $wp_error );
440
+
}
441
+
442
+
/**
443
+
* Unschedules a previously scheduled event.
444
+
*
445
+
* The `$timestamp` and `$hook` parameters are required so that the event can be
446
+
* identified.
447
+
*
448
+
* @since 2.1.0
449
+
* @since 5.1.0 Return value modified to boolean indicating success or failure,
450
+
* {@see 'pre_unschedule_event'} filter added to short-circuit the function.
451
+
* @since 5.7.0 The `$wp_error` parameter was added.
452
+
*
453
+
* @param int $timestamp Unix timestamp (UTC) of the event.
454
+
* @param string $hook Action hook of the event.
455
+
* @param array $args Optional. Array containing each separate argument to pass to the hook's callback function.
456
+
* Although not passed to a callback, these arguments are used to uniquely identify the
457
+
* event, so they should be the same as those used when originally scheduling the event.
458
+
* Default empty array.
459
+
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
460
+
* @return bool|WP_Error True if event successfully unscheduled. False or WP_Error on failure.
461
+
*/
462
+
function wp_unschedule_event( $timestamp, $hook, $args = array(), $wp_error = false ) {
463
+
// Make sure timestamp is a positive integer.
464
+
if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) {
465
+
if ( $wp_error ) {
466
+
return new WP_Error(
467
+
'invalid_timestamp',
468
+
__( 'Event timestamp must be a valid Unix timestamp.' )
469
+
);
470
+
}
471
+
472
+
return false;
473
+
}
474
+
475
+
/**
476
+
* Filter to override unscheduling of events.
477
+
*
478
+
* Returning a non-null value will short-circuit the normal unscheduling
479
+
* process, causing the function to return the filtered value instead.
480
+
*
481
+
* For plugins replacing wp-cron, return true if the event was successfully
482
+
* unscheduled, false or a WP_Error if not.
483
+
*
484
+
* @since 5.1.0
485
+
* @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned.
486
+
*
487
+
* @param null|bool|WP_Error $pre Value to return instead. Default null to continue unscheduling the event.
488
+
* @param int $timestamp Unix timestamp (UTC) for when to run the event.
489
+
* @param string $hook Action hook, the execution of which will be unscheduled.
490
+
* @param array $args Arguments to pass to the hook's callback function.
491
+
* @param bool $wp_error Whether to return a WP_Error on failure.
492
+
*/
493
+
$pre = apply_filters( 'pre_unschedule_event', null, $timestamp, $hook, $args, $wp_error );
494
+
495
+
if ( null !== $pre ) {
496
+
if ( $wp_error && false === $pre ) {
497
+
return new WP_Error(
498
+
'pre_unschedule_event_false',
499
+
__( 'A plugin prevented the event from being unscheduled.' )
500
+
);
501
+
}
502
+
503
+
if ( ! $wp_error && is_wp_error( $pre ) ) {
504
+
return false;
505
+
}
506
+
507
+
return $pre;
508
+
}
509
+
510
+
$crons = _get_cron_array();
511
+
$key = md5( serialize( $args ) );
512
+
513
+
unset( $crons[ $timestamp ][ $hook ][ $key ] );
514
+
515
+
if ( empty( $crons[ $timestamp ][ $hook ] ) ) {
516
+
unset( $crons[ $timestamp ][ $hook ] );
517
+
}
518
+
519
+
if ( empty( $crons[ $timestamp ] ) ) {
520
+
unset( $crons[ $timestamp ] );
521
+
}
522
+
523
+
return _set_cron_array( $crons, $wp_error );
524
+
}
525
+
526
+
/**
527
+
* Unschedules all events attached to the hook with the specified arguments.
528
+
*
529
+
* Warning: This function may return boolean false, but may also return a non-boolean
530
+
* value which evaluates to false. For information about casting to booleans see the
531
+
* {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use
532
+
* the `===` operator for testing the return value of this function.
533
+
*
534
+
* @since 2.1.0
535
+
* @since 5.1.0 Return value modified to indicate success or failure,
536
+
* {@see 'pre_clear_scheduled_hook'} filter added to short-circuit the function.
537
+
* @since 5.7.0 The `$wp_error` parameter was added.
538
+
*
539
+
* @param string $hook Action hook, the execution of which will be unscheduled.
540
+
* @param array $args Optional. Array containing each separate argument to pass to the hook's callback function.
541
+
* Although not passed to a callback, these arguments are used to uniquely identify the
542
+
* event, so they should be the same as those used when originally scheduling the event.
543
+
* Default empty array.
544
+
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
545
+
* @return int|false|WP_Error On success an integer indicating number of events unscheduled (0 indicates no
546
+
* events were registered with the hook and arguments combination), false or WP_Error
547
+
* if unscheduling one or more events fail.
548
+
*/
549
+
function wp_clear_scheduled_hook( $hook, $args = array(), $wp_error = false ) {
550
+
/*
551
+
* Backward compatibility.
552
+
* Previously, this function took the arguments as discrete vars rather than an array like the rest of the API.
553
+
*/
554
+
if ( ! is_array( $args ) ) {
555
+
_deprecated_argument(
556
+
__FUNCTION__,
557
+
'3.0.0',
558
+
__( 'This argument has changed to an array to match the behavior of the other cron functions.' )
559
+
);
560
+
561
+
$args = array_slice( func_get_args(), 1 ); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
562
+
$wp_error = false;
563
+
}
564
+
565
+
/**
566
+
* Filter to override clearing a scheduled hook.
567
+
*
568
+
* Returning a non-null value will short-circuit the normal unscheduling
569
+
* process, causing the function to return the filtered value instead.
570
+
*
571
+
* For plugins replacing wp-cron, return the number of events successfully
572
+
* unscheduled (zero if no events were registered with the hook) or false
573
+
* or a WP_Error if unscheduling one or more events fails.
574
+
*
575
+
* @since 5.1.0
576
+
* @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned.
577
+
*
578
+
* @param null|int|false|WP_Error $pre Value to return instead. Default null to continue unscheduling the event.
579
+
* @param string $hook Action hook, the execution of which will be unscheduled.
580
+
* @param array $args Arguments to pass to the hook's callback function.
581
+
* @param bool $wp_error Whether to return a WP_Error on failure.
582
+
*/
583
+
$pre = apply_filters( 'pre_clear_scheduled_hook', null, $hook, $args, $wp_error );
584
+
585
+
if ( null !== $pre ) {
586
+
if ( $wp_error && false === $pre ) {
587
+
return new WP_Error(
588
+
'pre_clear_scheduled_hook_false',
589
+
__( 'A plugin prevented the hook from being cleared.' )
590
+
);
591
+
}
592
+
593
+
if ( ! $wp_error && is_wp_error( $pre ) ) {
594
+
return false;
595
+
}
596
+
597
+
return $pre;
598
+
}
599
+
600
+
/*
601
+
* This logic duplicates wp_next_scheduled().
602
+
* It's required due to a scenario where wp_unschedule_event() fails due to update_option() failing,
603
+
* and, wp_next_scheduled() returns the same schedule in an infinite loop.
604
+
*/
605
+
$crons = _get_cron_array();
606
+
if ( empty( $crons ) ) {
607
+
return 0;
608
+
}
609
+
610
+
$results = array();
611
+
$key = md5( serialize( $args ) );
612
+
613
+
foreach ( $crons as $timestamp => $cron ) {
614
+
if ( isset( $cron[ $hook ][ $key ] ) ) {
615
+
$results[] = wp_unschedule_event( $timestamp, $hook, $args, true );
616
+
}
617
+
}
618
+
619
+
$errors = array_filter( $results, 'is_wp_error' );
620
+
$error = new WP_Error();
621
+
622
+
if ( $errors ) {
623
+
if ( $wp_error ) {
624
+
array_walk( $errors, array( $error, 'merge_from' ) );
625
+
626
+
return $error;
627
+
}
628
+
629
+
return false;
630
+
}
631
+
632
+
return count( $results );
633
+
}
634
+
635
+
/**
636
+
* Unschedules all events attached to the hook.
637
+
*
638
+
* Can be useful for plugins when deactivating to clean up the cron queue.
639
+
*
640
+
* Warning: This function may return boolean false, but may also return a non-boolean
641
+
* value which evaluates to false. For information about casting to booleans see the
642
+
* {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use
643
+
* the `===` operator for testing the return value of this function.
644
+
*
645
+
* @since 4.9.0
646
+
* @since 5.1.0 Return value added to indicate success or failure.
647
+
* @since 5.7.0 The `$wp_error` parameter was added.
648
+
*
649
+
* @param string $hook Action hook, the execution of which will be unscheduled.
650
+
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
651
+
* @return int|false|WP_Error On success an integer indicating number of events unscheduled (0 indicates no
652
+
* events were registered on the hook), false or WP_Error if unscheduling fails.
653
+
*/
654
+
function wp_unschedule_hook( $hook, $wp_error = false ) {
655
+
/**
656
+
* Filter to override clearing all events attached to the hook.
657
+
*
658
+
* Returning a non-null value will short-circuit the normal unscheduling
659
+
* process, causing the function to return the filtered value instead.
660
+
*
661
+
* For plugins replacing wp-cron, return the number of events successfully
662
+
* unscheduled (zero if no events were registered with the hook). If unscheduling
663
+
* one or more events fails then return either a WP_Error object or false depending
664
+
* on the value of the `$wp_error` parameter.
665
+
*
666
+
* @since 5.1.0
667
+
* @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned.
668
+
*
669
+
* @param null|int|false|WP_Error $pre Value to return instead. Default null to continue unscheduling the hook.
670
+
* @param string $hook Action hook, the execution of which will be unscheduled.
671
+
* @param bool $wp_error Whether to return a WP_Error on failure.
672
+
*/
673
+
$pre = apply_filters( 'pre_unschedule_hook', null, $hook, $wp_error );
674
+
675
+
if ( null !== $pre ) {
676
+
if ( $wp_error && false === $pre ) {
677
+
return new WP_Error(
678
+
'pre_unschedule_hook_false',
679
+
__( 'A plugin prevented the hook from being cleared.' )
680
+
);
681
+
}
682
+
683
+
if ( ! $wp_error && is_wp_error( $pre ) ) {
684
+
return false;
685
+
}
686
+
687
+
return $pre;
688
+
}
689
+
690
+
$crons = _get_cron_array();
691
+
if ( empty( $crons ) ) {
692
+
return 0;
693
+
}
694
+
695
+
$results = array();
696
+
697
+
foreach ( $crons as $timestamp => $args ) {
698
+
if ( ! empty( $crons[ $timestamp ][ $hook ] ) ) {
699
+
$results[] = count( $crons[ $timestamp ][ $hook ] );
700
+
}
701
+
702
+
unset( $crons[ $timestamp ][ $hook ] );
703
+
704
+
if ( empty( $crons[ $timestamp ] ) ) {
705
+
unset( $crons[ $timestamp ] );
706
+
}
707
+
}
708
+
709
+
/*
710
+
* If the results are empty (zero events to unschedule), no attempt
711
+
* to update the cron array is required.
712
+
*/
713
+
if ( empty( $results ) ) {
714
+
return 0;
715
+
}
716
+
717
+
$set = _set_cron_array( $crons, $wp_error );
718
+
719
+
if ( true === $set ) {
720
+
return array_sum( $results );
721
+
}
722
+
723
+
return $set;
724
+
}
725
+
726
+
/**
727
+
* Retrieves a scheduled event.
728
+
*
729
+
* Retrieves the full event object for a given event, if no timestamp is specified the next
730
+
* scheduled event is returned.
731
+
*
732
+
* @since 5.1.0
733
+
*
734
+
* @param string $hook Action hook of the event.
735
+
* @param array $args Optional. Array containing each separate argument to pass to the hook's callback function.
736
+
* Although not passed to a callback, these arguments are used to uniquely identify the
737
+
* event, so they should be the same as those used when originally scheduling the event.
738
+
* Default empty array.
739
+
* @param int|null $timestamp Optional. Unix timestamp (UTC) of the event. If not specified, the next scheduled event
740
+
* is returned. Default null.
741
+
* @return object|false {
742
+
* The event object. False if the event does not exist.
743
+
*
744
+
* @type string $hook Action hook to execute when the event is run.
745
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
746
+
* @type string|false $schedule How often the event should subsequently recur.
747
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
748
+
* @type int $interval Optional. The interval time in seconds for the schedule. Only present for recurring events.
749
+
* }
750
+
*/
751
+
function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) {
752
+
/**
753
+
* Filter to override retrieving a scheduled event.
754
+
*
755
+
* Returning a non-null value will short-circuit the normal process,
756
+
* returning the filtered value instead.
757
+
*
758
+
* Return false if the event does not exist, otherwise an event object
759
+
* should be returned.
760
+
*
761
+
* @since 5.1.0
762
+
*
763
+
* @param null|false|object $pre Value to return instead. Default null to continue retrieving the event.
764
+
* @param string $hook Action hook of the event.
765
+
* @param array $args Array containing each separate argument to pass to the hook's callback function.
766
+
* Although not passed to a callback, these arguments are used to uniquely identify
767
+
* the event.
768
+
* @param int|null $timestamp Unix timestamp (UTC) of the event. Null to retrieve next scheduled event.
769
+
*/
770
+
$pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp );
771
+
772
+
if ( null !== $pre ) {
773
+
return $pre;
774
+
}
775
+
776
+
if ( null !== $timestamp && ! is_numeric( $timestamp ) ) {
777
+
return false;
778
+
}
779
+
780
+
$crons = _get_cron_array();
781
+
if ( empty( $crons ) ) {
782
+
return false;
783
+
}
784
+
785
+
$key = md5( serialize( $args ) );
786
+
787
+
if ( ! $timestamp ) {
788
+
// Get next event.
789
+
$next = false;
790
+
foreach ( $crons as $timestamp => $cron ) {
791
+
if ( isset( $cron[ $hook ][ $key ] ) ) {
792
+
$next = $timestamp;
793
+
break;
794
+
}
795
+
}
796
+
797
+
if ( ! $next ) {
798
+
return false;
799
+
}
800
+
801
+
$timestamp = $next;
802
+
} elseif ( ! isset( $crons[ $timestamp ][ $hook ][ $key ] ) ) {
803
+
return false;
804
+
}
805
+
806
+
$event = (object) array(
807
+
'hook' => $hook,
808
+
'timestamp' => $timestamp,
809
+
'schedule' => $crons[ $timestamp ][ $hook ][ $key ]['schedule'],
810
+
'args' => $args,
811
+
);
812
+
813
+
if ( isset( $crons[ $timestamp ][ $hook ][ $key ]['interval'] ) ) {
814
+
$event->interval = $crons[ $timestamp ][ $hook ][ $key ]['interval'];
815
+
}
816
+
817
+
return $event;
818
+
}
819
+
820
+
/**
821
+
* Retrieves the timestamp of the next scheduled event for the given hook.
822
+
*
823
+
* @since 2.1.0
824
+
*
825
+
* @param string $hook Action hook of the event.
826
+
* @param array $args Optional. Array containing each separate argument to pass to the hook's callback function.
827
+
* Although not passed to a callback, these arguments are used to uniquely identify the
828
+
* event, so they should be the same as those used when originally scheduling the event.
829
+
* Default empty array.
830
+
* @return int|false The Unix timestamp (UTC) of the next time the event will occur. False if the event doesn't exist.
831
+
*/
832
+
function wp_next_scheduled( $hook, $args = array() ) {
833
+
$next_event = wp_get_scheduled_event( $hook, $args );
834
+
835
+
if ( ! $next_event ) {
836
+
return false;
837
+
}
838
+
839
+
/**
840
+
* Filters the timestamp of the next scheduled event for the given hook.
841
+
*
842
+
* @since 6.8.0
843
+
*
844
+
* @param int $timestamp Unix timestamp (UTC) for when to next run the event.
845
+
* @param object $next_event {
846
+
* An object containing an event's data.
847
+
*
848
+
* @type string $hook Action hook of the event.
849
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
850
+
* @type string $schedule How often the event should subsequently recur.
851
+
* @type array $args Array containing each separate argument to pass to the hook
852
+
* callback function.
853
+
* @type int $interval Optional. The interval time in seconds for the schedule. Only
854
+
* present for recurring events.
855
+
* }
856
+
* @param array $args Array containing each separate argument to pass to the hook
857
+
* callback function.
858
+
*/
859
+
return apply_filters( 'wp_next_scheduled', $next_event->timestamp, $next_event, $hook, $args );
860
+
}
861
+
862
+
/**
863
+
* Sends a request to run cron through HTTP request that doesn't halt page loading.
864
+
*
865
+
* @since 2.1.0
866
+
* @since 5.1.0 Return values added.
867
+
*
868
+
* @param int $gmt_time Optional. Unix timestamp (UTC). Default 0 (current time is used).
869
+
* @return bool True if spawned, false if no events spawned.
870
+
*/
871
+
function spawn_cron( $gmt_time = 0 ) {
872
+
if ( ! $gmt_time ) {
873
+
$gmt_time = microtime( true );
874
+
}
875
+
876
+
if ( defined( 'DOING_CRON' ) || isset( $_GET['doing_wp_cron'] ) ) {
877
+
return false;
878
+
}
879
+
880
+
/*
881
+
* Get the cron lock, which is a Unix timestamp of when the last cron was spawned
882
+
* and has not finished running.
883
+
*
884
+
* Multiple processes on multiple web servers can run this code concurrently,
885
+
* this lock attempts to make spawning as atomic as possible.
886
+
*/
887
+
$lock = (float) get_transient( 'doing_cron' );
888
+
889
+
if ( $lock > $gmt_time + 10 * MINUTE_IN_SECONDS ) {
890
+
$lock = 0;
891
+
}
892
+
893
+
// Don't run if another process is currently running it or more than once every 60 sec.
894
+
if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time ) {
895
+
return false;
896
+
}
897
+
898
+
// Confidence check.
899
+
$crons = wp_get_ready_cron_jobs();
900
+
if ( empty( $crons ) ) {
901
+
return false;
902
+
}
903
+
904
+
$keys = array_keys( $crons );
905
+
if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) {
906
+
return false;
907
+
}
908
+
909
+
if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
910
+
if ( 'GET' !== $_SERVER['REQUEST_METHOD'] || defined( 'DOING_AJAX' ) || defined( 'XMLRPC_REQUEST' ) ) {
911
+
return false;
912
+
}
913
+
914
+
$doing_wp_cron = sprintf( '%.22F', $gmt_time );
915
+
set_transient( 'doing_cron', $doing_wp_cron );
916
+
917
+
ob_start();
918
+
wp_redirect( add_query_arg( 'doing_wp_cron', $doing_wp_cron, wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
919
+
echo ' ';
920
+
921
+
// Flush any buffers and send the headers.
922
+
wp_ob_end_flush_all();
923
+
flush();
924
+
925
+
require_once ABSPATH . 'wp-cron.php';
926
+
return true;
927
+
}
928
+
929
+
// Set the cron lock with the current unix timestamp, when the cron is being spawned.
930
+
$doing_wp_cron = sprintf( '%.22F', $gmt_time );
931
+
set_transient( 'doing_cron', $doing_wp_cron );
932
+
933
+
/**
934
+
* Filters the cron request arguments.
935
+
*
936
+
* @since 3.5.0
937
+
* @since 4.5.0 The `$doing_wp_cron` parameter was added.
938
+
*
939
+
* @param array $cron_request_array {
940
+
* An array of cron request URL arguments.
941
+
*
942
+
* @type string $url The cron request URL.
943
+
* @type string $key The Unix timestamp (UTC) of the cron lock with microseconds.
944
+
* @type array $args {
945
+
* An array of cron request arguments.
946
+
*
947
+
* @type int $timeout The request timeout in seconds. Default .01 seconds.
948
+
* @type bool $blocking Whether to set blocking for the request. Default false.
949
+
* @type bool $sslverify Whether SSL should be verified for the request. Default false.
950
+
* }
951
+
* }
952
+
* @param string $doing_wp_cron The Unix timestamp (UTC) of the cron lock with microseconds.
953
+
*/
954
+
$cron_request = apply_filters(
955
+
'cron_request',
956
+
array(
957
+
'url' => add_query_arg( 'doing_wp_cron', $doing_wp_cron, site_url( 'wp-cron.php' ) ),
958
+
'key' => $doing_wp_cron,
959
+
'args' => array(
960
+
'timeout' => 0.01,
961
+
'blocking' => false,
962
+
/** This filter is documented in wp-includes/class-wp-http-streams.php */
963
+
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
964
+
),
965
+
),
966
+
$doing_wp_cron
967
+
);
968
+
969
+
$result = wp_remote_post( $cron_request['url'], $cron_request['args'] );
970
+
971
+
return ! is_wp_error( $result );
972
+
}
973
+
974
+
/**
975
+
* Registers _wp_cron() to run on the {@see 'shutdown'} action.
976
+
*
977
+
* The spawn_cron() function attempts to make a non-blocking loopback request to `wp-cron.php` (when alternative
978
+
* cron is not being used). However, the wp_remote_post() function does not always respect the `timeout` and
979
+
* `blocking` parameters. A timeout of `0.01` may end up taking 1 second. When this runs at the {@see 'wp_loaded'}
980
+
* action, it increases the Time To First Byte (TTFB) since the HTML cannot be sent while waiting for the cron request
981
+
* to initiate. Moving the spawning of cron to the {@see 'shutdown'} hook allows for the server to flush the HTML document to
982
+
* the browser while waiting for the request.
983
+
*
984
+
* @since 2.1.0
985
+
* @since 5.1.0 Return value added to indicate success or failure.
986
+
* @since 5.7.0 Functionality moved to _wp_cron() to which this becomes a wrapper.
987
+
* @since 6.9.0 The _wp_cron() callback is moved from {@see 'wp_loaded'} to the {@see 'shutdown'} action,
988
+
* unless `ALTERNATE_WP_CRON` is enabled; the function now always returns void.
989
+
*/
990
+
function wp_cron(): void {
991
+
if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
992
+
if ( did_action( 'wp_loaded' ) ) {
993
+
_wp_cron();
994
+
} else {
995
+
add_action( 'wp_loaded', '_wp_cron', 20 );
996
+
}
997
+
} elseif ( doing_action( 'shutdown' ) ) {
998
+
_wp_cron();
999
+
} else {
1000
+
add_action( 'shutdown', '_wp_cron' );
1001
+
}
1002
+
}
1003
+
1004
+
/**
1005
+
* Runs scheduled callbacks or spawns cron for all scheduled events.
1006
+
*
1007
+
* Warning: This function may return Boolean FALSE, but may also return a non-Boolean
1008
+
* value which evaluates to FALSE. For information about casting to booleans see the
1009
+
* {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use
1010
+
* the `===` operator for testing the return value of this function.
1011
+
*
1012
+
* @since 5.7.0
1013
+
* @access private
1014
+
*
1015
+
* @return int|false On success an integer indicating number of events spawned (0 indicates no
1016
+
* events needed to be spawned), false if spawning fails for one or more events.
1017
+
*/
1018
+
function _wp_cron() {
1019
+
// Prevent infinite loops caused by lack of wp-cron.php.
1020
+
if ( str_contains( $_SERVER['REQUEST_URI'], '/wp-cron.php' )
1021
+
|| ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON )
1022
+
) {
1023
+
return 0;
1024
+
}
1025
+
1026
+
$crons = wp_get_ready_cron_jobs();
1027
+
if ( empty( $crons ) ) {
1028
+
return 0;
1029
+
}
1030
+
1031
+
$gmt_time = microtime( true );
1032
+
$keys = array_keys( $crons );
1033
+
if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) {
1034
+
return 0;
1035
+
}
1036
+
1037
+
$schedules = wp_get_schedules();
1038
+
$results = array();
1039
+
1040
+
foreach ( $crons as $timestamp => $cronhooks ) {
1041
+
if ( $timestamp > $gmt_time ) {
1042
+
break;
1043
+
}
1044
+
1045
+
foreach ( (array) $cronhooks as $hook => $args ) {
1046
+
if ( isset( $schedules[ $hook ]['callback'] )
1047
+
&& ! call_user_func( $schedules[ $hook ]['callback'] )
1048
+
) {
1049
+
continue;
1050
+
}
1051
+
1052
+
$results[] = spawn_cron( $gmt_time );
1053
+
break 2;
1054
+
}
1055
+
}
1056
+
1057
+
if ( in_array( false, $results, true ) ) {
1058
+
return false;
1059
+
}
1060
+
1061
+
return count( $results );
1062
+
}
1063
+
1064
+
/**
1065
+
* Retrieves supported event recurrence schedules.
1066
+
*
1067
+
* The default supported recurrences are 'hourly', 'twicedaily', 'daily', and 'weekly'.
1068
+
* A plugin may add more by hooking into the {@see 'cron_schedules'} filter.
1069
+
* The filter accepts an array of arrays. The outer array has a key that is the name
1070
+
* of the schedule, for example 'monthly'. The value is an array with two keys,
1071
+
* one is 'interval' and the other is 'display'.
1072
+
*
1073
+
* The 'interval' is a number in seconds of when the cron job should run.
1074
+
* So for 'hourly' the time is `HOUR_IN_SECONDS` (`60 * 60` or `3600`). For 'monthly',
1075
+
* the value would be `MONTH_IN_SECONDS` (`30 * 24 * 60 * 60` or `2592000`).
1076
+
*
1077
+
* The 'display' is the description. For the 'monthly' key, the 'display'
1078
+
* would be `__( 'Once Monthly' )`.
1079
+
*
1080
+
* For your plugin, you will be passed an array. You can add your
1081
+
* schedule by doing the following:
1082
+
*
1083
+
* // Filter parameter variable name is 'array'.
1084
+
* $array['monthly'] = array(
1085
+
* 'interval' => MONTH_IN_SECONDS,
1086
+
* 'display' => __( 'Once Monthly' )
1087
+
* );
1088
+
*
1089
+
* @since 2.1.0
1090
+
* @since 5.4.0 The 'weekly' schedule was added.
1091
+
*
1092
+
* @return array {
1093
+
* The array of cron schedules keyed by the schedule name.
1094
+
*
1095
+
* @type array ...$0 {
1096
+
* Cron schedule information.
1097
+
*
1098
+
* @type int $interval The schedule interval in seconds.
1099
+
* @type string $display The schedule display name.
1100
+
* }
1101
+
* }
1102
+
*/
1103
+
function wp_get_schedules() {
1104
+
$schedules = array(
1105
+
'hourly' => array(
1106
+
'interval' => HOUR_IN_SECONDS,
1107
+
'display' => __( 'Once Hourly' ),
1108
+
),
1109
+
'twicedaily' => array(
1110
+
'interval' => 12 * HOUR_IN_SECONDS,
1111
+
'display' => __( 'Twice Daily' ),
1112
+
),
1113
+
'daily' => array(
1114
+
'interval' => DAY_IN_SECONDS,
1115
+
'display' => __( 'Once Daily' ),
1116
+
),
1117
+
'weekly' => array(
1118
+
'interval' => WEEK_IN_SECONDS,
1119
+
'display' => __( 'Once Weekly' ),
1120
+
),
1121
+
);
1122
+
1123
+
/**
1124
+
* Filters the non-default cron schedules.
1125
+
*
1126
+
* @since 2.1.0
1127
+
*
1128
+
* @param array $new_schedules {
1129
+
* An array of non-default cron schedules keyed by the schedule name. Default empty array.
1130
+
*
1131
+
* @type array ...$0 {
1132
+
* Cron schedule information.
1133
+
*
1134
+
* @type int $interval The schedule interval in seconds.
1135
+
* @type string $display The schedule display name.
1136
+
* }
1137
+
* }
1138
+
*/
1139
+
return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
1140
+
}
1141
+
1142
+
/**
1143
+
* Retrieves the name of the recurrence schedule for an event.
1144
+
*
1145
+
* @see wp_get_schedules() for available schedules.
1146
+
*
1147
+
* @since 2.1.0
1148
+
* @since 5.1.0 {@see 'get_schedule'} filter added.
1149
+
*
1150
+
* @param string $hook Action hook to identify the event.
1151
+
* @param array $args Optional. Arguments passed to the event's callback function.
1152
+
* Default empty array.
1153
+
* @return string|false Schedule name on success, false if no schedule.
1154
+
*/
1155
+
function wp_get_schedule( $hook, $args = array() ) {
1156
+
$schedule = false;
1157
+
$event = wp_get_scheduled_event( $hook, $args );
1158
+
1159
+
if ( $event ) {
1160
+
$schedule = $event->schedule;
1161
+
}
1162
+
1163
+
/**
1164
+
* Filters the schedule name for a hook.
1165
+
*
1166
+
* @since 5.1.0
1167
+
*
1168
+
* @param string|false $schedule Schedule for the hook. False if not found.
1169
+
* @param string $hook Action hook to execute when cron is run.
1170
+
* @param array $args Arguments to pass to the hook's callback function.
1171
+
*/
1172
+
return apply_filters( 'get_schedule', $schedule, $hook, $args );
1173
+
}
1174
+
1175
+
/**
1176
+
* Retrieves cron jobs ready to be run.
1177
+
*
1178
+
* Returns the results of _get_cron_array() limited to events ready to be run,
1179
+
* ie, with a timestamp in the past.
1180
+
*
1181
+
* @since 5.1.0
1182
+
*
1183
+
* @return array[] Array of cron job arrays ready to be run.
1184
+
*/
1185
+
function wp_get_ready_cron_jobs() {
1186
+
/**
1187
+
* Filter to override retrieving ready cron jobs.
1188
+
*
1189
+
* Returning an array will short-circuit the normal retrieval of ready
1190
+
* cron jobs, causing the function to return the filtered value instead.
1191
+
*
1192
+
* @since 5.1.0
1193
+
*
1194
+
* @param null|array[] $pre Array of ready cron tasks to return instead. Default null
1195
+
* to continue using results from _get_cron_array().
1196
+
*/
1197
+
$pre = apply_filters( 'pre_get_ready_cron_jobs', null );
1198
+
1199
+
if ( null !== $pre ) {
1200
+
return $pre;
1201
+
}
1202
+
1203
+
$crons = _get_cron_array();
1204
+
$gmt_time = microtime( true );
1205
+
$results = array();
1206
+
1207
+
foreach ( $crons as $timestamp => $cronhooks ) {
1208
+
if ( $timestamp > $gmt_time ) {
1209
+
break;
1210
+
}
1211
+
1212
+
$results[ $timestamp ] = $cronhooks;
1213
+
}
1214
+
1215
+
return $results;
1216
+
}
1217
+
1218
+
//
1219
+
// Private functions.
1220
+
//
1221
+
1222
+
/**
1223
+
* Retrieves cron info array option.
1224
+
*
1225
+
* @since 2.1.0
1226
+
* @since 6.1.0 Return type modified to consistently return an array.
1227
+
* @access private
1228
+
*
1229
+
* @return array[] Array of cron events.
1230
+
*/
1231
+
function _get_cron_array() {
1232
+
$cron = get_option( 'cron' );
1233
+
if ( ! is_array( $cron ) ) {
1234
+
return array();
1235
+
}
1236
+
1237
+
if ( ! isset( $cron['version'] ) ) {
1238
+
$cron = _upgrade_cron_array( $cron );
1239
+
}
1240
+
1241
+
unset( $cron['version'] );
1242
+
1243
+
return $cron;
1244
+
}
1245
+
1246
+
/**
1247
+
* Updates the cron option with the new cron array.
1248
+
*
1249
+
* @since 2.1.0
1250
+
* @since 5.1.0 Return value modified to outcome of update_option().
1251
+
* @since 5.7.0 The `$wp_error` parameter was added.
1252
+
*
1253
+
* @access private
1254
+
*
1255
+
* @param array[] $cron Array of cron info arrays from _get_cron_array().
1256
+
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
1257
+
* @return bool|WP_Error True if cron array updated. False or WP_Error on failure.
1258
+
*/
1259
+
function _set_cron_array( $cron, $wp_error = false ) {
1260
+
if ( ! is_array( $cron ) ) {
1261
+
$cron = array();
1262
+
}
1263
+
1264
+
$cron['version'] = 2;
1265
+
1266
+
$result = update_option( 'cron', $cron, true );
1267
+
1268
+
if ( $wp_error && ! $result ) {
1269
+
return new WP_Error(
1270
+
'could_not_set',
1271
+
__( 'The cron event list could not be saved.' )
1272
+
);
1273
+
}
1274
+
1275
+
return $result;
1276
+
}
1277
+
1278
+
/**
1279
+
* Upgrades a cron info array.
1280
+
*
1281
+
* This function upgrades the cron info array to version 2.
1282
+
*
1283
+
* @since 2.1.0
1284
+
* @access private
1285
+
*
1286
+
* @param array $cron Cron info array from _get_cron_array().
1287
+
* @return array An upgraded cron info array.
1288
+
*/
1289
+
function _upgrade_cron_array( $cron ) {
1290
+
if ( isset( $cron['version'] ) && 2 === $cron['version'] ) {
1291
+
return $cron;
1292
+
}
1293
+
1294
+
$new_cron = array();
1295
+
1296
+
foreach ( (array) $cron as $timestamp => $hooks ) {
1297
+
foreach ( (array) $hooks as $hook => $args ) {
1298
+
$key = md5( serialize( $args['args'] ) );
1299
+
1300
+
$new_cron[ $timestamp ][ $hook ][ $key ] = $args;
1301
+
}
1302
+
}
1303
+
1304
+
$new_cron['version'] = 2;
1305
+
1306
+
update_option( 'cron', $new_cron, true );
1307
+
1308
+
return $new_cron;
1309
+
}
1310
+