Skip to content

Commit 6ef8389

Browse files
committed
bump 1.2
- Code refactoring
1 parent 5a636f1 commit 6ef8389

16 files changed

+797
-621
lines changed

LICENSE.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Docket CronWP
22

3-
Copyright (c) 2021 Nawawi Jamili
3+
Copyright (c) 2021-current Nawawi Jamili
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Docket CronWP is a command-line tool for executing WordPress cron events in para
1010
This tool is part of the [Docket Cache](https://docketcache.com) project.
1111

1212
## Requirements
13-
- UNIX-like environment (OS X, Linux, FreeBSD, Cygwin, WSL)
13+
- UNIX-like environment
1414
- PHP >= 7.2.5
1515
- WordPress >= 5.4
1616
- PHP [pnctl](https://www.php.net/manual/en/book.pcntl.php) extension
@@ -53,7 +53,7 @@ sudo chmod +x /usr/local/bin/cronwp
5353
```
5454
$ cronwp -h
5555
56-
Docket CronWP v1.0.9.
56+
Docket CronWP v1.2.
5757
Execute WordPress cron events in parallel.
5858
5959
Usage:
@@ -82,6 +82,12 @@ Run WordPress cron with 3 events execute in parallel:
8282
cronwp /path-to/wordpress --jobs 3
8383
```
8484

85+
Or within the WordPress installation directory.
86+
87+
```sh
88+
cronwp --jobs 3
89+
```
90+
8591
Output:
8692
```
8793
Executed the cron event 'wp_privacy_delete_old_export_files' in 0.000s
@@ -184,10 +190,10 @@ Output: _( # Timestamp : Label : PID : Message )_
184190
Run WordPress cron with 3 events execute in parallel using server cron. Edit `/etc/crontab` and insert command below:
185191

186192
```
187-
* * * * * root /usr/local/bin/cronwp /path-to/wordpress -q -j 3 &>/dev/null
193+
* * * * * apache /usr/local/bin/cronwp /path-to/wordpress -q -j 3 &>/dev/null
188194
```
189195

190-
Replace **root** with web server or php-fpm user to avoid issue with filesystem permission.
196+
Replace **apache** with web server or php-fpm user to avoid issue with filesystem permission.
191197

192198
## Contributions
193199

bin/docket-cronwp.phar

500 Bytes
Binary file not shown.

docket-cronwp.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
'DOCKET_CRONWP',
3535
[
3636
'NAME' => 'Docket CronWP',
37-
'VERSION' => '1.1.0',
37+
'VERSION' => '1.2',
3838
'ROOT' => __DIR__,
3939
'SELF' => !empty($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : __FILE__,
4040
]

includes/src/Console.php

+6-14
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,12 @@ private function register_args()
189189
private function register_wpload()
190190
{
191191
$wpload = $this->args['wpdir'].'/wp-load.php';
192-
$wpcron = $this->args['dcdir'].'/includes/wp/cron.php';
193192

194-
if (!@is_file($wpload)) {
193+
if (!file_exists($wpload)) {
195194
$this->output('Failed to load: '.$wpload.\PHP_EOL, true);
196195
exit(1);
197196
}
198197

199-
if (!@is_file($wpcron)) {
200-
$this->output('Failed to load: '.$wpcron.\PHP_EOL, true);
201-
exit(1);
202-
}
203-
204198
$_SERVER['HTTP_HOST'] = '';
205199
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0';
206200
$_SERVER['HTTP_USER_AGENT'] = '';
@@ -224,8 +218,6 @@ private function register_wpload()
224218
\define('DOING_CRON', true);
225219

226220
require_once $wpload;
227-
require_once $wpcron;
228-
229221
$this->wpdb_suppress_errors();
230222
}
231223

@@ -274,7 +266,7 @@ public function run()
274266
}
275267

276268
add_filter(
277-
'dcronwp/lockfile',
269+
'docketcronwp/lockfile',
278270
function ($lockfile) use ($lock_file) {
279271
return $lock_file;
280272
}
@@ -324,7 +316,7 @@ function ($lockfile) use ($lock_file) {
324316

325317
$wp_get_schedules = wp_get_schedules();
326318
add_filter(
327-
'dcronwp/wp_get_schedules',
319+
'docketcronwp/upstream_get_schedules',
328320
function ($arr) use ($wp_get_schedules) {
329321
return $wp_get_schedules;
330322
}
@@ -349,12 +341,12 @@ function ($arr) use ($wp_get_schedules) {
349341
$schedule = $v['schedule'];
350342

351343
if ($schedule) {
352-
if (false === dc_wp_reschedule_event($timestamp, $schedule, $hook, $v['args'])) {
344+
if (false === Cron::reschedule_event($timestamp, $schedule, $hook, $v['args'])) {
353345
continue;
354346
}
355347
}
356348

357-
if (false === dc_wp_unschedule_event($timestamp, $hook, $v['args'])) {
349+
if (false === Cron::unschedule_event($timestamp, $hook, $v['args'])) {
358350
continue;
359351
}
360352

@@ -441,7 +433,7 @@ function () use ($hook, $args) {
441433
}
442434

443435
if (!$this->args['dryrun']) {
444-
$cron = dc_getdata();
436+
$cron = Cron::getdata();
445437
if (!empty($cron) && \is_array($cron)) {
446438
_set_cron_array($cron);
447439
}

includes/src/Cron.php

+265
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
<?php
2+
/**
3+
* Docket CronWP.
4+
*
5+
* @author Nawawi Jamili
6+
* @license MIT
7+
*
8+
* @see https://github.com/nawawi/docket-cronwp
9+
*/
10+
11+
namespace Nawawi\DocketCronWP;
12+
13+
\defined('DOCKET_CRONWP') || exit;
14+
15+
/*
16+
* Reference:
17+
* wp-includes/cron.php.
18+
*/
19+
final class Cron
20+
{
21+
public static function getdata()
22+
{
23+
$file = apply_filters('docketcronwp/lockfile', false);
24+
if (empty($file) || !is_file($file)) {
25+
return false;
26+
}
27+
28+
$data = include $file;
29+
if (!empty($data) && \is_array($data)) {
30+
return $data;
31+
}
32+
33+
return false;
34+
}
35+
36+
public static function putdata($data)
37+
{
38+
$file = apply_filters('docketcronwp/lockfile', false);
39+
if (empty($data) || !\is_array($data)) {
40+
return false;
41+
}
42+
43+
$code = '<?php return '.var_export($data, 1).';';
44+
45+
if (file_put_contents($file, $code, \LOCK_EX)) {
46+
chmod($file, 0666);
47+
48+
return true;
49+
}
50+
51+
return false;
52+
}
53+
54+
// wp_schedule_event
55+
public static function schedule_event($timestamp, $recurrence, $hook, $args = [])
56+
{
57+
if (!is_numeric($timestamp) || $timestamp <= 0) {
58+
return false;
59+
}
60+
61+
$schedules = self::get_schedules();
62+
63+
if (!isset($schedules[$recurrence])) {
64+
return false;
65+
}
66+
67+
$event = (object) [
68+
'hook' => $hook,
69+
'timestamp' => $timestamp,
70+
'schedule' => $recurrence,
71+
'args' => $args,
72+
'interval' => $schedules[$recurrence]['interval'],
73+
];
74+
75+
$pre = apply_filters('pre_schedule_event', null, $event, false);
76+
77+
if (null !== $pre) {
78+
if (is_wp_error($pre)) {
79+
return false;
80+
}
81+
82+
return $pre;
83+
}
84+
85+
$event = apply_filters('schedule_event', $event);
86+
87+
if (!$event) {
88+
return false;
89+
}
90+
91+
$key = md5(serialize($event->args));
92+
93+
$crons = self::get_cron_array();
94+
$crons[$event->timestamp][$event->hook][$key] = [
95+
'schedule' => $event->schedule,
96+
'args' => $event->args,
97+
'interval' => $event->interval,
98+
];
99+
uksort($crons, 'strnatcasecmp');
100+
101+
return self::set_cron_array($crons);
102+
}
103+
104+
// wp_reschedule_event
105+
public static function reschedule_event($timestamp, $recurrence, $hook, $args = [])
106+
{
107+
if (!is_numeric($timestamp) || $timestamp <= 0) {
108+
return false;
109+
}
110+
111+
$schedules = self::get_schedules();
112+
$interval = 0;
113+
114+
if (isset($schedules[$recurrence])) {
115+
$interval = $schedules[$recurrence]['interval'];
116+
}
117+
118+
if (0 === $interval) {
119+
$scheduled_event = self::get_scheduled_event($hook, $args, $timestamp);
120+
if ($scheduled_event && isset($scheduled_event->interval)) {
121+
$interval = $scheduled_event->interval;
122+
}
123+
}
124+
125+
$event = (object) [
126+
'hook' => $hook,
127+
'timestamp' => $timestamp,
128+
'schedule' => $recurrence,
129+
'args' => $args,
130+
'interval' => $interval,
131+
];
132+
133+
$pre = apply_filters('pre_reschedule_event', null, $event, false);
134+
135+
if (null !== $pre) {
136+
if (is_wp_error($pre)) {
137+
return false;
138+
}
139+
140+
return $pre;
141+
}
142+
143+
if (0 == $interval) {
144+
return false;
145+
}
146+
147+
$now = time();
148+
149+
if ($timestamp >= $now) {
150+
$timestamp = $now + $interval;
151+
} else {
152+
$timestamp = $now + ($interval - (($now - $timestamp) % $interval));
153+
}
154+
155+
return self::schedule_event($timestamp, $recurrence, $hook, $args);
156+
}
157+
158+
// wp_unschedule_event
159+
public static function unschedule_event($timestamp, $hook, $args = [])
160+
{
161+
if (!is_numeric($timestamp) || $timestamp <= 0) {
162+
return false;
163+
}
164+
165+
$pre = apply_filters('pre_unschedule_event', null, $timestamp, $hook, $args, false);
166+
167+
if (null !== $pre) {
168+
if (is_wp_error($pre)) {
169+
return false;
170+
}
171+
172+
return $pre;
173+
}
174+
175+
$crons = self::get_cron_array();
176+
$key = md5(serialize($args));
177+
unset($crons[$timestamp][$hook][$key]);
178+
if (empty($crons[$timestamp][$hook])) {
179+
unset($crons[$timestamp][$hook]);
180+
}
181+
if (empty($crons[$timestamp])) {
182+
unset($crons[$timestamp]);
183+
}
184+
185+
return self::set_cron_array($crons);
186+
}
187+
188+
// wp_get_scheduled_event
189+
public static function get_scheduled_event($hook, $args = [], $timestamp = null)
190+
{
191+
$pre = apply_filters('pre_get_scheduled_event', null, $hook, $args, $timestamp);
192+
if (null !== $pre) {
193+
return $pre;
194+
}
195+
196+
if (null !== $timestamp && !is_numeric($timestamp)) {
197+
return false;
198+
}
199+
200+
$crons = self::get_cron_array();
201+
if (empty($crons)) {
202+
return false;
203+
}
204+
205+
$key = md5(serialize($args));
206+
207+
if (!$timestamp) {
208+
$next = false;
209+
foreach ($crons as $timestamp => $cron) {
210+
if (isset($cron[$hook][$key])) {
211+
$next = $timestamp;
212+
break;
213+
}
214+
}
215+
if (!$next) {
216+
return false;
217+
}
218+
219+
$timestamp = $next;
220+
} elseif (!isset($crons[$timestamp][$hook][$key])) {
221+
return false;
222+
}
223+
224+
$event = (object) [
225+
'hook' => $hook,
226+
'timestamp' => $timestamp,
227+
'schedule' => $crons[$timestamp][$hook][$key]['schedule'],
228+
'args' => $args,
229+
];
230+
231+
if (isset($crons[$timestamp][$hook][$key]['interval'])) {
232+
$event->interval = $crons[$timestamp][$hook][$key]['interval'];
233+
}
234+
235+
return $event;
236+
}
237+
238+
// wp_get_schedules
239+
public static function get_schedules()
240+
{
241+
return apply_filters('docketcronwp/upstream_get_schedules', []);
242+
}
243+
244+
// _get_cron_array
245+
public static function get_cron_array()
246+
{
247+
$cron = self::getdata();
248+
if (!\is_array($cron)) {
249+
return false;
250+
}
251+
252+
unset($cron['version']);
253+
254+
return $cron;
255+
}
256+
257+
// __set_cron_array
258+
public static function set_cron_array($cron)
259+
{
260+
$cron['version'] = 2;
261+
$result = self::putdata($cron);
262+
263+
return $result;
264+
}
265+
}

0 commit comments

Comments
 (0)