CARVIEW |
Select Language
HTTP/2 200
server: nginx
date: Sat, 11 Oct 2025 20:40:16 GMT
content-type: text/html;charset=utf-8
vary: Accept-Encoding
cache-control: must-revalidate
alt-svc: h3=":443"; ma=86400
x-nc: MISS
content-encoding: gzip
wp-cron.php in trunk/src
– WordPress Trac
source:
trunk/src/wp-cron.php
source:
trunk/src/wp-cron.php
Last change on this file was 58842, checked in by SergeyBiryukov, 15 months ago | |
---|---|
Docs: Improve the wording for
Follow-up to [54258].
Props NekoJonez, audrasjb. |
|
|
|
File size: 5.5 KB |
Line | |
---|---|
1 | <?php |
2 | /** |
3 | * A pseudo-cron daemon for scheduling WordPress tasks. |
4 | * |
5 | * WP-Cron is triggered when the site receives a visit. In the scenario |
6 | * where a site may not receive enough visits to execute scheduled tasks |
7 | * in a timely manner, this file can be called directly or via a server |
8 | * cron daemon for X number of times. |
9 | * |
10 | * Defining DISABLE_WP_CRON as true and calling this file directly are |
11 | * mutually exclusive and the latter does not rely on the former to work. |
12 | * |
13 | * The HTTP request to this file will not slow down the visitor who happens to |
14 | * visit when a scheduled cron event runs. |
15 | * |
16 | * @package WordPress |
17 | */ |
18 | |
19 | ignore_user_abort( true ); |
20 | |
21 | if ( ! headers_sent() ) { |
22 | header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' ); |
23 | header( 'Cache-Control: no-cache, must-revalidate, max-age=0' ); |
24 | } |
25 | |
26 | // Don't run cron until the request finishes, if possible. |
27 | if ( function_exists( 'fastcgi_finish_request' ) ) { |
28 | fastcgi_finish_request(); |
29 | } elseif ( function_exists( 'litespeed_finish_request' ) ) { |
30 | litespeed_finish_request(); |
31 | } |
32 | |
33 | if ( ! empty( $_POST ) || defined( 'DOING_AJAX' ) || defined( 'DOING_CRON' ) ) { |
34 | die(); |
35 | } |
36 | |
37 | /** |
38 | * Tell WordPress the cron task is running. |
39 | * |
40 | * @var bool |
41 | */ |
42 | define( 'DOING_CRON', true ); |
43 | |
44 | if ( ! defined( 'ABSPATH' ) ) { |
45 | /** Set up WordPress environment */ |
46 | require_once __DIR__ . '/wp-load.php'; |
47 | } |
48 | |
49 | // Attempt to raise the PHP memory limit for cron event processing. |
50 | wp_raise_memory_limit( 'cron' ); |
51 | |
52 | /** |
53 | * Retrieves the cron lock. |
54 | * |
55 | * Returns the uncached `doing_cron` transient. |
56 | * |
57 | * @ignore |
58 | * @since 3.3.0 |
59 | * |
60 | * @global wpdb $wpdb WordPress database abstraction object. |
61 | * |
62 | * @return string|int|false Value of the `doing_cron` transient, 0|false otherwise. |
63 | */ |
64 | function _get_cron_lock() { |
65 | global $wpdb; |
66 | |
67 | $value = 0; |
68 | if ( wp_using_ext_object_cache() ) { |
69 | /* |
70 | * Skip local cache and force re-fetch of doing_cron transient |
71 | * in case another process updated the cache. |
72 | */ |
73 | $value = wp_cache_get( 'doing_cron', 'transient', true ); |
74 | } else { |
75 | $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) ); |
76 | if ( is_object( $row ) ) { |
77 | $value = $row->option_value; |
78 | } |
79 | } |
80 | |
81 | return $value; |
82 | } |
83 | |
84 | $crons = wp_get_ready_cron_jobs(); |
85 | if ( empty( $crons ) ) { |
86 | die(); |
87 | } |
88 | |
89 | $gmt_time = microtime( true ); |
90 | |
91 | // The cron lock: a unix timestamp from when the cron was spawned. |
92 | $doing_cron_transient = get_transient( 'doing_cron' ); |
93 | |
94 | // Use global $doing_wp_cron lock, otherwise use the GET lock. If no lock, try to grab a new lock. |
95 | if ( empty( $doing_wp_cron ) ) { |
96 | if ( empty( $_GET['doing_wp_cron'] ) ) { |
97 | // Called from external script/job. Try setting a lock. |
98 | if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) { |
99 | return; |
100 | } |
101 | $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); |
102 | $doing_cron_transient = $doing_wp_cron; |
103 | set_transient( 'doing_cron', $doing_wp_cron ); |
104 | } else { |
105 | $doing_wp_cron = $_GET['doing_wp_cron']; |
106 | } |
107 | } |
108 | |
109 | /* |
110 | * The cron lock (a unix timestamp set when the cron was spawned), |
111 | * must match $doing_wp_cron (the "key"). |
112 | */ |
113 | if ( $doing_cron_transient !== $doing_wp_cron ) { |
114 | return; |
115 | } |
116 | |
117 | foreach ( $crons as $timestamp => $cronhooks ) { |
118 | if ( $timestamp > $gmt_time ) { |
119 | break; |
120 | } |
121 | |
122 | foreach ( $cronhooks as $hook => $keys ) { |
123 | |
124 | foreach ( $keys as $k => $v ) { |
125 | |
126 | $schedule = $v['schedule']; |
127 | |
128 | if ( $schedule ) { |
129 | $result = wp_reschedule_event( $timestamp, $schedule, $hook, $v['args'], true ); |
130 | |
131 | if ( is_wp_error( $result ) ) { |
132 | error_log( |
133 | sprintf( |
134 | /* translators: 1: Hook name, 2: Error code, 3: Error message, 4: Event data. */ |
135 | __( 'Cron reschedule event error for hook: %1$s, Error code: %2$s, Error message: %3$s, Data: %4$s' ), |
136 | $hook, |
137 | $result->get_error_code(), |
138 | $result->get_error_message(), |
139 | wp_json_encode( $v ) |
140 | ) |
141 | ); |
142 | |
143 | /** |
144 | * Fires if an error happens when rescheduling a cron event. |
145 | * |
146 | * @since 6.1.0 |
147 | * |
148 | * @param WP_Error $result The WP_Error object. |
149 | * @param string $hook Action hook to execute when the event is run. |
150 | * @param array $v Event data. |
151 | */ |
152 | do_action( 'cron_reschedule_event_error', $result, $hook, $v ); |
153 | } |
154 | } |
155 | |
156 | $result = wp_unschedule_event( $timestamp, $hook, $v['args'], true ); |
157 | |
158 | if ( is_wp_error( $result ) ) { |
159 | error_log( |
160 | sprintf( |
161 | /* translators: 1: Hook name, 2: Error code, 3: Error message, 4: Event data. */ |
162 | __( 'Cron unschedule event error for hook: %1$s, Error code: %2$s, Error message: %3$s, Data: %4$s' ), |
163 | $hook, |
164 | $result->get_error_code(), |
165 | $result->get_error_message(), |
166 | wp_json_encode( $v ) |
167 | ) |
168 | ); |
169 | |
170 | /** |
171 | * Fires if an error happens when unscheduling a cron event. |
172 | * |
173 | * @since 6.1.0 |
174 | * |
175 | * @param WP_Error $result The WP_Error object. |
176 | * @param string $hook Action hook to execute when the event is run. |
177 | * @param array $v Event data. |
178 | */ |
179 | do_action( 'cron_unschedule_event_error', $result, $hook, $v ); |
180 | } |
181 | |
182 | /** |
183 | * Fires scheduled events. |
184 | * |
185 | * @ignore |
186 | * @since 2.1.0 |
187 | * |
188 | * @param string $hook Name of the hook that was scheduled to be fired. |
189 | * @param array $args The arguments to be passed to the hook. |
190 | */ |
191 | do_action_ref_array( $hook, $v['args'] ); |
192 | |
193 | // If the hook ran too long and another cron process stole the lock, quit. |
194 | if ( _get_cron_lock() !== $doing_wp_cron ) { |
195 | return; |
196 | } |
197 | } |
198 | } |
199 | } |
200 | |
201 | if ( _get_cron_lock() === $doing_wp_cron ) { |
202 | delete_transient( 'doing_cron' ); |
203 | } |
204 | |
205 | die(); |
Note: See TracBrowser
for help on using the repository browser.