Commit | Line | Data |
---|---|---|
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 | ||
2be4d090 MD |
245 | |
246 | if ($CFG->enablecompletion) { | |
247 | // Completion cron | |
248 | mtrace('Starting the completion cron...'); | |
249 | require_once($CFG->libdir . '/completion/cron.php'); | |
250 | completion_cron(); | |
251 | mtrace('done'); | |
252 | } | |
253 | ||
254 | ||
90658eef | 255 | if ($CFG->enableportfolios) { |
7e51bbce | 256 | // Portfolio cron |
257 | mtrace('Starting the portfolio cron...'); | |
258 | require_once($CFG->libdir . '/portfoliolib.php'); | |
259 | portfolio_cron(); | |
260 | mtrace('done'); | |
261 | } | |
a5d56dc1 | 262 | |
b2ce450a | 263 | /// Run all core cron jobs, but not every time since they aren't too important. |
20207b82 | 264 | /// These don't have a timer to reduce load, so we'll use a random number |
b2ce450a | 265 | /// to randomly choose the percentage of times we should run these jobs. |
c88f014a | 266 | |
b2ce450a | 267 | srand ((double) microtime() * 10000000); |
268 | $random100 = rand(0,100); | |
c88f014a | 269 | |
b2ce450a | 270 | if ($random100 < 20) { // Approximately 20% of the time. |
defaac4c | 271 | mtrace("Running clean-up tasks..."); |
b2ce450a | 272 | |
273 | /// Unenrol users who haven't logged in for $CFG->longtimenosee | |
274 | ||
275 | if ($CFG->longtimenosee) { // value in days | |
fce3ef94 | 276 | $cuttime = $timenow - ($CFG->longtimenosee * 3600 * 24); |
953d72db | 277 | $rs = $DB->get_recordset_sql ("SELECT id, userid, courseid |
278 | FROM {user_lastaccess} | |
279 | WHERE courseid != ".SITEID." | |
280 | AND timeaccess < ?", array($cuttime)); | |
281 | foreach ($rs as $assign) { | |
fce3ef94 | 282 | if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) { |
283 | if (role_unassign(0, $assign->userid, 0, $context->id)) { | |
ac7658aa | 284 | mtrace("removing user $assign->userid from course $assign->courseid as they have not accessed the course for over $CFG->longtimenosee days"); |
b2ce450a | 285 | } |
286 | } | |
287 | } | |
953d72db | 288 | $rs->close(); |
d9420631 | 289 | /// Execute the same query again, looking for remaining records and deleting them |
4f0c2d00 | 290 | /// if the user hasn't moodle/course:participate in the CONTEXT_COURSE context (orphan records) |
953d72db | 291 | $rs = $DB->get_recordset_sql ("SELECT id, userid, courseid |
292 | FROM {user_lastaccess} | |
293 | WHERE courseid != ".SITEID." | |
294 | AND timeaccess < ?", array($cuttime)); | |
295 | foreach ($rs as $assign) { | |
d9420631 | 296 | if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) { |
4f0c2d00 | 297 | if (!is_enrolled($context, $assign->userid) and !is_viewing($context, $assign->userid)) { |
953d72db | 298 | $DB->delete_records('user_lastaccess', array('userid'=>$assign->userid, 'courseid'=>$assign->courseid)); |
d9420631 | 299 | mtrace("Deleted orphan user_lastaccess for user $assign->userid from course $assign->courseid"); |
300 | } | |
301 | } | |
302 | } | |
953d72db | 303 | $rs->close(); |
b2ce450a | 304 | } |
fce3ef94 | 305 | flush(); |
306 | ||
307 | ||
6c61fd04 | 308 | /// Delete users who haven't confirmed within required period |
c6c43ae9 | 309 | |
8c182006 | 310 | if (!empty($CFG->deleteunconfirmed)) { |
fce3ef94 | 311 | $cuttime = $timenow - ($CFG->deleteunconfirmed * 3600); |
953d72db | 312 | $rs = $DB->get_recordset_sql ("SELECT id, firstname, lastname |
313 | FROM {user} | |
314 | WHERE confirmed = 0 AND firstaccess > 0 | |
315 | AND firstaccess < ?", array($cuttime)); | |
316 | foreach ($rs as $user) { | |
317 | if ($DB->delete_records('user', array('id'=>$user->id))) { | |
fce3ef94 | 318 | mtrace("Deleted unconfirmed user for ".fullname($user, true)." ($user->id)"); |
f282e631 | 319 | } |
6cb86b39 | 320 | } |
953d72db | 321 | $rs->close(); |
6cb86b39 | 322 | } |
69f78bcb | 323 | flush(); |
7b8cc339 | 324 | |
325 | ||
7b8cc339 | 326 | /// Delete users who haven't completed profile within required period |
327 | ||
a4a57da9 | 328 | if (!empty($CFG->deleteincompleteusers)) { |
329 | $cuttime = $timenow - ($CFG->deleteincompleteusers * 3600); | |
953d72db | 330 | $rs = $DB->get_recordset_sql ("SELECT id, username |
331 | FROM {user} | |
332 | WHERE confirmed = 1 AND lastaccess > 0 | |
333 | AND lastaccess < ? AND deleted = 0 | |
334 | AND (lastname = '' OR firstname = '' OR email = '')", | |
335 | array($cuttime)); | |
336 | foreach ($rs as $user) { | |
a4a57da9 | 337 | if (delete_user($user)) { |
fce3ef94 | 338 | mtrace("Deleted not fully setup user $user->username ($user->id)"); |
7b8cc339 | 339 | } |
340 | } | |
953d72db | 341 | $rs->close(); |
7b8cc339 | 342 | } |
343 | flush(); | |
344 | ||
345 | ||
b2ce450a | 346 | /// Delete old logs to save space (this might need a timer to slow it down...) |
fce3ef94 | 347 | |
b2ce450a | 348 | if (!empty($CFG->loglifetime)) { // value in days |
349 | $loglifetime = $timenow - ($CFG->loglifetime * 3600 * 24); | |
953d72db | 350 | if ($DB->delete_records_select("log", "time < ?", array($loglifetime))) { |
fce3ef94 | 351 | mtrace("Deleted old log records"); |
352 | } | |
b2ce450a | 353 | } |
69f78bcb | 354 | flush(); |
cb3a4484 | 355 | |
fce3ef94 | 356 | |
cb3a4484 | 357 | /// Delete old cached texts |
358 | ||
359 | if (!empty($CFG->cachetext)) { // Defined in config.php | |
a9743837 | 360 | $cachelifetime = time() - $CFG->cachetext - 60; // Add an extra minute to allow for really heavy sites |
953d72db | 361 | if ($DB->delete_records_select('cache_text', "timemodified < ?", array($cachelifetime))) { |
fce3ef94 | 362 | mtrace("Deleted old cache_text records"); |
363 | } | |
cb3a4484 | 364 | } |
69f78bcb | 365 | flush(); |
d846e50a | 366 | |
367 | if (!empty($CFG->notifyloginfailures)) { | |
368 | notify_login_failures(); | |
f1dc7614 | 369 | mtrace('Notified login failured'); |
d846e50a | 370 | } |
69f78bcb | 371 | flush(); |
d846e50a | 372 | |
b61efafb | 373 | sync_metacourses(); |
f1dc7614 | 374 | mtrace('Synchronised metacourses'); |
b61efafb | 375 | |
e3b6b2b0 | 376 | // |
20207b82 | 377 | // generate new password emails for users |
e3b6b2b0 | 378 | // |
379 | mtrace('checking for create_password'); | |
953d72db | 380 | if ($DB->count_records('user_preferences', array('name'=>'create_password', 'value'=>'1'))) { |
e3b6b2b0 | 381 | mtrace('creating passwords for new users'); |
20207b82 | 382 | $newusers = $DB->get_records_sql("SELECT u.id as id, u.email, u.firstname, |
953d72db | 383 | u.lastname, u.username, |
20207b82 PS |
384 | p.id as prefid |
385 | FROM {user} u | |
953d72db | 386 | JOIN {user_preferences} p ON u.id=p.userid |
32426545 | 387 | WHERE p.name='create_password' AND p.value='1' AND u.email !='' "); |
e3b6b2b0 | 388 | |
389 | foreach ($newusers as $newuserid => $newuser) { | |
390 | $newuser->emailstop = 0; // send email regardless | |
20207b82 | 391 | // email user |
e3b6b2b0 | 392 | if (setnew_password_and_mail($newuser)) { |
393 | // remove user pref | |
953d72db | 394 | $DB->delete_records('user_preferences', array('id'=>$newuser->prefid)); |
e3b6b2b0 | 395 | } else { |
396 | trigger_error("Could not create and mail new user password!"); | |
397 | } | |
398 | } | |
399 | } | |
20207b82 | 400 | |
2cb5f03a | 401 | if (!empty($CFG->usetags)) { |
19e41f75 | 402 | require_once($CFG->dirroot.'/tag/lib.php'); |
403 | tag_cron(); | |
f1dc7614 | 404 | mtrace ('Executed tag cron'); |
19e41f75 | 405 | } |
20207b82 | 406 | |
ad72d0d7 | 407 | // Accesslib stuff |
408 | cleanup_contexts(); | |
f1dc7614 | 409 | mtrace ('Cleaned up contexts'); |
fce3ef94 | 410 | gc_cache_flags(); |
f1dc7614 | 411 | mtrace ('Cleaned cache flags'); |
ad72d0d7 | 412 | // If you suspect that the context paths are somehow corrupt |
20207b82 | 413 | // replace the line below with: build_context_path(true); |
ad72d0d7 | 414 | build_context_path(); |
f1dc7614 | 415 | mtrace ('Built context paths'); |
416 | ||
417 | mtrace("Finished clean-up tasks..."); | |
ad72d0d7 | 418 | |
d846e50a | 419 | } // End of occasional clean-up tasks |
540bab47 | 420 | |
c717a0d3 EL |
421 | // Disabled until implemented. MDL-21432, MDL-22184 |
422 | if (1 == 2 && empty($CFG->disablescheduledbackups)) { // Defined in config.php | |
74736e49 | 423 | //Execute backup's cron |
424 | //Perhaps a long time and memory could help in large sites | |
a71bfa1c | 425 | @set_time_limit(0); |
8891e81c | 426 | @raise_memory_limit("192M"); |
a2ce7344 | 427 | if (function_exists('apache_child_terminate')) { |
20207b82 PS |
428 | // if we are running from Apache, give httpd a hint that |
429 | // it can recycle the process after it's done. Apache's | |
a2ce7344 | 430 | // memory management is truly awful but we can help it. |
431 | @apache_child_terminate(); | |
432 | } | |
74736e49 | 433 | if (file_exists("$CFG->dirroot/backup/backup_scheduled.php") and |
434 | file_exists("$CFG->dirroot/backup/backuplib.php") and | |
e91e2b6a | 435 | file_exists("$CFG->dirroot/backup/lib.php") and |
436 | file_exists("$CFG->libdir/blocklib.php")) { | |
74736e49 | 437 | include_once("$CFG->dirroot/backup/backup_scheduled.php"); |
438 | include_once("$CFG->dirroot/backup/backuplib.php"); | |
439 | include_once("$CFG->dirroot/backup/lib.php"); | |
defaac4c | 440 | mtrace("Running backups if required..."); |
20207b82 | 441 | |
74736e49 | 442 | if (! schedule_backup_cron()) { |
04ddd06c | 443 | mtrace("ERROR: Something went wrong while performing backup tasks!!!"); |
74736e49 | 444 | } else { |
defaac4c | 445 | mtrace("Backup tasks finished."); |
74736e49 | 446 | } |
e6d273eb | 447 | } |
d3159192 | 448 | } |
449 | ||
d14383e0 | 450 | /// Run the auth cron, if any |
1619d109 | 451 | /// before enrolments because it might add users that will be needed in enrol plugins |
c7b10b5f | 452 | $auths = get_enabled_auth_plugins(); |
453 | ||
d14383e0 | 454 | mtrace("Running auth crons if required..."); |
455 | foreach ($auths as $auth) { | |
456 | $authplugin = get_auth_plugin($auth); | |
457 | if (method_exists($authplugin, 'cron')) { | |
458 | mtrace("Running cron for auth/$auth..."); | |
459 | $authplugin->cron(); | |
460 | if (!empty($authplugin->log)) { | |
461 | mtrace($authplugin->log); | |
462 | } | |
463 | } | |
464 | unset($authplugin); | |
465 | } | |
466 | ||
1619d109 | 467 | /// Run the enrolment cron, if any |
468 | if (!($plugins = explode(',', $CFG->enrol_plugins_enabled))) { | |
469 | $plugins = array($CFG->enrol); | |
470 | } | |
471 | require_once($CFG->dirroot .'/enrol/enrol.class.php'); | |
472 | foreach ($plugins as $p) { | |
473 | $enrol = enrolment_factory::factory($p); | |
474 | if (method_exists($enrol, 'cron')) { | |
475 | $enrol->cron(); | |
476 | } | |
477 | if (!empty($enrol->log)) { | |
478 | mtrace($enrol->log); | |
479 | } | |
480 | unset($enrol); | |
481 | } | |
482 | ||
72df7e1e | 483 | if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) { |
61460dd6 | 484 | require_once($CFG->dirroot.'/lib/statslib.php'); |
4900433c | 485 | // check we're not before our runtime |
61460dd6 | 486 | $timetocheck = stats_get_base_daily() + $CFG->statsruntimestarthour*60*60 + $CFG->statsruntimestartminute*60; |
4900433c | 487 | |
488 | if (time() > $timetocheck) { | |
5e7206a8 | 489 | // process configured number of days as max (defaulting to 31) |
490 | $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays); | |
491 | if (stats_cron_daily($maxdays)) { | |
61460dd6 | 492 | if (stats_cron_weekly()) { |
493 | if (stats_cron_monthly()) { | |
494 | stats_clean_old(); | |
495 | } | |
4900433c | 496 | } |
f3221af9 | 497 | } |
61460dd6 | 498 | @set_time_limit(0); |
6fdde1d2 | 499 | } else { |
5a4b2e8e | 500 | mtrace('Next stats run after:'. userdate($timetocheck)); |
f3221af9 | 501 | } |
502 | } | |
1ee0df06 | 503 | |
ce34ed3a | 504 | // run gradebook import/export/report cron |
17da2e6f | 505 | if ($gradeimports = get_plugin_list('gradeimport')) { |
20207b82 | 506 | foreach ($gradeimports as $gradeimport => $plugindir) { |
17da2e6f | 507 | if (file_exists($plugindir.'/lib.php')) { |
508 | require_once($plugindir.'/lib.php'); | |
20207b82 | 509 | $cron_function = 'grade_import_'.$gradeimport.'_cron'; |
ce34ed3a | 510 | if (function_exists($cron_function)) { |
511 | mtrace("Processing gradebook import function $cron_function ...", ''); | |
384531d5 | 512 | $cron_function(); |
ce34ed3a | 513 | } |
514 | } | |
20207b82 | 515 | } |
ce34ed3a | 516 | } |
517 | ||
17da2e6f | 518 | if ($gradeexports = get_plugin_list('gradeexport')) { |
20207b82 | 519 | foreach ($gradeexports as $gradeexport => $plugindir) { |
17da2e6f | 520 | if (file_exists($plugindir.'/lib.php')) { |
521 | require_once($plugindir.'/lib.php'); | |
20207b82 | 522 | $cron_function = 'grade_export_'.$gradeexport.'_cron'; |
ce34ed3a | 523 | if (function_exists($cron_function)) { |
524 | mtrace("Processing gradebook export function $cron_function ...", ''); | |
384531d5 | 525 | $cron_function(); |
ce34ed3a | 526 | } |
527 | } | |
528 | } | |
529 | } | |
1ee0df06 | 530 | |
17da2e6f | 531 | if ($gradereports = get_plugin_list('gradereport')) { |
20207b82 | 532 | foreach ($gradereports as $gradereport => $plugindir) { |
17da2e6f | 533 | if (file_exists($plugindir.'/lib.php')) { |
534 | require_once($plugindir.'/lib.php'); | |
20207b82 | 535 | $cron_function = 'grade_report_'.$gradereport.'_cron'; |
ce34ed3a | 536 | if (function_exists($cron_function)) { |
537 | mtrace("Processing gradebook report function $cron_function ...", ''); | |
384531d5 | 538 | $cron_function(); |
ce34ed3a | 539 | } |
540 | } | |
541 | } | |
542 | } | |
20207b82 | 543 | |
cae83708 | 544 | // Run external blog cron if needed |
545 | if ($CFG->useexternalblogs) { | |
546 | require_once($CFG->dirroot . '/blog/lib.php'); | |
ec22ccd5 | 547 | mtrace("Fetching external blog entries...", ''); |
17e5633c PS |
548 | $sql = "timefetched < ? OR timefetched = 0"; |
549 | $externalblogs = $DB->get_records_select('blog_external', $sql, array(mktime() - $CFG->externalblogcrontime)); | |
20207b82 | 550 | |
1fc216ff | 551 | foreach ($externalblogs as $eb) { |
ec22ccd5 | 552 | blog_sync_external_entries($eb); |
cae83708 | 553 | } |
554 | } | |
1aa01caf | 555 | |
ec22ccd5 NC |
556 | // Run blog associations cleanup |
557 | if ($CFG->useblogassociations) { | |
558 | require_once($CFG->dirroot . '/blog/lib.php'); | |
559 | // delete entries whose contextids no longer exists | |
560 | mtrace("Deleting blog associations linked to non-existent contexts...", ''); | |
561 | $DB->delete_records_select('blog_association', 'contextid NOT IN (SELECT id FROM {context})'); | |
562 | } | |
563 | ||
1aa01caf | 564 | // cleanup file trash |
565 | $fs = get_file_storage(); | |
566 | $fs->cron(); | |
567 | ||
2d0acbd5 JP |
568 | //cleanup old session linked tokens |
569 | //deletes the session linked tokens that are over a day old. | |
570 | mtrace("Deleting session linked tokens more than one day old...", ''); | |
571 | $DB->delete_records_select('external_tokens', 'lastaccess < {onedayago} AND tokentype = {tokentype}', | |
572 | array('onedayago' => time() - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED)); | |
573 | ||
ba9b44f9 | 574 | // run any customized cronjobs, if any |
17da2e6f | 575 | if ($locals = get_plugin_list('local')) { |
576 | mtrace('Processing customized cron scripts ...', ''); | |
577 | foreach ($locals as $local => $localdir) { | |
578 | if (file_exists("$localdir/cron.php")) { | |
579 | include("$localdir/cron.php"); | |
580 | } | |
581 | } | |
ba9b44f9 | 582 | mtrace('done.'); |
583 | } | |
584 | ||
f3221af9 | 585 | |
defaac4c | 586 | mtrace("Cron script completed correctly"); |
f9903ed0 | 587 | |
498d4032 | 588 | $difftime = microtime_diff($starttime, microtime()); |
20207b82 | 589 | mtrace("Execution took ".$difftime." seconds"); |
498d4032 | 590 | |
28a082f1 | 591 | /// finish the IE hack |
58e8f85b | 592 | if (check_browser_version('MSIE')) { |
593 | echo "</xmp>"; | |
594 | } | |
595 | ||
f578af59 | 596 |