Пример #1
0
/**
 * Executes cron functions for a specific type of plugin.
 *
 * @param string $plugintype Plugin type (e.g. 'report')
 * @param string $description If specified, will display 'Starting (whatever)'
 *   and 'Finished (whatever)' lines, otherwise does not display
 */
function cron_execute_plugin_type($plugintype, $description = null)
{
    global $DB;
    // Get list from plugin => function for all plugins
    $plugins = get_plugin_list_with_function($plugintype, 'cron');
    // Modify list for backward compatibility (different files/names)
    $plugins = cron_bc_hack_plugin_functions($plugintype, $plugins);
    // Return if no plugins with cron function to process
    if (!$plugins) {
        return;
    }
    if ($description) {
        mtrace('Starting ' . $description);
    }
    foreach ($plugins as $component => $cronfunction) {
        $dir = core_component::get_component_directory($component);
        // Get cron period if specified in version.php, otherwise assume every cron
        $cronperiod = 0;
        if (file_exists("{$dir}/version.php")) {
            $plugin = new stdClass();
            include "{$dir}/version.php";
            if (isset($plugin->cron)) {
                $cronperiod = $plugin->cron;
            }
        }
        // Using last cron and cron period, don't run if it already ran recently
        $lastcron = get_config($component, 'lastcron');
        if ($cronperiod && $lastcron) {
            if ($lastcron + $cronperiod > time()) {
                // do not execute cron yet
                continue;
            }
        }
        mtrace('Processing cron function for ' . $component . '...');
        cron_trace_time_and_memory();
        $pre_dbqueries = $DB->perf_get_queries();
        $pre_time = microtime(true);
        $cronfunction();
        mtrace("done. (" . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries, " . round(microtime(true) - $pre_time, 2) . " seconds)");
        set_config('lastcron', time(), $component);
        @set_time_limit(0);
    }
    if ($description) {
        mtrace('Finished ' . $description);
    }
}
 /**
  * Runs the automated backups if required
  *
  * @global moodle_database $DB
  */
 public static function run_automated_backup($rundirective = self::RUN_ON_SCHEDULE)
 {
     global $CFG, $DB;
     $status = true;
     $emailpending = false;
     $now = time();
     $config = get_config('backup');
     mtrace("Checking automated backup status", '...');
     $state = backup_cron_automated_helper::get_automated_backup_state($rundirective);
     if ($state === backup_cron_automated_helper::STATE_DISABLED) {
         mtrace('INACTIVE');
         return $state;
     } else {
         if ($state === backup_cron_automated_helper::STATE_RUNNING) {
             mtrace('RUNNING');
             if ($rundirective == self::RUN_IMMEDIATELY) {
                 mtrace('Automated backups are already running. If this script is being run by cron this constitues an error. You will need to increase the time between executions within cron.');
             } else {
                 mtrace("automated backup are already running. Execution delayed");
             }
             return $state;
         } else {
             mtrace('OK');
         }
     }
     backup_cron_automated_helper::set_state_running();
     mtrace("Getting admin info");
     $admin = get_admin();
     if (!$admin) {
         mtrace("Error: No admin account was found");
         $state = false;
     }
     if ($status) {
         mtrace("Checking courses");
         mtrace("Skipping deleted courses", '...');
         mtrace(sprintf("%d courses", backup_cron_automated_helper::remove_deleted_courses_from_schedule()));
     }
     if ($status) {
         mtrace('Running required automated backups...');
         cron_trace_time_and_memory();
         // This could take a while!
         core_php_time_limit::raise();
         raise_memory_limit(MEMORY_EXTRA);
         $nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup($admin->timezone, $now);
         $showtime = "undefined";
         if ($nextstarttime > 0) {
             $showtime = date('r', $nextstarttime);
         }
         $rs = $DB->get_recordset('course');
         foreach ($rs as $course) {
             $backupcourse = $DB->get_record('backup_courses', array('courseid' => $course->id));
             if (!$backupcourse) {
                 $backupcourse = new stdClass();
                 $backupcourse->courseid = $course->id;
                 $backupcourse->laststatus = self::BACKUP_STATUS_NOTYETRUN;
                 $DB->insert_record('backup_courses', $backupcourse);
                 $backupcourse = $DB->get_record('backup_courses', array('courseid' => $course->id));
             }
             // The last backup is considered as successful when OK or SKIPPED.
             $lastbackupwassuccessful = ($backupcourse->laststatus == self::BACKUP_STATUS_SKIPPED || $backupcourse->laststatus == self::BACKUP_STATUS_OK) && ($backupcourse->laststarttime > 0 && $backupcourse->lastendtime > 0);
             // Assume that we are not skipping anything.
             $skipped = false;
             $skippedmessage = '';
             // Check if we are going to be running the backup now.
             $shouldrunnow = $backupcourse->nextstarttime > 0 && $backupcourse->nextstarttime < $now || $rundirective == self::RUN_IMMEDIATELY;
             // If config backup_auto_skip_hidden is set to true, skip courses that are not visible.
             if ($shouldrunnow && $config->backup_auto_skip_hidden) {
                 $skipped = $config->backup_auto_skip_hidden && !$course->visible;
                 $skippedmessage = 'Not visible';
             }
             // If config backup_auto_skip_modif_days is set to true, skip courses
             // that have not been modified since the number of days defined.
             if ($shouldrunnow && !$skipped && $lastbackupwassuccessful && $config->backup_auto_skip_modif_days) {
                 $timenotmodifsincedays = $now - $config->backup_auto_skip_modif_days * DAYSECS;
                 // Check log if there were any modifications to the course content.
                 $logexists = self::is_course_modified($course->id, $timenotmodifsincedays);
                 $skipped = $course->timemodified <= $timenotmodifsincedays && !$logexists;
                 $skippedmessage = 'Not modified in the past ' . $config->backup_auto_skip_modif_days . ' days';
             }
             // If config backup_auto_skip_modif_prev is set to true, skip courses
             // that have not been modified since previous backup.
             if ($shouldrunnow && !$skipped && $lastbackupwassuccessful && $config->backup_auto_skip_modif_prev) {
                 // Check log if there were any modifications to the course content.
                 $logexists = self::is_course_modified($course->id, $backupcourse->laststarttime);
                 $skipped = $course->timemodified <= $backupcourse->laststarttime && !$logexists;
                 $skippedmessage = 'Not modified since previous backup';
             }
             // Check if the course is not scheduled to run right now.
             if (!$shouldrunnow) {
                 $backupcourse->nextstarttime = $nextstarttime;
                 $DB->update_record('backup_courses', $backupcourse);
                 mtrace('Skipping ' . $course->fullname . ' (Not scheduled for backup until ' . $showtime . ')');
             } else {
                 if ($skipped) {
                     // Must have been skipped for a reason.
                     $backupcourse->laststatus = self::BACKUP_STATUS_SKIPPED;
                     $backupcourse->nextstarttime = $nextstarttime;
                     $DB->update_record('backup_courses', $backupcourse);
                     mtrace('Skipping ' . $course->fullname . ' (' . $skippedmessage . ')');
                     mtrace('Backup of \'' . $course->fullname . '\' is scheduled on ' . $showtime);
                 } else {
                     // Backup every non-skipped courses.
                     mtrace('Backing up ' . $course->fullname . '...');
                     // We have to send an email because we have included at least one backup.
                     $emailpending = true;
                     // Only make the backup if laststatus isn't 2-UNFINISHED (uncontrolled error).
                     if ($backupcourse->laststatus != self::BACKUP_STATUS_UNFINISHED) {
                         // Set laststarttime.
                         $starttime = time();
                         $backupcourse->laststarttime = time();
                         $backupcourse->laststatus = self::BACKUP_STATUS_UNFINISHED;
                         $DB->update_record('backup_courses', $backupcourse);
                         $backupcourse->laststatus = backup_cron_automated_helper::launch_automated_backup($course, $backupcourse->laststarttime, $admin->id);
                         $backupcourse->lastendtime = time();
                         $backupcourse->nextstarttime = $nextstarttime;
                         $DB->update_record('backup_courses', $backupcourse);
                         if ($backupcourse->laststatus === self::BACKUP_STATUS_OK) {
                             // Clean up any excess course backups now that we have
                             // taken a successful backup.
                             $removedcount = backup_cron_automated_helper::remove_excess_backups($course);
                         }
                     }
                     mtrace("complete - next execution: {$showtime}");
                 }
             }
         }
         $rs->close();
     }
     //Send email to admin if necessary
     if ($emailpending) {
         mtrace("Sending email to admin");
         $message = "";
         $count = backup_cron_automated_helper::get_backup_status_array();
         $haserrors = $count[self::BACKUP_STATUS_ERROR] != 0 || $count[self::BACKUP_STATUS_UNFINISHED] != 0;
         // Build the message text.
         // Summary.
         $message .= get_string('summary') . "\n";
         $message .= "==================================================\n";
         $message .= '  ' . get_string('courses') . '; ' . array_sum($count) . "\n";
         $message .= '  ' . get_string('ok') . '; ' . $count[self::BACKUP_STATUS_OK] . "\n";
         $message .= '  ' . get_string('skipped') . '; ' . $count[self::BACKUP_STATUS_SKIPPED] . "\n";
         $message .= '  ' . get_string('error') . '; ' . $count[self::BACKUP_STATUS_ERROR] . "\n";
         $message .= '  ' . get_string('unfinished') . '; ' . $count[self::BACKUP_STATUS_UNFINISHED] . "\n";
         $message .= '  ' . get_string('warning') . '; ' . $count[self::BACKUP_STATUS_WARNING] . "\n";
         $message .= '  ' . get_string('backupnotyetrun') . '; ' . $count[self::BACKUP_STATUS_NOTYETRUN] . "\n\n";
         //Reference
         if ($haserrors) {
             $message .= "  " . get_string('backupfailed') . "\n\n";
             $dest_url = "{$CFG->wwwroot}/report/backups/index.php";
             $message .= "  " . get_string('backuptakealook', '', $dest_url) . "\n\n";
             //Set message priority
             $admin->priority = 1;
             //Reset unfinished to error
             $DB->set_field('backup_courses', 'laststatus', '0', array('laststatus' => '2'));
         } else {
             $message .= "  " . get_string('backupfinished') . "\n";
         }
         //Build the message subject
         $site = get_site();
         $prefix = format_string($site->shortname, true, array('context' => context_course::instance(SITEID))) . ": ";
         if ($haserrors) {
             $prefix .= "[" . strtoupper(get_string('error')) . "] ";
         }
         $subject = $prefix . get_string('automatedbackupstatus', 'backup');
         //Send the message
         $eventdata = new stdClass();
         $eventdata->modulename = 'moodle';
         $eventdata->userfrom = $admin;
         $eventdata->userto = $admin;
         $eventdata->subject = $subject;
         $eventdata->fullmessage = $message;
         $eventdata->fullmessageformat = FORMAT_PLAIN;
         $eventdata->fullmessagehtml = '';
         $eventdata->smallmessage = '';
         $eventdata->component = 'moodle';
         $eventdata->name = 'backup';
         message_send($eventdata);
     }
     //Everything is finished stop backup_auto_running
     backup_cron_automated_helper::set_state_running(false);
     mtrace('Automated backups complete.');
     return $status;
 }
Пример #3
0
/**
 * Update calendar subscriptions.
 *
 * @return bool
 */
function calendar_cron()
{
    global $CFG, $DB;
    // In order to execute this we need bennu.
    require_once $CFG->libdir . '/bennu/bennu.inc.php';
    mtrace('Updating calendar subscriptions:');
    cron_trace_time_and_memory();
    $time = time();
    $subscriptions = $DB->get_records_sql('SELECT * FROM {event_subscriptions} WHERE pollinterval > 0 AND lastupdated + pollinterval < ?', array($time));
    foreach ($subscriptions as $sub) {
        mtrace("Updating calendar subscription {$sub->name} in course {$sub->courseid}");
        try {
            $log = calendar_update_subscription_events($sub->id);
            mtrace(trim(strip_tags($log)));
        } catch (moodle_exception $ex) {
            mtrace('Error updating calendar subscription: ' . $ex->getMessage());
        }
    }
    mtrace('Finished updating calendar subscriptions.');
    return true;
}
Пример #4
0
 /**
  * Cron cleanup job.
  */
 public function cron()
 {
     global $CFG, $DB;
     require_once $CFG->libdir . '/cronlib.php';
     // find out all stale draft areas (older than 4 days) and purge them
     // those are identified by time stamp of the /. root dir
     mtrace('Deleting old draft files... ', '');
     cron_trace_time_and_memory();
     $old = time() - 60 * 60 * 24 * 4;
     $sql = "SELECT *\n                  FROM {files}\n                 WHERE component = 'user' AND filearea = 'draft' AND filepath = '/' AND filename = '.'\n                       AND timecreated < :old";
     $rs = $DB->get_recordset_sql($sql, array('old' => $old));
     foreach ($rs as $dir) {
         $this->delete_area_files($dir->contextid, $dir->component, $dir->filearea, $dir->itemid);
     }
     $rs->close();
     mtrace('done.');
     // remove orphaned preview files (that is files in the core preview filearea without
     // the existing original file)
     mtrace('Deleting orphaned preview files... ', '');
     cron_trace_time_and_memory();
     $sql = "SELECT p.*\n                  FROM {files} p\n             LEFT JOIN {files} o ON (p.filename = o.contenthash)\n                 WHERE p.contextid = ? AND p.component = 'core' AND p.filearea = 'preview' AND p.itemid = 0\n                       AND o.id IS NULL";
     $syscontext = context_system::instance();
     $rs = $DB->get_recordset_sql($sql, array($syscontext->id));
     foreach ($rs as $orphan) {
         $file = $this->get_file_instance($orphan);
         if (!$file->is_directory()) {
             $file->delete();
         }
     }
     $rs->close();
     mtrace('done.');
     // Remove orphaned converted files (that is files in the core documentconversion filearea without
     // the existing original file).
     mtrace('Deleting orphaned document conversion files... ', '');
     cron_trace_time_and_memory();
     $sql = "SELECT p.*\n                  FROM {files} p\n             LEFT JOIN {files} o ON (p.filename = o.contenthash)\n                 WHERE p.contextid = ? AND p.component = 'core' AND p.filearea = 'documentconversion' AND p.itemid = 0\n                       AND o.id IS NULL";
     $syscontext = context_system::instance();
     $rs = $DB->get_recordset_sql($sql, array($syscontext->id));
     foreach ($rs as $orphan) {
         $file = $this->get_file_instance($orphan);
         if (!$file->is_directory()) {
             $file->delete();
         }
     }
     $rs->close();
     mtrace('done.');
     // remove trash pool files once a day
     // if you want to disable purging of trash put $CFG->fileslastcleanup=time(); into config.php
     if (empty($CFG->fileslastcleanup) or $CFG->fileslastcleanup < time() - 60 * 60 * 24) {
         require_once $CFG->libdir . '/filelib.php';
         // Delete files that are associated with a context that no longer exists.
         mtrace('Cleaning up files from deleted contexts... ', '');
         cron_trace_time_and_memory();
         $sql = "SELECT DISTINCT f.contextid\n                    FROM {files} f\n                    LEFT OUTER JOIN {context} c ON f.contextid = c.id\n                    WHERE c.id IS NULL";
         $rs = $DB->get_recordset_sql($sql);
         if ($rs->valid()) {
             $fs = get_file_storage();
             foreach ($rs as $ctx) {
                 $fs->delete_area_files($ctx->contextid);
             }
         }
         $rs->close();
         mtrace('done.');
         mtrace('Deleting trash files... ', '');
         cron_trace_time_and_memory();
         fulldelete($this->trashdir);
         set_config('fileslastcleanup', time());
         mtrace('done.');
     }
 }
Пример #5
0
/**
 * used by admin/cron.php to get similarity scores from submitted files.
 *
 */
function plagiarism_cron()
{
    global $CFG;
    if (empty($CFG->enableplagiarism)) {
        return '';
    }
    $plagiarismplugins = plagiarism_load_available_plugins();
    foreach ($plagiarismplugins as $plugin => $dir) {
        mtrace('Processing cron function for plagiarism_plugin_' . $plugin . '...', '');
        cron_trace_time_and_memory();
        require_once $dir . '/lib.php';
        $plagiarismclass = "plagiarism_plugin_{$plugin}";
        $plagiarismplugin = new $plagiarismclass();
        $plagiarismplugin->cron();
    }
}
Пример #6
0
/**
 * Remove old stats data
 */
function stats_clean_old()
{
    global $DB;
    mtrace("Running stats cleanup tasks...");
    cron_trace_time_and_memory();
    $deletebefore = stats_get_base_monthly();
    // delete dailies older than 3 months (to be safe)
    $deletebefore = strtotime('-3 months', $deletebefore);
    $DB->delete_records_select('stats_daily', "timeend < {$deletebefore}");
    $DB->delete_records_select('stats_user_daily', "timeend < {$deletebefore}");
    // delete weeklies older than 9  months (to be safe)
    $deletebefore = strtotime('-6 months', $deletebefore);
    $DB->delete_records_select('stats_weekly', "timeend < {$deletebefore}");
    $DB->delete_records_select('stats_user_weekly', "timeend < {$deletebefore}");
    // don't delete monthlies
    mtrace("...stats cleanup finished");
}
    if ($input == 'n') {
        mtrace('exited');
        exit;
    }
}
set_time_limit(0);
$starttime = microtime();
// Increase memory limit
raise_memory_limit(MEMORY_EXTRA);
// Emulate normal session - we use admin accoutn by default
cron_setup_user();
// Start output log
$timenow = time();
mtrace("Server Time: " . date('r', $timenow) . "\n\n");
mtrace("Processing Dialogue module cron ...", '');
cron_trace_time_and_memory();
$pre_dbqueries = null;
$pre_dbqueries = $DB->perf_get_queries();
$pre_time = microtime(1);
// Process bulk open rules
dialogue_process_bulk_openrules();
if (isset($pre_dbqueries)) {
    mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries");
    mtrace("... used " . (microtime(1) - $pre_time) . " seconds");
}
// Reset possible changes by modules to time_limit. MDL-11597
@set_time_limit(0);
mtrace("done.");
gc_collect_cycles();
mtrace('Cron completed at ' . date('H:i:s') . '. Memory used ' . display_size(memory_get_usage()) . '.');
$difftime = microtime_diff($starttime, microtime());