just a little note for other devs looking for cli info
[moodle.git] / admin / cron.php
CommitLineData
f578af59 1<?php
f9903ed0 2
540bab47 3/// This script looks through all the module directories for cron.php files
4/// and runs them. These files can contain cleanup functions, email functions
5/// or anything that needs to be run on a regular basis.
6///
7/// This file is best run from cron on the host system (ie outside PHP).
8/// The script can either be invoked via the web server or via a standalone
9/// version of PHP compiled for CGI.
10///
11/// eg wget -q -O /dev/null 'http://moodle.somewhere.edu/admin/cron.php'
20207b82 12/// or php /web/moodle/admin/cron.php
168df8f3 13 set_time_limit(0);
498d4032 14 $starttime = microtime();
f9f4d999 15
a91b910e 16/// this cron script might be considered to be a CLI script even when accessed over HTTP,
17/// we do not want HTML in output and there is no real session ;-)
e13914ac
PS
18/// NOTE: do not use this hack in your cli scripts, it is defined automatically
19/// in lib/setup.php, all you need to do is to prevent access via web
a91b910e 20 define('CLI_SCRIPT', true);
21
11e7b506 22/// Following hack used to identify cron and other CLI scripts - use CLI_SCRIPT or $FULLME == "/$CFG->admin/cropn.php" instead
23 //define('FULLME', 'cron');
9152fc99 24
25/// Do not set moodle cookie because we do not need it here, it is better to emulate session
6800d78e 26 define('NO_MOODLE_COOKIES', true);
9152fc99 27
331ca297 28 require_once(dirname(__FILE__) . '/../config.php');
6e4dc10f 29 require_once($CFG->libdir.'/adminlib.php');
2650c51e 30 require_once($CFG->libdir.'/gradelib.php');
f9903ed0 31
63a11f3c 32/// Extra debugging (set in config.php)
33 if (!empty($CFG->showcronsql)) {
f33e1ed4 34 $DB->set_debug(true);
63a11f3c 35 }
36 if (!empty($CFG->showcrondebugging)) {
37 $CFG->debug = DEBUG_DEVELOPER;
7f51af40 38 $CFG->debugdisplay = true;
63a11f3c 39 }
40
9152fc99 41/// extra safety
dd9e22f8 42 session_get_instance()->write_close();
9152fc99 43
44/// check if execution allowed
e08df351 45 if (isset($_SERVER['REMOTE_ADDR'])) { // if the script is accessed via the web.
20207b82 46 if (!empty($CFG->cronclionly)) {
e08df351 47 // This script can only be run via the cli.
48 print_error('cronerrorclionly', 'admin');
49 exit;
50 }
51 // This script is being called via the web, so check the password if there is one.
52 if (!empty($CFG->cronremotepassword)) {
53 $pass = optional_param('password', '', PARAM_RAW);
54 if($pass != $CFG->cronremotepassword) {
55 // wrong password.
20207b82 56 print_error('cronerrorpassword', 'admin');
e08df351 57 exit;
58 }
59 }
60 }
61
afabdb14 62
9152fc99 63/// emulate normal session
e8b7114d 64 cron_setup_user();
5e601222 65
66/// send mime type and encoding
58e8f85b 67 if (check_browser_version('MSIE')) {
68 //ugly IE hack to work around downloading instead of viewing
810944af 69 @header('Content-Type: text/html; charset=utf-8');
58e8f85b 70 echo "<xmp>"; //<pre> is not good enough for us here
71 } else {
72 //send proper plaintext header
810944af 73 @header('Content-Type: text/plain; charset=utf-8');
58e8f85b 74 }
5e601222 75
9152fc99 76/// no more headers and buffers
77 while(@ob_end_flush());
78
4eefee97 79/// increase memory limit (PHP 5.2 does different calculation, we need more memory now)
80 @raise_memory_limit('128M');
81
428b6fec 82/// Start output log
f9903ed0 83
f9903ed0 84 $timenow = time();
428b6fec 85
defaac4c 86 mtrace("Server Time: ".date('r',$timenow)."\n\n");
f9903ed0 87
dd9e22f8 88
89/// Session gc
90
91 mtrace("Cleaning up stale sessions");
e8656bef 92 session_gc();
dd9e22f8 93
b2ce450a 94/// Run all cron jobs for each module
c88f014a 95
defaac4c 96 mtrace("Starting activity modules");
c2f6fe2f 97 get_mailer('buffer');
953d72db 98 if ($mods = $DB->get_records_select("modules", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
f9903ed0 99 foreach ($mods as $mod) {
673de292 100 $libfile = "$CFG->dirroot/mod/$mod->name/lib.php";
101 if (file_exists($libfile)) {
102 include_once($libfile);
103 $cron_function = $mod->name."_cron";
104 if (function_exists($cron_function)) {
defaac4c 105 mtrace("Processing module function $cron_function ...", '');
d9b06327 106 $pre_dbqueries = null;
ec22e380 107 $pre_dbqueries = $DB->perf_get_queries();
ab130a0b 108 $pre_time = microtime(1);
673de292 109 if ($cron_function()) {
953d72db 110 if (!$DB->set_field("modules", "lastcron", $timenow, array("id"=>$mod->id))) {
defaac4c 111 mtrace("Error: could not update timestamp for $mod->fullname");
673de292 112 }
113 }
ff991c05 114 if (isset($pre_dbqueries)) {
ec22e380 115 mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries");
ff991c05 116 mtrace("... used " . (microtime(1) - $pre_time) . " seconds");
117 }
5e867b23 118 /// Reset possible changes by modules to time_limit. MDL-11597
119 @set_time_limit(0);
defaac4c 120 mtrace("done.");
f9903ed0 121 }
122 }
123 }
124 }
c2f6fe2f 125 get_mailer('close');
defaac4c 126 mtrace("Finished activity modules");
c88f014a 127
f9648e77 128 mtrace("Starting blocks");
953d72db 129 if ($blocks = $DB->get_records_select("block", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
f9648e77 130 // we will need the base class.
131 require_once($CFG->dirroot.'/blocks/moodleblock.class.php');
132 foreach ($blocks as $block) {
133 $blockfile = $CFG->dirroot.'/blocks/'.$block->name.'/block_'.$block->name.'.php';
134 if (file_exists($blockfile)) {
135 require_once($blockfile);
136 $classname = 'block_'.$block->name;
20207b82 137 $blockobj = new $classname;
f9648e77 138 if (method_exists($blockobj,'cron')) {
139 mtrace("Processing cron function for ".$block->name.'....','');
140 if ($blockobj->cron()) {
953d72db 141 if (!$DB->set_field('block', 'lastcron', $timenow, array('id'=>$block->id))) {
f9648e77 142 mtrace('Error: could not update timestamp for '.$block->name);
143 }
144 }
44853b81 145 /// Reset possible changes by blocks to time_limit. MDL-11597
146 @set_time_limit(0);
f9648e77 147 mtrace('done.');
148 }
149 }
150
151 }
152 }
0616d3e8 153 mtrace('Finished blocks');
f9648e77 154
17f1782c 155 mtrace("Starting quiz reports");
156 if ($reports = $DB->get_records_select('quiz_report', "cron > 0 AND ((? - lastcron) > cron)", array($timenow))) {
157 foreach ($reports as $report) {
158 $cronfile = "$CFG->dirroot/mod/quiz/report/$report->name/cron.php";
159 if (file_exists($cronfile)) {
160 include_once($cronfile);
161 $cron_function = 'quiz_report_'.$report->name."_cron";
162 if (function_exists($cron_function)) {
163 mtrace("Processing quiz report cron function $cron_function ...", '');
164 $pre_dbqueries = null;
165 $pre_dbqueries = $DB->perf_get_queries();
166 $pre_time = microtime(1);
167 if ($cron_function()) {
168 if (!$DB->set_field('quiz_report', "lastcron", $timenow, array("id"=>$report->id))) {
169 mtrace("Error: could not update timestamp for $report->name");
170 }
171 }
172 if (isset($pre_dbqueries)) {
173 mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries");
174 mtrace("... used " . (microtime(1) - $pre_time) . " seconds");
175 }
176 mtrace("done.");
177 }
178 }
179 }
180 }
181 mtrace("Finished quiz reports");
20207b82 182
d9b06327 183 mtrace('Starting admin reports');
184 // Admin reports do not have a database table that lists them. Instead a
185 // report includes cron.php with function report_reportname_cron() if it wishes
186 // to be cronned. It is up to cron.php to handle e.g. if it only needs to
187 // actually do anything occasionally.
17da2e6f 188 $reports = get_plugin_list('report');
189 foreach($reports as $report => $reportdir) {
190 $cronfile = $reportdir.'/cron.php';
d9b06327 191 if (file_exists($cronfile)) {
192 require_once($cronfile);
40ad295c 193 $cronfunction = 'report_'.$report.'_cron';
d9b06327 194 mtrace('Processing cron function for '.$report.'...', '');
195 $pre_dbqueries = null;
ec22e380 196 $pre_dbqueries = $DB->perf_get_queries();
ab130a0b 197 $pre_time = microtime(true);
d9b06327 198 $cronfunction();
199 if (isset($pre_dbqueries)) {
ec22e380 200 mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries");
d9b06327 201 mtrace("... used " . round(microtime(true) - $pre_time, 2) . " seconds");
202 }
203 mtrace('done.');
204 }
205 }
206 mtrace('Finished admin reports');
207
0616d3e8 208 mtrace('Removing expired enrolments ...', ''); // See MDL-8785
209 $timenow = time();
cf057534 210 $somefound = false;
3dce78e1 211 // The preferred way saves memory, datablib
cf057534 212 // find courses where limited enrolment is enabled
953d72db 213 $sql = "SELECT ra.roleid, ra.userid, ra.contextid
214 FROM {course} c
215 JOIN {context} cx ON cx.instanceid = c.id
216 JOIN {role_assignments} ra ON ra.contextid = cx.id
217 WHERE cx.contextlevel = '".CONTEXT_COURSE."'
218 AND ra.timeend > 0
219 AND ra.timeend < ?
220 AND c.enrolperiod > 0";
221 if ($rs = $DB->get_recordset_sql($sql, array($timenow))) {
222 foreach ($rs as $oldenrolment) {
223 role_unassign($oldenrolment->roleid, $oldenrolment->userid, 0, $oldenrolment->contextid);
224 $somefound = true;
225 }
226 $rs->close();
cf057534 227 }
953d72db 228 if ($somefound) {
0616d3e8 229 mtrace('Done');
230 } else {
231 mtrace('none found');
232 }
233
d6ead3a2 234
d9b06327 235
1ee0df06 236 mtrace('Starting main gradebook job ...');
2650c51e 237 grade_cron();
1ee0df06 238 mtrace('done.');
2650c51e 239
240
a5d56dc1 241 mtrace('Starting processing the event queue...');
242 events_cron();
243 mtrace('done.');
244
90658eef 245 if ($CFG->enableportfolios) {
7e51bbce 246 // Portfolio cron
247 mtrace('Starting the portfolio cron...');
248 require_once($CFG->libdir . '/portfoliolib.php');
249 portfolio_cron();
250 mtrace('done');
251 }
a5d56dc1 252
b2ce450a 253/// Run all core cron jobs, but not every time since they aren't too important.
20207b82 254/// These don't have a timer to reduce load, so we'll use a random number
b2ce450a 255/// to randomly choose the percentage of times we should run these jobs.
c88f014a 256
b2ce450a 257 srand ((double) microtime() * 10000000);
258 $random100 = rand(0,100);
c88f014a 259
b2ce450a 260 if ($random100 < 20) { // Approximately 20% of the time.
defaac4c 261 mtrace("Running clean-up tasks...");
b2ce450a 262
263 /// Unenrol users who haven't logged in for $CFG->longtimenosee
264
265 if ($CFG->longtimenosee) { // value in days
fce3ef94 266 $cuttime = $timenow - ($CFG->longtimenosee * 3600 * 24);
953d72db 267 $rs = $DB->get_recordset_sql ("SELECT id, userid, courseid
268 FROM {user_lastaccess}
269 WHERE courseid != ".SITEID."
270 AND timeaccess < ?", array($cuttime));
271 foreach ($rs as $assign) {
fce3ef94 272 if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) {
273 if (role_unassign(0, $assign->userid, 0, $context->id)) {
ac7658aa 274 mtrace("removing user $assign->userid from course $assign->courseid as they have not accessed the course for over $CFG->longtimenosee days");
b2ce450a 275 }
276 }
277 }
953d72db 278 $rs->close();
d9420631 279 /// Execute the same query again, looking for remaining records and deleting them
4f0c2d00 280 /// if the user hasn't moodle/course:participate in the CONTEXT_COURSE context (orphan records)
953d72db 281 $rs = $DB->get_recordset_sql ("SELECT id, userid, courseid
282 FROM {user_lastaccess}
283 WHERE courseid != ".SITEID."
284 AND timeaccess < ?", array($cuttime));
285 foreach ($rs as $assign) {
d9420631 286 if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) {
4f0c2d00 287 if (!is_enrolled($context, $assign->userid) and !is_viewing($context, $assign->userid)) {
953d72db 288 $DB->delete_records('user_lastaccess', array('userid'=>$assign->userid, 'courseid'=>$assign->courseid));
d9420631 289 mtrace("Deleted orphan user_lastaccess for user $assign->userid from course $assign->courseid");
290 }
291 }
292 }
953d72db 293 $rs->close();
b2ce450a 294 }
fce3ef94 295 flush();
296
297
6c61fd04 298 /// Delete users who haven't confirmed within required period
c6c43ae9 299
8c182006 300 if (!empty($CFG->deleteunconfirmed)) {
fce3ef94 301 $cuttime = $timenow - ($CFG->deleteunconfirmed * 3600);
953d72db 302 $rs = $DB->get_recordset_sql ("SELECT id, firstname, lastname
303 FROM {user}
304 WHERE confirmed = 0 AND firstaccess > 0
305 AND firstaccess < ?", array($cuttime));
306 foreach ($rs as $user) {
307 if ($DB->delete_records('user', array('id'=>$user->id))) {
fce3ef94 308 mtrace("Deleted unconfirmed user for ".fullname($user, true)." ($user->id)");
f282e631 309 }
6cb86b39 310 }
953d72db 311 $rs->close();
6cb86b39 312 }
69f78bcb 313 flush();
7b8cc339 314
315
7b8cc339 316 /// Delete users who haven't completed profile within required period
317
a4a57da9 318 if (!empty($CFG->deleteincompleteusers)) {
319 $cuttime = $timenow - ($CFG->deleteincompleteusers * 3600);
953d72db 320 $rs = $DB->get_recordset_sql ("SELECT id, username
321 FROM {user}
322 WHERE confirmed = 1 AND lastaccess > 0
323 AND lastaccess < ? AND deleted = 0
324 AND (lastname = '' OR firstname = '' OR email = '')",
325 array($cuttime));
326 foreach ($rs as $user) {
a4a57da9 327 if (delete_user($user)) {
fce3ef94 328 mtrace("Deleted not fully setup user $user->username ($user->id)");
7b8cc339 329 }
330 }
953d72db 331 $rs->close();
7b8cc339 332 }
333 flush();
334
335
b2ce450a 336 /// Delete old logs to save space (this might need a timer to slow it down...)
fce3ef94 337
b2ce450a 338 if (!empty($CFG->loglifetime)) { // value in days
339 $loglifetime = $timenow - ($CFG->loglifetime * 3600 * 24);
953d72db 340 if ($DB->delete_records_select("log", "time < ?", array($loglifetime))) {
fce3ef94 341 mtrace("Deleted old log records");
342 }
b2ce450a 343 }
69f78bcb 344 flush();
cb3a4484 345
fce3ef94 346
cb3a4484 347 /// Delete old cached texts
348
349 if (!empty($CFG->cachetext)) { // Defined in config.php
a9743837 350 $cachelifetime = time() - $CFG->cachetext - 60; // Add an extra minute to allow for really heavy sites
953d72db 351 if ($DB->delete_records_select('cache_text', "timemodified < ?", array($cachelifetime))) {
fce3ef94 352 mtrace("Deleted old cache_text records");
353 }
cb3a4484 354 }
69f78bcb 355 flush();
d846e50a 356
357 if (!empty($CFG->notifyloginfailures)) {
358 notify_login_failures();
f1dc7614 359 mtrace('Notified login failured');
d846e50a 360 }
69f78bcb 361 flush();
d846e50a 362
b61efafb 363 sync_metacourses();
f1dc7614 364 mtrace('Synchronised metacourses');
b61efafb 365
e3b6b2b0 366 //
20207b82 367 // generate new password emails for users
e3b6b2b0 368 //
369 mtrace('checking for create_password');
953d72db 370 if ($DB->count_records('user_preferences', array('name'=>'create_password', 'value'=>'1'))) {
e3b6b2b0 371 mtrace('creating passwords for new users');
20207b82 372 $newusers = $DB->get_records_sql("SELECT u.id as id, u.email, u.firstname,
953d72db 373 u.lastname, u.username,
20207b82
PS
374 p.id as prefid
375 FROM {user} u
953d72db 376 JOIN {user_preferences} p ON u.id=p.userid
32426545 377 WHERE p.name='create_password' AND p.value='1' AND u.email !='' ");
e3b6b2b0 378
379 foreach ($newusers as $newuserid => $newuser) {
380 $newuser->emailstop = 0; // send email regardless
20207b82 381 // email user
e3b6b2b0 382 if (setnew_password_and_mail($newuser)) {
383 // remove user pref
953d72db 384 $DB->delete_records('user_preferences', array('id'=>$newuser->prefid));
e3b6b2b0 385 } else {
386 trigger_error("Could not create and mail new user password!");
387 }
388 }
389 }
20207b82 390
2cb5f03a 391 if (!empty($CFG->usetags)) {
19e41f75 392 require_once($CFG->dirroot.'/tag/lib.php');
393 tag_cron();
f1dc7614 394 mtrace ('Executed tag cron');
19e41f75 395 }
20207b82 396
ad72d0d7 397 // Accesslib stuff
398 cleanup_contexts();
f1dc7614 399 mtrace ('Cleaned up contexts');
fce3ef94 400 gc_cache_flags();
f1dc7614 401 mtrace ('Cleaned cache flags');
ad72d0d7 402 // If you suspect that the context paths are somehow corrupt
20207b82 403 // replace the line below with: build_context_path(true);
ad72d0d7 404 build_context_path();
f1dc7614 405 mtrace ('Built context paths');
406
407 mtrace("Finished clean-up tasks...");
ad72d0d7 408
d846e50a 409 } // End of occasional clean-up tasks
540bab47 410
750eeaeb 411
50999a0b 412 if (empty($CFG->disablescheduledbackups)) { // Defined in config.php
74736e49 413 //Execute backup's cron
414 //Perhaps a long time and memory could help in large sites
a71bfa1c 415 @set_time_limit(0);
8891e81c 416 @raise_memory_limit("192M");
a2ce7344 417 if (function_exists('apache_child_terminate')) {
20207b82
PS
418 // if we are running from Apache, give httpd a hint that
419 // it can recycle the process after it's done. Apache's
a2ce7344 420 // memory management is truly awful but we can help it.
421 @apache_child_terminate();
422 }
74736e49 423 if (file_exists("$CFG->dirroot/backup/backup_scheduled.php") and
424 file_exists("$CFG->dirroot/backup/backuplib.php") and
e91e2b6a 425 file_exists("$CFG->dirroot/backup/lib.php") and
426 file_exists("$CFG->libdir/blocklib.php")) {
74736e49 427 include_once("$CFG->dirroot/backup/backup_scheduled.php");
428 include_once("$CFG->dirroot/backup/backuplib.php");
429 include_once("$CFG->dirroot/backup/lib.php");
defaac4c 430 mtrace("Running backups if required...");
20207b82 431
74736e49 432 if (! schedule_backup_cron()) {
04ddd06c 433 mtrace("ERROR: Something went wrong while performing backup tasks!!!");
74736e49 434 } else {
defaac4c 435 mtrace("Backup tasks finished.");
74736e49 436 }
e6d273eb 437 }
d3159192 438 }
439
8adcb49f 440 if (!empty($CFG->enablerssfeeds)) { //Defined in admin/variables page
3c02d134 441 include_once("$CFG->libdir/rsslib.php");
442 mtrace("Running rssfeeds if required...");
8adcb49f 443
3c02d134 444 if ( ! cron_rss_feeds()) {
445 mtrace("Something went wrong while generating rssfeeds!!!");
446 } else {
447 mtrace("Rssfeeds finished");
8adcb49f 448 }
449 }
450
d14383e0 451/// Run the auth cron, if any
1619d109 452/// before enrolments because it might add users that will be needed in enrol plugins
c7b10b5f 453 $auths = get_enabled_auth_plugins();
454
d14383e0 455 mtrace("Running auth crons if required...");
456 foreach ($auths as $auth) {
457 $authplugin = get_auth_plugin($auth);
458 if (method_exists($authplugin, 'cron')) {
459 mtrace("Running cron for auth/$auth...");
460 $authplugin->cron();
461 if (!empty($authplugin->log)) {
462 mtrace($authplugin->log);
463 }
464 }
465 unset($authplugin);
466 }
467
1619d109 468/// Run the enrolment cron, if any
469 if (!($plugins = explode(',', $CFG->enrol_plugins_enabled))) {
470 $plugins = array($CFG->enrol);
471 }
472 require_once($CFG->dirroot .'/enrol/enrol.class.php');
473 foreach ($plugins as $p) {
474 $enrol = enrolment_factory::factory($p);
475 if (method_exists($enrol, 'cron')) {
476 $enrol->cron();
477 }
478 if (!empty($enrol->log)) {
479 mtrace($enrol->log);
480 }
481 unset($enrol);
482 }
483
72df7e1e 484 if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) {
61460dd6 485 require_once($CFG->dirroot.'/lib/statslib.php');
4900433c 486 // check we're not before our runtime
61460dd6 487 $timetocheck = stats_get_base_daily() + $CFG->statsruntimestarthour*60*60 + $CFG->statsruntimestartminute*60;
4900433c 488
489 if (time() > $timetocheck) {
5e7206a8 490 // process configured number of days as max (defaulting to 31)
491 $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays);
492 if (stats_cron_daily($maxdays)) {
61460dd6 493 if (stats_cron_weekly()) {
494 if (stats_cron_monthly()) {
495 stats_clean_old();
496 }
4900433c 497 }
f3221af9 498 }
61460dd6 499 @set_time_limit(0);
6fdde1d2 500 } else {
5a4b2e8e 501 mtrace('Next stats run after:'. userdate($timetocheck));
f3221af9 502 }
503 }
1ee0df06 504
ce34ed3a 505 // run gradebook import/export/report cron
17da2e6f 506 if ($gradeimports = get_plugin_list('gradeimport')) {
20207b82 507 foreach ($gradeimports as $gradeimport => $plugindir) {
17da2e6f 508 if (file_exists($plugindir.'/lib.php')) {
509 require_once($plugindir.'/lib.php');
20207b82 510 $cron_function = 'grade_import_'.$gradeimport.'_cron';
ce34ed3a 511 if (function_exists($cron_function)) {
512 mtrace("Processing gradebook import function $cron_function ...", '');
384531d5 513 $cron_function();
ce34ed3a 514 }
515 }
20207b82 516 }
ce34ed3a 517 }
518
17da2e6f 519 if ($gradeexports = get_plugin_list('gradeexport')) {
20207b82 520 foreach ($gradeexports as $gradeexport => $plugindir) {
17da2e6f 521 if (file_exists($plugindir.'/lib.php')) {
522 require_once($plugindir.'/lib.php');
20207b82 523 $cron_function = 'grade_export_'.$gradeexport.'_cron';
ce34ed3a 524 if (function_exists($cron_function)) {
525 mtrace("Processing gradebook export function $cron_function ...", '');
384531d5 526 $cron_function();
ce34ed3a 527 }
528 }
529 }
530 }
1ee0df06 531
17da2e6f 532 if ($gradereports = get_plugin_list('gradereport')) {
20207b82 533 foreach ($gradereports as $gradereport => $plugindir) {
17da2e6f 534 if (file_exists($plugindir.'/lib.php')) {
535 require_once($plugindir.'/lib.php');
20207b82 536 $cron_function = 'grade_report_'.$gradereport.'_cron';
ce34ed3a 537 if (function_exists($cron_function)) {
538 mtrace("Processing gradebook report function $cron_function ...", '');
384531d5 539 $cron_function();
ce34ed3a 540 }
541 }
542 }
543 }
20207b82 544
cae83708 545 // Run external blog cron if needed
546 if ($CFG->useexternalblogs) {
547 require_once($CFG->dirroot . '/blog/lib.php');
ec22ccd5 548 mtrace("Fetching external blog entries...", '');
17e5633c
PS
549 $sql = "timefetched < ? OR timefetched = 0";
550 $externalblogs = $DB->get_records_select('blog_external', $sql, array(mktime() - $CFG->externalblogcrontime));
20207b82 551
1fc216ff 552 foreach ($externalblogs as $eb) {
ec22ccd5 553 blog_sync_external_entries($eb);
cae83708 554 }
555 }
1aa01caf 556
ec22ccd5
NC
557 // Run blog associations cleanup
558 if ($CFG->useblogassociations) {
559 require_once($CFG->dirroot . '/blog/lib.php');
560 // delete entries whose contextids no longer exists
561 mtrace("Deleting blog associations linked to non-existent contexts...", '');
562 $DB->delete_records_select('blog_association', 'contextid NOT IN (SELECT id FROM {context})');
563 }
564
1aa01caf 565 // cleanup file trash
566 $fs = get_file_storage();
567 $fs->cron();
568
ba9b44f9 569 // run any customized cronjobs, if any
17da2e6f 570 if ($locals = get_plugin_list('local')) {
571 mtrace('Processing customized cron scripts ...', '');
572 foreach ($locals as $local => $localdir) {
573 if (file_exists("$localdir/cron.php")) {
574 include("$localdir/cron.php");
575 }
576 }
ba9b44f9 577 mtrace('done.');
578 }
579
f3221af9 580
defaac4c 581 mtrace("Cron script completed correctly");
f9903ed0 582
498d4032 583 $difftime = microtime_diff($starttime, microtime());
20207b82 584 mtrace("Execution took ".$difftime." seconds");
498d4032 585
28a082f1 586/// finish the IE hack
58e8f85b 587 if (check_browser_version('MSIE')) {
588 echo "</xmp>";
589 }
590
f578af59 591