예제 #1
0
 protected function disable_plugin()
 {
     $enabled = enrol_get_plugins(true);
     unset($enabled['meta']);
     $enabled = array_keys($enabled);
     set_config('enrol_plugins_enabled', implode(',', $enabled));
 }
예제 #2
0
 public function test_get_enrolment_plugins()
 {
     $this->resetAfterTest(true);
     $actual = tool_uploadcourse_helper::get_enrolment_plugins();
     $this->assertSame(array_keys(enrol_get_plugins(false)), array_keys($actual));
     // This should be identical as cached.
     $secondactual = tool_uploadcourse_helper::get_enrolment_plugins();
     $this->assertEquals($actual, $secondactual);
 }
예제 #3
0
파일: locallib.php 프로젝트: nuckey/moodle
 /**
  * Gets all of the enrolment plugins that are active for this course.
  *
  * @return array
  */
 public function get_enrolment_plugins() {
     if ($this->_plugins === null) {
         $this->_plugins = enrol_get_plugins(true);
     }
     return $this->_plugins;
 }
예제 #4
0
    /**
     * Test moodle_enrol_manual_enrol_users web service function
     * This test will:
     * 1- create a user (core call)
     * 2- enrol this user in the courses supporting enrolment
     * 3- unenrol this user (core call)
     *
     * @param webservice_rest_client|webservice_soap_client|webservice_xmlrpc_client $client the protocol test client
     */
    private function moodle_enrol_manual_enrol_users($client) {
        global $DB, $CFG;

        require_once($CFG->dirroot . "/user/lib.php");
        require_once($CFG->dirroot . "/user/profile/lib.php");
        require_once($CFG->dirroot . "/lib/enrollib.php");

        // Delete some previous test data
        if ($user = $DB->get_record('user', array('username' => 'veryimprobabletestusername2'))) {
            $DB->delete_records('user', array('id' => $user->id));
        }
        if ($role = $DB->get_record('role', array('shortname' => 'role1thatshouldnotexist'))) {
            set_role_contextlevels($role->id, array(CONTEXT_COURSE));
            delete_role($role->id);
        }

        // create a user
        $user = new stdClass();
        $user->username = '******';
        $user->password = '******';
        $user->firstname = 'testfirstname2';
        $user->lastname = 'testlastname2';
        $user->email = '*****@*****.**';
        $user->id = user_create_user($user);

        $roleid = create_role('role1thatshouldnotexist', 'role1thatshouldnotexist', '');
        set_role_contextlevels($roleid, array(CONTEXT_COURSE));

        $enrolments = array();
        $courses = $DB->get_records('course');

        foreach ($courses as $course) {
            if ($course->id > 1) {
                $enrolments[] = array('roleid' => $roleid,
                    'userid' => $user->id, 'courseid' => $course->id);
                $enrolledcourses[] = $course;
            }
        }

        // web service call
        $function = 'moodle_enrol_manual_enrol_users';
        $wsparams = array('enrolments' => $enrolments);
        $enrolmentsresult = $client->call($function, $wsparams);

        // get instance that can unenrol
        $enrols = enrol_get_plugins(true);
        $enrolinstances = enrol_get_instances($course->id, true);
        $unenrolled = false;
        foreach ($enrolinstances as $instance) {
            if (!$unenrolled and $enrols[$instance->enrol]->allow_unenrol($instance)) {
                $unenrolinstance = $instance;
                $unenrolled = true;
            }
        }

        // test and unenrol the user
        $enrolledusercourses = enrol_get_users_courses($user->id);
        foreach ($enrolledcourses as $course) {
            // test
            $this->assertEqual(true, isset($enrolledusercourses[$course->id]));

            // unenrol the user
            $enrols[$unenrolinstance->enrol]->unenrol_user($unenrolinstance, $user->id, $roleid);
        }

        // delete user
        $DB->delete_records('user', array('id' => $user->id));

        // delete the context level
        set_role_contextlevels($roleid, array(CONTEXT_COURSE));

        // delete role
        delete_role($roleid);
    }
예제 #5
0
파일: moodlelib.php 프로젝트: hitphp/moodle
/**
 * This function will empty a course of user data.
 * It will retain the activities and the structure of the course.
 *
 * @param object $data an object containing all the settings including courseid (without magic quotes)
 * @return array status array of array component, item, error
 */
function reset_course_userdata($data)
{
    global $CFG, $USER, $DB;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/completionlib.php';
    require_once $CFG->dirroot . '/group/lib.php';
    $data->courseid = $data->id;
    $context = get_context_instance(CONTEXT_COURSE, $data->courseid);
    // calculate the time shift of dates
    if (!empty($data->reset_start_date)) {
        // time part of course startdate should be zero
        $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old);
    } else {
        $data->timeshift = 0;
    }
    // result array: component, item, error
    $status = array();
    // start the resetting
    $componentstr = get_string('general');
    // move the course start time
    if (!empty($data->reset_start_date) and $data->timeshift) {
        // change course start data
        $DB->set_field('course', 'startdate', $data->reset_start_date, array('id' => $data->courseid));
        // update all course and group events - do not move activity events
        $updatesql = "UPDATE {event}\n                         SET timestart = timestart + ?\n                       WHERE courseid=? AND instance=0";
        $DB->execute($updatesql, array($data->timeshift, $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false);
    }
    if (!empty($data->reset_logs)) {
        $DB->delete_records('log', array('course' => $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelogs'), 'error' => false);
    }
    if (!empty($data->reset_events)) {
        $DB->delete_records('event', array('courseid' => $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false);
    }
    if (!empty($data->reset_notes)) {
        require_once $CFG->dirroot . '/notes/lib.php';
        note_delete_all($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false);
    }
    if (!empty($data->delete_blog_associations)) {
        require_once $CFG->dirroot . '/blog/lib.php';
        blog_remove_associations_for_course($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteblogassociations', 'blog'), 'error' => false);
    }
    if (!empty($data->reset_course_completion)) {
        // Delete course completion information
        $course = $DB->get_record('course', array('id' => $data->courseid));
        $cc = new completion_info($course);
        $cc->delete_course_completion_data();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecoursecompletiondata', 'completion'), 'error' => false);
    }
    $componentstr = get_string('roles');
    if (!empty($data->reset_roles_overrides)) {
        $children = get_child_contexts($context);
        foreach ($children as $child) {
            $DB->delete_records('role_capabilities', array('contextid' => $child->id));
        }
        $DB->delete_records('role_capabilities', array('contextid' => $context->id));
        //force refresh for logged in users
        mark_context_dirty($context->path);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false);
    }
    if (!empty($data->reset_roles_local)) {
        $children = get_child_contexts($context);
        foreach ($children as $child) {
            role_unassign_all(array('contextid' => $child->id));
        }
        //force refresh for logged in users
        mark_context_dirty($context->path);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false);
    }
    // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc.
    $data->unenrolled = array();
    if (!empty($data->unenrol_users)) {
        $plugins = enrol_get_plugins(true);
        $instances = enrol_get_instances($data->courseid, true);
        foreach ($instances as $key => $instance) {
            if (!isset($plugins[$instance->enrol])) {
                unset($instances[$key]);
                continue;
            }
            if (!$plugins[$instance->enrol]->allow_unenrol($instance)) {
                unset($instances[$key]);
            }
        }
        $sqlempty = $DB->sql_empty();
        foreach ($data->unenrol_users as $withroleid) {
            $sql = "SELECT DISTINCT ue.userid, ue.enrolid\n                      FROM {user_enrolments} ue\n                      JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                      JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n                      JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.roleid = :roleid AND ra.userid = ue.userid)";
            $params = array('courseid' => $data->courseid, 'roleid' => $withroleid, 'courselevel' => CONTEXT_COURSE);
            $rs = $DB->get_recordset_sql($sql, $params);
            foreach ($rs as $ue) {
                if (!isset($instances[$ue->enrolid])) {
                    continue;
                }
                $plugins[$instances[$ue->enrolid]->enrol]->unenrol_user($instances[$ue->enrolid], $ue->userid);
                $data->unenrolled[$ue->userid] = $ue->userid;
            }
        }
    }
    if (!empty($data->unenrolled)) {
        $status[] = array('component' => $componentstr, 'item' => get_string('unenrol', 'enrol') . ' (' . count($data->unenrolled) . ')', 'error' => false);
    }
    $componentstr = get_string('groups');
    // remove all group members
    if (!empty($data->reset_groups_members)) {
        groups_delete_group_members($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false);
    }
    // remove all groups
    if (!empty($data->reset_groups_remove)) {
        groups_delete_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false);
    }
    // remove all grouping members
    if (!empty($data->reset_groupings_members)) {
        groups_delete_groupings_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false);
    }
    // remove all groupings
    if (!empty($data->reset_groupings_remove)) {
        groups_delete_groupings($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false);
    }
    // Look in every instance of every module for data to delete
    $unsupported_mods = array();
    if ($allmods = $DB->get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            if (!$DB->count_records($modname, array('course' => $data->courseid))) {
                continue;
                // skip mods with no instances
            }
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddeleteuserdata = $modname . '_reset_userdata';
            // Function to delete user data
            if (file_exists($modfile)) {
                include_once $modfile;
                if (function_exists($moddeleteuserdata)) {
                    $modstatus = $moddeleteuserdata($data);
                    if (is_array($modstatus)) {
                        $status = array_merge($status, $modstatus);
                    } else {
                        debugging('Module ' . $modname . ' returned incorrect staus - must be an array!');
                    }
                } else {
                    $unsupported_mods[] = $mod;
                }
            } else {
                debugging('Missing lib.php in ' . $modname . ' module!');
            }
        }
    }
    // mention unsupported mods
    if (!empty($unsupported_mods)) {
        foreach ($unsupported_mods as $mod) {
            $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented'));
        }
    }
    $componentstr = get_string('gradebook', 'grades');
    // reset gradebook
    if (!empty($data->reset_gradebook_items)) {
        remove_course_grades($data->courseid, false);
        grade_grab_course_grades($data->courseid);
        grade_regrade_final_grades($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false);
    } else {
        if (!empty($data->reset_gradebook_grades)) {
            grade_course_reset($data->courseid);
            $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false);
        }
    }
    // reset comments
    if (!empty($data->reset_comments)) {
        require_once $CFG->dirroot . '/comment/lib.php';
        comment::reset_course_page_comments($context);
    }
    return $status;
}
예제 #6
0
 /**
  * Builds the XHTML to display the control
  *
  * @param string $data Unused
  * @param string $query
  * @return string
  */
 public function output_html($data, $query = '')
 {
     global $CFG, $OUTPUT, $DB;
     // display strings
     $strup = get_string('up');
     $strdown = get_string('down');
     $strsettings = get_string('settings');
     $strenable = get_string('enable');
     $strdisable = get_string('disable');
     $struninstall = get_string('uninstallplugin', 'admin');
     $strusage = get_string('enrolusage', 'enrol');
     $enrols_available = enrol_get_plugins(false);
     $active_enrols = enrol_get_plugins(true);
     $allenrols = array();
     foreach ($active_enrols as $key => $enrol) {
         $allenrols[$key] = true;
     }
     foreach ($enrols_available as $key => $enrol) {
         $allenrols[$key] = true;
     }
     // now find all borked plugins and at least allow then to uninstall
     $borked = array();
     $condidates = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {enrol}");
     foreach ($condidates as $candidate) {
         if (empty($allenrols[$candidate])) {
             $allenrols[$candidate] = true;
         }
     }
     $return = $OUTPUT->heading(get_string('actenrolshhdr', 'enrol'), 3, 'main', true);
     $return .= $OUTPUT->box_start('generalbox enrolsui');
     $table = new html_table();
     $table->head = array(get_string('name'), $strusage, $strenable, $strup . '/' . $strdown, $strsettings, $struninstall);
     $table->align = array('left', 'center', 'center', 'center', 'center', 'center');
     $table->width = '90%';
     $table->data = array();
     // iterate through enrol plugins and add to the display table
     $updowncount = 1;
     $enrolcount = count($active_enrols);
     $url = new moodle_url('/admin/enrol.php', array('sesskey' => sesskey()));
     $printed = array();
     foreach ($allenrols as $enrol => $unused) {
         if (get_string_manager()->string_exists('pluginname', 'enrol_' . $enrol)) {
             $name = get_string('pluginname', 'enrol_' . $enrol);
         } else {
             $name = $enrol;
         }
         //usage
         $ci = $DB->count_records('enrol', array('enrol' => $enrol));
         $cp = $DB->count_records_select('user_enrolments', "enrolid IN (SELECT id FROM {enrol} WHERE enrol = ?)", array($enrol));
         $usage = "{$ci} / {$cp}";
         // hide/show link
         if (isset($active_enrols[$enrol])) {
             $aurl = new moodle_url($url, array('action' => 'disable', 'enrol' => $enrol));
             $hideshow = "<a href=\"{$aurl}\">";
             $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"{$strdisable}\" /></a>";
             $enabled = true;
             $displayname = "<span>{$name}</span>";
         } else {
             if (isset($enrols_available[$enrol])) {
                 $aurl = new moodle_url($url, array('action' => 'enable', 'enrol' => $enrol));
                 $hideshow = "<a href=\"{$aurl}\">";
                 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"{$strenable}\" /></a>";
                 $enabled = false;
                 $displayname = "<span class=\"dimmed_text\">{$name}</span>";
             } else {
                 $hideshow = '';
                 $enabled = false;
                 $displayname = '<span class="notifyproblem">' . $name . '</span>';
             }
         }
         // up/down link (only if enrol is enabled)
         $updown = '';
         if ($enabled) {
             if ($updowncount > 1) {
                 $aurl = new moodle_url($url, array('action' => 'up', 'enrol' => $enrol));
                 $updown .= "<a href=\"{$aurl}\">";
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"{$strup}\" /></a>&nbsp;";
             } else {
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />&nbsp;";
             }
             if ($updowncount < $enrolcount) {
                 $aurl = new moodle_url($url, array('action' => 'down', 'enrol' => $enrol));
                 $updown .= "<a href=\"{$aurl}\">";
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"{$strdown}\" /></a>";
             } else {
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />";
             }
             ++$updowncount;
         }
         // settings link
         if (isset($active_enrols[$enrol]) or file_exists($CFG->dirroot . '/enrol/' . $enrol . '/settings.php')) {
             $surl = new moodle_url('/admin/settings.php', array('section' => 'enrolsettings' . $enrol));
             $settings = "<a href=\"{$surl}\">{$strsettings}</a>";
         } else {
             $settings = '';
         }
         // uninstall
         $aurl = new moodle_url($url, array('action' => 'uninstall', 'enrol' => $enrol));
         $uninstall = "<a href=\"{$aurl}\">{$struninstall}</a>";
         // add a row to the table
         $table->data[] = array($displayname, $usage, $hideshow, $updown, $settings, $uninstall);
         $printed[$enrol] = true;
     }
     $return .= html_writer::table($table);
     $return .= get_string('configenrolplugins', 'enrol') . '<br />' . get_string('tablenosave', 'admin');
     $return .= $OUTPUT->box_end();
     return highlight($query, $return);
 }
예제 #7
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';
    require_once $CFG->libdir . '/gradelib.php';
    if (!empty($CFG->showcronsql)) {
        $DB->set_debug(true);
    }
    if (!empty($CFG->showcrondebugging)) {
        set_debugging(DEBUG_DEVELOPER, true);
    }
    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");
    // Run cleanup core cron jobs, but not every time since they aren't too important.
    // These don't have a timer to reduce load, so we'll use a random number
    // to randomly choose the percentage of times we should run these jobs.
    $random100 = rand(0, 100);
    if ($random100 < 20) {
        // Approximately 20% of the time.
        mtrace("Running clean-up tasks...");
        cron_trace_time_and_memory();
        // Delete users who haven't confirmed within required period
        if (!empty($CFG->deleteunconfirmed)) {
            $cuttime = $timenow - $CFG->deleteunconfirmed * 3600;
            $rs = $DB->get_recordset_sql("SELECT *\n                                             FROM {user}\n                                            WHERE confirmed = 0 AND firstaccess > 0\n                                                  AND firstaccess < ?", array($cuttime));
            foreach ($rs as $user) {
                delete_user($user);
                // we MUST delete user properly first
                $DB->delete_records('user', array('id' => $user->id));
                // this is a bloody hack, but it might work
                mtrace(" Deleted unconfirmed user for " . fullname($user, true) . " ({$user->id})");
            }
            $rs->close();
        }
        // Delete users who haven't completed profile within required period
        if (!empty($CFG->deleteincompleteusers)) {
            $cuttime = $timenow - $CFG->deleteincompleteusers * 3600;
            $rs = $DB->get_recordset_sql("SELECT *\n                                             FROM {user}\n                                            WHERE confirmed = 1 AND lastaccess > 0\n                                                  AND lastaccess < ? AND deleted = 0\n                                                  AND (lastname = '' OR firstname = '' OR email = '')", array($cuttime));
            foreach ($rs as $user) {
                if (isguestuser($user) or is_siteadmin($user)) {
                    continue;
                }
                delete_user($user);
                mtrace(" Deleted not fully setup user {$user->username} ({$user->id})");
            }
            $rs->close();
        }
        // Delete old logs to save space (this might need a timer to slow it down...)
        if (!empty($CFG->loglifetime)) {
            // value in days
            $loglifetime = $timenow - $CFG->loglifetime * 3600 * 24;
            $DB->delete_records_select("log", "time < ?", array($loglifetime));
            mtrace(" Deleted old log records");
        }
        // Delete old backup_controllers and logs.
        $loglifetime = get_config('backup', 'loglifetime');
        if (!empty($loglifetime)) {
            // Value in days.
            $loglifetime = $timenow - $loglifetime * 3600 * 24;
            // Delete child records from backup_logs.
            $DB->execute("DELETE FROM {backup_logs}\n                           WHERE EXISTS (\n                               SELECT 'x'\n                                 FROM {backup_controllers} bc\n                                WHERE bc.backupid = {backup_logs}.backupid\n                                  AND bc.timecreated < ?)", array($loglifetime));
            // Delete records from backup_controllers.
            $DB->execute("DELETE FROM {backup_controllers}\n                          WHERE timecreated < ?", array($loglifetime));
            mtrace(" Deleted old backup records");
        }
        // Delete old cached texts
        if (!empty($CFG->cachetext)) {
            // Defined in config.php
            $cachelifetime = time() - $CFG->cachetext - 60;
            // Add an extra minute to allow for really heavy sites
            $DB->delete_records_select('cache_text', "timemodified < ?", array($cachelifetime));
            mtrace(" Deleted old cache_text records");
        }
        if (!empty($CFG->usetags)) {
            require_once $CFG->dirroot . '/tag/lib.php';
            tag_cron();
            mtrace(' Executed tag cron');
        }
        // Context maintenance stuff
        context_helper::cleanup_instances();
        mtrace(' Cleaned up context instances');
        context_helper::build_all_paths(false);
        // If you suspect that the context paths are somehow corrupt
        // replace the line below with: context_helper::build_all_paths(true);
        mtrace(' Built context paths');
        // Remove expired cache flags
        gc_cache_flags();
        mtrace(' Cleaned cache flags');
        // Cleanup messaging
        if (!empty($CFG->messagingdeletereadnotificationsdelay)) {
            $notificationdeletetime = time() - $CFG->messagingdeletereadnotificationsdelay;
            $DB->delete_records_select('message_read', 'notification=1 AND timeread<:notificationdeletetime', array('notificationdeletetime' => $notificationdeletetime));
            mtrace(' Cleaned up read notifications');
        }
        mtrace(' Deleting temporary files...');
        cron_delete_from_temp();
        // Cleanup user password reset records
        // Delete any reset request records which are expired by more than a day.
        // (We keep recently expired requests around so we can give a different error msg to users who
        // are trying to user a recently expired reset attempt).
        $pwresettime = isset($CFG->pwresettime) ? $CFG->pwresettime : 1800;
        $earliestvalid = time() - $pwresettime - DAYSECS;
        $DB->delete_records_select('user_password_resets', "timerequested < ?", array($earliestvalid));
        mtrace(' Cleaned up old password reset records');
        mtrace("...finished clean-up tasks");
    }
    // End of occasional clean-up tasks
    // Send login failures notification - brute force protection in moodle is weak,
    // we should at least send notices early in each cron execution
    if (notify_login_failures()) {
        mtrace(' Notified login failures');
    }
    // Make sure all context instances are properly created - they may be required in auth, enrol, etc.
    context_helper::create_instances();
    mtrace(' Created missing context instances');
    // Session gc.
    mtrace("Running session gc tasks...");
    \core\session\manager::gc();
    mtrace("...finished stale session cleanup");
    // Run the auth cron, if any before enrolments
    // because it might add users that will be needed in enrol plugins
    $auths = get_enabled_auth_plugins();
    mtrace("Running auth crons if required...");
    cron_trace_time_and_memory();
    foreach ($auths as $auth) {
        $authplugin = get_auth_plugin($auth);
        if (method_exists($authplugin, 'cron')) {
            mtrace("Running cron for auth/{$auth}...");
            $authplugin->cron();
            if (!empty($authplugin->log)) {
                mtrace($authplugin->log);
            }
        }
        unset($authplugin);
    }
    // Generate new password emails for users - ppl expect these generated asap
    if ($DB->count_records('user_preferences', array('name' => 'create_password', 'value' => '1'))) {
        mtrace('Creating passwords for new users...');
        $usernamefields = get_all_user_name_fields(true, 'u');
        $newusers = $DB->get_recordset_sql("SELECT u.id as id, u.email,\n                                                 {$usernamefields}, u.username, u.lang,\n                                                 p.id as prefid\n                                            FROM {user} u\n                                            JOIN {user_preferences} p ON u.id=p.userid\n                                           WHERE p.name='create_password' AND p.value='1' AND u.email !='' AND u.suspended = 0 AND u.auth != 'nologin' AND u.deleted = 0");
        // note: we can not send emails to suspended accounts
        foreach ($newusers as $newuser) {
            // Use a low cost factor when generating bcrypt hash otherwise
            // hashing would be slow when emailing lots of users. Hashes
            // will be automatically updated to a higher cost factor the first
            // time the user logs in.
            if (setnew_password_and_mail($newuser, true)) {
                unset_user_preference('create_password', $newuser);
                set_user_preference('auth_forcepasswordchange', 1, $newuser);
            } else {
                trigger_error("Could not create and mail new user password!");
            }
        }
        $newusers->close();
    }
    // It is very important to run enrol early
    // because other plugins depend on correct enrolment info.
    mtrace("Running enrol crons if required...");
    $enrols = enrol_get_plugins(true);
    foreach ($enrols as $ename => $enrol) {
        // do this for all plugins, disabled plugins might want to cleanup stuff such as roles
        if (!$enrol->is_cron_required()) {
            continue;
        }
        mtrace("Running cron for enrol_{$ename}...");
        cron_trace_time_and_memory();
        $enrol->cron();
        $enrol->set_config('lastcron', time());
    }
    // Run all cron jobs for each module
    mtrace("Starting activity modules");
    get_mailer('buffer');
    if ($mods = $DB->get_records_select("modules", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
        foreach ($mods as $mod) {
            $libfile = "{$CFG->dirroot}/mod/{$mod->name}/lib.php";
            if (file_exists($libfile)) {
                include_once $libfile;
                $cron_function = $mod->name . "_cron";
                if (function_exists($cron_function)) {
                    mtrace("Processing module function {$cron_function} ...", '');
                    cron_trace_time_and_memory();
                    $pre_dbqueries = null;
                    $pre_dbqueries = $DB->perf_get_queries();
                    $pre_time = microtime(1);
                    if ($cron_function()) {
                        $DB->set_field("modules", "lastcron", $timenow, array("id" => $mod->id));
                    }
                    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.");
                }
            }
        }
    }
    get_mailer('close');
    mtrace("Finished activity modules");
    mtrace("Starting blocks");
    if ($blocks = $DB->get_records_select("block", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
        // We will need the base class.
        require_once $CFG->dirroot . '/blocks/moodleblock.class.php';
        foreach ($blocks as $block) {
            $blockfile = $CFG->dirroot . '/blocks/' . $block->name . '/block_' . $block->name . '.php';
            if (file_exists($blockfile)) {
                require_once $blockfile;
                $classname = 'block_' . $block->name;
                $blockobj = new $classname();
                if (method_exists($blockobj, 'cron')) {
                    mtrace("Processing cron function for " . $block->name . '....', '');
                    cron_trace_time_and_memory();
                    if ($blockobj->cron()) {
                        $DB->set_field('block', 'lastcron', $timenow, array('id' => $block->id));
                    }
                    // Reset possible changes by blocks to time_limit. MDL-11597
                    @set_time_limit(0);
                    mtrace('done.');
                }
            }
        }
    }
    mtrace('Finished blocks');
    mtrace('Starting admin reports');
    cron_execute_plugin_type('report');
    mtrace('Finished admin reports');
    mtrace('Starting main gradebook job...');
    cron_trace_time_and_memory();
    grade_cron();
    mtrace('done.');
    mtrace('Starting processing the event queue...');
    cron_trace_time_and_memory();
    events_cron();
    mtrace('done.');
    if ($CFG->enablecompletion) {
        // Completion cron
        mtrace('Starting the completion cron...');
        cron_trace_time_and_memory();
        require_once $CFG->dirroot . '/completion/cron.php';
        completion_cron();
        mtrace('done');
    }
    if ($CFG->enableportfolios) {
        // Portfolio cron
        mtrace('Starting the portfolio cron...');
        cron_trace_time_and_memory();
        require_once $CFG->libdir . '/portfoliolib.php';
        portfolio_cron();
        mtrace('done');
    }
    //now do plagiarism checks
    require_once $CFG->libdir . '/plagiarismlib.php';
    plagiarism_cron();
    mtrace('Starting course reports');
    cron_execute_plugin_type('coursereport');
    mtrace('Finished course reports');
    // run gradebook import/export/report cron
    mtrace('Starting gradebook plugins');
    cron_execute_plugin_type('gradeimport');
    cron_execute_plugin_type('gradeexport');
    cron_execute_plugin_type('gradereport');
    mtrace('Finished gradebook plugins');
    // run calendar cron
    require_once "{$CFG->dirroot}/calendar/lib.php";
    calendar_cron();
    // Run external blog cron if needed
    if (!empty($CFG->enableblogs) && $CFG->useexternalblogs) {
        require_once $CFG->dirroot . '/blog/lib.php';
        mtrace("Fetching external blog entries...", '');
        cron_trace_time_and_memory();
        $sql = "timefetched < ? OR timefetched = 0";
        $externalblogs = $DB->get_records_select('blog_external', $sql, array(time() - $CFG->externalblogcrontime));
        foreach ($externalblogs as $eb) {
            blog_sync_external_entries($eb);
        }
        mtrace('done.');
    }
    // Run blog associations cleanup
    if (!empty($CFG->enableblogs) && $CFG->useblogassociations) {
        require_once $CFG->dirroot . '/blog/lib.php';
        // delete entries whose contextids no longer exists
        mtrace("Deleting blog associations linked to non-existent contexts...", '');
        cron_trace_time_and_memory();
        $DB->delete_records_select('blog_association', 'contextid NOT IN (SELECT id FROM {context})');
        mtrace('done.');
    }
    // Run question bank clean-up.
    mtrace("Starting the question bank cron...", '');
    cron_trace_time_and_memory();
    require_once $CFG->libdir . '/questionlib.php';
    question_bank::cron();
    mtrace('done.');
    //Run registration updated cron
    mtrace(get_string('siteupdatesstart', 'hub'));
    cron_trace_time_and_memory();
    require_once $CFG->dirroot . '/' . $CFG->admin . '/registration/lib.php';
    $registrationmanager = new registration_manager();
    $registrationmanager->cron();
    mtrace(get_string('siteupdatesend', 'hub'));
    // If enabled, fetch information about available updates and eventually notify site admins
    if (empty($CFG->disableupdatenotifications)) {
        $updateschecker = \core\update\checker::instance();
        $updateschecker->cron();
    }
    //cleanup old session linked tokens
    //deletes the session linked tokens that are over a day old.
    mtrace("Deleting session linked tokens more than one day old...", '');
    cron_trace_time_and_memory();
    $DB->delete_records_select('external_tokens', 'lastaccess < :onedayago AND tokentype = :tokentype', array('onedayago' => time() - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED));
    mtrace('done.');
    // all other plugins
    cron_execute_plugin_type('message', 'message plugins');
    cron_execute_plugin_type('filter', 'filters');
    cron_execute_plugin_type('editor', 'editors');
    cron_execute_plugin_type('format', 'course formats');
    cron_execute_plugin_type('profilefield', 'profile fields');
    cron_execute_plugin_type('webservice', 'webservices');
    cron_execute_plugin_type('repository', 'repository plugins');
    cron_execute_plugin_type('qbehaviour', 'question behaviours');
    cron_execute_plugin_type('qformat', 'question import/export formats');
    cron_execute_plugin_type('qtype', 'question types');
    cron_execute_plugin_type('plagiarism', 'plagiarism plugins');
    cron_execute_plugin_type('theme', 'themes');
    cron_execute_plugin_type('tool', 'admin tools');
    // and finally run any local cronjobs, if any
    if ($locals = core_component::get_plugin_list('local')) {
        mtrace('Processing customized cron scripts ...', '');
        // new cron functions in lib.php first
        cron_execute_plugin_type('local');
        // legacy cron files are executed directly
        foreach ($locals as $local => $localdir) {
            if (file_exists("{$localdir}/cron.php")) {
                include "{$localdir}/cron.php";
            }
        }
        mtrace('done.');
    }
    mtrace('Running cache cron routines');
    cache_helper::cron();
    mtrace('done.');
    // Run automated backups if required - these may take a long time to execute
    require_once $CFG->dirroot . '/backup/util/includes/backup_includes.php';
    require_once $CFG->dirroot . '/backup/util/helper/backup_cron_helper.class.php';
    backup_cron_automated_helper::run_automated_backup();
    // Run stats as at the end because they are known to take very long time on large sites
    if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) {
        require_once $CFG->dirroot . '/lib/statslib.php';
        // check we're not before our runtime
        $timetocheck = stats_get_base_daily() + $CFG->statsruntimestarthour * 60 * 60 + $CFG->statsruntimestartminute * 60;
        if (time() > $timetocheck) {
            // process configured number of days as max (defaulting to 31)
            $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays);
            if (stats_cron_daily($maxdays)) {
                if (stats_cron_weekly()) {
                    if (stats_cron_monthly()) {
                        stats_clean_old();
                    }
                }
            }
            @set_time_limit(0);
        } else {
            mtrace('Next stats run after:' . userdate($timetocheck));
        }
    }
    // Run badges review cron.
    mtrace("Starting badges cron...");
    require_once $CFG->dirroot . '/badges/cron.php';
    badge_cron();
    mtrace('done.');
    // cleanup file trash - not very important
    $fs = get_file_storage();
    $fs->cron();
    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");
}
예제 #8
0
 function display_savenew()
 {
     // action_savenew()
     global $USER, $CFG, $DB;
     $clsid = cm_get_param('clsid', 0);
     $class = new pmclass($clsid);
     $now = time();
     if (!$class->is_enrollable()) {
         print_error('notenrollable', 'enrol');
         // TBD
     }
     // check if class is full
     if (!empty($class->maxstudents) && student::count_enroled($class->id) >= $class->maxstudents) {
         $form = $this->create_waitlistform($classid);
         $form->display();
         return;
     }
     // call the Moodle enrolment plugin if attached to a Moodle course, and
     // it's not the elis plugin
     //todo: check Moodle enrolment plugins here
     $cuserid = cm_get_crlmuserid($USER->id);
     $sturecord = array();
     $sturecord['classid'] = $class->id;
     $sturecord['userid'] = $cuserid;
     // Set the enrolment time from class startdate if it's in the future or just set
     // current time if class has an associated Moodle course that has already started
     $enrolmenttime = $class->startdate;
     if ($moodlecourseid = moodle_get_course($clsid)) {
         if ($startdate = $DB->get_field('course', 'startdate', array('id' => $moodlecourseid))) {
             $enrolmenttime = $startdate < $now ? $now : $class->startdate;
         }
     }
     $sturecord['enrolmenttime'] = max($now, $enrolmenttime);
     $sturecord['completetime'] = 0;
     $newstu = new student($sturecord);
     $courseid = $class->get_moodle_course_id();
     if ($courseid) {
         $course = $DB->get_record('course', array('id' => $courseid));
         // check that the elis plugin allows for enrolments from the course
         // catalog -- if not, see if there are other plugins that allow
         // self-enrolment.
         $plugin = enrol_get_plugin('elis');
         $enrol = $plugin->get_or_create_instance($course);
         if (!$enrol->{enrol_elis_plugin::ENROL_FROM_COURSE_CATALOG_DB}) {
             // get course enrolment plugins, and see if any of them allow self-enrolment
             $enrols = enrol_get_plugins(true);
             $enrolinstances = enrol_get_instances($course->id, true);
             foreach ($enrolinstances as $instance) {
                 if (!isset($enrols[$instance->enrol])) {
                     continue;
                 }
                 $form = $enrols[$instance->enrol]->enrol_page_hook($instance);
                 if ($form) {
                     // at least one plugin allows self-enrolment -- send
                     // the user to the course enrolment page, and prevent
                     // automatic enrolment
                     $newstu->no_moodle_enrol = true;
                     $newstu->save();
                     redirect("{$CFG->wwwroot}/course/enrol.php?id={$courseid}");
                     return;
                 }
             }
         }
     }
     $newstu->save();
     $tmppage = new coursecatalogpage(array('action' => 'default'));
     redirect($tmppage->url);
 }
예제 #9
0
    /**
     * Create enrolment instances.
     *
     * This has to be called after creation of roles
     * and before adding of role assignments.
     *
     * @param mixed $data
     * @return void
     */
    public function process_enrol($data) {
        global $DB;

        $data = (object)$data;
        $oldid = $data->id; // We'll need this later

        $restoretype = plugin_supports('enrol', $data->enrol, ENROL_RESTORE_TYPE, null);

        if ($restoretype !== ENROL_RESTORE_EXACT and $restoretype !== ENROL_RESTORE_NOUSERS) {
            // TODO: add complex restore support via custom class
            debugging("Skipping '{$data->enrol}' enrolment plugin. Will be implemented before 2.0 release", DEBUG_DEVELOPER);
            $this->set_mapping('enrol', $oldid, 0);
            return;
        }

        // Perform various checks to decide what to do with the enrol plugin
        if (!array_key_exists($data->enrol, enrol_get_plugins(false))) {
            // TODO: decide if we want to switch to manual enrol - we need UI for this
            debugging("Enrol plugin data can not be restored because it is not installed");
            $this->set_mapping('enrol', $oldid, 0);
            return;

        }
        if (!enrol_is_enabled($data->enrol)) {
            // TODO: decide if we want to switch to manual enrol - we need UI for this
            debugging("Enrol plugin data can not be restored because it is not enabled");
            $this->set_mapping('enrol', $oldid, 0);
            return;
        }

        // map standard fields - plugin has to process custom fields from own restore class
        $data->roleid = $this->get_mappingid('role', $data->roleid);
        //TODO: should we move the enrol start and end date here?

        // always add instance, if the course does not support multiple instances it just returns NULL
        $enrol = enrol_get_plugin($data->enrol);
        $courserec = $DB->get_record('course', array('id' => $this->get_courseid())); // Requires object, uses only id!!
        if ($newitemid = $enrol->add_instance($courserec, (array)$data)) {
            // ok
        } else {
            if ($instances = $DB->get_records('enrol', array('courseid'=>$courserec->id, 'enrol'=>$data->enrol))) {
                // most probably plugin that supports only one instance
                $newitemid = key($instances);
            } else {
                debugging('Can not create new enrol instance or reuse existing');
                $newitemid = 0;
            }
        }

        if ($restoretype === ENROL_RESTORE_NOUSERS) {
            // plugin requests to prevent restore of any users
            $newitemid = 0;
        }

        $this->set_mapping('enrol', $oldid, $newitemid);
    }
예제 #10
0
/**
 * Cron functions.
 *
 * @package    core
 * @subpackage admin
 * @copyright  1999 onwards Martin Dougiamas  http://dougiamas.com
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
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';
    require_once $CFG->libdir . '/gradelib.php';
    if (!empty($CFG->showcronsql)) {
        $DB->set_debug(true);
    }
    if (!empty($CFG->showcrondebugging)) {
        $CFG->debug = DEBUG_DEVELOPER;
        $CFG->debugdisplay = true;
    }
    set_time_limit(0);
    $starttime = microtime();
    /// increase memory limit
    raise_memory_limit(MEMORY_EXTRA);
    /// emulate normal session
    cron_setup_user();
    /// Start output log
    $timenow = time();
    mtrace("Server Time: " . date('r', $timenow) . "\n\n");
    /// Session gc
    mtrace("Cleaning up stale sessions");
    session_gc();
    /// Run all cron jobs for each module
    mtrace("Starting activity modules");
    get_mailer('buffer');
    if ($mods = $DB->get_records_select("modules", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
        foreach ($mods as $mod) {
            $libfile = "{$CFG->dirroot}/mod/{$mod->name}/lib.php";
            if (file_exists($libfile)) {
                include_once $libfile;
                $cron_function = $mod->name . "_cron";
                if (function_exists($cron_function)) {
                    mtrace("Processing module function {$cron_function} ...", '');
                    $pre_dbqueries = null;
                    $pre_dbqueries = $DB->perf_get_queries();
                    $pre_time = microtime(1);
                    if ($cron_function()) {
                        $DB->set_field("modules", "lastcron", $timenow, array("id" => $mod->id));
                    }
                    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.");
                }
            }
        }
    }
    get_mailer('close');
    mtrace("Finished activity modules");
    mtrace("Starting blocks");
    if ($blocks = $DB->get_records_select("block", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
        // we will need the base class.
        require_once $CFG->dirroot . '/blocks/moodleblock.class.php';
        foreach ($blocks as $block) {
            $blockfile = $CFG->dirroot . '/blocks/' . $block->name . '/block_' . $block->name . '.php';
            if (file_exists($blockfile)) {
                require_once $blockfile;
                $classname = 'block_' . $block->name;
                $blockobj = new $classname();
                if (method_exists($blockobj, 'cron')) {
                    mtrace("Processing cron function for " . $block->name . '....', '');
                    if ($blockobj->cron()) {
                        $DB->set_field('block', 'lastcron', $timenow, array('id' => $block->id));
                    }
                    /// Reset possible changes by blocks to time_limit. MDL-11597
                    @set_time_limit(0);
                    mtrace('done.');
                }
            }
        }
    }
    mtrace('Finished blocks');
    //now do plagiarism checks
    require_once $CFG->libdir . '/plagiarismlib.php';
    plagiarism_cron();
    mtrace("Starting quiz reports");
    if ($reports = $DB->get_records_select('quiz_report', "cron > 0 AND ((? - lastcron) > cron)", array($timenow))) {
        foreach ($reports as $report) {
            $cronfile = "{$CFG->dirroot}/mod/quiz/report/{$report->name}/cron.php";
            if (file_exists($cronfile)) {
                include_once $cronfile;
                $cron_function = 'quiz_report_' . $report->name . "_cron";
                if (function_exists($cron_function)) {
                    mtrace("Processing quiz report cron function {$cron_function} ...", '');
                    $pre_dbqueries = null;
                    $pre_dbqueries = $DB->perf_get_queries();
                    $pre_time = microtime(1);
                    if ($cron_function()) {
                        $DB->set_field('quiz_report', "lastcron", $timenow, array("id" => $report->id));
                    }
                    if (isset($pre_dbqueries)) {
                        mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries");
                        mtrace("... used " . (microtime(1) - $pre_time) . " seconds");
                    }
                    mtrace("done.");
                }
            }
        }
    }
    mtrace("Finished quiz reports");
    mtrace('Starting admin reports');
    // Admin reports do not have a database table that lists them. Instead a
    // report includes cron.php with function report_reportname_cron() if it wishes
    // to be cronned. It is up to cron.php to handle e.g. if it only needs to
    // actually do anything occasionally.
    $reports = get_plugin_list('report');
    foreach ($reports as $report => $reportdir) {
        $cronfile = $reportdir . '/cron.php';
        if (file_exists($cronfile)) {
            require_once $cronfile;
            $cronfunction = 'report_' . $report . '_cron';
            mtrace('Processing cron function for ' . $report . '...', '');
            $pre_dbqueries = null;
            $pre_dbqueries = $DB->perf_get_queries();
            $pre_time = microtime(true);
            $cronfunction();
            if (isset($pre_dbqueries)) {
                mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries");
                mtrace("... used " . round(microtime(true) - $pre_time, 2) . " seconds");
            }
            mtrace('done.');
        }
    }
    mtrace('Finished admin reports');
    mtrace('Starting main gradebook job ...');
    grade_cron();
    mtrace('done.');
    mtrace('Starting processing the event queue...');
    events_cron();
    mtrace('done.');
    if ($CFG->enablecompletion) {
        // Completion cron
        mtrace('Starting the completion cron...');
        require_once $CFG->libdir . '/completion/cron.php';
        completion_cron();
        mtrace('done');
    }
    if ($CFG->enableportfolios) {
        // Portfolio cron
        mtrace('Starting the portfolio cron...');
        require_once $CFG->libdir . '/portfoliolib.php';
        portfolio_cron();
        mtrace('done');
    }
    /// Run all core cron jobs, but not every time since they aren't too important.
    /// These don't have a timer to reduce load, so we'll use a random number
    /// to randomly choose the percentage of times we should run these jobs.
    srand((double) microtime() * 10000000);
    $random100 = rand(0, 100);
    if ($random100 < 20) {
        // Approximately 20% of the time.
        mtrace("Running clean-up tasks...");
        /// Delete users who haven't confirmed within required period
        if (!empty($CFG->deleteunconfirmed)) {
            $cuttime = $timenow - $CFG->deleteunconfirmed * 3600;
            $rs = $DB->get_recordset_sql("SELECT id, firstname, lastname\n                                             FROM {user}\n                                            WHERE confirmed = 0 AND firstaccess > 0\n                                                  AND firstaccess < ?", array($cuttime));
            foreach ($rs as $user) {
                if ($DB->delete_records('user', array('id' => $user->id))) {
                    mtrace("Deleted unconfirmed user for " . fullname($user, true) . " ({$user->id})");
                }
            }
            $rs->close();
        }
        flush();
        /// Delete users who haven't completed profile within required period
        if (!empty($CFG->deleteincompleteusers)) {
            $cuttime = $timenow - $CFG->deleteincompleteusers * 3600;
            $rs = $DB->get_recordset_sql("SELECT id, username\n                                             FROM {user}\n                                            WHERE confirmed = 1 AND lastaccess > 0\n                                                  AND lastaccess < ? AND deleted = 0\n                                                  AND (lastname = '' OR firstname = '' OR email = '')", array($cuttime));
            foreach ($rs as $user) {
                if (delete_user($user)) {
                    mtrace("Deleted not fully setup user {$user->username} ({$user->id})");
                }
            }
            $rs->close();
        }
        flush();
        /// Delete old logs to save space (this might need a timer to slow it down...)
        if (!empty($CFG->loglifetime)) {
            // value in days
            $loglifetime = $timenow - $CFG->loglifetime * 3600 * 24;
            if ($DB->delete_records_select("log", "time < ?", array($loglifetime))) {
                mtrace("Deleted old log records");
            }
        }
        flush();
        // Delete old backup_controllers and logs
        if (!empty($CFG->loglifetime)) {
            // value in days
            $loglifetime = $timenow - $CFG->loglifetime * 3600 * 24;
            // Delete child records from backup_logs
            $DB->execute("DELETE FROM {backup_logs}\n                           WHERE EXISTS (\n                               SELECT 'x'\n                                 FROM {backup_controllers} bc\n                                WHERE bc.backupid = {backup_logs}.backupid\n                                  AND bc.timecreated < ?)", array($loglifetime));
            // Delete records from backup_controllers
            $DB->execute("DELETE FROM {backup_controllers}\n                          WHERE timecreated < ?", array($loglifetime));
            mtrace("Deleted old backup records");
        }
        flush();
        /// Delete old cached texts
        if (!empty($CFG->cachetext)) {
            // Defined in config.php
            $cachelifetime = time() - $CFG->cachetext - 60;
            // Add an extra minute to allow for really heavy sites
            if ($DB->delete_records_select('cache_text', "timemodified < ?", array($cachelifetime))) {
                mtrace("Deleted old cache_text records");
            }
        }
        flush();
        if (!empty($CFG->notifyloginfailures)) {
            notify_login_failures();
            mtrace('Notified login failured');
        }
        flush();
        //
        // generate new password emails for users
        //
        mtrace('checking for create_password');
        if ($DB->count_records('user_preferences', array('name' => 'create_password', 'value' => '1'))) {
            mtrace('creating passwords for new users');
            $newusers = $DB->get_records_sql("SELECT u.id as id, u.email, u.firstname,\n                                                     u.lastname, u.username,\n                                                     p.id as prefid\n                                                FROM {user} u\n                                                JOIN {user_preferences} p ON u.id=p.userid\n                                               WHERE p.name='create_password' AND p.value='1' AND u.email !='' ");
            foreach ($newusers as $newuserid => $newuser) {
                // email user
                if (setnew_password_and_mail($newuser)) {
                    // remove user pref
                    $DB->delete_records('user_preferences', array('id' => $newuser->prefid));
                } else {
                    trigger_error("Could not create and mail new user password!");
                }
            }
        }
        if (!empty($CFG->usetags)) {
            require_once $CFG->dirroot . '/tag/lib.php';
            tag_cron();
            mtrace('Executed tag cron');
        }
        // Accesslib stuff
        cleanup_contexts();
        mtrace('Cleaned up contexts');
        gc_cache_flags();
        mtrace('Cleaned cache flags');
        // If you suspect that the context paths are somehow corrupt
        // replace the line below with: build_context_path(true);
        build_context_path();
        mtrace('Built context paths');
        if (!empty($CFG->messagingdeletereadnotificationsdelay)) {
            $notificationdeletetime = time() - $CFG->messagingdeletereadnotificationsdelay;
            $DB->delete_records_select('message_read', 'notification=1 AND timeread<:notificationdeletetime', array('notificationdeletetime' => $notificationdeletetime));
            mtrace('Cleaned up read notifications');
        }
        mtrace("Finished clean-up tasks...");
    }
    // End of occasional clean-up tasks
    // Run automated backups if required.
    require_once $CFG->dirroot . '/backup/util/includes/backup_includes.php';
    require_once $CFG->dirroot . '/backup/util/helper/backup_cron_helper.class.php';
    backup_cron_automated_helper::run_automated_backup();
    /// Run the auth cron, if any
    /// before enrolments because it might add users that will be needed in enrol plugins
    $auths = get_enabled_auth_plugins();
    mtrace("Running auth crons if required...");
    foreach ($auths as $auth) {
        $authplugin = get_auth_plugin($auth);
        if (method_exists($authplugin, 'cron')) {
            mtrace("Running cron for auth/{$auth}...");
            $authplugin->cron();
            if (!empty($authplugin->log)) {
                mtrace($authplugin->log);
            }
        }
        unset($authplugin);
    }
    mtrace("Running enrol crons if required...");
    $enrols = enrol_get_plugins(true);
    foreach ($enrols as $ename => $enrol) {
        // do this for all plugins, disabled plugins might want to cleanup stuff such as roles
        if (!$enrol->is_cron_required()) {
            continue;
        }
        mtrace("Running cron for enrol_{$ename}...");
        $enrol->cron();
        $enrol->set_config('lastcron', time());
    }
    if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) {
        require_once $CFG->dirroot . '/lib/statslib.php';
        // check we're not before our runtime
        $timetocheck = stats_get_base_daily() + $CFG->statsruntimestarthour * 60 * 60 + $CFG->statsruntimestartminute * 60;
        if (time() > $timetocheck) {
            // process configured number of days as max (defaulting to 31)
            $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays);
            if (stats_cron_daily($maxdays)) {
                if (stats_cron_weekly()) {
                    if (stats_cron_monthly()) {
                        stats_clean_old();
                    }
                }
            }
            @set_time_limit(0);
        } else {
            mtrace('Next stats run after:' . userdate($timetocheck));
        }
    }
    // run gradebook import/export/report cron
    if ($gradeimports = get_plugin_list('gradeimport')) {
        foreach ($gradeimports as $gradeimport => $plugindir) {
            if (file_exists($plugindir . '/lib.php')) {
                require_once $plugindir . '/lib.php';
                $cron_function = 'grade_import_' . $gradeimport . '_cron';
                if (function_exists($cron_function)) {
                    mtrace("Processing gradebook import function {$cron_function} ...", '');
                    $cron_function();
                }
            }
        }
    }
    if ($gradeexports = get_plugin_list('gradeexport')) {
        foreach ($gradeexports as $gradeexport => $plugindir) {
            if (file_exists($plugindir . '/lib.php')) {
                require_once $plugindir . '/lib.php';
                $cron_function = 'grade_export_' . $gradeexport . '_cron';
                if (function_exists($cron_function)) {
                    mtrace("Processing gradebook export function {$cron_function} ...", '');
                    $cron_function();
                }
            }
        }
    }
    if ($gradereports = get_plugin_list('gradereport')) {
        foreach ($gradereports as $gradereport => $plugindir) {
            if (file_exists($plugindir . '/lib.php')) {
                require_once $plugindir . '/lib.php';
                $cron_function = 'grade_report_' . $gradereport . '_cron';
                if (function_exists($cron_function)) {
                    mtrace("Processing gradebook report function {$cron_function} ...", '');
                    $cron_function();
                }
            }
        }
    }
    // Run external blog cron if needed
    if ($CFG->useexternalblogs) {
        require_once $CFG->dirroot . '/blog/lib.php';
        mtrace("Fetching external blog entries...", '');
        $sql = "timefetched < ? OR timefetched = 0";
        $externalblogs = $DB->get_records_select('blog_external', $sql, array(mktime() - $CFG->externalblogcrontime));
        foreach ($externalblogs as $eb) {
            blog_sync_external_entries($eb);
        }
    }
    // Run blog associations cleanup
    if ($CFG->useblogassociations) {
        require_once $CFG->dirroot . '/blog/lib.php';
        // delete entries whose contextids no longer exists
        mtrace("Deleting blog associations linked to non-existent contexts...", '');
        $DB->delete_records_select('blog_association', 'contextid NOT IN (SELECT id FROM {context})');
    }
    //Run registration updated cron
    mtrace(get_string('siteupdatesstart', 'hub'));
    require_once $CFG->dirroot . '/admin/registration/lib.php';
    $registrationmanager = new registration_manager();
    $registrationmanager->cron();
    mtrace(get_string('siteupdatesend', 'hub'));
    // cleanup file trash
    $fs = get_file_storage();
    $fs->cron();
    //cleanup old session linked tokens
    //deletes the session linked tokens that are over a day old.
    mtrace("Deleting session linked tokens more than one day old...", '');
    $DB->delete_records_select('external_tokens', 'lastaccess < :onedayago AND tokentype = :tokentype', array('onedayago' => time() - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED));
    mtrace('done.');
    // run any customized cronjobs, if any
    if ($locals = get_plugin_list('local')) {
        mtrace('Processing customized cron scripts ...', '');
        foreach ($locals as $local => $localdir) {
            if (file_exists("{$localdir}/cron.php")) {
                include "{$localdir}/cron.php";
            }
        }
        mtrace('done.');
    }
    mtrace("Cron script completed correctly");
    $difftime = microtime_diff($starttime, microtime());
    mtrace("Execution took " . $difftime . " seconds");
}
예제 #11
0
// Everybody is enrolled on the frontpage
if ($course->id == SITEID) {
    redirect("{$CFG->wwwroot}/");
}
if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) {
    print_error('coursehidden');
}
$PAGE->set_course($course);
$PAGE->set_pagelayout('course');
$PAGE->set_url('/enrol/index.php', array('id' => $course->id));
// do not allow enrols when in login-as session
if (\core\session\manager::is_loggedinas() and $USER->loginascontext->contextlevel == CONTEXT_COURSE) {
    print_error('loginasnoenrol', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid);
}
// get all enrol forms available in this course
$enrols = enrol_get_plugins(true);
$enrolinstances = enrol_get_instances($course->id, true);
$forms = array();
foreach ($enrolinstances as $instance) {
    if (!isset($enrols[$instance->enrol])) {
        continue;
    }
    $form = $enrols[$instance->enrol]->enrol_page_hook($instance);
    if ($form) {
        $forms[$instance->id] = $form;
    }
}
// Check if user already enrolled
if (is_enrolled($context, $USER, '', true)) {
    if (!empty($SESSION->wantsurl)) {
        $destination = $SESSION->wantsurl;
예제 #12
0
/**
 * Returns true if the user is able to access the course.
 *
 * This function is in no way, shape, or form a substitute for require_login.
 * It should only be used in circumstances where it is not possible to call require_login
 * such as the navigation.
 *
 * This function checks many of the methods of access to a course such as the view
 * capability, enrollments, and guest access. It also makes use of the cache
 * generated by require_login for guest access.
 *
 * The flags within the $USER object that are used here should NEVER be used outside
 * of this function can_access_course and require_login. Doing so WILL break future
 * versions.
 *
 * @global moodle_database $DB
 * @param stdClass $context
 * @param stdClass|null $user
 * @param string $withcapability Check for this capability as well.
 * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions
 * @param boolean $trustcache If set to false guest access will always be checked
 *                             against the enrolment plugins from the course, rather
 *                             than the cache generated by require_login.
 * @return boolean Returns true if the user is able to access the course
 */
function can_access_course($context, $user = null, $withcapability = '', $onlyactive = false, $trustcache = true)
{
    global $DB, $USER;
    $coursecontext = get_course_context($context);
    $courseid = $coursecontext->instanceid;
    // First check the obvious, is the user viewing or is the user enrolled.
    if (is_viewing($coursecontext, $user, $withcapability) || is_enrolled($coursecontext, $user, $withcapability, $onlyactive)) {
        // How easy was that!
        return true;
    }
    $access = false;
    if (!isset($USER->enrol)) {
        // Cache hasn't been generated yet so we can't trust it
        $trustcache = false;
        /**
         * These flags within the $USER object should NEVER be used outside of this
         * function can_access_course and the function require_login.
         * Doing so WILL break future versions!!!!
         */
        $USER->enrol = array();
        $USER->enrol['enrolled'] = array();
        $USER->enrol['tempguest'] = array();
    }
    // If we don't trust the cache we need to check with the courses enrolment
    // plugin instances to see if the user can access the course as a guest.
    if (!$trustcache) {
        // Ok, off to the database we go!
        $instances = $DB->get_records('enrol', array('courseid' => $courseid, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC');
        $enrols = enrol_get_plugins(true);
        foreach ($instances as $instance) {
            if (!isset($enrols[$instance->enrol])) {
                continue;
            }
            $until = $enrols[$instance->enrol]->try_guestaccess($instance);
            if ($until !== false) {
                // Never use me anywhere but here and require_login
                $USER->enrol['tempguest'][$courseid] = $until;
                $access = true;
                break;
            }
        }
    }
    // If we don't already have access (from above) check the cache and see whether
    // there is record of it in there.
    if (!$access && isset($USER->enrol['tempguest'][$courseid])) {
        // Never use me anywhere but here and require_login
        if ($USER->enrol['tempguest'][$courseid] == 0) {
            $access = true;
        } else {
            if ($USER->enrol['tempguest'][$courseid] > time()) {
                $access = true;
            } else {
                //expired
                unset($USER->enrol['tempguest'][$courseid]);
            }
        }
    }
    return $access;
}
예제 #13
0
 /**
  * Do the job.
  * Throw exceptions on errors (the job will be retried).
  */
 public function execute()
 {
     global $CFG, $DB;
     $timenow = time();
     // Run the auth cron, if any before enrolments
     // because it might add users that will be needed in enrol plugins.
     $auths = get_enabled_auth_plugins();
     mtrace("Running auth crons if required...");
     foreach ($auths as $auth) {
         $authplugin = get_auth_plugin($auth);
         if (method_exists($authplugin, 'cron')) {
             mtrace("Running cron for auth/{$auth}...");
             $authplugin->cron();
             if (!empty($authplugin->log)) {
                 mtrace($authplugin->log);
             }
         }
         unset($authplugin);
     }
     // It is very important to run enrol early
     // because other plugins depend on correct enrolment info.
     mtrace("Running enrol crons if required...");
     $enrols = enrol_get_plugins(true);
     foreach ($enrols as $ename => $enrol) {
         // Do this for all plugins, disabled plugins might want to cleanup stuff such as roles.
         if (!$enrol->is_cron_required()) {
             continue;
         }
         mtrace("Running cron for enrol_{$ename}...");
         $enrol->cron();
         $enrol->set_config('lastcron', time());
     }
     // Run all cron jobs for each module.
     mtrace("Starting activity modules");
     if ($mods = $DB->get_records_select("modules", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
         foreach ($mods as $mod) {
             $libfile = "{$CFG->dirroot}/mod/{$mod->name}/lib.php";
             if (file_exists($libfile)) {
                 include_once $libfile;
                 $cronfunction = $mod->name . "_cron";
                 if (function_exists($cronfunction)) {
                     mtrace("Processing module function {$cronfunction} ...\n", '');
                     $predbqueries = null;
                     $predbqueries = $DB->perf_get_queries();
                     $pretime = microtime(1);
                     if ($cronfunction()) {
                         $DB->set_field("modules", "lastcron", $timenow, array("id" => $mod->id));
                     }
                     if (isset($predbqueries)) {
                         mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries");
                         mtrace("... used " . (microtime(1) - $pretime) . " seconds");
                     }
                     // Reset possible changes by modules to time_limit. MDL-11597.
                     \core_php_time_limit::raise();
                     mtrace("done.");
                 }
             }
         }
     }
     mtrace("Finished activity modules");
     mtrace("Starting blocks");
     if ($blocks = $DB->get_records_select("block", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) {
         // We will need the base class.
         require_once $CFG->dirroot . '/blocks/moodleblock.class.php';
         foreach ($blocks as $block) {
             $blockfile = $CFG->dirroot . '/blocks/' . $block->name . '/block_' . $block->name . '.php';
             if (file_exists($blockfile)) {
                 require_once $blockfile;
                 $classname = '\\block_' . $block->name;
                 $blockobj = new $classname();
                 if (method_exists($blockobj, 'cron')) {
                     mtrace("Processing cron function for " . $block->name . '....', '');
                     if ($blockobj->cron()) {
                         $DB->set_field('block', 'lastcron', $timenow, array('id' => $block->id));
                     }
                     // Reset possible changes by blocks to time_limit. MDL-11597.
                     \core_php_time_limit::raise();
                     mtrace('done.');
                 }
             }
         }
     }
     mtrace('Finished blocks');
     mtrace('Starting admin reports');
     cron_execute_plugin_type('report');
     mtrace('Finished admin reports');
     mtrace('Starting course reports');
     cron_execute_plugin_type('coursereport');
     mtrace('Finished course reports');
     // Run gradebook import/export/report cron.
     mtrace('Starting gradebook plugins');
     cron_execute_plugin_type('gradeimport');
     cron_execute_plugin_type('gradeexport');
     cron_execute_plugin_type('gradereport');
     mtrace('Finished gradebook plugins');
     // All other plugins.
     cron_execute_plugin_type('message', 'message plugins');
     cron_execute_plugin_type('filter', 'filters');
     cron_execute_plugin_type('editor', 'editors');
     cron_execute_plugin_type('format', 'course formats');
     cron_execute_plugin_type('profilefield', 'profile fields');
     cron_execute_plugin_type('webservice', 'webservices');
     cron_execute_plugin_type('repository', 'repository plugins');
     cron_execute_plugin_type('qbehaviour', 'question behaviours');
     cron_execute_plugin_type('qformat', 'question import/export formats');
     cron_execute_plugin_type('qtype', 'question types');
     cron_execute_plugin_type('plagiarism', 'plagiarism plugins');
     cron_execute_plugin_type('theme', 'themes');
     cron_execute_plugin_type('tool', 'admin tools');
     cron_execute_plugin_type('local', 'local plugins');
 }
/**
 * Duplicate a course
 *
 * @param int $courseid
 * @param string $fullname Duplicated course fullname
 * @param int $newcourse Destination course
 * @param array $options List of backup options
 * @return stdClass New course info
 */
function local_ltiprovider_duplicate_course($courseid, $newcourse, $visible = 1, $options = array(), $useridcreating = null, $context)
{
    global $CFG, $USER, $DB;
    require_once $CFG->dirroot . '/backup/util/includes/backup_includes.php';
    require_once $CFG->dirroot . '/backup/util/includes/restore_includes.php';
    if (empty($USER)) {
        // Emulate session.
        cron_setup_user();
    }
    // Context validation.
    if (!($course = $DB->get_record('course', array('id' => $courseid)))) {
        throw new moodle_exception('invalidcourseid', 'error');
    }
    $removeoptions = array();
    $removeoptions['keep_roles_and_enrolments'] = true;
    $removeoptions['keep_groups_and_groupings'] = true;
    remove_course_contents($newcourse->id, false, $removeoptions);
    $backupdefaults = array('activities' => 1, 'blocks' => 1, 'filters' => 1, 'users' => 0, 'role_assignments' => 0, 'comments' => 0, 'userscompletion' => 0, 'logs' => 0, 'grade_histories' => 0);
    $backupsettings = array();
    // Check for backup and restore options.
    if (!empty($options)) {
        foreach ($options as $option) {
            // Strict check for a correct value (allways 1 or 0, true or false).
            $value = clean_param($option['value'], PARAM_INT);
            if ($value !== 0 and $value !== 1) {
                throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']);
            }
            if (!isset($backupdefaults[$option['name']])) {
                throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']);
            }
            $backupsettings[$option['name']] = $value;
        }
    }
    // Backup the course.
    $admin = get_admin();
    $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $admin->id);
    foreach ($backupsettings as $name => $value) {
        $bc->get_plan()->get_setting($name)->set_value($value);
    }
    $backupid = $bc->get_backupid();
    $backupbasepath = $bc->get_plan()->get_basepath();
    $bc->execute_plan();
    $results = $bc->get_results();
    $file = $results['backup_destination'];
    $bc->destroy();
    // Restore the backup immediately.
    // Check if we need to unzip the file because the backup temp dir does not contains backup files.
    if (!file_exists($backupbasepath . "/moodle_backup.xml")) {
        $file->extract_to_pathname(get_file_packer(), $backupbasepath);
    }
    $rc = new restore_controller($backupid, $newcourse->id, backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $admin->id, backup::TARGET_CURRENT_DELETING);
    foreach ($backupsettings as $name => $value) {
        $setting = $rc->get_plan()->get_setting($name);
        if ($setting->get_status() == backup_setting::NOT_LOCKED) {
            $setting->set_value($value);
        }
    }
    if (!$rc->execute_precheck()) {
        $precheckresults = $rc->get_precheck_results();
        if (is_array($precheckresults) && !empty($precheckresults['errors'])) {
            if (empty($CFG->keeptempdirectoriesonbackup)) {
                fulldelete($backupbasepath);
            }
            $errorinfo = '';
            foreach ($precheckresults['errors'] as $error) {
                $errorinfo .= $error;
            }
            if (array_key_exists('warnings', $precheckresults)) {
                foreach ($precheckresults['warnings'] as $warning) {
                    $errorinfo .= $warning;
                }
            }
            throw new moodle_exception('backupprecheckerrors', 'webservice', '', $errorinfo);
        }
    }
    $rc->execute_plan();
    $rc->destroy();
    $course = $DB->get_record('course', array('id' => $newcourse->id), '*', MUST_EXIST);
    $course->visible = $visible;
    $course->fullname = $newcourse->fullname;
    $course->shortname = $newcourse->shortname;
    $course->idnumber = $newcourse->idnumber;
    // Set shortname and fullname back.
    $DB->update_record('course', $course);
    if (empty($CFG->keeptempdirectoriesonbackup)) {
        fulldelete($backupbasepath);
    }
    // Delete the course backup file created by this WebService. Originally located in the course backups area.
    $file->delete();
    // We have to unenroll all the user except the one that create the course.
    if (get_config('local_ltiprovider', 'duplicatecourseswithoutusers') and $useridcreating) {
        require_once $CFG->dirroot . '/group/lib.php';
        // Previous to unenrol users, we assign some type of activities to the user that created the course.
        if ($user = $DB->get_record('user', array('id' => $useridcreating))) {
            if ($databases = $DB->get_records('data', array('course' => $course->id))) {
                foreach ($databases as $data) {
                    $DB->execute("UPDATE {data_records} SET userid = ? WHERE dataid = ?", array($user->id, $data->id));
                }
            }
            if ($glossaries = $DB->get_records('glossary', array('course' => $course->id))) {
                foreach ($glossaries as $glossary) {
                    $DB->execute("UPDATE {glossary_entries} SET userid = ? WHERE glossaryid = ?", array($user->id, $glossary->id));
                }
            }
            // Same for questions.
            $newcoursecontextid = context_course::instance($course->id);
            if ($qcategories = $DB->get_records('question_categories', array('contextid' => $newcoursecontextid->id))) {
                foreach ($qcategories as $qcategory) {
                    $DB->execute("UPDATE {question} SET createdby = ?, modifiedby = ? WHERE category = ?", array($user->id, $user->id, $qcategory->id));
                }
            }
            // Enrol the user.
            if ($tool = $DB->get_record('local_ltiprovider', array('contextid' => $newcoursecontextid->id))) {
                $roles = explode(',', strtolower($context->info['roles']));
                local_ltiprovider_enrol_user($tool, $user, $roles, true);
            }
            // Now, we unenrol all the users except the one who created the course.
            $plugins = enrol_get_plugins(true);
            $instances = enrol_get_instances($course->id, true);
            foreach ($instances as $key => $instance) {
                if (!isset($plugins[$instance->enrol])) {
                    unset($instances[$key]);
                    continue;
                }
            }
            $sql = "SELECT ue.*\n                          FROM {user_enrolments} ue\n                          JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                          JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)";
            $params = array('courseid' => $course->id, 'courselevel' => CONTEXT_COURSE);
            $rs = $DB->get_recordset_sql($sql, $params);
            foreach ($rs as $ue) {
                if ($ue->userid == $user->id) {
                    continue;
                }
                if (!isset($instances[$ue->enrolid])) {
                    continue;
                }
                $instance = $instances[$ue->enrolid];
                $plugin = $plugins[$instance->enrol];
                if (!$plugin->allow_unenrol($instance) and !$plugin->allow_unenrol_user($instance, $ue)) {
                    continue;
                }
                $plugin->unenrol_user($instance, $ue->userid);
            }
            $rs->close();
            groups_delete_group_members($course->id);
            groups_delete_groups($course->id, false);
            groups_delete_groupings_groups($course->id, false);
            groups_delete_groupings($course->id, false);
        }
    }
    return $course;
}
예제 #15
0
 /**
  * generate list of course tools
  *
  * @author Guy Thomas
  * @date 2014-04-23
  * @return string
  */
 public static function appendices()
 {
     global $CFG, $COURSE, $PAGE, $OUTPUT;
     $links = array();
     $localplugins = core_component::get_plugin_list('local');
     $coursecontext = context_course::instance($COURSE->id);
     // Turn editing on.
     $iconsrc = $OUTPUT->pix_url('icon', 'label');
     $editcourseicon = '<img class="svg-icon" alt="" title="" src="' . $iconsrc . '">';
     $url = new moodle_url('/course/view.php', ['id' => $COURSE->id, 'sesskey' => sesskey()]);
     if ($PAGE->user_is_editing()) {
         $url->param('edit', 'off');
         $editstring = get_string('turneditingoff');
     } else {
         $url->param('edit', 'on');
         $editstring = get_string('editcoursecontent', 'theme_snap');
     }
     $links[] = array('link' => $url, 'title' => $editcourseicon . $editstring, 'capability' => 'moodle/course:update');
     // Course settings.
     $settingsicon = '<svg viewBox="0 0 100 100" class="svg-icon">
     <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-settings"></use></svg>';
     $links[] = array('link' => 'course/edit.php?id=' . $COURSE->id, 'title' => $settingsicon . get_string('editcoursesettings', 'theme_snap'), 'capability' => 'moodle/course:update');
     // Participants.
     $participanticon = '<svg viewBox="0 0 100 100" class="svg-icon">
     <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-participants"></use></svg>';
     $links[] = array('link' => 'user/index.php?id=' . $COURSE->id . '&mode=1', 'title' => $participanticon . get_string('participants'), 'capability' => 'moodle/course:viewparticipants');
     // Gradebook.
     $gradebookicon = '<svg viewBox="0 0 100 100" class="svg-icon">
     <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-gradbook"></use></svg>';
     if (self::gradebook_accessible($coursecontext)) {
         // Gradebook.
         $links[] = array('link' => 'grade/index.php?id=' . $COURSE->id, 'title' => $gradebookicon . get_string('gradebook', 'grades'));
     }
     // Only show if joule grader is installed.
     if (array_key_exists('joulegrader', $localplugins)) {
         if (has_capability('local/joulegrader:grade', $coursecontext) || has_capability('local/joulegrader:view', $coursecontext)) {
             $links[] = array('link' => 'local/joulegrader/view.php?courseid=' . $COURSE->id, 'title' => $gradebookicon . get_string('pluginname', 'local_joulegrader'));
         }
     }
     // Only show Norton grader if installed.
     if (array_key_exists('nortongrader', $localplugins)) {
         if (has_capability('local/nortongrader:grade', $coursecontext) || has_capability('local/nortongrader:view', $coursecontext)) {
             $links[] = array('link' => $CFG->wwwroot . '/local/nortongrader/view.php?courseid=' . $COURSE->id, 'title' => $gradebookicon . get_string('pluginname', 'local_nortongrader'));
         }
     }
     // Only show core outcomes if enabled.
     $outcomesicon = '<svg viewBox="0 0 100 100" class="svg-icon">
     <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-outcomes"></use></svg>';
     if (!empty($CFG->core_outcome_enable) && has_capability('moodle/grade:edit', $coursecontext)) {
         $links[] = array('link' => 'outcome/course.php?contextid=' . $coursecontext->id, 'title' => $outcomesicon . get_string('outcomes', 'outcome'));
     } else {
         if (!empty($CFG->core_outcome_enable) && !is_guest($coursecontext)) {
             $outcomesets = new \core_outcome\model\outcome_set_repository();
             if ($outcomesets->course_has_any_outcome_sets($COURSE->id)) {
                 $links[] = array('link' => 'outcome/course.php?contextid=' . $coursecontext->id . '&action=report_course_user_performance_table', 'title' => $participanticon . get_string('report:course_user_performance_table', 'outcome'));
             }
         }
     }
     $badgesicon = '<svg viewBox="0 0 100 100" class="svg-icon">
         <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-badges"></use></svg>';
     // Course badges.
     if (!empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges)) {
         // Match capabilities used by badges subsystem.
         $studentcaps = array('moodle/badges:earnbadge', 'moodle/badges:viewbadges');
         $teachercaps = array('moodle/badges:viewawarded', 'moodle/badges:createbadge', 'moodle/badges:awardbadge', 'moodle/badges:configuremessages', 'moodle/badges:configuredetails', 'moodle/badges:deletebadge');
         // Show link for students.
         if (!is_guest($coursecontext) && has_any_capability($studentcaps, $coursecontext)) {
             $links[] = array('link' => 'badges/view.php?type=' . BADGE_TYPE_COURSE . '&id=' . $COURSE->id, 'title' => $badgesicon . get_string('badgesview', 'badges'), 'capability' => '!moodle/course:update');
         }
         // Show link for trachers / admin staff.
         if (!is_guest($coursecontext) && has_any_capability($teachercaps, $coursecontext)) {
             $links[] = array('link' => 'badges/index.php?type=' . BADGE_TYPE_COURSE . '&id=' . $COURSE->id, 'title' => $badgesicon . get_string('managebadges', 'badges'));
         }
     }
     // Only show Joule reports if installed.
     $reportsicon = '<svg viewBox="0 0 100 100" class="svg-icon">
         <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-reports"></use></svg>';
     if (array_key_exists('reports', core_component::get_plugin_list('block'))) {
         if (has_capability('block/reports:viewown', $coursecontext, null, false) || has_capability('block/reports:view', $coursecontext)) {
             $links[] = array('link' => $CFG->wwwroot . '/blocks/reports/view.php?action=dashboard&courseid=' . $COURSE->id, 'title' => $reportsicon . get_string('joulereports', 'block_reports'));
         }
     }
     // Personalised Learning Designer.
     $pldicon = '<svg viewBox="0 0 100 100" class="svg-icon">
     <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-pld"></use></svg>';
     $pldname = get_string('pld', 'theme_snap');
     $links[] = array('link' => 'local/pld/view.php?courseid=' . $COURSE->id, 'title' => $pldicon . $pldname, 'capability' => 'moodle/course:update');
     // Course enrolment link.
     $plugins = enrol_get_plugins(true);
     $instances = enrol_get_instances($COURSE->id, true);
     $selfenrol = false;
     foreach ($instances as $instance) {
         // Need to check enrolment methods for self enrol.
         if ($instance->enrol === 'self') {
             $plugin = $plugins[$instance->enrol];
             if (is_enrolled($coursecontext)) {
                 // Prepare unenrolment link.
                 $enrolurl = $plugin->get_unenrolself_link($instance);
                 if ($enrolurl) {
                     $selfenrol = true;
                     $enrolstr = get_string('unenrolme', 'theme_snap');
                     break;
                 }
             } else {
                 if ($plugin->show_enrolme_link($instance)) {
                     // Prepare enrolment link.
                     $selfenrol = true;
                     $enrolurl = new moodle_url('/enrol/index.php', array('id' => $COURSE->id));
                     $enrolstr = get_string('enrolme', 'core_enrol');
                     break;
                 }
             }
         }
     }
     if ($selfenrol) {
         $enrolicon = '<svg viewBox="0 0 100 100" class="svg-icon">
         <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-settings"></use></svg>';
         $links[] = array('link' => $enrolurl, 'title' => $enrolicon . $enrolstr);
     }
     $toolssvg = self::inline_svg('tools.svg');
     // Output course tools.
     $coursetools = get_string('coursetools', 'theme_snap');
     $o = "<h2>{$coursetools}</h2>";
     $o .= "<div class='row'><div class='col-xs-4'>{$toolssvg}</div><div class='col-xs-8'><div id='coursetools-list'>" . self::render_appendices($links) . "</div></div></div><hr>";
     return $o;
 }
예제 #16
0
 function action($action)
 {
     $enabled = enrol_get_plugins(true);
     $all = enrol_get_plugins(false);
     $syscontext = context_system::instance();
     switch ($action) {
         case 'enable':
             if (!isset($all[$this->plugin])) {
                 break;
             }
             $enabled = array_keys($enabled);
             $enabled[] = $this->plugin;
             set_config('enrol_plugins_enabled', implode(',', $enabled));
             // Resets all enrol caches.
             $syscontext->mark_dirty();
             break;
         case 'disable':
             unset($enabled[$this->plugin]);
             set_config('enrol_plugins_enabled', implode(',', array_keys($enabled)));
             $syscontext->mark_dirty();
             // resets all enrol caches
             break;
     }
     return 0;
 }
예제 #17
0
 /**
  * Function that will contain all the code to be executed.
  */
 protected function define_execution()
 {
     global $DB;
     $plugins = enrol_get_plugins(true);
     $enrols = $DB->get_records('enrol', array('courseid' => $this->task->get_courseid()));
     // Allow each enrol plugin to add annotations.
     foreach ($enrols as $enrol) {
         if (isset($plugins[$enrol->enrol])) {
             $plugins[$enrol->enrol]->backup_annotate_custom_fields($this, $enrol);
         }
     }
 }
예제 #18
0
 /**
  * Gets all of the enrolment plugins that are active for this course.
  *
  * @param bool $onlyenabled return only enabled enrol plugins
  * @return array
  */
 public function get_enrolment_plugins($onlyenabled = true)
 {
     if ($this->_plugins === null) {
         $this->_plugins = enrol_get_plugins(true);
     }
     if ($onlyenabled) {
         return $this->_plugins;
     }
     if ($this->_allplugins === null) {
         // Make sure we have the same objects in _allplugins and _plugins.
         $this->_allplugins = $this->_plugins;
         foreach (enrol_get_plugins(false) as $name => $plugin) {
             if (!isset($this->_allplugins[$name])) {
                 $this->_allplugins[$name] = $plugin;
             }
         }
     }
     return $this->_allplugins;
 }
예제 #19
0
 /**
  * Returns course details in an array ready to be printed.
  *
  * @global \moodle_database $DB
  * @param \course_in_list $course
  * @return array
  */
 public static function get_course_detail_array(\course_in_list $course)
 {
     global $DB;
     $canaccess = $course->can_access();
     $format = \course_get_format($course->id);
     $modinfo = \get_fast_modinfo($course->id);
     $modules = $modinfo->get_used_module_names();
     $sections = array();
     if ($format->uses_sections()) {
         foreach ($modinfo->get_section_info_all() as $section) {
             if ($section->uservisible) {
                 $sections[] = $format->get_section_name($section);
             }
         }
     }
     $category = \coursecat::get($course->category);
     $categoryurl = new \moodle_url('/course/management.php', array('categoryid' => $course->category));
     $categoryname = $category->get_formatted_name();
     $details = array('fullname' => array('key' => \get_string('fullname'), 'value' => $course->get_formatted_fullname()), 'shortname' => array('key' => \get_string('shortname'), 'value' => $course->get_formatted_shortname()), 'idnumber' => array('key' => \get_string('idnumber'), 'value' => s($course->idnumber)), 'category' => array('key' => \get_string('category'), 'value' => \html_writer::link($categoryurl, $categoryname)));
     if (has_capability('moodle/site:accessallgroups', $course->get_context())) {
         $groups = \groups_get_course_data($course->id);
         $details += array('groupings' => array('key' => \get_string('groupings', 'group'), 'value' => count($groups->groupings)), 'groups' => array('key' => \get_string('groups'), 'value' => count($groups->groups)));
     }
     if ($canaccess) {
         $names = \role_get_names($course->get_context());
         $sql = 'SELECT ra.roleid, COUNT(ra.id) AS rolecount
                   FROM {role_assignments} ra
                  WHERE ra.contextid = :contextid
               GROUP BY ra.roleid';
         $rolecounts = $DB->get_records_sql($sql, array('contextid' => $course->get_context()->id));
         $roledetails = array();
         foreach ($rolecounts as $result) {
             $a = new \stdClass();
             $a->role = $names[$result->roleid]->localname;
             $a->count = $result->rolecount;
             $roledetails[] = \get_string('assignedrolecount', 'moodle', $a);
         }
         $details['roleassignments'] = array('key' => \get_string('roleassignments'), 'value' => join('<br />', $roledetails));
     }
     if ($course->can_review_enrolments()) {
         $enrolmentlines = array();
         $instances = \enrol_get_instances($course->id, true);
         $plugins = \enrol_get_plugins(true);
         foreach ($instances as $instance) {
             if (!isset($plugins[$instance->enrol])) {
                 // Weird.
                 continue;
             }
             $plugin = $plugins[$instance->enrol];
             $enrolmentlines[] = $plugin->get_instance_name($instance);
         }
         $details['enrolmentmethods'] = array('key' => \get_string('enrolmentmethods'), 'value' => join('<br />', $enrolmentlines));
     }
     if ($canaccess) {
         $details['format'] = array('key' => \get_string('format'), 'value' => \course_get_format($course)->get_format_name());
         $details['sections'] = array('key' => \get_string('sections'), 'value' => join('<br />', $sections));
         $details['modulesused'] = array('key' => \get_string('modulesused'), 'value' => join('<br />', $modules));
     }
     return $details;
 }
예제 #20
0
 /**
  *
  * @global object $CFG
  * @uses $CFG
  * @uses $OUTPUT
  */
 public function enrol()
 {
     global $CFG;
     $class = new pmclass($this->classid);
     // enrol directly in the course
     $student = new student();
     // TBD: new student($this); didn't work!!!
     $student->userid = $this->userid;
     $student->classid = $this->classid;
     $student->enrolmenttime = max(time(), $class->startdate);
     // Disable validation rules for prerequisites and enrolment_limits
     $student->validation_overrides[] = 'prerequisites';
     $student->validation_overrides[] = 'enrolment_limit';
     $courseid = $class->get_moodle_course_id();
     if ($courseid) {
         $course = $this->_db->get_record('course', array('id' => $courseid));
         // check that the elis plugin allows for enrolments from the course
         // catalog -- if not, see if there are other plugins that allow
         // self-enrolment.
         $plugin = enrol_get_plugin('elis');
         $enrol = $plugin->get_or_create_instance($course);
         if (!$enrol->{enrol_elis_plugin::ENROL_FROM_COURSE_CATALOG_DB}) {
             // get course enrolment plugins, and see if any of them allow self-enrolment
             $enrols = enrol_get_plugins(true);
             $enrolinstances = enrol_get_instances($course->id, true);
             foreach ($enrolinstances as $instance) {
                 if (!isset($enrols[$instance->enrol])) {
                     continue;
                 }
                 $form = $enrols[$instance->enrol]->enrol_page_hook($instance);
                 if ($form) {
                     // at least one plugin allows self-enrolment -- send
                     // the user to the course enrolment page, and prevent
                     // automatic enrolment
                     $a = new stdClass();
                     $a->id = $course->id;
                     $a->idnumber = $class->idnumber;
                     $a->wwwroot = $CFG->wwwroot;
                     $subject = get_string('moodleenrol_subj', self::LANG_FILE, $a);
                     $message = get_string('moodleenrol', self::LANG_FILE, $a);
                     $student->no_moodle_enrol = true;
                     break;
                 }
             }
         }
     }
     $student->save();
     // Send notification, if enabled.
     $sendnotification = !empty(elis::$config->local_elisprogram->notify_enroledfromwaitlist_user) ? true : false;
     if ($sendnotification === true) {
         if (!isset($message)) {
             $a = new stdClass();
             $a->idnum = $class->idnumber;
             $subject = get_string('nowenroled', self::LANG_FILE, $a);
             $message = get_string('nowenroled', self::LANG_FILE, $a);
         }
         $cuser = new user($this->userid);
         $cuser->load();
         $from = get_admin();
         notification::notify($message, $cuser, $from);
     }
     $this->delete();
 }
예제 #21
0
function moodlebook_require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
{
    global $CFG, $SESSION, $USER, $FULLME, $DB;
    // setup global $COURSE, themes, language and locale
    if (!empty($courseorid)) {
        if (is_object($courseorid)) {
            $course = $courseorid;
        } else {
            if ($courseorid == SITEID) {
                $course = clone $SITE;
            } else {
                $course = $DB->get_record('course', array('id' => $courseorid), '*', MUST_EXIST);
            }
        }
        if ($cm) {
            if ($cm->course != $course->id) {
                throw new coding_exception('course and cm parameters in require_login() call do not match!!');
            }
            // make sure we have a $cm from get_fast_modinfo as this contains activity access details
            if (!$cm instanceof cm_info) {
                // note: nearly all pages call get_fast_modinfo anyway and it does not make any
                // db queries so this is not really a performance concern, however it is obviously
                // better if you use get_fast_modinfo to get the cm before calling this.
                $modinfo = get_fast_modinfo($course);
                $cm = $modinfo->get_cm($cm->id);
            }
        }
    } else {
        // do not touch global $COURSE via $PAGE->set_course(),
        // the reasons is we need to be able to call require_login() at any time!!
        $course = $SITE;
        if ($cm) {
            throw new coding_exception('cm parameter in require_login() requires valid course parameter!');
        }
    }
    // If the user is not even logged in yet then make sure they are
    if (!isloggedin()) {
        if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests)) {
            if (!($guest = get_complete_user_data('id', $CFG->siteguest))) {
                // misconfigured site guest, just redirect to login page
                redirect(get_login_url());
                exit;
                // never reached
            }
            $lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang;
            complete_user_login($guest);
            $USER->autologinguest = true;
            $SESSION->lang = $lang;
        } else {
            //NOTE: $USER->site check was obsoleted by session test cookie,
            //      $USER->confirmed test is in login/index.php
            if ($preventredirect) {
                throw new require_login_exception('You are not logged in');
            }
            if ($setwantsurltome) {
                // TODO: switch to PAGE->url
                $SESSION->wantsurl = $FULLME;
            }
            if (!empty($_SERVER['HTTP_REFERER'])) {
                $SESSION->fromurl = $_SERVER['HTTP_REFERER'];
            }
            redirect(get_login_url());
            exit;
            // never reached
        }
    }
    // loginas as redirection if needed
    if ($course->id != SITEID and session_is_loggedinas()) {
        if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) {
            if ($USER->loginascontext->instanceid != $course->id) {
                print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid);
            }
        }
    }
    // check whether the user should be changing password (but only if it is REALLY them)
    if (get_user_preferences('auth_forcepasswordchange') && !session_is_loggedinas()) {
        $userauth = get_auth_plugin($USER->auth);
        if ($userauth->can_change_password() and !$preventredirect) {
            $SESSION->wantsurl = $FULLME;
            if ($changeurl = $userauth->change_password_url()) {
                //use plugin custom url
                redirect($changeurl);
            } else {
                //use moodle internal method
                if (empty($CFG->loginhttps)) {
                    redirect($CFG->wwwroot . '/login/change_password.php');
                } else {
                    $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot);
                    redirect($wwwroot . '/login/change_password.php');
                }
            }
        } else {
            print_error('nopasswordchangeforced', 'auth');
        }
    }
    // Check that the user account is properly set up
    if (user_not_fully_set_up($USER)) {
        if ($preventredirect) {
            throw new require_login_exception('User not fully set-up');
        }
        $SESSION->wantsurl = $FULLME;
        redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&amp;course=' . SITEID);
    }
    // Make sure the USER has a sesskey set up. Used for CSRF protection.
    sesskey();
    // Do not bother admins with any formalities
    if (is_siteadmin()) {
        return;
    }
    // Fetch the system context, the course context, and prefetch its child contexts
    $sysctx = get_context_instance(CONTEXT_SYSTEM);
    $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
    if ($cm) {
        $cmcontext = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST);
    } else {
        $cmcontext = null;
    }
    // make sure the course itself is not hidden
    if ($course->id == SITEID) {
        // frontpage can not be hidden
    } else {
        if (is_role_switched($course->id)) {
            // when switching roles ignore the hidden flag - user had to be in course to do the switch
        } else {
            if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
                // originally there was also test of parent category visibility,
                // BUT is was very slow in complex queries involving "my courses"
                // now it is also possible to simply hide all courses user is not enrolled in :-)
                if ($preventredirect) {
                    throw new require_login_exception('Course is hidden');
                }
                notice(get_string('coursehidden'), $CFG->wwwroot . '/');
            }
        }
    }
    // is the user enrolled?
    if ($course->id == SITEID) {
        // everybody is enrolled on the frontpage
    } else {
        if (session_is_loggedinas()) {
            // Make sure the REAL person can access this course first
            $realuser = session_get_realuser();
            if (!is_enrolled($coursecontext, $realuser->id, '', true) and !is_viewing($coursecontext, $realuser->id) and !is_siteadmin($realuser->id)) {
                if ($preventredirect) {
                    throw new require_login_exception('Invalid course login-as access');
                }
                echo $OUTPUT->header();
                notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/');
            }
        }
        // very simple enrolment caching - changes in course setting are not reflected immediately
        if (!isset($USER->enrol)) {
            $USER->enrol = array();
            $USER->enrol['enrolled'] = array();
            $USER->enrol['tempguest'] = array();
        }
        $access = false;
        if (is_viewing($coursecontext, $USER)) {
            // ok, no need to mess with enrol
            $access = true;
        } else {
            if (isset($USER->enrol['enrolled'][$course->id])) {
                if ($USER->enrol['enrolled'][$course->id] == 0) {
                    $access = true;
                } else {
                    if ($USER->enrol['enrolled'][$course->id] > time()) {
                        $access = true;
                    } else {
                        //expired
                        unset($USER->enrol['enrolled'][$course->id]);
                    }
                }
            }
            if (isset($USER->enrol['tempguest'][$course->id])) {
                if ($USER->enrol['tempguest'][$course->id] == 0) {
                    $access = true;
                } else {
                    if ($USER->enrol['tempguest'][$course->id] > time()) {
                        $access = true;
                    } else {
                        //expired
                        unset($USER->enrol['tempguest'][$course->id]);
                        $USER->access = remove_temp_roles($coursecontext, $USER->access);
                    }
                }
            }
            if ($access) {
                // cache ok
            } else {
                if (is_enrolled($coursecontext, $USER, '', true)) {
                    // active participants may always access
                    // TODO: refactor this into some new function
                    $now = time();
                    $sql = "SELECT MAX(ue.timeend)\n                          FROM {user_enrolments} ue\n                          JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                          JOIN {user} u ON u.id = ue.userid\n                         WHERE ue.userid = :userid AND ue.status = :active AND e.status = :enabled AND u.deleted = 0\n                               AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)";
                    $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'userid' => $USER->id, 'courseid' => $coursecontext->instanceid, 'now1' => $now, 'now2' => $now);
                    $until = $DB->get_field_sql($sql, $params);
                    if (!$until or $until > time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD) {
                        $until = time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD;
                    }
                    $USER->enrol['enrolled'][$course->id] = $until;
                    $access = true;
                    // remove traces of previous temp guest access
                    if (function_exists('remove_temp_course_roles')) {
                        if ($coursecontext->instanceid !== SITEID) {
                            remove_temp_course_roles($coursecontext);
                        }
                    } else {
                        $USER->access = remove_temp_roles($coursecontext, $USER->access);
                    }
                } else {
                    $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC');
                    $enrols = enrol_get_plugins(true);
                    // first ask all enabled enrol instances in course if they want to auto enrol user
                    foreach ($instances as $instance) {
                        if (!isset($enrols[$instance->enrol])) {
                            continue;
                        }
                        // Get a duration for the guestaccess, a timestamp in the future or false.
                        $until = $enrols[$instance->enrol]->try_autoenrol($instance);
                        if ($until !== false) {
                            $USER->enrol['enrolled'][$course->id] = $until;
                            $USER->access = remove_temp_roles($coursecontext, $USER->access);
                            $access = true;
                            break;
                        }
                    }
                    // if not enrolled yet try to gain temporary guest access
                    if (!$access) {
                        foreach ($instances as $instance) {
                            if (!isset($enrols[$instance->enrol])) {
                                continue;
                            }
                            // Get a duration for the guestaccess, a timestamp in the future or false.
                            $until = $enrols[$instance->enrol]->try_guestaccess($instance);
                            if ($until !== false) {
                                $USER->enrol['tempguest'][$course->id] = $until;
                                $access = true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        if (!$access) {
            if ($preventredirect) {
                throw new require_login_exception('Not enrolled');
            }
            $SESSION->wantsurl = $FULLME;
            redirect($CFG->wwwroot . '/enrol/index.php?id=' . $course->id);
        }
    }
    // Check visibility of activity to current user; includes visible flag, groupmembersonly,
    // conditional availability, etc
    if ($cm && !$cm->uservisible) {
        if ($preventredirect) {
            throw new require_login_exception('Activity is hidden');
        }
        redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden'));
    }
}
예제 #22
0
 /**
  * Enable enrol_lti plugin.
  */
 protected function enable_enrol()
 {
     $enabled = enrol_get_plugins(true);
     $enabled['lti'] = true;
     $enabled = array_keys($enabled);
     set_config('enrol_plugins_enabled', implode(',', $enabled));
 }
예제 #23
0
/**
 * This function will empty a course of user data.
 * It will retain the activities and the structure of the course.
 *
 * @param object $data an object containing all the settings including courseid (without magic quotes)
 * @return array status array of array component, item, error
 */
function reset_course_userdata($data)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/completionlib.php';
    require_once $CFG->dirroot . '/group/lib.php';
    $data->courseid = $data->id;
    $context = context_course::instance($data->courseid);
    $eventparams = array('context' => $context, 'courseid' => $data->id, 'other' => array('reset_options' => (array) $data));
    $event = \core\event\course_reset_started::create($eventparams);
    $event->trigger();
    // Calculate the time shift of dates.
    if (!empty($data->reset_start_date)) {
        // Time part of course startdate should be zero.
        $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old);
    } else {
        $data->timeshift = 0;
    }
    // Result array: component, item, error.
    $status = array();
    // Start the resetting.
    $componentstr = get_string('general');
    // Move the course start time.
    if (!empty($data->reset_start_date) and $data->timeshift) {
        // Change course start data.
        $DB->set_field('course', 'startdate', $data->reset_start_date, array('id' => $data->courseid));
        // Update all course and group events - do not move activity events.
        $updatesql = "UPDATE {event}\n                         SET timestart = timestart + ?\n                       WHERE courseid=? AND instance=0";
        $DB->execute($updatesql, array($data->timeshift, $data->courseid));
        // Update any date activity restrictions.
        if ($CFG->enableavailability) {
            \availability_date\condition::update_all_dates($data->courseid, $data->timeshift);
        }
        $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false);
    }
    if (!empty($data->reset_end_date)) {
        // If the user set a end date value respect it.
        $DB->set_field('course', 'enddate', $data->reset_end_date, array('id' => $data->courseid));
    } else {
        if ($data->timeshift > 0 && $data->reset_end_date_old) {
            // If there is a time shift apply it to the end date as well.
            $enddate = $data->reset_end_date_old + $data->timeshift;
            $DB->set_field('course', 'enddate', $enddate, array('id' => $data->courseid));
        }
    }
    if (!empty($data->reset_events)) {
        $DB->delete_records('event', array('courseid' => $data->courseid));
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false);
    }
    if (!empty($data->reset_notes)) {
        require_once $CFG->dirroot . '/notes/lib.php';
        note_delete_all($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false);
    }
    if (!empty($data->delete_blog_associations)) {
        require_once $CFG->dirroot . '/blog/lib.php';
        blog_remove_associations_for_course($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteblogassociations', 'blog'), 'error' => false);
    }
    if (!empty($data->reset_completion)) {
        // Delete course and activity completion information.
        $course = $DB->get_record('course', array('id' => $data->courseid));
        $cc = new completion_info($course);
        $cc->delete_all_completion_data();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecompletiondata', 'completion'), 'error' => false);
    }
    if (!empty($data->reset_competency_ratings)) {
        \core_competency\api::hook_course_reset_competency_ratings($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecompetencyratings', 'core_competency'), 'error' => false);
    }
    $componentstr = get_string('roles');
    if (!empty($data->reset_roles_overrides)) {
        $children = $context->get_child_contexts();
        foreach ($children as $child) {
            $DB->delete_records('role_capabilities', array('contextid' => $child->id));
        }
        $DB->delete_records('role_capabilities', array('contextid' => $context->id));
        // Force refresh for logged in users.
        $context->mark_dirty();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false);
    }
    if (!empty($data->reset_roles_local)) {
        $children = $context->get_child_contexts();
        foreach ($children as $child) {
            role_unassign_all(array('contextid' => $child->id));
        }
        // Force refresh for logged in users.
        $context->mark_dirty();
        $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false);
    }
    // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc.
    $data->unenrolled = array();
    if (!empty($data->unenrol_users)) {
        $plugins = enrol_get_plugins(true);
        $instances = enrol_get_instances($data->courseid, true);
        foreach ($instances as $key => $instance) {
            if (!isset($plugins[$instance->enrol])) {
                unset($instances[$key]);
                continue;
            }
        }
        foreach ($data->unenrol_users as $withroleid) {
            if ($withroleid) {
                $sql = "SELECT ue.*\n                          FROM {user_enrolments} ue\n                          JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                          JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n                          JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.roleid = :roleid AND ra.userid = ue.userid)";
                $params = array('courseid' => $data->courseid, 'roleid' => $withroleid, 'courselevel' => CONTEXT_COURSE);
            } else {
                // Without any role assigned at course context.
                $sql = "SELECT ue.*\n                          FROM {user_enrolments} ue\n                          JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                          JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n                     LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.userid = ue.userid)\n                         WHERE ra.id IS null";
                $params = array('courseid' => $data->courseid, 'courselevel' => CONTEXT_COURSE);
            }
            $rs = $DB->get_recordset_sql($sql, $params);
            foreach ($rs as $ue) {
                if (!isset($instances[$ue->enrolid])) {
                    continue;
                }
                $instance = $instances[$ue->enrolid];
                $plugin = $plugins[$instance->enrol];
                if (!$plugin->allow_unenrol($instance) and !$plugin->allow_unenrol_user($instance, $ue)) {
                    continue;
                }
                $plugin->unenrol_user($instance, $ue->userid);
                $data->unenrolled[$ue->userid] = $ue->userid;
            }
            $rs->close();
        }
    }
    if (!empty($data->unenrolled)) {
        $status[] = array('component' => $componentstr, 'item' => get_string('unenrol', 'enrol') . ' (' . count($data->unenrolled) . ')', 'error' => false);
    }
    $componentstr = get_string('groups');
    // Remove all group members.
    if (!empty($data->reset_groups_members)) {
        groups_delete_group_members($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false);
    }
    // Remove all groups.
    if (!empty($data->reset_groups_remove)) {
        groups_delete_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false);
    }
    // Remove all grouping members.
    if (!empty($data->reset_groupings_members)) {
        groups_delete_groupings_groups($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false);
    }
    // Remove all groupings.
    if (!empty($data->reset_groupings_remove)) {
        groups_delete_groupings($data->courseid, false);
        $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false);
    }
    // Look in every instance of every module for data to delete.
    $unsupportedmods = array();
    if ($allmods = $DB->get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddeleteuserdata = $modname . '_reset_userdata';
            // Function to delete user data.
            if (file_exists($modfile)) {
                if (!$DB->count_records($modname, array('course' => $data->courseid))) {
                    continue;
                    // Skip mods with no instances.
                }
                include_once $modfile;
                if (function_exists($moddeleteuserdata)) {
                    $modstatus = $moddeleteuserdata($data);
                    if (is_array($modstatus)) {
                        $status = array_merge($status, $modstatus);
                    } else {
                        debugging('Module ' . $modname . ' returned incorrect staus - must be an array!');
                    }
                } else {
                    $unsupportedmods[] = $mod;
                }
            } else {
                debugging('Missing lib.php in ' . $modname . ' module!');
            }
        }
    }
    // Mention unsupported mods.
    if (!empty($unsupportedmods)) {
        foreach ($unsupportedmods as $mod) {
            $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented'));
        }
    }
    $componentstr = get_string('gradebook', 'grades');
    // Reset gradebook,.
    if (!empty($data->reset_gradebook_items)) {
        remove_course_grades($data->courseid, false);
        grade_grab_course_grades($data->courseid);
        grade_regrade_final_grades($data->courseid);
        $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false);
    } else {
        if (!empty($data->reset_gradebook_grades)) {
            grade_course_reset($data->courseid);
            $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false);
        }
    }
    // Reset comments.
    if (!empty($data->reset_comments)) {
        require_once $CFG->dirroot . '/comment/lib.php';
        comment::reset_course_page_comments($context);
    }
    $event = \core\event\course_reset_ended::create($eventparams);
    $event->trigger();
    return $status;
}
예제 #24
0
파일: instances.php 프로젝트: JP-Git/moodle
                    // plugin specific state - do not mess with it!
                    $edit[] = html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/show'), 'alt' => '', 'class' => 'smallicon'));
                }
            }
        }
    }
    // link to instance management
    if (enrol_is_enabled($instance->enrol)) {
        if ($icons = $plugin->get_action_icons($instance)) {
            $edit = array_merge($edit, $icons);
        }
    }
    // add a row to the table
    $table->data[] = array($displayname, $users, implode('&nbsp;', $updown), implode('&nbsp;', $edit));
}
echo html_writer::table($table);
// access security is in each plugin
$candidates = array();
foreach (enrol_get_plugins(true) as $name => $plugin) {
    if (!($link = $plugin->get_newinstance_link($course->id))) {
        continue;
    }
    $candidates[$link->out(false)] = get_string('pluginname', 'enrol_' . $name);
}
if ($candidates) {
    $select = new url_select($candidates);
    $select->set_label(get_string('addinstance', 'enrol'));
    echo $OUTPUT->render($select);
}
echo $OUTPUT->box_end();
echo $OUTPUT->footer();
예제 #25
0
 /**
  * Builds the XHTML to display the control
  *
  * @param string $data Unused
  * @param string $query
  * @return string
  */
 public function output_html($data, $query = '')
 {
     global $CFG, $OUTPUT, $DB, $PAGE;
     // Display strings.
     $strup = get_string('up');
     $strdown = get_string('down');
     $strsettings = get_string('settings');
     $strenable = get_string('enable');
     $strdisable = get_string('disable');
     $struninstall = get_string('uninstallplugin', 'core_admin');
     $strusage = get_string('enrolusage', 'enrol');
     $strversion = get_string('version');
     $strtest = get_string('testsettings', 'core_enrol');
     $pluginmanager = core_plugin_manager::instance();
     $enrols_available = enrol_get_plugins(false);
     $active_enrols = enrol_get_plugins(true);
     $allenrols = array();
     foreach ($active_enrols as $key => $enrol) {
         $allenrols[$key] = true;
     }
     foreach ($enrols_available as $key => $enrol) {
         $allenrols[$key] = true;
     }
     // Now find all borked plugins and at least allow then to uninstall.
     $condidates = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {enrol}");
     foreach ($condidates as $candidate) {
         if (empty($allenrols[$candidate])) {
             $allenrols[$candidate] = true;
         }
     }
     $return = $OUTPUT->heading(get_string('actenrolshhdr', 'enrol'), 3, 'main', true);
     $return .= $OUTPUT->box_start('generalbox enrolsui');
     $table = new html_table();
     $table->head = array(get_string('name'), $strusage, $strversion, $strenable, $strup . '/' . $strdown, $strsettings, $strtest, $struninstall);
     $table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign');
     $table->id = 'courseenrolmentplugins';
     $table->attributes['class'] = 'admintable generaltable';
     $table->data = array();
     // Iterate through enrol plugins and add to the display table.
     $updowncount = 1;
     $enrolcount = count($active_enrols);
     $url = new moodle_url('/admin/enrol.php', array('sesskey' => sesskey()));
     $printed = array();
     foreach ($allenrols as $enrol => $unused) {
         $plugininfo = $pluginmanager->get_plugin_info('enrol_' . $enrol);
         $version = get_config('enrol_' . $enrol, 'version');
         if ($version === false) {
             $version = '';
         }
         if (get_string_manager()->string_exists('pluginname', 'enrol_' . $enrol)) {
             $name = get_string('pluginname', 'enrol_' . $enrol);
         } else {
             $name = $enrol;
         }
         // Usage.
         $ci = $DB->count_records('enrol', array('enrol' => $enrol));
         $cp = $DB->count_records_select('user_enrolments', "enrolid IN (SELECT id FROM {enrol} WHERE enrol = ?)", array($enrol));
         $usage = "{$ci} / {$cp}";
         // Hide/show links.
         $class = '';
         if (isset($active_enrols[$enrol])) {
             $aurl = new moodle_url($url, array('action' => 'disable', 'enrol' => $enrol));
             $hideshow = "<a href=\"{$aurl}\">";
             $hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/hide') . "\" class=\"iconsmall\" alt=\"{$strdisable}\" /></a>";
             $enabled = true;
             $displayname = $name;
         } else {
             if (isset($enrols_available[$enrol])) {
                 $aurl = new moodle_url($url, array('action' => 'enable', 'enrol' => $enrol));
                 $hideshow = "<a href=\"{$aurl}\">";
                 $hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/show') . "\" class=\"iconsmall\" alt=\"{$strenable}\" /></a>";
                 $enabled = false;
                 $displayname = $name;
                 $class = 'dimmed_text';
             } else {
                 $hideshow = '';
                 $enabled = false;
                 $displayname = '<span class="notifyproblem">' . $name . '</span>';
             }
         }
         if ($PAGE->theme->resolve_image_location('icon', 'enrol_' . $name, false)) {
             $icon = $OUTPUT->pix_icon('icon', '', 'enrol_' . $name, array('class' => 'icon pluginicon'));
         } else {
             $icon = $OUTPUT->pix_icon('spacer', '', 'moodle', array('class' => 'icon pluginicon noicon'));
         }
         // Up/down link (only if enrol is enabled).
         $updown = '';
         if ($enabled) {
             if ($updowncount > 1) {
                 $aurl = new moodle_url($url, array('action' => 'up', 'enrol' => $enrol));
                 $updown .= "<a href=\"{$aurl}\">";
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"{$strup}\" class=\"iconsmall\" /></a>&nbsp;";
             } else {
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" />&nbsp;";
             }
             if ($updowncount < $enrolcount) {
                 $aurl = new moodle_url($url, array('action' => 'down', 'enrol' => $enrol));
                 $updown .= "<a href=\"{$aurl}\">";
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"{$strdown}\" class=\"iconsmall\" /></a>";
             } else {
                 $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" />";
             }
             ++$updowncount;
         }
         // Add settings link.
         if (!$version) {
             $settings = '';
         } else {
             if ($surl = $plugininfo->get_settings_url()) {
                 $settings = html_writer::link($surl, $strsettings);
             } else {
                 $settings = '';
             }
         }
         // Add uninstall info.
         $uninstall = '';
         if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('enrol_' . $enrol, 'manage')) {
             $uninstall = html_writer::link($uninstallurl, $struninstall);
         }
         $test = '';
         if (!empty($enrols_available[$enrol]) and method_exists($enrols_available[$enrol], 'test_settings')) {
             $testsettingsurl = new moodle_url('/enrol/test_settings.php', array('enrol' => $enrol, 'sesskey' => sesskey()));
             $test = html_writer::link($testsettingsurl, $strtest);
         }
         // Add a row to the table.
         $row = new html_table_row(array($icon . $displayname, $usage, $version, $hideshow, $updown, $settings, $test, $uninstall));
         if ($class) {
             $row->attributes['class'] = $class;
         }
         $table->data[] = $row;
         $printed[$enrol] = true;
     }
     $return .= html_writer::table($table);
     $return .= get_string('configenrolplugins', 'enrol') . '<br />' . get_string('tablenosave', 'admin');
     $return .= $OUTPUT->box_end();
     return highlight($query, $return);
 }
예제 #26
0
 * @copyright  2010 Petr Skoda {@link http://skodak.org}
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
define('NO_OUTPUT_BUFFERING', true);
require_once '../config.php';
require_once $CFG->libdir . '/adminlib.php';
$action = required_param('action', PARAM_ALPHANUMEXT);
$enrol = required_param('enrol', PARAM_PLUGIN);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/enrol.php');
$PAGE->set_context(context_system::instance());
require_login();
require_capability('moodle/site:config', context_system::instance());
require_sesskey();
$enabled = enrol_get_plugins(true);
$all = enrol_get_plugins(false);
$return = new moodle_url('/admin/settings.php', array('section' => 'manageenrols'));
$syscontext = context_system::instance();
switch ($action) {
    case 'disable':
        unset($enabled[$enrol]);
        set_config('enrol_plugins_enabled', implode(',', array_keys($enabled)));
        core_plugin_manager::reset_caches();
        $syscontext->mark_dirty();
        // resets all enrol caches
        break;
    case 'enable':
        if (!isset($all[$enrol])) {
            break;
        }
        $enabled = array_keys($enabled);
예제 #27
0
 /**
  * Create user enrolments.
  *
  * This has to be called after creation of enrolment instances
  * and before adding of role assignments.
  *
  * Roles are assigned in restore_ras_and_caps_structure_step::process_assignment() processing afterwards.
  *
  * @param mixed $data
  * @return void
  */
 public function process_enrolment($data)
 {
     global $DB;
     if (!isset($this->plugins)) {
         $this->plugins = enrol_get_plugins(true);
     }
     $data = (object) $data;
     // Process only if parent instance have been mapped.
     if ($enrolid = $this->get_new_parentid('enrol')) {
         $oldinstancestatus = ENROL_INSTANCE_ENABLED;
         $oldenrolid = $this->get_old_parentid('enrol');
         if (isset($this->originalstatus[$oldenrolid])) {
             $oldinstancestatus = $this->originalstatus[$oldenrolid];
         }
         if ($instance = $DB->get_record('enrol', array('id' => $enrolid))) {
             // And only if user is a mapped one.
             if ($userid = $this->get_mappingid('user', $data->userid)) {
                 if (isset($this->plugins[$instance->enrol])) {
                     $this->plugins[$instance->enrol]->restore_user_enrolment($this, $data, $instance, $userid, $oldinstancestatus);
                 }
             }
         }
     }
 }
예제 #28
0
/**
 * Is there a chance users might self enrol
 * @param int $courseid
 * @return bool
 */
function enrol_selfenrol_available($courseid)
{
    $result = false;
    $plugins = enrol_get_plugins(true);
    $enrolinstances = enrol_get_instances($courseid, true);
    foreach ($enrolinstances as $instance) {
        if (!isset($plugins[$instance->enrol])) {
            continue;
        }
        if ($instance->enrol === 'guest') {
            // blacklist known temporary guest plugins
            continue;
        }
        if ($plugins[$instance->enrol]->show_enrolme_link($instance)) {
            $result = true;
            break;
        }
    }
    return $result;
}
예제 #29
0
/**
 * Returns true if the user is able to access the course.
 *
 * This function is in no way, shape, or form a substitute for require_login.
 * It should only be used in circumstances where it is not possible to call require_login
 * such as the navigation.
 *
 * This function checks many of the methods of access to a course such as the view
 * capability, enrollments, and guest access. It also makes use of the cache
 * generated by require_login for guest access.
 *
 * The flags within the $USER object that are used here should NEVER be used outside
 * of this function can_access_course and require_login. Doing so WILL break future
 * versions.
 *
 * @param stdClass $course record
 * @param stdClass|int|null $user user record or id, current user if null
 * @param string $withcapability Check for this capability as well.
 * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions
 * @return boolean Returns true if the user is able to access the course
 */
function can_access_course(stdClass $course, $user = null, $withcapability = '', $onlyactive = false)
{
    global $DB, $USER;
    // this function originally accepted $coursecontext parameter
    if ($course instanceof context) {
        if ($course instanceof context_course) {
            debugging('deprecated context parameter, please use $course record');
            $coursecontext = $course;
            $course = $DB->get_record('course', array('id' => $coursecontext->instanceid));
        } else {
            debugging('Invalid context parameter, please use $course record');
            return false;
        }
    } else {
        $coursecontext = context_course::instance($course->id);
    }
    if (!isset($USER->id)) {
        // should never happen
        $USER->id = 0;
    }
    // make sure there is a user specified
    if ($user === null) {
        $userid = $USER->id;
    } else {
        $userid = is_object($user) ? $user->id : $user;
    }
    unset($user);
    if ($withcapability and !has_capability($withcapability, $coursecontext, $userid)) {
        return false;
    }
    if ($userid == $USER->id) {
        if (!empty($USER->access['rsw'][$coursecontext->path])) {
            // the fact that somebody switched role means they can access the course no matter to what role they switched
            return true;
        }
    }
    if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext, $userid)) {
        return false;
    }
    if (is_viewing($coursecontext, $userid)) {
        return true;
    }
    if ($userid != $USER->id) {
        // for performance reasons we do not verify temporary guest access for other users, sorry...
        return is_enrolled($coursecontext, $userid, '', $onlyactive);
    }
    // === from here we deal only with $USER ===
    $coursecontext->reload_if_dirty();
    if (isset($USER->enrol['enrolled'][$course->id])) {
        if ($USER->enrol['enrolled'][$course->id] > time()) {
            return true;
        }
    }
    if (isset($USER->enrol['tempguest'][$course->id])) {
        if ($USER->enrol['tempguest'][$course->id] > time()) {
            return true;
        }
    }
    if (is_enrolled($coursecontext, $USER, '', $onlyactive)) {
        return true;
    }
    // if not enrolled try to gain temporary guest access
    $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC');
    $enrols = enrol_get_plugins(true);
    foreach ($instances as $instance) {
        if (!isset($enrols[$instance->enrol])) {
            continue;
        }
        // Get a duration for the guest access, a timestamp in the future, 0 (always) or false.
        $until = $enrols[$instance->enrol]->try_guestaccess($instance);
        if ($until !== false and $until > time()) {
            $USER->enrol['tempguest'][$course->id] = $until;
            return true;
        }
    }
    if (isset($USER->enrol['tempguest'][$course->id])) {
        unset($USER->enrol['tempguest'][$course->id]);
        remove_temp_course_roles($coursecontext);
    }
    return false;
}
예제 #30
0
/**
 * Returns true if the user is able to access the course.
 *
 * This function is in no way, shape, or form a substitute for require_login.
 * It should only be used in circumstances where it is not possible to call require_login
 * such as the navigation.
 *
 * This function checks many of the methods of access to a course such as the view
 * capability, enrollments, and guest access. It also makes use of the cache
 * generated by require_login for guest access.
 *
 * The flags within the $USER object that are used here should NEVER be used outside
 * of this function can_access_course and require_login. Doing so WILL break future
 * versions.
 *
 * @param stdClass $course record
 * @param stdClass|int|null $user user record or id, current user if null
 * @param string $withcapability Check for this capability as well.
 * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions
 * @return boolean Returns true if the user is able to access the course
 */
function can_access_course(stdClass $course, $user = null, $withcapability = '', $onlyactive = false)
{
    global $DB, $USER;
    // this function originally accepted $coursecontext parameter
    if ($course instanceof context) {
        if ($course instanceof context_course) {
            debugging('deprecated context parameter, please use $course record');
            $coursecontext = $course;
            $course = $DB->get_record('course', array('id' => $coursecontext->instanceid));
        } else {
            debugging('Invalid context parameter, please use $course record');
            return false;
        }
    } else {
        $coursecontext = context_course::instance($course->id);
    }
    if (!isset($USER->id)) {
        // should never happen
        $USER->id = 0;
    }
    // make sure there is a user specified
    if ($user === null) {
        $userid = $USER->id;
    } else {
        $userid = is_object($user) ? $user->id : $user;
    }
    unset($user);
    if ($withcapability and !has_capability($withcapability, $coursecontext, $userid)) {
        return false;
    }
    if ($userid == $USER->id) {
        if (!empty($USER->access['rsw'][$coursecontext->path])) {
            // the fact that somebody switched role means they can access the course no matter to what role they switched
            return true;
        }
    }
    if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext, $userid)) {
        return false;
    }
    if (is_viewing($coursecontext, $userid)) {
        return true;
    }
    if ($userid != $USER->id) {
        // for performance reasons we do not verify temporary guest access for other users, sorry...
        return is_enrolled($coursecontext, $userid, '', $onlyactive);
    }
    // === from here we deal only with $USER ===
    // verify our caches
    if (!isset($USER->enrol)) {
        /**
         * These flags within the $USER object should NEVER be used outside of this
         * function can_access_course and the function require_login.
         * Doing so WILL break future versions!!!!
         */
        $USER->enrol = array();
        $USER->enrol['enrolled'] = array();
        $USER->enrol['tempguest'] = array();
    }
    if (isset($USER->enrol['enrolled'][$course->id])) {
        if ($USER->enrol['enrolled'][$course->id] == 0) {
            return true;
        } else {
            if ($USER->enrol['enrolled'][$course->id] > time()) {
                return true;
            }
        }
    }
    if (isset($USER->enrol['tempguest'][$course->id])) {
        if ($USER->enrol['tempguest'][$course->id] == 0) {
            return true;
        } else {
            if ($USER->enrol['tempguest'][$course->id] > time()) {
                return true;
            }
        }
    }
    if (is_enrolled($coursecontext, $USER, '', true)) {
        // active participants may always access
        // TODO: refactor this into some new function
        $now = time();
        $sql = "SELECT MAX(ue.timeend)\n                  FROM {user_enrolments} ue\n                  JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n                  JOIN {user} u ON u.id = ue.userid\n                 WHERE ue.userid = :userid AND ue.status = :active AND e.status = :enabled AND u.deleted = 0\n                       AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)";
        $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'userid' => $USER->id, 'courseid' => $coursecontext->instanceid, 'now1' => $now, 'now2' => $now);
        $until = $DB->get_field_sql($sql, $params);
        if (!$until or $until > time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD) {
            $until = time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD;
        }
        $USER->enrol['enrolled'][$course->id] = $until;
        // remove traces of previous temp guest access
        remove_temp_course_roles($coursecontext);
        return true;
    }
    unset($USER->enrol['enrolled'][$course->id]);
    // if not enrolled try to gain temporary guest access
    $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC');
    $enrols = enrol_get_plugins(true);
    foreach ($instances as $instance) {
        if (!isset($enrols[$instance->enrol])) {
            continue;
        }
        // Get a duration for the guestaccess, a timestamp in the future or false.
        $until = $enrols[$instance->enrol]->try_guestaccess($instance);
        if ($until !== false) {
            $USER->enrol['tempguest'][$course->id] = $until;
            return true;
        }
    }
    unset($USER->enrol['tempguest'][$course->id]);
    return false;
}