예제 #1
0
 public function test_get_next_adhoc_task()
 {
     $this->resetAfterTest(true);
     // Create an adhoc task.
     $task = new \core\task\adhoc_test_task();
     // Queue it.
     $task = \core\task\manager::queue_adhoc_task($task);
     $now = time();
     // Get it from the scheduler.
     $task = \core\task\manager::get_next_adhoc_task($now);
     $this->assertNotNull($task);
     $task->execute();
     \core\task\manager::adhoc_task_failed($task);
     // Should not get any task.
     $task = \core\task\manager::get_next_adhoc_task($now);
     $this->assertNull($task);
     // Should get the adhoc task (retry after delay).
     $task = \core\task\manager::get_next_adhoc_task($now + 120);
     $this->assertNotNull($task);
     $task->execute();
     \core\task\manager::adhoc_task_complete($task);
     // Should not get any task.
     $task = \core\task\manager::get_next_adhoc_task($now);
     $this->assertNull($task);
 }
 public function definition()
 {
     $mform = $this->_form;
     /** @var \core\task\scheduled_task $task */
     $task = $this->_customdata;
     $lastrun = $task->get_last_run_time() ? userdate($task->get_last_run_time()) : get_string('never');
     $nextrun = $task->get_next_run_time();
     if ($task->get_disabled()) {
         $nextrun = get_string('disabled', 'tool_task');
     } else {
         if ($nextrun > time()) {
             $nextrun = userdate($nextrun);
         } else {
             $nextrun = get_string('asap', 'tool_task');
         }
     }
     $mform->addElement('static', 'lastrun', get_string('lastruntime', 'tool_task'), $lastrun);
     $mform->addElement('static', 'nextrun', get_string('nextruntime', 'tool_task'), $nextrun);
     $mform->addElement('text', 'minute', get_string('taskscheduleminute', 'tool_task'));
     $mform->setType('minute', PARAM_RAW);
     $mform->addHelpButton('minute', 'taskscheduleminute', 'tool_task');
     $mform->addElement('text', 'hour', get_string('taskschedulehour', 'tool_task'));
     $mform->setType('hour', PARAM_RAW);
     $mform->addHelpButton('hour', 'taskschedulehour', 'tool_task');
     $mform->addElement('text', 'day', get_string('taskscheduleday', 'tool_task'));
     $mform->setType('day', PARAM_RAW);
     $mform->addHelpButton('day', 'taskscheduleday', 'tool_task');
     $mform->addElement('text', 'month', get_string('taskschedulemonth', 'tool_task'));
     $mform->setType('month', PARAM_RAW);
     $mform->addHelpButton('month', 'taskschedulemonth', 'tool_task');
     $mform->addElement('text', 'dayofweek', get_string('taskscheduledayofweek', 'tool_task'));
     $mform->setType('dayofweek', PARAM_RAW);
     $mform->addHelpButton('dayofweek', 'taskscheduledayofweek', 'tool_task');
     $mform->addElement('advcheckbox', 'disabled', get_string('disabled', 'tool_task'));
     $mform->addHelpButton('disabled', 'disabled', 'tool_task');
     $mform->addElement('advcheckbox', 'resettodefaults', get_string('resettasktodefaults', 'tool_task'));
     $mform->addHelpButton('resettodefaults', 'resettasktodefaults', 'tool_task');
     $mform->disabledIf('minute', 'resettodefaults', 'checked');
     $mform->disabledIf('hour', 'resettodefaults', 'checked');
     $mform->disabledIf('day', 'resettodefaults', 'checked');
     $mform->disabledIf('dayofweek', 'resettodefaults', 'checked');
     $mform->disabledIf('month', 'resettodefaults', 'checked');
     $mform->disabledIf('disabled', 'resettodefaults', 'checked');
     $mform->addElement('hidden', 'task', get_class($task));
     $mform->setType('task', PARAM_RAW);
     $mform->addElement('hidden', 'action', 'edit');
     $mform->setType('action', PARAM_ALPHANUMEXT);
     $this->add_action_buttons(true, get_string('savechanges'));
     // Do not use defaults for existing values, the set_data() is the correct way.
     $this->set_data(\core\task\manager::record_from_scheduled_task($task));
 }
예제 #3
0
 /**
  * Store new setting
  *
  * @param mixed $data string or array, must not be NULL
  * @return string empty string if ok, string error message otherwise
  */
 public function write_setting($data)
 {
     $oldvalue = get_config($this->plugin, $this->name);
     if ($oldvalue == $data && !empty($data)) {
         return '';
     }
     if (!empty($data)) {
         $this->config_write($this->name, $data);
         $this->config_write('sharepoint_initialized', '0');
         $sharepointinit = new \local_o365\task\sharepointinit();
         \core\task\manager::queue_adhoc_task($sharepointinit);
     } else {
         // Support default value so it doesn't prompt for setting on install.
         $this->config_write($this->name, '');
     }
     return '';
 }
예제 #4
0
 public function check_status(thresholds $thresholds, $params = array())
 {
     if (!isset($params['task'])) {
         throw new invalid_service_exception("Task parameter required");
     }
     if (!($task = \core\task\manager::get_scheduled_task($params['task']))) {
         throw new invalid_service_exception("Task not found");
     }
     $result = new status_result();
     $lastrun = $task->get_last_run_time();
     if (!$lastrun) {
         $result->text = 'Task has never run';
         $result->status = service::NAGIOS_STATUS_UNKNOWN;
     } else {
         $timeelapsed = time() - $lastrun;
         $result->status = $thresholds->check($timeelapsed);
         $result->text = "Last ran at " . date(DATE_RSS, $lastrun) . ", {$timeelapsed} seconds ago";
     }
     return $result;
 }
 /**
  * Called when an role has been removed.
  */
 public static function roledeleted(\core\event\role_unassigned $event)
 {
     global $CFG;
     if (\panopto_data::get_panopto_course_id($event->courseid) === false || $CFG->version < $requiredVersion) {
         return;
     }
     $task = new \block_panopto\task\update_user();
     $task->set_custom_data(array('courseid' => $event->courseid, 'relateduserid' => $event->relateduserid, 'contextid' => $event->contextid, 'eventtype' => "role"));
     if ($CFG->block_panopto_async_tasks) {
         \core\task\manager::queue_adhoc_task($task);
     } else {
         $task->execute();
     }
 }
예제 #6
0
 *   - For debugging & better logging, you are encouraged to use in the command line:
 *     -d log_errors=1 -d error_reporting=E_ALL -d display_errors=0 -d html_errors=0
 *
 * Performance notes:
 * We have optimized it as best as we could for PostgreSQL and MySQL, with 27K students
 * we have seen this take 10 minutes.
 *
 * @package    auth_cas
 * @copyright  2007 Jerome Gutierrez - based on code by Martin Langhoff
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @deprecated since Moodle 3.0 MDL-51824 - please do not use this CLI script any more, use scheduled task instead.
 * @todo MDL-50264 This will be deleted in Moodle 3.2.
 */
define('CLI_SCRIPT', true);
require __DIR__ . '/../../../config.php';
require_once $CFG->dirroot . '/course/lib.php';
require_once $CFG->libdir . '/clilib.php';
// Ensure errors are well explained
set_debugging(DEBUG_DEVELOPER, true);
if (!is_enabled_auth('cas')) {
    error_log('[AUTH CAS] ' . get_string('pluginnotenabled', 'auth_ldap'));
    die;
}
cli_problem('[AUTH CAS] The sync users cron has been deprecated. Please use the scheduled task instead.');
// Abort execution of the CLI script if the auth_cas\task\sync_task is enabled.
$task = \core\task\manager::get_scheduled_task('auth_cas\\task\\sync_task');
if (!$task->get_disabled()) {
    cli_error('[AUTH CAS] The scheduled task sync_task is enabled, the cron execution has been aborted.');
}
$casauth = get_auth_plugin('cas');
$casauth->sync_users(true);
예제 #7
0
    try {
        get_mailer('buffer');
        $task->execute();
        if (isset($predbqueries)) {
            mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries");
            mtrace("... used " . (microtime(1) - $pretime) . " seconds");
        }
        mtrace("Task completed.");
        \core\task\manager::scheduled_task_complete($task);
        get_mailer('close');
        exit(0);
    } catch (Exception $e) {
        if ($DB->is_transaction_started()) {
            $DB->force_transaction_rollback();
        }
        mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries");
        mtrace("... used " . (microtime(true) - $pretime) . " seconds");
        mtrace("Task failed: " . $e->getMessage());
        if ($CFG->debugdeveloper) {
            if (!empty($e->debuginfo)) {
                mtrace("Debug info:");
                mtrace($e->debuginfo);
            }
            mtrace("Backtrace:");
            mtrace(format_backtrace($e->getTrace(), true));
        }
        \core\task\manager::scheduled_task_failed($task);
        get_mailer('close');
        exit(1);
    }
}
예제 #8
0
 /**
  * Run adhoc tasks.
  */
 protected function run_adhock_tasks()
 {
     while ($task = \core\task\manager::get_next_adhoc_task(time())) {
         $task->execute();
         \core\task\manager::adhoc_task_complete($task);
     }
 }
예제 #9
0
 public function test_get_broken_scheduled_task()
 {
     global $DB;
     $this->resetAfterTest(true);
     // Delete all existing scheduled tasks.
     $DB->delete_records('task_scheduled');
     // Add a scheduled task.
     // A broken task that runs all the time.
     $record = new stdClass();
     $record->blocking = true;
     $record->minute = '*';
     $record->hour = '*';
     $record->dayofweek = '*';
     $record->day = '*';
     $record->month = '*';
     $record->component = 'test_scheduled_task';
     $record->classname = '\\core\\task\\scheduled_test_task_broken';
     $DB->insert_record('task_scheduled', $record);
     $now = time();
     // Should not get any task.
     $task = \core\task\manager::get_next_scheduled_task($now);
     $this->assertDebuggingCalled();
     $this->assertNull($task);
 }
예제 #10
0
 /**
  * Runs all ad-hoc tasks in the queue.
  *
  * This is faster and more reliable than running cron (running cron won't
  * work more than once in the same test, for instance). However it is
  * a little less 'realistic'.
  *
  * While the task is running, we suppress mtrace output because it makes
  * the Behat result look ugly.
  *
  * @Given /^I run all adhoc tasks$/
  * @throws DriverException
  */
 public function i_run_all_adhoc_tasks()
 {
     // Do setup for cron task.
     cron_setup_user();
     // Run tasks. Locking is handled by get_next_adhoc_task.
     $now = time();
     ob_start();
     // Discard task output as not appropriate for Behat output!
     while (($task = \core\task\manager::get_next_adhoc_task($now)) !== null) {
         try {
             $task->execute();
             // Mark task complete.
             \core\task\manager::adhoc_task_complete($task);
         } catch (Exception $e) {
             // Mark task failed and throw exception.
             \core\task\manager::adhoc_task_failed($task);
             ob_end_clean();
             throw new DriverException('An adhoc task failed', 0, $e);
         }
     }
     ob_end_clean();
 }
예제 #11
0
/**
 * Invalidates browser caches and cached data in temp.
 *
 * IMPORTANT - If you are adding anything here to do with the cache directory you should also have a look at
 * {@link phpunit_util::reset_dataroot()}
 *
 * @return void
 */
function purge_all_caches()
{
    global $CFG, $DB;
    reset_text_filters_cache();
    js_reset_all_caches();
    theme_reset_all_caches();
    get_string_manager()->reset_caches();
    core_text::reset_caches();
    if (class_exists('core_plugin_manager')) {
        core_plugin_manager::reset_caches();
    }
    // Bump up cacherev field for all courses.
    try {
        increment_revision_number('course', 'cacherev', '');
    } catch (moodle_exception $e) {
        // Ignore exception since this function is also called before upgrade script when field course.cacherev does not exist yet.
    }
    $DB->reset_caches();
    cache_helper::purge_all();
    // Purge all other caches: rss, simplepie, etc.
    clearstatcache();
    remove_dir($CFG->cachedir . '', true);
    // Make sure cache dir is writable, throws exception if not.
    make_cache_directory('');
    // This is the only place where we purge local caches, we are only adding files there.
    // The $CFG->localcachedirpurged flag forces local directories to be purged on cluster nodes.
    remove_dir($CFG->localcachedir, true);
    set_config('localcachedirpurged', time());
    make_localcache_directory('', true);
    \core\task\manager::clear_static_caches();
}
    /**
     * Test that the file_temp_cleanup_task removes directories and
     * files as expected.
     */
    public function test_file_temp_cleanup_task() {
        global $CFG;

        // Create directories.
        $dir = $CFG->tempdir . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'backup01' . DIRECTORY_SEPARATOR . 'courses';
        mkdir($dir, 0777, true);

        // Create files to be checked and then deleted.
        $file01 = $dir . DIRECTORY_SEPARATOR . 'sections.xml';
        file_put_contents($file01, 'test data 001');
        $file02 = $dir . DIRECTORY_SEPARATOR . 'modules.xml';
        file_put_contents($file02, 'test data 002');
        // Change the time modified for the first file, to a time that will be deleted by the task (greater than seven days).
        touch($file01, time() - (8 * 24 * 3600));

        $task = \core\task\manager::get_scheduled_task('\\core\\task\\file_temp_cleanup_task');
        $this->assertInstanceOf('\core\task\file_temp_cleanup_task', $task);
        $task->execute();

        // Scan the directory. Only modules.xml should be left.
        $filesarray = scandir($dir);
        $this->assertEquals('modules.xml', $filesarray[2]);
        $this->assertEquals(3, count($filesarray));

        // Change the time modified on modules.xml.
        touch($file02, time() - (8 * 24 * 3600));
        // Change the time modified on the courses directory.
        touch($CFG->tempdir . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'backup01' . DIRECTORY_SEPARATOR .
                'courses', time() - (8 * 24 * 3600));
        // Run the scheduled task to remove the file and directory.
        $task->execute();
        $filesarray = scandir($CFG->tempdir . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'backup01');
        // There should only be two items in the array, '.' and '..'.
        $this->assertEquals(2, count($filesarray));

        // Change the time modified on all of the files and directories.
        $dir = new \RecursiveDirectoryIterator($CFG->tempdir);
        // Show all child nodes prior to their parent.
        $iter = new \RecursiveIteratorIterator($dir, \RecursiveIteratorIterator::CHILD_FIRST);

        for ($iter->rewind(); $iter->valid(); $iter->next()) {
            $node = $iter->getRealPath();
            touch($node, time() - (8 * 24 * 3600));
        }

        // Run the scheduled task again to remove all of the files and directories.
        $task->execute();
        $filesarray = scandir($CFG->tempdir);
        // All of the files and directories should be deleted.
        // There should only be two items in the array, '.' and '..'.
        $this->assertEquals(2, count($filesarray));
    }
예제 #13
0
 /**
  * Run adhoc tasks.
  */
 protected function run_adhock_tasks()
 {
     while ($task = \core\task\manager::get_next_adhoc_task(time())) {
         $task->execute();
         \core\task\manager::adhoc_task_complete($task);
     }
     $this->expectOutputRegex("/^Sending message to the user with id \\d+ for the subscription with id \\d+\\.\\.\\..Sent./ms");
 }
 /**
  * Execute task
  * 
  * @global \moodle_database $DB
  * @global \stdClass $CFG
  * @return void
  * @throws \moodle_exception
  */
 public function execute()
 {
     global $DB, $CFG;
     // Not going to work if we're missing settings.
     if (!isset($CFG->block_mailchimp_apicode) || !isset($CFG->block_mailchimp_listid) || !isset($CFG->block_mailchimp_linked_profile_field)) {
         return;
     }
     echo '== Beginning synchronization of MailChimp subscribers ==', "\n";
     // Get all users in MailChimp and synchronize.
     echo 'Getting list of users in MailChimp.', "\n";
     $listusers = \block_mailchimp\helper::getMembersSync();
     if (!$listusers) {
         debugging("ERROR: Failed to get list of all members. Unable to synchronize users.");
         return;
     }
     // If there is an interest specified, filter out users who do not have this interest marked.
     if (isset($CFG->block_mailchimp_interest) && !$CFG->block_mailchimp_interest == "0") {
         foreach ($listusers['members'] as $key => $externaluser) {
             if ($externaluser['interests'][$CFG->block_mailchimp_interest] == false) {
                 unset($listusers['members'][$key]);
             }
         }
         // Reindex the array
         $listusers['members'] = array_values($listusers['members']);
     }
     $listuserscount = count($listusers['members']);
     // Get list of users in Moodle
     echo 'Getting list of users in Moodle.', "\n";
     $moodleusers = $DB->get_records('user');
     $moodleuserscount = count($moodleusers);
     // Convert Moodle email addresses to lower case. Mailchimp stores emails in lower case and calculates the MD5 hash on the lower case email.
     foreach ($moodleusers as $moodleuser) {
         $moodleuser->email = strtolower($moodleuser->email);
     }
     // Sort MailChimp users list
     echo 'Sorting list of MailChimp users.', "\n";
     foreach ($listusers['members'] as $key => $row) {
         $emails[$key] = $row['email_address'];
     }
     array_multisort($emails, SORT_ASC, $listusers['members']);
     unset($emails);
     // Sort Moodle users list
     echo 'Sorting list of Moodle users.', "\n";
     foreach ($moodleusers as $key => $row) {
         $emails[$key] = $row->email;
     }
     array_multisort($emails, SORT_ASC, $moodleusers);
     unset($emails);
     // Syncronize the list of users in Moodle with those in Mailchimp
     echo '== Starting sync of Moodle users with users in MailChimp ==', "\n";
     foreach ($moodleusers as $moodleusersynckey => $moodleuser) {
         $statuspercent = round($moodleusersynckey / $moodleuserscount * 100, 1, PHP_ROUND_HALF_UP);
         echo $statuspercent, "%        \r";
         if (isguestuser($moodleuser)) {
             continue;
         }
         $this->synchronize_user($moodleuser, $listusers);
     }
     echo 'Done.', "\n";
     //Iterate through mailchimp list and compare to moodle users' emails. If the email is not found in moodle, delete from mailchimp list.
     echo '== Starting MailChimp list cleanup ==', "\n";
     foreach ($listusers['members'] as $listuserskey => $externaluser) {
         $statuspercent = round($listuserskey / $listuserscount * 100, 1, PHP_ROUND_HALF_UP);
         echo $statuspercent, "%        \r";
         $this->synchronize_mcuser($externaluser, $moodleusers);
     }
     echo 'Done.', "\n";
     echo '== Finished MailChimp syncronization ==', "\n";
     // Clean up static caches, since this process runs for a long time and (potentially) changes many DB records. See https://docs.moodle.org/dev/Task_API#Caches
     \core\task\manager::clear_static_caches();
 }
예제 #15
0
 /**
  * Test future adhoc task execution.
  */
 public function test_get_next_adhoc_task_future()
 {
     $this->resetAfterTest(true);
     $now = time();
     // Create an adhoc task in future.
     $task = new \core\task\adhoc_test_task();
     $task->set_next_run_time($now + 1000);
     \core\task\manager::queue_adhoc_task($task);
     // Fetching the next task should not return anything.
     $this->assertNull(\core\task\manager::get_next_adhoc_task($now));
     // Fetching in the future should return the task.
     $task = \core\task\manager::get_next_adhoc_task($now + 1020);
     $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task);
     $task->execute();
     \core\task\manager::adhoc_task_complete($task);
 }
예제 #16
0
/**
 * Execute cron tasks
 */
function cron_run()
{
    global $DB, $CFG, $OUTPUT;
    if (CLI_MAINTENANCE) {
        echo "CLI maintenance mode active, cron execution suspended.\n";
        exit(1);
    }
    if (moodle_needs_upgrading()) {
        echo "Moodle upgrade pending, cron execution suspended.\n";
        exit(1);
    }
    require_once $CFG->libdir . '/adminlib.php';
    if (!empty($CFG->showcronsql)) {
        $DB->set_debug(true);
    }
    if (!empty($CFG->showcrondebugging)) {
        set_debugging(DEBUG_DEVELOPER, true);
    }
    core_php_time_limit::raise();
    $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");
    // Run all scheduled tasks.
    while (!\core\task\manager::static_caches_cleared_since($timenow) && ($task = \core\task\manager::get_next_scheduled_task($timenow))) {
        mtrace("Execute scheduled task: " . $task->get_name());
        cron_trace_time_and_memory();
        $predbqueries = null;
        $predbqueries = $DB->perf_get_queries();
        $pretime = microtime(1);
        try {
            get_mailer('buffer');
            $task->execute();
            if ($DB->is_transaction_started()) {
                throw new coding_exception("Task left transaction open");
            }
            if (isset($predbqueries)) {
                mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries");
                mtrace("... used " . (microtime(1) - $pretime) . " seconds");
            }
            mtrace("Scheduled task complete: " . $task->get_name());
            \core\task\manager::scheduled_task_complete($task);
        } catch (Exception $e) {
            if ($DB && $DB->is_transaction_started()) {
                error_log('Database transaction aborted automatically in ' . get_class($task));
                $DB->force_transaction_rollback();
            }
            if (isset($predbqueries)) {
                mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries");
                mtrace("... used " . (microtime(1) - $pretime) . " seconds");
            }
            mtrace("Scheduled task failed: " . $task->get_name() . "," . $e->getMessage());
            if ($CFG->debugdeveloper) {
                if (!empty($e->debuginfo)) {
                    mtrace("Debug info:");
                    mtrace($e->debuginfo);
                }
                mtrace("Backtrace:");
                mtrace(format_backtrace($e->getTrace(), true));
            }
            \core\task\manager::scheduled_task_failed($task);
        }
        get_mailer('close');
        unset($task);
    }
    // Run all adhoc tasks.
    while (!\core\task\manager::static_caches_cleared_since($timenow) && ($task = \core\task\manager::get_next_adhoc_task($timenow))) {
        mtrace("Execute adhoc task: " . get_class($task));
        cron_trace_time_and_memory();
        $predbqueries = null;
        $predbqueries = $DB->perf_get_queries();
        $pretime = microtime(1);
        try {
            get_mailer('buffer');
            $task->execute();
            if ($DB->is_transaction_started()) {
                throw new coding_exception("Task left transaction open");
            }
            if (isset($predbqueries)) {
                mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries");
                mtrace("... used " . (microtime(1) - $pretime) . " seconds");
            }
            mtrace("Adhoc task complete: " . get_class($task));
            \core\task\manager::adhoc_task_complete($task);
        } catch (Exception $e) {
            if ($DB && $DB->is_transaction_started()) {
                error_log('Database transaction aborted automatically in ' . get_class($task));
                $DB->force_transaction_rollback();
            }
            if (isset($predbqueries)) {
                mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries");
                mtrace("... used " . (microtime(1) - $pretime) . " seconds");
            }
            mtrace("Adhoc task failed: " . get_class($task) . "," . $e->getMessage());
            if ($CFG->debugdeveloper) {
                if (!empty($e->debuginfo)) {
                    mtrace("Debug info:");
                    mtrace($e->debuginfo);
                }
                mtrace("Backtrace:");
                mtrace(format_backtrace($e->getTrace(), true));
            }
            \core\task\manager::adhoc_task_failed($task);
        }
        get_mailer('close');
        unset($task);
    }
    mtrace("Cron script completed correctly");
    gc_collect_cycles();
    mtrace('Cron completed at ' . date('H:i:s') . '. Memory used ' . display_size(memory_get_usage()) . '.');
    $difftime = microtime_diff($starttime, microtime());
    mtrace("Execution took " . $difftime . " seconds");
}
예제 #17
0
/**
 * Course section deletion, using an adhoc task for deletion of the modules it contains.
 * 1. Schedule all modules within the section for adhoc removal.
 * 2. Move all modules to course section 0.
 * 3. Delete the resulting empty section.
 *
 * @param \stdClass $section the section to schedule for deletion.
 * @param bool $forcedeleteifnotempty whether to force section deletion if it contains modules.
 * @return bool true if the section was scheduled for deletion, false otherwise.
 */
function course_delete_section_async($section, $forcedeleteifnotempty = true)
{
    global $DB, $USER;
    // Objects only, and only valid ones.
    if (!is_object($section) || empty($section->id)) {
        return false;
    }
    // Does the object currently exist in the DB for removal (check for stale objects).
    $section = $DB->get_record('course_sections', array('id' => $section->id));
    if (!$section || !$section->section) {
        // No section exists, or the section is 0. Can't proceed.
        return false;
    }
    // Check whether the section can be removed.
    if (!$forcedeleteifnotempty && (!empty($section->sequence) || !empty($section->summary))) {
        return false;
    }
    $format = course_get_format($section->course);
    $sectionname = $format->get_section_name($section);
    // Flag those modules having no existing deletion flag. Some modules may have been scheduled for deletion manually, and we don't
    // want to create additional adhoc deletion tasks for these. Moving them to section 0 will suffice.
    $affectedmods = $DB->get_records_select('course_modules', 'course = ? AND section = ? AND deletioninprogress <> ?', [$section->course, $section->id, 1], '', 'id');
    $DB->set_field('course_modules', 'deletioninprogress', '1', ['course' => $section->course, 'section' => $section->id]);
    // Move all modules to section 0.
    $modules = $DB->get_records('course_modules', ['section' => $section->id], '');
    $sectionzero = $DB->get_record('course_sections', ['course' => $section->course, 'section' => '0']);
    foreach ($modules as $mod) {
        moveto_module($mod, $sectionzero);
    }
    // Create and queue an adhoc task for the deletion of the modules.
    $removaltask = new \core_course\task\course_delete_modules();
    $data = array('cms' => $affectedmods, 'userid' => $USER->id, 'realuserid' => \core\session\manager::get_realuser()->id);
    $removaltask->set_custom_data($data);
    \core\task\manager::queue_adhoc_task($removaltask);
    // Delete the now empty section, passing in only the section number, which forces the function to fetch a new object.
    // The refresh is needed because the section->sequence is now stale.
    $result = $format->delete_section($section->section, $forcedeleteifnotempty);
    // Trigger an event for course section deletion.
    if ($result) {
        $context = \context_course::instance($section->course);
        $event = \core\event\course_section_deleted::create(array('objectid' => $section->id, 'courseid' => $section->course, 'context' => $context, 'other' => array('sectionnum' => $section->section, 'sectionname' => $sectionname)));
        $event->add_record_snapshot('course_sections', $section);
        $event->trigger();
    }
    rebuild_course_cache($section->course, true);
    return $result;
}
예제 #18
0
 *     -d log_errors=1 -d error_reporting=E_ALL -d display_errors=0 -d html_errors=0
 *
 * Performance notes:
 * We have optimized it as best as we could for PostgreSQL and MySQL, with 27K students
 * we have seen this take 10 minutes.
 *
 * @package    auth_ldap
 * @copyright  2004 Martin Langhoff
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @deprecated since Moodle 3.0 MDL-51824 - please do not use this CLI script any more, use scheduled task instead.
 * @todo MDL-50264 This will be deleted in Moodle 3.2.
 */
define('CLI_SCRIPT', true);
require __DIR__ . '/../../../config.php';
// global moodle config file.
require_once $CFG->dirroot . '/course/lib.php';
require_once $CFG->libdir . '/clilib.php';
// Ensure errors are well explained
set_debugging(DEBUG_DEVELOPER, true);
if (!is_enabled_auth('ldap')) {
    error_log('[AUTH LDAP] ' . get_string('pluginnotenabled', 'auth_ldap'));
    die;
}
cli_problem('[AUTH LDAP] The users sync cron has been deprecated. Please use the scheduled task instead.');
// Abort execution of the CLI script if the auth_ldap\task\sync_task is enabled.
$taskdisabled = \core\task\manager::get_scheduled_task('auth_ldap\\task\\sync_task');
if (!$taskdisabled->get_disabled()) {
    cli_error('[AUTH LDAP] The scheduled task sync_task is enabled, the cron execution has been aborted.');
}
$ldapauth = get_auth_plugin('ldap');
$ldapauth->sync_users(true);
예제 #19
0
파일: util.php 프로젝트: EsdrasCaleb/moodle
 /**
  * Executes all adhoc tasks in the queue. Useful for testing asynchronous behaviour.
  *
  * @return void
  */
 public static function run_all_adhoc_tasks()
 {
     $now = time();
     while (($task = \core\task\manager::get_next_adhoc_task($now)) !== null) {
         try {
             $task->execute();
             \core\task\manager::adhoc_task_complete($task);
         } catch (Exception $e) {
             \core\task\manager::adhoc_task_failed($task);
         }
     }
 }
예제 #20
0
 /**
  * Handle role_deleted event
  *
  * Does the following:
  *     - Unfortunately the role has already been deleted when we hear about it here, and have no way to determine the affected
  *     users. Therefore, we have to do a global sync.
  *
  * @param \core\event\role_deleted $event The triggered event.
  * @return bool Success/Failure.
  */
 public static function handle_role_deleted(\core\event\role_deleted $event)
 {
     if (\local_o365\utils::is_configured() !== true) {
         return false;
     }
     $roleid = $event->objectid;
     // Role deletions can be heavy - run in cron.
     $spaccesssync = new \local_o365\task\sharepointaccesssync();
     $spaccesssync->set_custom_data(['roleid' => '*', 'userid' => '*', 'contextid' => null]);
     \core\task\manager::queue_adhoc_task($spaccesssync);
     return true;
 }
예제 #21
0
 public function test_complete_plans_task()
 {
     global $DB;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     $dg = $this->getDataGenerator();
     $lpg = $dg->get_plugin_generator('core_competency');
     $user = $dg->create_user();
     $up1 = $lpg->create_plan(array('userid' => $user->id, 'status' => \core_competency\plan::STATUS_DRAFT));
     $up2 = $lpg->create_plan(array('userid' => $user->id, 'status' => \core_competency\plan::STATUS_ACTIVE));
     // Set duedate in the past.
     $date = new \DateTime('yesterday');
     $record1 = $up1->to_record();
     $record2 = $up2->to_record();
     $record1->duedate = $date->getTimestamp();
     $record2->duedate = $date->getTimestamp();
     $DB->update_record(plan::TABLE, $record1);
     $DB->update_record(plan::TABLE, $record2);
     $task = \core\task\manager::get_scheduled_task('\\core\\task\\complete_plans_task');
     $this->assertInstanceOf('\\core\\task\\complete_plans_task', $task);
     // Test that draft plan can not be completed on running task.
     $task->execute();
     $plandraft = api::read_plan($up1->get_id());
     $this->assertEquals(\core_competency\plan::STATUS_DRAFT, $plandraft->get_status());
     // Test that active plan can be completed on running task.
     $task->execute();
     $planactive = api::read_plan($up2->get_id());
     $this->assertEquals(\core_competency\plan::STATUS_COMPLETE, $planactive->get_status());
 }
 /**
  * Run adhoc tasks.
  */
 protected function run_adhock_tasks()
 {
     ob_start();
     while ($task = \core\task\manager::get_next_adhoc_task(time())) {
         $task->execute();
         \core\task\manager::adhoc_task_complete($task);
     }
     ob_clean();
     // Suppress mtrace debugging info.
 }
예제 #23
0
 /**
  * Runs a scheduled task immediately, given full class name.
  *
  * This is faster and more reliable than running cron (running cron won't
  * work more than once in the same test, for instance). However it is
  * a little less 'realistic'.
  *
  * While the task is running, we suppress mtrace output because it makes
  * the Behat result look ugly.
  *
  * Note: Most of the code relating to running a task is based on
  * admin/tool/task/cli/schedule_task.php.
  *
  * @Given /^I run the scheduled task "(?P<task_name>[^"]+)"$/
  * @param string $taskname Name of task e.g. 'mod_whatever\task\do_something'
  */
 public function i_run_the_scheduled_task($taskname)
 {
     $task = \core\task\manager::get_scheduled_task($taskname);
     if (!$task) {
         throw new DriverException('The "' . $taskname . '" scheduled task does not exist');
     }
     // Do setup for cron task.
     raise_memory_limit(MEMORY_EXTRA);
     cron_setup_user();
     // Get lock.
     $cronlockfactory = \core\lock\lock_config::get_lock_factory('cron');
     if (!($cronlock = $cronlockfactory->get_lock('core_cron', 10))) {
         throw new DriverException('Unable to obtain core_cron lock for scheduled task');
     }
     if (!($lock = $cronlockfactory->get_lock('\\' . get_class($task), 10))) {
         $cronlock->release();
         throw new DriverException('Unable to obtain task lock for scheduled task');
     }
     $task->set_lock($lock);
     if (!$task->is_blocking()) {
         $cronlock->release();
     } else {
         $task->set_cron_lock($cronlock);
     }
     try {
         // Discard task output as not appropriate for Behat output!
         ob_start();
         $task->execute();
         ob_end_clean();
         // Mark task complete.
         \core\task\manager::scheduled_task_complete($task);
     } catch (Exception $e) {
         // Mark task failed and throw exception.
         \core\task\manager::scheduled_task_failed($task);
         throw new DriverException('The "' . $taskname . '" scheduled task failed', 0, $e);
     }
 }
예제 #24
0
             $task->set_month($defaulttask->get_month());
             $task->set_day_of_week($defaulttask->get_day_of_week());
             $task->set_day($defaulttask->get_day());
             $task->set_disabled($defaulttask->get_disabled());
             $task->set_customised(false);
         } else {
             $task->set_minute($data->minute);
             $task->set_hour($data->hour);
             $task->set_month($data->month);
             $task->set_day_of_week($data->dayofweek);
             $task->set_day($data->day);
             $task->set_disabled($data->disabled);
             $task->set_customised(true);
         }
         try {
             \core\task\manager::configure_scheduled_task($task);
             redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
         } catch (Exception $e) {
             redirect($PAGE->url, $e->getMessage(), null, \core\output\notification::NOTIFY_ERROR);
         }
     } else {
         echo $OUTPUT->header();
         echo $OUTPUT->heading(get_string('edittaskschedule', 'tool_task', $task->get_name()));
         $mform->display();
         echo $OUTPUT->footer();
     }
 } else {
     echo $OUTPUT->header();
     $tasks = core\task\manager::get_all_scheduled_tasks();
     echo $renderer->scheduled_tasks_table($tasks);
     echo $OUTPUT->footer();
예제 #25
0
function convert_with_ffmpeg_bg($filerecord, $tempdir, $tempfilename, $convfilenamebase, $convext)
{
    global $CFG;
    //init our fs object
    $fs = get_file_storage();
    $convfilename = $convfilenamebase . $convext;
    $placeholderfilename = "convertingmessage" . $convext;
    $filerecord->filename = $convfilename;
    $stored_file = $fs->create_file_from_pathname($filerecord, $CFG->dirroot . '/filter/poodll/' . $placeholderfilename);
    //we need this id later, to find the old draft file and remove it, in ad hoc task
    $filerecord->id = $stored_file->get_id();
    // set up task and add custom data
    $conv_task = new \filter_poodll\task\adhoc_convert_media();
    $qdata = array('filerecord' => $filerecord, 'filename' => $convfilename, 'tempdir' => $tempdir, 'tempfilename' => $tempfilename, 'convfilenamebase' => $convfilenamebase, 'convext' => $convext);
    $conv_task->set_custom_data($qdata);
    // queue it
    \core\task\manager::queue_adhoc_task($conv_task);
    //error_log('queeued:' . $convfilename);
    //error_log(print_r($qdata,true));
    return $stored_file;
}
예제 #26
0
    public function test_get_next_scheduled_task() {
        global $DB;

        $this->resetAfterTest(true);
        // Delete all existing scheduled tasks.
        $DB->delete_records('task_scheduled');
        // Add a scheduled task.

        // A task that runs once per hour.
        $record = new stdClass();
        $record->blocking = true;
        $record->minute = '0';
        $record->hour = '0';
        $record->dayofweek = '*';
        $record->day = '*';
        $record->month = '*';
        $record->component = 'test_scheduled_task';
        $record->classname = '\core\task\scheduled_test_task';

        $DB->insert_record('task_scheduled', $record);
        // And another one to test failures.
        $record->classname = '\core\task\scheduled_test2_task';
        $DB->insert_record('task_scheduled', $record);
        // And disabled test.
        $record->classname = '\core\task\scheduled_test3_task';
        $record->disabled = 1;
        $DB->insert_record('task_scheduled', $record);

        $now = time();

        // Should get handed the first task.
        $task = \core\task\manager::get_next_scheduled_task($now);
        $this->assertInstanceOf('\core\task\scheduled_test_task', $task);
        $task->execute();

        \core\task\manager::scheduled_task_complete($task);
        // Should get handed the second task.
        $task = \core\task\manager::get_next_scheduled_task($now);
        $this->assertInstanceOf('\core\task\scheduled_test2_task', $task);
        $task->execute();

        \core\task\manager::scheduled_task_failed($task);
        // Should not get any task.
        $task = \core\task\manager::get_next_scheduled_task($now);
        $this->assertNull($task);

        // Should get the second task (retry after delay).
        $task = \core\task\manager::get_next_scheduled_task($now + 120);
        $this->assertInstanceOf('\core\task\scheduled_test2_task', $task);
        $task->execute();

        \core\task\manager::scheduled_task_complete($task);

        // Should not get any task.
        $task = \core\task\manager::get_next_scheduled_task($now);
        $this->assertNull($task);
    }
예제 #27
0
/**
 * Upgrade moodle core
 * @param float $version target version
 * @param bool $verbose
 * @return void, may throw exception
 */
function upgrade_core($version, $verbose) {
    global $CFG, $SITE, $DB, $COURSE;

    raise_memory_limit(MEMORY_EXTRA);

    require_once($CFG->libdir.'/db/upgrade.php');    // Defines upgrades

    try {
        // Reset caches before any output.
        cache_helper::purge_all(true);
        purge_all_caches();

        // Upgrade current language pack if we can
        upgrade_language_pack();

        print_upgrade_part_start('moodle', false, $verbose);

        // Pre-upgrade scripts for local hack workarounds.
        $preupgradefile = "$CFG->dirroot/local/preupgrade.php";
        if (file_exists($preupgradefile)) {
            core_php_time_limit::raise();
            require($preupgradefile);
            // Reset upgrade timeout to default.
            upgrade_set_timeout();
        }

        $result = xmldb_main_upgrade($CFG->version);
        if ($version > $CFG->version) {
            // store version if not already there
            upgrade_main_savepoint($result, $version, false);
        }

        // In case structure of 'course' table has been changed and we forgot to update $SITE, re-read it from db.
        $SITE = $DB->get_record('course', array('id' => $SITE->id));
        $COURSE = clone($SITE);

        // perform all other component upgrade routines
        update_capabilities('moodle');
        log_update_descriptions('moodle');
        external_update_descriptions('moodle');
        events_update_definition('moodle');
        \core\task\manager::reset_scheduled_tasks_for_component('moodle');
        message_update_providers('moodle');
        \core\message\inbound\manager::update_handlers_for_component('moodle');
        // Update core definitions.
        cache_helper::update_definitions(true);

        // Purge caches again, just to be sure we arn't holding onto old stuff now.
        cache_helper::purge_all(true);
        purge_all_caches();

        // Clean up contexts - more and more stuff depends on existence of paths and contexts
        context_helper::cleanup_instances();
        context_helper::create_instances(null, false);
        context_helper::build_all_paths(false);
        $syscontext = context_system::instance();
        $syscontext->mark_dirty();

        print_upgrade_part_end('moodle', false, $verbose);
    } catch (Exception $ex) {
        upgrade_handle_exception($ex);
    }
}
예제 #28
0
 /**
  * Handle calendar_unsubscribed event - queue calendar sync jobs for cron.
  *
  * @param \local_o365\event\calendar_unsubscribed $event The triggered event.
  * @return bool Success/Failure.
  */
 public static function handle_calendar_unsubscribed(\local_o365\event\calendar_unsubscribed $event)
 {
     $eventdata = $event->get_data();
     $calunsubscribe = new \local_o365\feature\calsync\task\syncoldevents();
     $calunsubscribe->set_custom_data(['caltype' => $eventdata['other']['caltype'], 'caltypeid' => isset($eventdata['other']['caltypeid']) ? $eventdata['other']['caltypeid'] : 0, 'userid' => $eventdata['userid'], 'timecreated' => time()]);
     \core\task\manager::queue_adhoc_task($calunsubscribe);
     return true;
 }
예제 #29
0
 /**
  * This method process all events stored in the buffer.
  *
  * This is a multi purpose api. It does the following:-
  * 1. Write event data to tool_monitor_events
  * 2. Find out users that need to be notified about rule completion and schedule a task to send them messages.
  */
 public function process_buffer()
 {
     global $DB;
     $events = $this->flush();
     // Flush data.
     $select = "SELECT COUNT(id) FROM {tool_monitor_events} ";
     $now = time();
     $messagestosend = array();
     $allsubids = array();
     // Let us now process the events and check for subscriptions.
     foreach ($events as $eventobj) {
         $subscriptions = subscription_manager::get_subscriptions_by_event($eventobj);
         $idstosend = array();
         foreach ($subscriptions as $subscription) {
             $starttime = $now - $subscription->timewindow;
             $starttime = $starttime > $subscription->lastnotificationsent ? $starttime : $subscription->lastnotificationsent;
             if ($subscription->courseid == 0) {
                 // Site level subscription. Count all events.
                 $where = "eventname = :eventname AND timecreated >  :starttime";
                 $params = array('eventname' => $eventobj->eventname, 'starttime' => $starttime);
             } else {
                 // Course level subscription.
                 if ($subscription->cmid == 0) {
                     // All modules.
                     $where = "eventname = :eventname AND courseid = :courseid AND timecreated > :starttime";
                     $params = array('eventname' => $eventobj->eventname, 'courseid' => $eventobj->courseid, 'starttime' => $starttime);
                 } else {
                     // Specific module.
                     $where = "eventname = :eventname AND courseid = :courseid AND contextinstanceid = :cmid\n                                AND timecreated > :starttime";
                     $params = array('eventname' => $eventobj->eventname, 'courseid' => $eventobj->courseid, 'cmid' => $eventobj->contextinstanceid, 'starttime' => $starttime);
                 }
             }
             $sql = $select . "WHERE " . $where;
             $count = $DB->count_records_sql($sql, $params);
             if (!empty($count) && $count >= $subscription->frequency) {
                 $idstosend[] = $subscription->id;
                 // Trigger a subscription_criteria_met event.
                 // It's possible that the course has been deleted since the criteria was met, so in that case use
                 // the system context. Set it here and change later if needed.
                 $context = \context_system::instance();
                 // We can't perform if (!empty($subscription->courseid)) below as it uses the magic method
                 // __get to return the variable, which will always result in being empty.
                 $courseid = $subscription->courseid;
                 if (!empty($courseid)) {
                     if ($coursecontext = \context_course::instance($courseid, IGNORE_MISSING)) {
                         $context = $coursecontext;
                     }
                 }
                 $params = array('userid' => $subscription->userid, 'courseid' => $subscription->courseid, 'context' => $context, 'other' => array('subscriptionid' => $subscription->id));
                 $event = \tool_monitor\event\subscription_criteria_met::create($params);
                 $event->trigger();
             }
         }
         if (!empty($idstosend)) {
             $messagestosend[] = array('subscriptionids' => $idstosend, 'event' => $eventobj);
             $allsubids = array_merge($allsubids, $idstosend);
         }
     }
     if (!empty($allsubids)) {
         // Update the last trigger flag.
         list($sql, $params) = $DB->get_in_or_equal($allsubids, SQL_PARAMS_NAMED);
         $params['now'] = $now;
         $sql = "UPDATE {tool_monitor_subscriptions} SET lastnotificationsent = :now WHERE id {$sql}";
         $DB->execute($sql, $params);
     }
     // Schedule a task to send notification.
     if (!empty($messagestosend)) {
         $adhocktask = new notification_task();
         $adhocktask->set_custom_data($messagestosend);
         $adhocktask->set_component('tool_monitor');
         \core\task\manager::queue_adhoc_task($adhocktask);
     }
 }
 private function process_publish_allocations()
 {
     $now = time();
     if ($this->ratingallocate->accesstimestop < $now) {
         global $USER, $OUTPUT;
         $this->origdbrecord->{this_db\ratingallocate::PUBLISHED} = true;
         $this->origdbrecord->{this_db\ratingallocate::PUBLISHDATE} = time();
         $this->origdbrecord->{this_db\ratingallocate::NOTIFICATIONSEND} = -1;
         $this->ratingallocate = new ratingallocate_db_wrapper($this->origdbrecord);
         $this->db->update_record(this_db\ratingallocate::TABLE, $this->origdbrecord);
         // create the instance
         $domination = new mod_ratingallocate\task\send_distribution_notification();
         // set blocking if required (it probably isn't)
         // $domination->set_blocking(true);
         // add custom data
         $domination->set_component('mod_ratingallocate');
         $domination->set_custom_data(array('userid' => $USER->id, 'ratingallocateid' => $this->ratingallocateid));
         // queue it
         \core\task\manager::queue_adhoc_task($domination);
         //Logging
         $event = \mod_ratingallocate\event\allocation_published::create_simple(context_course::instance($this->course->id), $this->ratingallocateid);
         $event->trigger();
         /* @var $renderer mod_ratingallocate_renderer */
         $renderer = $this->get_renderer();
         $renderer->add_notification(get_string('distribution_published', ratingallocate_MOD_NAME), self::NOTIFY_SUCCESS);
         return $this->process_default();
     }
 }