Commit | Line | Data |
---|---|---|
28bd3d9a PS |
1 | <?php |
2 | ||
3 | // This file is part of Moodle - http://moodle.org/ | |
4 | // | |
5 | // Moodle is free software: you can redistribute it and/or modify | |
6 | // it under the terms of the GNU General Public License as published by | |
7 | // the Free Software Foundation, either version 3 of the License, or | |
8 | // (at your option) any later version. | |
9 | // | |
10 | // Moodle is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU General Public License | |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
18 | /** | |
19 | * Cron functions. | |
20 | * | |
21 | * @package core | |
22 | * @subpackage admin | |
23 | * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com | |
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | */ | |
26 | ||
27 | function cron_run() { | |
28 | global $DB, $CFG, $OUTPUT; | |
29 | ||
9957af68 PS |
30 | if (CLI_MAINTENANCE) { |
31 | echo "CLI maintenance mode active, cron execution suspended.\n"; | |
32 | exit(1); | |
33 | } | |
34 | ||
4c56c7bf PS |
35 | if (moodle_needs_upgrading()) { |
36 | echo "Moodle upgrade pending, cron execution suspended.\n"; | |
37 | exit(1); | |
38 | } | |
39 | ||
28bd3d9a PS |
40 | require_once($CFG->libdir.'/adminlib.php'); |
41 | require_once($CFG->libdir.'/gradelib.php'); | |
42 | ||
43 | if (!empty($CFG->showcronsql)) { | |
44 | $DB->set_debug(true); | |
45 | } | |
46 | if (!empty($CFG->showcrondebugging)) { | |
47 | $CFG->debug = DEBUG_DEVELOPER; | |
48 | $CFG->debugdisplay = true; | |
49 | } | |
50 | ||
51 | set_time_limit(0); | |
52 | $starttime = microtime(); | |
53 | ||
41209c1e | 54 | /// increase memory limit |
346c5887 | 55 | raise_memory_limit(MEMORY_EXTRA); |
28bd3d9a PS |
56 | |
57 | /// emulate normal session | |
58 | cron_setup_user(); | |
59 | ||
60 | /// Start output log | |
61 | ||
62 | $timenow = time(); | |
63 | ||
64 | mtrace("Server Time: ".date('r',$timenow)."\n\n"); | |
65 | ||
66 | ||
67 | /// Session gc | |
68 | ||
69 | mtrace("Cleaning up stale sessions"); | |
70 | session_gc(); | |
71 | ||
72 | /// Run all cron jobs for each module | |
73 | ||
74 | mtrace("Starting activity modules"); | |
75 | get_mailer('buffer'); | |
76 | if ($mods = $DB->get_records_select("modules", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) { | |
77 | foreach ($mods as $mod) { | |
78 | $libfile = "$CFG->dirroot/mod/$mod->name/lib.php"; | |
79 | if (file_exists($libfile)) { | |
80 | include_once($libfile); | |
81 | $cron_function = $mod->name."_cron"; | |
82 | if (function_exists($cron_function)) { | |
83 | mtrace("Processing module function $cron_function ...", ''); | |
84 | $pre_dbqueries = null; | |
85 | $pre_dbqueries = $DB->perf_get_queries(); | |
86 | $pre_time = microtime(1); | |
87 | if ($cron_function()) { | |
f685e830 | 88 | $DB->set_field("modules", "lastcron", $timenow, array("id"=>$mod->id)); |
28bd3d9a PS |
89 | } |
90 | if (isset($pre_dbqueries)) { | |
91 | mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries"); | |
92 | mtrace("... used " . (microtime(1) - $pre_time) . " seconds"); | |
93 | } | |
94 | /// Reset possible changes by modules to time_limit. MDL-11597 | |
95 | @set_time_limit(0); | |
96 | mtrace("done."); | |
97 | } | |
98 | } | |
99 | } | |
100 | } | |
101 | get_mailer('close'); | |
102 | mtrace("Finished activity modules"); | |
103 | ||
104 | mtrace("Starting blocks"); | |
105 | if ($blocks = $DB->get_records_select("block", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) { | |
106 | // we will need the base class. | |
107 | require_once($CFG->dirroot.'/blocks/moodleblock.class.php'); | |
108 | foreach ($blocks as $block) { | |
109 | $blockfile = $CFG->dirroot.'/blocks/'.$block->name.'/block_'.$block->name.'.php'; | |
110 | if (file_exists($blockfile)) { | |
111 | require_once($blockfile); | |
112 | $classname = 'block_'.$block->name; | |
113 | $blockobj = new $classname; | |
114 | if (method_exists($blockobj,'cron')) { | |
115 | mtrace("Processing cron function for ".$block->name.'....',''); | |
116 | if ($blockobj->cron()) { | |
f685e830 | 117 | $DB->set_field('block', 'lastcron', $timenow, array('id'=>$block->id)); |
28bd3d9a PS |
118 | } |
119 | /// Reset possible changes by blocks to time_limit. MDL-11597 | |
120 | @set_time_limit(0); | |
121 | mtrace('done.'); | |
122 | } | |
123 | } | |
124 | ||
125 | } | |
126 | } | |
127 | mtrace('Finished blocks'); | |
128 | ||
129 | mtrace("Starting quiz reports"); | |
f2557823 | 130 | if ($reports = $DB->get_records_select('quiz_reports', "cron > 0 AND ((? - lastcron) > cron)", array($timenow))) { |
28bd3d9a PS |
131 | foreach ($reports as $report) { |
132 | $cronfile = "$CFG->dirroot/mod/quiz/report/$report->name/cron.php"; | |
133 | if (file_exists($cronfile)) { | |
134 | include_once($cronfile); | |
135 | $cron_function = 'quiz_report_'.$report->name."_cron"; | |
136 | if (function_exists($cron_function)) { | |
137 | mtrace("Processing quiz report cron function $cron_function ...", ''); | |
138 | $pre_dbqueries = null; | |
139 | $pre_dbqueries = $DB->perf_get_queries(); | |
140 | $pre_time = microtime(1); | |
141 | if ($cron_function()) { | |
f2557823 | 142 | $DB->set_field('quiz_reports', "lastcron", $timenow, array("id"=>$report->id)); |
28bd3d9a PS |
143 | } |
144 | if (isset($pre_dbqueries)) { | |
145 | mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries"); | |
146 | mtrace("... used " . (microtime(1) - $pre_time) . " seconds"); | |
147 | } | |
148 | mtrace("done."); | |
149 | } | |
150 | } | |
151 | } | |
152 | } | |
153 | mtrace("Finished quiz reports"); | |
154 | ||
b5541735 PS |
155 | mtrace('Starting admin reports'); |
156 | cron_execute_plugin_type('report'); | |
157 | mtrace('Finished admin reports'); | |
158 | ||
28bd3d9a PS |
159 | mtrace('Starting main gradebook job ...'); |
160 | grade_cron(); | |
161 | mtrace('done.'); | |
162 | ||
163 | ||
164 | mtrace('Starting processing the event queue...'); | |
165 | events_cron(); | |
166 | mtrace('done.'); | |
167 | ||
168 | ||
169 | if ($CFG->enablecompletion) { | |
170 | // Completion cron | |
171 | mtrace('Starting the completion cron...'); | |
172 | require_once($CFG->libdir . '/completion/cron.php'); | |
173 | completion_cron(); | |
174 | mtrace('done'); | |
175 | } | |
176 | ||
177 | ||
178 | if ($CFG->enableportfolios) { | |
179 | // Portfolio cron | |
180 | mtrace('Starting the portfolio cron...'); | |
181 | require_once($CFG->libdir . '/portfoliolib.php'); | |
182 | portfolio_cron(); | |
183 | mtrace('done'); | |
184 | } | |
185 | ||
8cf1862c DM |
186 | //now do plagiarism checks |
187 | require_once($CFG->libdir.'/plagiarismlib.php'); | |
188 | plagiarism_cron(); | |
189 | ||
28bd3d9a PS |
190 | /// Run all core cron jobs, but not every time since they aren't too important. |
191 | /// These don't have a timer to reduce load, so we'll use a random number | |
192 | /// to randomly choose the percentage of times we should run these jobs. | |
193 | ||
194 | srand ((double) microtime() * 10000000); | |
195 | $random100 = rand(0,100); | |
196 | ||
197 | if ($random100 < 20) { // Approximately 20% of the time. | |
198 | mtrace("Running clean-up tasks..."); | |
199 | ||
200 | /// Delete users who haven't confirmed within required period | |
201 | ||
202 | if (!empty($CFG->deleteunconfirmed)) { | |
203 | $cuttime = $timenow - ($CFG->deleteunconfirmed * 3600); | |
204 | $rs = $DB->get_recordset_sql ("SELECT id, firstname, lastname | |
205 | FROM {user} | |
206 | WHERE confirmed = 0 AND firstaccess > 0 | |
207 | AND firstaccess < ?", array($cuttime)); | |
208 | foreach ($rs as $user) { | |
209 | if ($DB->delete_records('user', array('id'=>$user->id))) { | |
210 | mtrace("Deleted unconfirmed user for ".fullname($user, true)." ($user->id)"); | |
211 | } | |
212 | } | |
213 | $rs->close(); | |
214 | } | |
215 | flush(); | |
216 | ||
217 | ||
218 | /// Delete users who haven't completed profile within required period | |
219 | ||
220 | if (!empty($CFG->deleteincompleteusers)) { | |
221 | $cuttime = $timenow - ($CFG->deleteincompleteusers * 3600); | |
f91f3f63 | 222 | $rs = $DB->get_recordset_sql ("SELECT * |
28bd3d9a PS |
223 | FROM {user} |
224 | WHERE confirmed = 1 AND lastaccess > 0 | |
225 | AND lastaccess < ? AND deleted = 0 | |
226 | AND (lastname = '' OR firstname = '' OR email = '')", | |
227 | array($cuttime)); | |
228 | foreach ($rs as $user) { | |
229 | if (delete_user($user)) { | |
230 | mtrace("Deleted not fully setup user $user->username ($user->id)"); | |
231 | } | |
232 | } | |
233 | $rs->close(); | |
234 | } | |
235 | flush(); | |
236 | ||
237 | ||
238 | /// Delete old logs to save space (this might need a timer to slow it down...) | |
239 | ||
240 | if (!empty($CFG->loglifetime)) { // value in days | |
241 | $loglifetime = $timenow - ($CFG->loglifetime * 3600 * 24); | |
242 | if ($DB->delete_records_select("log", "time < ?", array($loglifetime))) { | |
243 | mtrace("Deleted old log records"); | |
244 | } | |
245 | } | |
246 | flush(); | |
247 | ||
cbb9e9b8 EL |
248 | // Delete old backup_controllers and logs |
249 | ||
250 | if (!empty($CFG->loglifetime)) { // value in days | |
251 | $loglifetime = $timenow - ($CFG->loglifetime * 3600 * 24); | |
252 | // Delete child records from backup_logs | |
253 | $DB->execute("DELETE FROM {backup_logs} | |
254 | WHERE EXISTS ( | |
255 | SELECT 'x' | |
256 | FROM {backup_controllers} bc | |
257 | WHERE bc.backupid = {backup_logs}.backupid | |
258 | AND bc.timecreated < ?)", array($loglifetime)); | |
259 | // Delete records from backup_controllers | |
260 | $DB->execute("DELETE FROM {backup_controllers} | |
261 | WHERE timecreated < ?", array($loglifetime)); | |
262 | mtrace("Deleted old backup records"); | |
263 | } | |
264 | flush(); | |
265 | ||
266 | ||
28bd3d9a PS |
267 | |
268 | /// Delete old cached texts | |
269 | ||
270 | if (!empty($CFG->cachetext)) { // Defined in config.php | |
271 | $cachelifetime = time() - $CFG->cachetext - 60; // Add an extra minute to allow for really heavy sites | |
272 | if ($DB->delete_records_select('cache_text', "timemodified < ?", array($cachelifetime))) { | |
273 | mtrace("Deleted old cache_text records"); | |
274 | } | |
275 | } | |
276 | flush(); | |
277 | ||
278 | if (!empty($CFG->notifyloginfailures)) { | |
279 | notify_login_failures(); | |
280 | mtrace('Notified login failured'); | |
281 | } | |
282 | flush(); | |
283 | ||
284 | // | |
285 | // generate new password emails for users | |
286 | // | |
287 | mtrace('checking for create_password'); | |
288 | if ($DB->count_records('user_preferences', array('name'=>'create_password', 'value'=>'1'))) { | |
289 | mtrace('creating passwords for new users'); | |
bc61aa40 | 290 | $newusers = $DB->get_recordset_sql("SELECT u.id as id, u.email, u.firstname, |
28bd3d9a PS |
291 | u.lastname, u.username, |
292 | p.id as prefid | |
293 | FROM {user} u | |
294 | JOIN {user_preferences} p ON u.id=p.userid | |
295 | WHERE p.name='create_password' AND p.value='1' AND u.email !='' "); | |
296 | ||
bc61aa40 | 297 | foreach ($newusers as $newuser) { |
28bd3d9a PS |
298 | // email user |
299 | if (setnew_password_and_mail($newuser)) { | |
bc61aa40 PS |
300 | unset_user_preference('create_password', $newuser); |
301 | set_user_preference('auth_forcepasswordchange', 1, $newuser); | |
28bd3d9a PS |
302 | } else { |
303 | trigger_error("Could not create and mail new user password!"); | |
304 | } | |
305 | } | |
bc61aa40 | 306 | $newusers->close(); |
28bd3d9a PS |
307 | } |
308 | ||
309 | if (!empty($CFG->usetags)) { | |
310 | require_once($CFG->dirroot.'/tag/lib.php'); | |
311 | tag_cron(); | |
312 | mtrace ('Executed tag cron'); | |
313 | } | |
314 | ||
315 | // Accesslib stuff | |
316 | cleanup_contexts(); | |
317 | mtrace ('Cleaned up contexts'); | |
318 | gc_cache_flags(); | |
319 | mtrace ('Cleaned cache flags'); | |
320 | // If you suspect that the context paths are somehow corrupt | |
321 | // replace the line below with: build_context_path(true); | |
322 | build_context_path(); | |
323 | mtrace ('Built context paths'); | |
324 | ||
212badff | 325 | if (!empty($CFG->messagingdeletereadnotificationsdelay)) { |
7868480a | 326 | $notificationdeletetime = time() - $CFG->messagingdeletereadnotificationsdelay; |
212badff AD |
327 | $DB->delete_records_select('message_read', 'notification=1 AND timeread<:notificationdeletetime', array('notificationdeletetime'=>$notificationdeletetime)); |
328 | mtrace('Cleaned up read notifications'); | |
329 | } | |
330 | ||
28bd3d9a PS |
331 | mtrace("Finished clean-up tasks..."); |
332 | ||
333 | } // End of occasional clean-up tasks | |
334 | ||
bac233d3 SH |
335 | // Run automated backups if required. |
336 | require_once($CFG->dirroot.'/backup/util/includes/backup_includes.php'); | |
337 | require_once($CFG->dirroot.'/backup/util/helper/backup_cron_helper.class.php'); | |
338 | backup_cron_automated_helper::run_automated_backup(); | |
28bd3d9a PS |
339 | |
340 | /// Run the auth cron, if any | |
341 | /// before enrolments because it might add users that will be needed in enrol plugins | |
342 | $auths = get_enabled_auth_plugins(); | |
343 | ||
344 | mtrace("Running auth crons if required..."); | |
345 | foreach ($auths as $auth) { | |
346 | $authplugin = get_auth_plugin($auth); | |
347 | if (method_exists($authplugin, 'cron')) { | |
348 | mtrace("Running cron for auth/$auth..."); | |
349 | $authplugin->cron(); | |
350 | if (!empty($authplugin->log)) { | |
351 | mtrace($authplugin->log); | |
352 | } | |
353 | } | |
354 | unset($authplugin); | |
355 | } | |
356 | ||
357 | mtrace("Running enrol crons if required..."); | |
358 | $enrols = enrol_get_plugins(true); | |
359 | foreach($enrols as $ename=>$enrol) { | |
360 | // do this for all plugins, disabled plugins might want to cleanup stuff such as roles | |
361 | if (!$enrol->is_cron_required()) { | |
362 | continue; | |
363 | } | |
364 | mtrace("Running cron for enrol_$ename..."); | |
365 | $enrol->cron(); | |
366 | $enrol->set_config('lastcron', time()); | |
367 | } | |
368 | ||
369 | if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) { | |
370 | require_once($CFG->dirroot.'/lib/statslib.php'); | |
371 | // check we're not before our runtime | |
372 | $timetocheck = stats_get_base_daily() + $CFG->statsruntimestarthour*60*60 + $CFG->statsruntimestartminute*60; | |
373 | ||
374 | if (time() > $timetocheck) { | |
375 | // process configured number of days as max (defaulting to 31) | |
376 | $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays); | |
377 | if (stats_cron_daily($maxdays)) { | |
378 | if (stats_cron_weekly()) { | |
379 | if (stats_cron_monthly()) { | |
380 | stats_clean_old(); | |
381 | } | |
382 | } | |
383 | } | |
384 | @set_time_limit(0); | |
385 | } else { | |
386 | mtrace('Next stats run after:'. userdate($timetocheck)); | |
387 | } | |
388 | } | |
389 | ||
28bd3d9a | 390 | |
b5541735 PS |
391 | mtrace('Starting course reports'); |
392 | cron_execute_plugin_type('coursereport'); | |
393 | mtrace('Finished course reports'); | |
28bd3d9a | 394 | |
b5541735 PS |
395 | // run gradebook import/export/report cron |
396 | mtrace('Starting gradebook plugins'); | |
397 | cron_execute_plugin_type('gradeimport'); | |
398 | cron_execute_plugin_type('gradeexport'); | |
399 | cron_execute_plugin_type('gradereport'); | |
400 | mtrace('Finished gradebook plugins'); | |
28bd3d9a PS |
401 | |
402 | // Run external blog cron if needed | |
403 | if ($CFG->useexternalblogs) { | |
404 | require_once($CFG->dirroot . '/blog/lib.php'); | |
405 | mtrace("Fetching external blog entries...", ''); | |
406 | $sql = "timefetched < ? OR timefetched = 0"; | |
407 | $externalblogs = $DB->get_records_select('blog_external', $sql, array(mktime() - $CFG->externalblogcrontime)); | |
408 | ||
409 | foreach ($externalblogs as $eb) { | |
410 | blog_sync_external_entries($eb); | |
411 | } | |
b5541735 | 412 | mtrace('done.'); |
28bd3d9a PS |
413 | } |
414 | ||
415 | // Run blog associations cleanup | |
416 | if ($CFG->useblogassociations) { | |
417 | require_once($CFG->dirroot . '/blog/lib.php'); | |
418 | // delete entries whose contextids no longer exists | |
419 | mtrace("Deleting blog associations linked to non-existent contexts...", ''); | |
420 | $DB->delete_records_select('blog_association', 'contextid NOT IN (SELECT id FROM {context})'); | |
b5541735 | 421 | mtrace('done.'); |
28bd3d9a PS |
422 | } |
423 | ||
424 | //Run registration updated cron | |
425 | mtrace(get_string('siteupdatesstart', 'hub')); | |
426 | require_once($CFG->dirroot . '/admin/registration/lib.php'); | |
427 | $registrationmanager = new registration_manager(); | |
428 | $registrationmanager->cron(); | |
429 | mtrace(get_string('siteupdatesend', 'hub')); | |
430 | ||
431 | // cleanup file trash | |
432 | $fs = get_file_storage(); | |
433 | $fs->cron(); | |
434 | ||
435 | //cleanup old session linked tokens | |
436 | //deletes the session linked tokens that are over a day old. | |
437 | mtrace("Deleting session linked tokens more than one day old...", ''); | |
438 | $DB->delete_records_select('external_tokens', 'lastaccess < :onedayago AND tokentype = :tokentype', | |
439 | array('onedayago' => time() - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED)); | |
440 | mtrace('done.'); | |
441 | ||
b5541735 PS |
442 | // all other plugins |
443 | cron_execute_plugin_type('message', 'message plugins'); | |
444 | cron_execute_plugin_type('filter', 'filters'); | |
e4a626b9 | 445 | cron_execute_plugin_type('editor', 'editors'); |
b5541735 PS |
446 | cron_execute_plugin_type('format', 'course formats'); |
447 | cron_execute_plugin_type('profilefield', 'profile fields'); | |
448 | cron_execute_plugin_type('webservice', 'webservices'); | |
e4a626b9 | 449 | // TODO: Repository lib.php files are messed up (include many other files, etc), so it is |
450 | // currently not possible to implement repository plugin cron using this infrastructure | |
cd092ece | 451 | // cron_execute_plugin_type('repository', 'repository plugins'); |
b5541735 PS |
452 | cron_execute_plugin_type('qtype', 'question types'); |
453 | cron_execute_plugin_type('plagiarism', 'plagiarism plugins'); | |
454 | cron_execute_plugin_type('theme', 'themes'); | |
67a6243a | 455 | cron_execute_plugin_type('tool', 'admin tools'); |
b5541735 PS |
456 | |
457 | // and finally run any local cronjobs, if any | |
28bd3d9a PS |
458 | if ($locals = get_plugin_list('local')) { |
459 | mtrace('Processing customized cron scripts ...', ''); | |
b5541735 PS |
460 | // new cron functions in lib.php first |
461 | cron_execute_plugin_type('local'); | |
462 | // legacy cron files are executed directly | |
28bd3d9a PS |
463 | foreach ($locals as $local => $localdir) { |
464 | if (file_exists("$localdir/cron.php")) { | |
465 | include("$localdir/cron.php"); | |
466 | } | |
467 | } | |
468 | mtrace('done.'); | |
469 | } | |
470 | ||
28bd3d9a PS |
471 | mtrace("Cron script completed correctly"); |
472 | ||
473 | $difftime = microtime_diff($starttime, microtime()); | |
474 | mtrace("Execution took ".$difftime." seconds"); | |
cbb9e9b8 | 475 | } |
b5541735 | 476 | |
e4a626b9 | 477 | /** |
478 | * Executes cron functions for a specific type of plugin. | |
479 | * @param string $plugintype Plugin type (e.g. 'report') | |
480 | * @param string $description If specified, will display 'Starting (whatever)' | |
481 | * and 'Finished (whatever)' lines, otherwise does not display | |
482 | */ | |
b5541735 PS |
483 | function cron_execute_plugin_type($plugintype, $description = null) { |
484 | global $DB; | |
485 | ||
e4a626b9 | 486 | // Get list from plugin => function for all plugins |
487 | $plugins = get_plugin_list_with_function($plugintype, 'cron'); | |
488 | ||
489 | // Modify list for backward compatibility (different files/names) | |
490 | $plugins = cron_bc_hack_plugin_functions($plugintype, $plugins); | |
b5541735 | 491 | |
e4a626b9 | 492 | // Return if no plugins with cron function to process |
b5541735 PS |
493 | if (!$plugins) { |
494 | return; | |
495 | } | |
496 | ||
497 | if ($description) { | |
498 | mtrace('Starting '.$description); | |
499 | } | |
500 | ||
501 | foreach ($plugins as $component=>$cronfunction) { | |
cd092ece | 502 | $dir = get_component_directory($component); |
e4a626b9 | 503 | |
504 | // Get cron period if specified in version.php, otherwise assume every cron | |
b5541735 PS |
505 | $cronperiod = 0; |
506 | if (file_exists("$dir/version.php")) { | |
507 | $plugin = new stdClass(); | |
508 | include("$dir/version.php"); | |
509 | if (isset($plugin->cron)) { | |
510 | $cronperiod = $plugin->cron; | |
511 | } | |
512 | } | |
513 | ||
e4a626b9 | 514 | // Using last cron and cron period, don't run if it already ran recently |
b5541735 | 515 | $lastcron = get_config($component, 'lastcron'); |
e4a626b9 | 516 | if ($cronperiod && $lastcron) { |
b5541735 PS |
517 | if ($lastcron + $cronperiod > time()) { |
518 | // do not execute cron yet | |
519 | continue; | |
520 | } | |
521 | } | |
522 | ||
e4a626b9 | 523 | mtrace('Processing cron function for ' . $component . '...'); |
b5541735 | 524 | $pre_dbqueries = $DB->perf_get_queries(); |
e4a626b9 | 525 | $pre_time = microtime(true); |
b5541735 PS |
526 | |
527 | $cronfunction(); | |
528 | ||
e4a626b9 | 529 | mtrace("done. (" . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries, " . |
530 | round(microtime(true) - $pre_time, 2) . " seconds)"); | |
b5541735 PS |
531 | |
532 | set_config('lastcron', time(), $component); | |
533 | } | |
534 | ||
535 | if ($description) { | |
e4a626b9 | 536 | mtrace('Finished ' . $description); |
b5541735 PS |
537 | } |
538 | } | |
539 | ||
e4a626b9 | 540 | /** |
541 | * Used to add in old-style cron functions within plugins that have not been converted to the | |
542 | * new standard API. (The standard API is frankenstyle_name_cron() in lib.php; some types used | |
543 | * cron.php and some used a different name.) | |
544 | * @param string $plugintype Plugin type e.g. 'report' | |
545 | * @param array $plugins Array from plugin name (e.g. 'report_frog') to function name (e.g. | |
546 | * 'report_frog_cron') for plugin cron functions that were already found using the new API | |
547 | * @return array Revised version of $plugins that adds in any extra plugin functions found by | |
548 | * looking in the older location | |
549 | */ | |
550 | function cron_bc_hack_plugin_functions($plugintype, $plugins) { | |
551 | global $CFG; // mandatory in case it is referenced by include()d PHP script | |
552 | ||
553 | if ($plugintype === 'report') { | |
554 | // Admin reports only - not course report because course report was | |
555 | // never implemented before, so doesn't need BC | |
556 | foreach (get_plugin_list($plugintype) as $pluginname=>$dir) { | |
557 | $component = $plugintype . '_' . $pluginname; | |
b5541735 | 558 | if (isset($plugins[$component])) { |
e4a626b9 | 559 | // We already have detected the function using the new API |
b5541735 PS |
560 | continue; |
561 | } | |
562 | if (!file_exists("$dir/cron.php")) { | |
e4a626b9 | 563 | // No old style cron file present |
b5541735 PS |
564 | continue; |
565 | } | |
566 | include_once("$dir/cron.php"); | |
e4a626b9 | 567 | $cronfunction = $component . '_cron'; |
b5541735 PS |
568 | if (function_exists($cronfunction)) { |
569 | $plugins[$component] = $cronfunction; | |
570 | } else { | |
e4a626b9 | 571 | debugging("Invalid legacy cron.php detected in $component, " . |
572 | "please use lib.php instead"); | |
b5541735 PS |
573 | } |
574 | } | |
b5541735 | 575 | } else if (strpos($plugintype, 'grade') === 0) { |
e4a626b9 | 576 | // Detect old style cron function names |
577 | // Plugin gradeexport_frog used to use grade_export_frog_cron() instead of | |
578 | // new standard API gradeexport_frog_cron(). Also applies to gradeimport, gradereport | |
b5541735 PS |
579 | foreach(get_plugin_list($plugintype) as $pluginname=>$dir) { |
580 | $component = $plugintype.'_'.$pluginname; | |
581 | if (isset($plugins[$component])) { | |
e4a626b9 | 582 | // We already have detected the function using the new API |
b5541735 PS |
583 | continue; |
584 | } | |
585 | if (!file_exists("$dir/lib.php")) { | |
586 | continue; | |
587 | } | |
588 | include_once("$dir/lib.php"); | |
e4a626b9 | 589 | $cronfunction = str_replace('grade', 'grade_', $plugintype) . '_' . |
590 | $pluginname . '_cron'; | |
b5541735 PS |
591 | if (function_exists($cronfunction)) { |
592 | $plugins[$component] = $cronfunction; | |
593 | } | |
594 | } | |
595 | } | |
596 | ||
597 | return $plugins; | |
598 | } |