/**
 * taskchain_navigation_accesscontrol_form
 *
 * @param xxx $course
 * @param xxx $block_instance
 */
function taskchain_navigation_accesscontrol_form($course, $block_instance, $action)
{
    global $CFG, $DB, $OUTPUT, $PAGE;
    // site and system contexts
    if (class_exists('context')) {
        $sitecontext = context_course::instance(SITEID);
        $systemcontext = context_system::instance();
    } else {
        $sitecontext = get_context_instance(CONTEXT_COURSE, SITEID);
        $systemcontext = get_context_instance(CONTEXT_SYSTEM);
    }
    $hassiteconfig = has_capability('moodle/site:config', $systemcontext);
    // decode block config settings, in case they are needed later
    $block_instance->config = unserialize(base64_decode($block_instance->configdata));
    // we need the DB manager to check which
    // DB tables and fields are available
    $dbman = $DB->get_manager();
    $plugin = 'block_taskchain_navigation';
    $select_size = 5;
    $cm_namelength = 40;
    $cm_headlength = 10;
    $cm_taillength = 10;
    $section_namelength = 48;
    $section_headlength = 18;
    $section_taillength = 18;
    // get previous or default form values
    $sections_array = optional_param_array('sections', array(), PARAM_INT);
    $modules_array = optional_param_array('modules', array(), PARAM_ALPHA);
    $cmids_array = optional_param_array('cmids', array(), PARAM_INT);
    $include = optional_param('include', '', PARAM_TEXT);
    $exclude = optional_param('exclude', '', PARAM_TEXT);
    $visibility = optional_param('visibility', -1, PARAM_INT);
    // available from/until dates
    $time = time();
    $fromdisable = optional_param('fromdisable', 0, PARAM_INT);
    $untildisable = optional_param('untildisable', 0, PARAM_INT);
    $cutoffdisable = optional_param('cutoffdisable', 0, PARAM_INT);
    list($availablefrom, $fromdate) = get_timestamp_and_date('from', null, $time, $fromdisable);
    list($availableuntil, $untildate) = get_timestamp_and_date('until', null, $time, $untildisable);
    list($availablecutoff, $cutoffdate) = get_timestamp_and_date('cutoff', null, $time, $cutoffdisable);
    $sortgradeitems = optional_param('sortgradeitems', 0, PARAM_INT);
    $creategradecats = optional_param('creategradecats', 0, PARAM_INT);
    $removegradecats = optional_param('removegradecats', 0, PARAM_INT);
    $rating = optional_param('rating', 0, PARAM_INT);
    $maxgrade = optional_param('maxgrade', 100, PARAM_INT);
    $gradepass = optional_param('gradepass', 60, PARAM_INT);
    $gradecat = optional_param('gradecat', 0, PARAM_INT);
    $gradeitemhidden = optional_param('gradeitemhidden', 0, PARAM_INT);
    $extracredit = optional_param('extracredit', 0, PARAM_INT);
    $regrade = optional_param('regrade', 0, PARAM_INT);
    $groupmode = optional_param('groupmode', 0, PARAM_INT);
    $groupingid = optional_param('groupingid', 0, PARAM_INT);
    $groupmembersonly = optional_param('groupmembersonly', 0, PARAM_INT);
    $sortactivities = optional_param('sortactivities', 0, PARAM_INT);
    $visible = optional_param('visible', 1, PARAM_INT);
    $indent = optional_param('indent', 0, PARAM_INT);
    $section = optional_param('section', 0, PARAM_INT);
    $position = optional_param('position', 0, PARAM_INT);
    $uploadlimit = optional_param('uploadlimit', 0, PARAM_INT);
    $siteuploadlimit = get_config(null, 'maxbytes');
    $courseuploadlimit = $course->maxbytes;
    $uploadlimitmenu = get_max_upload_sizes($siteuploadlimit, $courseuploadlimit);
    $removeconditions = optional_param('removeconditions', 0, PARAM_INT);
    $removecompletion = optional_param('removecompletion', 0, PARAM_INT);
    $erasecompletion = optional_param('erasecompletion', 0, PARAM_INT);
    // course_modules_availability OR course_modules.availability
    $conditiondatedirection = optional_param_array('conditiondatedirection', array(0), PARAM_INT);
    $conditiongradeitemid = optional_param_array('conditiongradeitemid', array(0), PARAM_INT);
    $conditiongrademin = optional_param_array('conditiongrademin', array(60), PARAM_INT);
    $conditiongrademax = optional_param_array('conditiongrademax', array(100), PARAM_INT);
    $conditionfieldname = optional_param_array('conditionfieldname', array(''), PARAM_ALPHANUM);
    $conditionfieldoperator = optional_param_array('conditionfieldoperator', array(''), PARAM_ALPHANUM);
    $conditionfieldvalue = optional_param_array('conditionfieldvalue', array(''), PARAM_ALPHANUM);
    $conditiongroupid = optional_param_array('conditiongroupid', array(0), PARAM_INT);
    $conditiongroupingid = optional_param_array('conditiongroupingid', array(0), PARAM_INT);
    $conditioncmid = optional_param_array('conditioncmid', array(0), PARAM_INT);
    // may be negative NEXT/PREVIOUS_ANY_COURSE/SECTION
    $conditioncmungraded = optional_param_array('conditioncmungraded', array(0), PARAM_INT);
    // 0=skip, 1=include ungraded activities
    $conditioncmresources = optional_param_array('conditioncmresources', array(0), PARAM_INT);
    // 0=skip, 1=include resources
    $conditioncmlabels = optional_param_array('conditioncmlabels', array(0), PARAM_INT);
    // 0=skip, 1=include labels
    $conditioncmcompletion = optional_param_array('conditioncmcompletion', array(1), PARAM_INT);
    // 0=incomplete, 1=complete, 2=pass, 3=fail
    $conditionaction = optional_param_array('conditionaction', array(1), PARAM_INT);
    // 0=hide, 1=show(greyed out)
    // course_modules.xxx
    $completiontracking = optional_param('completiontracking', 0, PARAM_INT);
    $completionday = optional_param('completionday', 0, PARAM_INT);
    $completionmonth = optional_param('completionmonth', 0, PARAM_INT);
    $completionyear = optional_param('completionyear', 0, PARAM_INT);
    // there may also be a number of activity-specific completion fields
    // (e.g. the "completionpass" field used by the Quiz and TaskChain modules)
    // there may also be a number of fields to enable/disable filters
    // (e.g. "filterglossary", "filtermediaplugin")
    // Competency settings
    $competencyrule = optional_param('competencyrule', 0, PARAM_INT);
    $conditiondate = array();
    $conditiondatetime = array();
    foreach ($conditiondatedirection as $i => $d) {
        switch ($d) {
            case 1:
                $d = '>=';
                break;
            case 2:
                $d = '<=';
                break;
            default:
                continue;
        }
        list($t, $date) = get_timestamp_and_date('conditiondatetime', $i, $time);
        $conditiondate[$i] = (object) array('type' => 'date', 'd' => $d, 't' => $t);
        $conditiondatetime[$i] = $date;
    }
    $conditiongrade = array();
    foreach ($conditiongradeitemid as $i => $id) {
        if ($id == 0) {
            continue;
        }
        $conditiongrade[] = (object) array('type' => 'grade', 'id' => $id, 'min' => empty($conditiongrademin[$i]) ? 0 : $conditiongrademin[$i], 'max' => empty($conditiongrademax[$i]) ? 100 : $conditiongrademax[$i]);
    }
    $conditionfield = array();
    foreach ($conditionfieldname as $i => $name) {
        if ($name == '') {
            continue;
        }
        $conditionfield[] = (object) array('type' => 'profile', 'sf' => $name, 'op' => empty($conditionfieldoperator[$i]) ? '' : $conditionfieldoperator[$i], 'v' => empty($conditionfieldvalue[$i]) ? '' : $conditionfieldvalue[$i]);
    }
    $conditiongroup = array();
    foreach ($conditiongroupid as $i => $id) {
        if ($id == 0) {
            continue;
        }
        $conditiongroup[] = (object) array('type' => 'group', 'id' => $id);
    }
    $conditiongrouping = array();
    foreach ($conditiongroupingid as $i => $id) {
        if ($id == 0) {
            continue;
        }
        $conditiongrouping[] = (object) array('type' => 'grouping', 'id' => $id);
    }
    $conditioncm = array();
    foreach ($conditioncmid as $i => $id) {
        if ($id == 0) {
            continue;
        }
        $conditioncm[] = (object) array('type' => 'completion', 'cm' => $id, 'e' => isset($conditioncmcompletion[$i]) ? $conditioncmcompletion[$i] : 1, 'ungraded' => empty($conditioncmungraded[$i]) ? 0 : 1, 'resources' => empty($conditioncmresources[$i]) ? 0 : 1, 'labels' => empty($conditioncmlabels[$i]) ? 0 : 1);
    }
    if ($completionday && $completionmonth && $completionyear) {
        $completiondate = make_timestamp($completionyear, $completionmonth, $completionday, 0, 0, 0, 99, false);
    } else {
        $completiondate = 0;
    }
    // add standard settings
    $settings = array('availablefrom', 'availableuntil', 'availablecutoff', 'rating', 'maxgrade', 'gradepass', 'gradecat', 'gradeitemhidden', 'extracredit', 'regrade', 'groupmode', 'groupingid', 'groupmembersonly', 'visible', 'indent', 'section', 'uploadlimit');
    // add switches to enable/disable filters
    $filters = filter_get_available_in_context($course->context);
    foreach (array_keys($filters) as $filter) {
        $setting = 'filter' . $filter;
        echo $setting;
        $settings[] = $setting;
        ${$setting} = optional_param($setting, null, PARAM_INT);
    }
    // add "availability" settings, if enabled
    if (empty($CFG->enableavailability)) {
        $enableavailability = false;
    } else {
        $enableavailability = true;
    }
    if ($enableavailability) {
        array_push($settings, 'removeconditions', 'conditiondate', 'conditiongrade', 'conditionfield', 'conditiongroup', 'conditiongrouping', 'conditioncm', 'conditionaction');
    }
    // add "completion" settings, if enabled
    if (empty($CFG->enablecompletion) || empty($course->enablecompletion)) {
        $enablecompletion = false;
    } else {
        $enablecompletion = true;
    }
    if ($enablecompletion) {
        array_push($settings, 'removecompletion', 'erasecompletion', 'completiontracking', 'completiondate');
    }
    // are we using competencies
    // (available in Moodle >= 3.1)
    if (get_config('core_competency', 'enabled')) {
        $enablecompetency = true;
    } else {
        $enablecompetency = false;
    }
    if ($enablecompetency) {
        array_push($settings, 'competencyrule');
    }
    // custom html tags that delimit section title in the section summary
    $sectiontags = $block_instance->config->sectiontitletags;
    $sectiontags = optional_param('sectiontags', $sectiontags, PARAM_TEXT);
    // set course section type
    if ($course->format == 'weeks') {
        $sectiontype = 'week';
    } else {
        if ($course->format == 'topics') {
            $sectiontype = 'topic';
        } else {
            $sectiontype = 'section';
        }
    }
    if (count($sections_array) || count($modules_array) || $include || $exclude || $visibility >= 0 || count($cmids_array)) {
        $select_defaultvalue = true;
    } else {
        $select_defaultvalue = false;
    }
    // set date format for course sections
    $weekdateformat = '%b %d';
    // get_string('strftimedateshort');
    if ($sortactivities) {
        $select = 'cm.id, gi.sortorder';
        $from = '{grade_items} gi ' . 'JOIN {modules} m ON gi.itemmodule = m.name ' . 'JOIN {course_modules} cm ON cm.module = m.id AND cm.instance = gi.iteminstance';
        $where = 'gi.courseid = ? AND gi.itemtype = ?';
        $order = 'gi.sortorder';
        $params = array($course->id, 'mod');
        $items = $DB->get_records_sql("SELECT {$select} FROM {$from} WHERE {$where} ORDER BY {$order}", $params);
        $select = 'id,sequence,section,summary';
        $from = '{course_sections}';
        $where = 'course = ? AND sequence IS NOT NULL AND sequence <> ?';
        $order = 'section';
        $params = array($course->id, '');
        $sections = $DB->get_records_sql("SELECT {$select} FROM {$from} WHERE {$where} ORDER BY {$order}", $params);
        if ($items && $sections) {
            $modinfo = get_fast_modinfo($course);
            $rebuild_course_cache = false;
            foreach (array_keys($sections) as $id) {
                $sequence = explode(',', $sections[$id]->sequence);
                $sequence = array_flip($sequence);
                foreach (array_keys($sequence) as $cmid) {
                    if (array_key_exists($cmid, $items)) {
                        // assign new sortorder to activity
                        $sequence[$cmid] = $items[$cmid]->sortorder;
                    } else {
                        if (isset($modinfo->cms[$cmid])) {
                            // no grade book item (e.g. label)
                            $name = urldecode($modinfo->cms[$cmid]->name);
                            $name = block_taskchain_navigation::filter_text($name);
                            $name = trim(strip_tags($name));
                            $sequence[$cmid] = $name;
                            unset($modinfo->cms[$cmid]);
                        } else {
                            unset($sequence[$cmid]);
                            // shouldn't happen !!
                        }
                    }
                }
                uasort($sequence, 'activity_sequence_uasort');
                $sequence = array_keys($sequence);
                $sequence = implode(',', $sequence);
                if ($sequence != $sections[$id]->sequence) {
                    $DB->set_field('course_sections', 'sequence', $sequence, array('id' => $id));
                    $rebuild_course_cache = true;
                }
            }
            if ($rebuild_course_cache) {
                rebuild_course_cache($course->id);
                if (class_exists('course_modinfo')) {
                    // Moodle >= 2.4
                    get_fast_modinfo($course, 0, true);
                } else {
                    // Moodle <= 2.3
                    get_fast_modinfo('reset');
                }
                $course = $DB->get_record('course', array('id' => $course->id));
            }
        }
        unset($items, $sections, $modinfo, $sequence, $name, $cmid, $id);
    }
    $cms = array();
    $modules = array();
    $sections = array();
    $filemods = array();
    $labelmods = array();
    $ratingmods = array();
    $resourcemods = array();
    $gradingmods = array();
    $cutoffdatemods = array();
    $completionfields = array();
    $durationfields = array('completiontimespent');
    $count_cmids = 0;
    $selected_cmids = array();
    $strman = get_string_manager();
    // cache of section visibility by sectionnum
    // Note: could be ommited if we are not bothered about visibility
    // if ($visibility>=0 || array_key_exists('visible', $selected_settings)) {
    // }
    $section_visible = $DB->get_records_menu('course_sections', array('course' => $course->id), 'section', 'section, visible');
    $section_visible = array_map('intval', $section_visible);
    $section_visible[0] = 1;
    // intro is always visible
    $modinfo = get_fast_modinfo($course);
    foreach ($modinfo->sections as $sectionnum => $cmids) {
        // loop through the course modules
        foreach ($cmids as $cmid) {
            if (empty($modinfo->cms[$cmid])) {
                continue;
                // shouldn't happen
            }
            // shortcut to current course modules
            $cm = $modinfo->cms[$cmid];
            $count_cmids++;
            $sections[$sectionnum] = true;
            if (empty($modules[$cm->modname])) {
                $modules[$cm->modname] = get_string('modulename', $cm->modname);
                if ($modhaslibfile = file_exists("{$CFG->dirroot}/mod/{$cm->modname}/lib.php")) {
                    $modcompletion = plugin_supports('mod', $cm->modname, FEATURE_COMPLETION_HAS_RULES, false);
                } else {
                    $modcompletion = false;
                }
                // get completion fields
                if ($enablecompletion) {
                    if ($modcompletion) {
                        $fields = $DB->get_columns($cm->modname);
                        $names = array_keys($fields);
                        $names = preg_grep('/^completion.+$/', $names);
                        $names = array_values($names);
                        // re-index the array
                    } else {
                        $names = array();
                        // no module-specific fields
                        $fields = array();
                    }
                    if ($modhaslibfile) {
                        // fields that are common to all modules - see "lib/moodleform_mod.php"
                        if (plugin_supports('mod', $cm->modname, FEATURE_GRADE_HAS_GRADE, false)) {
                            array_unshift($names, 'completiongrade');
                        }
                        if (plugin_supports('mod', $cm->modname, FEATURE_COMPLETION_TRACKS_VIEWS, false)) {
                            array_unshift($names, 'completionview');
                        }
                    }
                    foreach ($names as $name) {
                        if (empty($completionfields[$name])) {
                            $settings[] = $name;
                            if (isset($_POST[$name]) && is_array($_POST[$name])) {
                                ${$name} = optional_param_array($name, array(), PARAM_INT);
                                ${$name} = array_sum(${$name});
                                // i.e. same as logical AND
                            } else {
                                ${$name} = optional_param($name, 0, PARAM_INT);
                            }
                            if (in_array($name, $durationfields)) {
                                ${$name} *= optional_param($name . '_unit', 1, PARAM_INT);
                            }
                            $completionfields[$name] = get_completionfield($strman, $plugin, $cm->modname, $name, ${$name}, $fields);
                        }
                        $completionfields[$name]->mods[$cm->modname] = $modules[$cm->modname];
                    }
                    unset($fields, $names, $name);
                }
                // get file sitewide upload limits, if any, for this module
                switch ($cm->modname) {
                    case 'assign':
                        $filemods[$cm->modname] = get_config('assignsubmission_file', 'maxbytes');
                        break;
                    case 'assignment':
                        $filemods[$cm->modname] = get_config(null, 'assignment_maxbytes');
                        break;
                    case 'forum':
                        $filemods[$cm->modname] = get_config(null, 'forum_maxbytes');
                        break;
                    case 'workshop':
                        $filemods[$cm->modname] = get_config('workshop', 'maxbytes');
                        break;
                }
                if ($modhaslibfile) {
                    $is_label = plugin_supports('mod', $cm->modname, FEATURE_NO_VIEW_LINK, false) == true;
                    $is_resource = plugin_supports('mod', $cm->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER) == MOD_ARCHETYPE_RESOURCE;
                    $has_rating = plugin_supports('mod', $cm->modname, FEATURE_RATE, false) == true;
                } else {
                    $is_label = in_array($cm->modname, array('label'));
                    $is_resource = in_array($cm->modname, array('book', 'folder', 'imscp', 'page', 'resource', 'url'));
                    $has_rating = in_array($cm->modname, array('data', 'forum', 'glossary'));
                }
                if ($has_grading = defined('FEATURE_ADVANCED_GRADING')) {
                    // Moodle >= 2.2
                    if ($modhaslibfile) {
                        $has_grading = plugin_supports('mod', $cm->modname, FEATURE_ADVANCED_GRADING, false) == true;
                    } else {
                        $has_grading = in_array($cm->modname, array('assign'));
                    }
                }
                if ($is_label) {
                    $labelmods[] = $cm->modname;
                } else {
                    if ($is_resource) {
                        $resourcemods[] = $cm->modname;
                    }
                }
                if ($has_rating) {
                    $ratingmods[$cm->modname] = $modules[$cm->modname];
                }
                // ==================================
                // disabled until fully functional
                // ==================================
                // if ($has_grading) {
                //     $gradingareas[$cm->modname] = grading_manager::available_areas('mod_'.$cm->modname);
                //     if (empty($gradingareas[$cm->modname])) {
                //         unset($gradingareas[$cm->modname]);
                //     } else {
                //         $gradingmods[$cm->modname] = $modules[$cm->modname];
                //     }
                // }
                if (in_array($cm->modname, array('assign'))) {
                    $cutoffdatemods[$cm->modname] = $modules[$cm->modname];
                }
                unset($is_label, $is_resource, $has_rating, $has_grading, $modhaslibfile, $modcompletion);
            }
            if (empty($cms[$sectionnum])) {
                $cms[$sectionnum] = array();
            }
            if (in_array($cmid, $cmids_array)) {
                $selected = ' selected="selected"';
            } else {
                $selected = '';
            }
            $url = $PAGE->theme->pix_url('icon', $cm->modname)->out();
            $style = ' style="background-image: url(' . $url . '); background-repeat: no-repeat; background-position: 1px 2px; min-height: 20px; padding-left: 12px;"';
            $name = urldecode($cm->name);
            $name = block_taskchain_navigation::filter_text($name);
            $name = trim(strip_tags($name));
            $name = block_taskchain_navigation::trim_text($name, $cm_namelength, $cm_headlength, $cm_taillength);
            $cms[$sectionnum][] = '<option value="' . $cm->id . '"' . $selected . $style . '>' . $name . '</option>';
            $select = $select_defaultvalue;
            if ($select && count($sections_array)) {
                $select = in_array($cm->sectionnum, $sections_array);
            }
            if ($select && count($modules_array)) {
                $select = in_array($cm->modname, $modules_array);
            }
            if ($select && $include) {
                $select = preg_match('/' . $include . '/', $cm->name);
            }
            if ($select && $exclude) {
                $select = !preg_match('/' . $exclude . '/', $cm->name);
            }
            if ($select && $visibility >= 0) {
                if ($section_visible[$cm->sectionnum]) {
                    $select = $visibility == $cm->visible;
                } else {
                    // in a hidden section, we need to check the activity module's "visibleold" setting
                    $select = $visibility == $DB->get_field('course_modules', 'visibleold', array('id' => $cm->id));
                }
            }
            if ($select && count($cmids_array)) {
                $select = in_array($cm->id, $cmids_array);
            }
            if ($select) {
                $selected_cmids[$cm->id] = $cm;
            }
        }
    }
    // $completionfields now contains additional "completion"
    // fields used by activity modules on this Moodle site
    // these fields have also been added to $settings
    $selected_settings = array();
    if ($action == 'apply') {
        foreach ($settings as $setting) {
            $select = 'select_' . $setting;
            if (optional_param($select, 0, PARAM_INT)) {
                $selected_settings[] = $setting;
            }
        }
    }
    $sectionmenu = array(-1 => get_string('currentsection', $plugin), '-' => '-----');
    // separator
    $sectionnums = array_keys($sections);
    if ($sections = $DB->get_records('course_sections', array('course' => $course->id), 'section', 'section,name,summary')) {
        foreach ($sections as $sectionnum => $sectioninfo) {
            // extract section title from section name or summary
            if ($text = block_taskchain_navigation::filter_text($sectioninfo->name)) {
                $text = block_taskchain_navigation::trim_text($text, $section_namelength, $section_headlength, $section_taillength);
            } else {
                if ($text = block_taskchain_navigation::filter_text($sectioninfo->summary)) {
                    // remove script and style blocks
                    $select = '/\\s*<(script|style)[^>]*>.*?<\\/\\1>\\s*/is';
                    $text = preg_replace($select, '', $text);
                    if ($tags = $sectiontags) {
                        $tags = preg_split('/[^a-zA-Z0-9]+/', $tags);
                        $tags = array_map('trim', $tags);
                        $tags = array_filter($tags);
                        $tags = implode('|', $tags);
                        if ($tags) {
                            $tags .= '|';
                        }
                    }
                    $tags .= 'h1|h2|h3|h4|h5|h6';
                    if (preg_match('/<(' . $tags . ')\\b[^>]*>(.*?)<\\/\\1>/is', $text, $matches)) {
                        $text = $matches[2];
                    } else {
                        // otherwise, get first line of text
                        $text = preg_split('/<br[^>]*>/', $text);
                        $text = array_map('strip_tags', $text);
                        $text = array_map('trim', $text);
                        $text = array_filter($text);
                        if (empty($text)) {
                            $text = '';
                        } else {
                            $text = reset($text);
                        }
                    }
                    $text = trim(strip_tags($text));
                    $text = block_taskchain_navigation::trim_text($text, $section_namelength, $section_taillength, $section_taillength);
                }
            }
            // set default section title, if necessary
            if ($text == '') {
                $format = 'format_' . $course->format;
                switch (true) {
                    case $sectiontype == 'week' && $sectionnum > 0:
                        $date = $course->startdate + 7200 + ($sectionnum - 1) * 604800;
                        $text = userdate($date, $weekdateformat) . ' - ' . userdate($date + 518400, $weekdateformat);
                        break;
                    case $strman->string_exists('section' . $sectionnum . 'name', $format):
                        $text = get_string('section' . $sectionnum . 'name', $format);
                        break;
                    case $strman->string_exists('sectionname', $format):
                        $text = get_string('sectionname', $format) . ' ' . $sectionnum;
                        break;
                    case $strman->string_exists($sectiontype, 'moodle'):
                        $text = get_string('sectionname') . ' ' . $sectionnum;
                        break;
                    default:
                        $text = $sectiontype . ' ' . $sectionnum;
                }
            }
            // assign section title
            if (in_array($sectionnum, $sectionnums)) {
                $sections[$sectionnum] = $text;
            } else {
                unset($sections[$sectionnum]);
            }
            $sectionmenu[$sectionnum] = $text;
        }
    }
    foreach ($cms as $sectionnum => $options) {
        unset($cms[$sectionnum]);
        $text = $sections[$sectionnum];
        $cms[$text] = '<optgroup label="' . $text . '">' . "\n" . implode("\n", $options) . '</optgroup>';
    }
    $cms = implode("\n", $cms);
    $cms = '<select id="id_cmids" name="cmids[]" size="' . min($select_size, $count_cmids) . '" multiple="multiple">' . "\n" . $cms . "\n" . '</select>' . "\n";
    foreach ($sections as $sectionnum => $text) {
        if (in_array($sectionnum, $sections_array)) {
            $selected = ' selected="selected"';
        } else {
            $selected = '';
        }
        $sections[$sectionnum] = '<option value="' . $sectionnum . '"' . $selected . '>' . $text . '</option>';
    }
    $count_sections = count($sections);
    $sections = implode("\n", $sections);
    $sections = '<select id="id_sections" name="sections[]" size="' . min($select_size, $count_sections) . '" multiple="multiple">' . "\n" . $sections . "\n" . '</select>' . "\n";
    asort($modules);
    foreach ($modules as $module => $text) {
        if (in_array($module, $modules_array)) {
            $selected = ' selected="selected"';
        } else {
            $selected = '';
        }
        if (empty($CFG->modpixpath)) {
            $style = '';
            // shouldn't happen
        } else {
            $url = $CFG->modpixpath . '/' . $module . '/icon.gif';
            $style = ' style="background-image: url(' . $url . '); background-repeat: no-repeat; background-position: 1px 2px; min-height: 20px; padding-left: 20px;"';
        }
        $modules[$module] = '<option value="' . $module . '"' . $selected . $style . '>' . $text . '</option>';
    }
    $count_modules = count($modules);
    $modules = implode("\n", $modules);
    $modules = '<select id="id_modules" name="modules[]" size="' . min($select_size, $count_modules) . '" multiple="multiple">' . "\n" . $modules . "\n" . '</select>' . "\n";
    $days = array();
    for ($i = 1; $i <= 31; $i++) {
        $days[$i] = $i;
    }
    $months = array();
    for ($i = 1; $i <= 12; $i++) {
        $months[$i] = userdate(gmmktime(12, 0, 0, $i, 15, 2000), '%B');
    }
    $years = array();
    for ($i = 1970; $i <= 2020; $i++) {
        $years[$i] = $i;
    }
    $hours = array();
    for ($i = 0; $i <= 23; $i++) {
        $hours[$i] = sprintf('%02d', $i);
    }
    $minutes = array();
    for ($i = 0; $i < 60; $i += 5) {
        $minutes[$i] = sprintf('%02d', $i);
    }
    $visibilitymenu = array(-1 => '', 0 => get_string('hidden', 'grades'), 1 => get_string('visible'));
    $visiblemenu = array(0 => get_string('hide'), 1 => get_string('show'));
    $ratings = new rating_manager();
    $ratings = $ratings->get_aggregate_types();
    $gradings = array();
    $maxgrades = array();
    $gradepassmenu = array();
    for ($i = 100; $i >= 1; $i--) {
        $maxgrades[$i] = $i . '%';
        $gradepassmenu[$i] = $i . '%';
    }
    $maxgrades[0] = get_string('nograde');
    $gradecategories = grade_get_categories_menu($course->id);
    $groupmodes = array(NOGROUPS => get_string('groupsnone'), SEPARATEGROUPS => get_string('groupsseparate'), VISIBLEGROUPS => get_string('groupsvisible'));
    //groupings selector - used for normal grouping mode or also when restricting access with groupmembersonly
    $groupings = array();
    if ($records = $DB->get_records('groupings', array('courseid' => $course->id))) {
        $groupings = array(0 => get_string('none'));
        foreach ($records as $record) {
            $groupings[$record->id] = format_string($record->name);
        }
    }
    $indentmenu = array();
    for ($i = -5; $i <= 5; $i++) {
        if ($i == 0) {
            $indentmenu[$i] = get_string('reset');
        } else {
            $indentmenu[$i] = ($i < 0 ? '-' : '+') . abs($i);
        }
    }
    $positionmenu = array(1 => get_string('startofsection', $plugin), 2 => get_string('endofsection', $plugin));
    if ($strman->string_exists('direction_from', 'availability_date')) {
        // Moodle >= 2.7
        $conditiondatedirectionmenu = array(1 => get_string('direction_from', 'availability_date'), 2 => get_string('direction_until', 'availability_date'));
    } else {
        // Moodle >= 2.6
        $conditiondatedirectionmenu = array(1 => get_string('from'), 2 => get_string('durationuntil', 'calendar'));
    }
    $conditiongradeitemidmenu = array();
    $conditioncmidmenu = array();
    $conditionfieldnamemenu = array();
    $conditionfieldoperatormenu = array();
    $conditiongroupidmenu = array();
    $conditiongroupingidmenu = array();
    $conditionactionmenu = array();
    $conditioncmcompletionmenu = array();
    if ($enableavailability) {
        $basemenuitems = array('0' => get_string('none', 'moodle'), '00' => '=====', PREVIOUS_ANY_COURSE => get_string('previousanycourse', $plugin), PREVIOUS_ANY_SECTION => get_string('previousanysection', $plugin), PREVIOUS_SAME_COURSE => get_string('previoussamecourse', $plugin), PREVIOUS_SAME_SECTION => get_string('previoussamesection', $plugin), '000' => '=====', NEXT_ANY_COURSE => get_string('nextanycourse', $plugin), NEXT_ANY_SECTION => get_string('nextanysection', $plugin), NEXT_SAME_COURSE => get_string('nextsamecourse', $plugin), NEXT_SAME_SECTION => get_string('nextsamesection', $plugin), '0000' => '=====');
        $categories = grade_category::fetch_all(array('courseid' => $course->id));
        if ($items = grade_item::fetch_all(array('courseid' => $course->id))) {
            uasort($items, 'grade_items_uasort');
            $spaces = '';
            $space = '│ ';
            $ids = array_keys($items);
            foreach ($ids as $i => $id) {
                $item = $items[$id];
                if ($item->is_course_item()) {
                    $depth = 0;
                    $index = '';
                } else {
                    if ($item->is_category_item()) {
                        if ($depth = $DB->get_field('grade_categories', 'depth', array('id' => $item->iteminstance))) {
                            if ($depth > 1) {
                                $depth--;
                            }
                        }
                        $spaces = str_repeat($space, $depth - 1);
                    } else {
                        $spaces = str_repeat($space, $depth);
                    }
                }
                $name = $spaces . get_tree_char($depth, $i, $ids, $items, $categories) . $item->get_name(true);
                $name = block_taskchain_navigation::trim_text($name, $cm_namelength, $cm_headlength + strlen($spaces), $cm_taillength);
                $items[$id] = $name;
            }
            if (count($items)) {
                $conditiongradeitemidmenu = $basemenuitems + $items;
            }
        }
        if ($enablecompletion) {
            $items = array();
            $modinfo = get_fast_modinfo($course);
            foreach ($modinfo->cms as $id => $cm) {
                if ($cm->completion) {
                    $items[$id] = $cm->name;
                }
            }
            if (count($items)) {
                asort($items);
                $conditioncmidmenu = $basemenuitems + $items;
            }
        }
        $conditionfieldnamemenu = array('' => get_string('none', 'moodle'));
        $conditionfieldoperatormenu = array();
        $filepath = $CFG->dirroot . '/availability/condition/profile/classes/frontend.php';
        if (file_exists($filepath)) {
            // Moodle >= 2.7
            $contents = file_get_contents($filepath);
            $search = "/'([a-zA-Z0-9]+)' => get_user_field_name\\('\\1'\\)/";
            if (preg_match_all($search, $contents, $items)) {
                foreach ($items[1] as $item) {
                    $conditionfieldnamemenu[$item] = get_user_field_name($item);
                }
            }
            $search = "/(?<=')op_([a-zA-Z0-9]+)(?=')/";
            if (preg_match_all($search, $contents, $items)) {
                foreach ($items[1] as $i => $item) {
                    $conditionfieldoperatormenu[$item] = get_string($items[0][$i], 'availability_profile');
                }
            }
            require_once $CFG->dirroot . '/user/profile/lib.php';
            if ($items = profile_get_custom_fields(true)) {
                foreach ($items as $item) {
                    $conditionfieldnamemenu[$item->shortname] = $item->name;
                }
            }
        } else {
            if (method_exists('condition_info', 'get_condition_user_fields')) {
                // Moodle >= 2.4
                if ($items = condition_info::get_condition_user_fields(array('context' => $course->context))) {
                    $conditionfieldnamemenu += $items;
                }
                $conditionfieldoperatormenu = condition_info::get_condition_user_field_operators();
            } else {
                // Moodle <= 2.3 doesn't have conditional user fields
                $conditionfieldnamemenu = array();
            }
        }
        if ($dbman->field_exists('course_modules', 'availability')) {
            // Moodle >= 2.7
            if ($items = groups_get_all_groups($course->id)) {
                foreach ($items as $item) {
                    $name = $item->name;
                    $name = block_taskchain_navigation::filter_text($name);
                    $name = block_taskchain_navigation::trim_text($name);
                    $conditiongroupidmenu[$item->id] = $name;
                }
            }
            if ($items = groups_get_all_groupings($course->id)) {
                foreach ($items as $item) {
                    $name = $item->name;
                    $name = block_taskchain_navigation::filter_text($name);
                    $name = block_taskchain_navigation::trim_text($name);
                    $conditiongroupingidmenu[$item->id] = $name;
                }
            }
        }
        $str = new stdClass();
        if ($strman->string_exists('accessrestrictions', 'availability')) {
            // Moodle >= 2.7
            $str->accessrestrictions = get_string('accessrestrictions', 'availability');
            $str->datetitle = get_string('title', 'availability_date');
            $str->userfield = get_string('conditiontitle', 'availability_profile');
            $str->gradetitle = get_string('title', 'availability_grade');
            $str->grademin = get_string('option_min', 'availability_grade');
            $str->grademax = get_string('option_max', 'availability_grade');
            $str->activitycompletion = get_string('activitycompletion', 'completion');
            $conditioncmcompletionmenu = array(COMPLETION_COMPLETE => get_string('option_complete', 'availability_completion'), COMPLETION_INCOMPLETE => get_string('option_incomplete', 'availability_completion'), COMPLETION_COMPLETE_PASS => get_string('option_pass', 'availability_completion'), COMPLETION_COMPLETE_FAIL => get_string('option_fail', 'availability_completion'));
            $str->showavailability = get_string('display', 'form');
            // Note: CONDITION_STUDENTVIEW_xxx constants are not defined in Moodle >= 2.9
            $hide = defined('CONDITION_STUDENTVIEW_HIDE') ? CONDITION_STUDENTVIEW_HIDE : 0;
            $show = defined('CONDITION_STUDENTVIEW_SHOW') ? CONDITION_STUDENTVIEW_SHOW : 1;
            $conditionactionmenu = array($hide => get_string('hidden_all', 'availability'), $show => get_string('shown_all', 'availability'));
        } else {
            // Moodle <= 2.6
            $str->accessrestrictions = get_string('availabilityconditions', 'condition');
            $str->datetitle = get_string('date');
            if ($strman->string_exists('userfield', 'condition')) {
                // Moodle >= 2.4
                $str->userfield = get_string('userfield', 'condition');
            }
            $str->gradetitle = get_string('gradecondition', 'condition');
            $str->grademin = get_string('grade_atleast', 'condition');
            $str->grademax = get_string('grade_upto', 'condition');
            $str->activitycompletion = get_string('completioncondition', 'condition');
            $conditioncmcompletionmenu = array(COMPLETION_COMPLETE => get_string('completion_complete', 'condition'), COMPLETION_INCOMPLETE => get_string('completion_incomplete', 'condition'), COMPLETION_COMPLETE_PASS => get_string('completion_pass', 'condition'), COMPLETION_COMPLETE_FAIL => get_string('completion_fail', 'condition'));
            $str->showavailability = get_string('showavailability', 'condition');
            $conditionactionmenu = array(CONDITION_STUDENTVIEW_HIDE => get_string('showavailability_hide', 'condition'), CONDITION_STUDENTVIEW_SHOW => get_string('showavailability_show', 'condition'));
        }
        $icon = new pix_icon('i/hide', '');
        $icon = $OUTPUT->render($icon);
        $str->showavailability = $icon . ' ' . $str->showavailability;
        if ($enablecompletion) {
            $str->conditioncmungraded = get_string('conditioncmungraded', $plugin);
            $str->conditioncmresources = get_string('conditioncmresources', $plugin);
            $str->conditioncmlabels = get_string('conditioncmlabels', $plugin);
        }
    }
    if ($enablecompletion) {
        $completiontrackingmenu = array(0 => get_string('completion_none', 'completion'), 1 => get_string('completion_manual', 'completion'), 2 => get_string('completion_automatic', 'completion'));
    } else {
        $completiontrackingmenu = array();
    }
    if (class_exists('core_competency\\course_module_competency')) {
        // Moodle >= 3.1
        $competencyrulemenu = \core_competency\course_module_competency::get_ruleoutcome_list();
    } else {
        $competencyrulemenu = array();
    }
    $filtermenu = array(TEXTFILTER_INHERIT => '', TEXTFILTER_OFF => get_string('off', 'filters'), TEXTFILTER_ON => get_string('on', 'filters'));
    $filterdefaulton = get_string('defaultx', 'filters', $filtermenu[TEXTFILTER_ON]);
    $filterdefaultoff = get_string('defaultx', 'filters', $filtermenu[TEXTFILTER_OFF]);
    // initialize state flags
    $success = null;
    $started_list = false;
    $reset_filter_caches = false;
    $rebuild_course_cache = false;
    $regrade_course_grades = false;
    // create grade categories, if necessary
    if ($creategradecats) {
        $modinfo = get_fast_modinfo($course);
        // default aggregate is "simple weighted mean of grades"
        // TODO: set default aggregate from form
        $aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2;
        // get max sortorder from database
        if ($sortorder = $DB->get_field('grade_items', 'MAX(sortorder)', array('courseid' => $course->id))) {
            $sortorder++;
        } else {
            $sortorder = 1;
        }
        // create course grade category - not usually necessary
        $fullname = '?';
        // special name for course grade category
        $params = array('courseid' => $course->id, 'depth' => 1, 'fullname' => $fullname);
        if ($course_grade_category_id = $DB->get_field('grade_categories', 'id', $params)) {
            $DB->set_field('grade_categories', 'aggregation', $aggregation, $params);
        } else {
            $course_grade_category_id = create_grade_category($course, $fullname, null, $aggregation, 0.0, $sortorder++, GRADE_DISPLAY_TYPE_PERCENTAGE);
        }
        // create/update section grade categories
        foreach ($sectionmenu as $sectionnum => $sectiontext) {
            if (empty($modinfo->sections[$sectionnum])) {
                continue;
            }
            $grade_category_id = 0;
            foreach ($modinfo->sections[$sectionnum] as $cmid) {
                if (empty($modinfo->cms[$cmid])) {
                    continue;
                }
                $params = array('courseid' => $course->id, 'itemtype' => 'mod', 'itemmodule' => $modinfo->cms[$cmid]->modname, 'iteminstance' => $modinfo->cms[$cmid]->instance);
                if (!($grade_items = $DB->get_records('grade_items', $params))) {
                    continue;
                }
                // note that some activities can have more than on grade item per instance
                // e.g. mod_workshop creates both "submission" and "assessment" grade items
                foreach ($grade_items as $grade_item) {
                    if ($grade_category_id == 0) {
                        $fullname = $sectiontext;
                        $params = array('courseid' => $course->id, 'depth' => 2, 'fullname' => $fullname);
                        if ($grade_category_id = $DB->get_field('grade_categories', 'id', $params)) {
                            $DB->set_field('grade_categories', 'aggregation', $aggregation, array('id' => $grade_category_id));
                        } else {
                            $grade_category_id = create_grade_category($course, $fullname, $course_grade_category_id, $aggregation, 0.0, $sortorder++);
                        }
                    }
                    $DB->set_field('grade_items', 'categoryid', $grade_category_id, array('id' => $grade_item->id));
                    $DB->set_field('grade_items', 'sortorder', $sortorder++, array('id' => $grade_item->id));
                }
            }
        }
        $regrade_course_grades = true;
    }
    // remove grade categories, if necessary
    if ($removegradecats) {
        $select = 'DISTINCT categoryid';
        $from = '{grade_items}';
        $where = 'courseid = ? AND itemtype <> ? AND itemtype <> ?';
        $params = array($course->id, 'course', 'category');
        $select = "id IN (SELECT {$select} FROM {$from} WHERE {$where})";
        if ($ids = $DB->get_records_select('grade_categories', $select, $params, 'id', 'id,path')) {
            foreach (array_keys($ids) as $id) {
                $ids[$id] = trim($ids[$id]->path, '/');
            }
            $ids = array_filter($ids);
            $ids = implode('/', $ids);
            $ids = explode('/', $ids);
            $ids = array_unique($ids);
        } else {
            if ($ids = $DB->get_records('grade_categories', array('courseid' => $course->id, 'depth' => 1, 'fullname' => '?'))) {
                $ids = array(key($ids));
                // the course category
            }
        }
        if (empty($ids)) {
            $ids = '';
            $params = array();
        } else {
            list($ids, $params) = $DB->get_in_or_equal($ids, SQL_PARAMS_QM, '', false);
            // i.e. NOT IN
        }
        $select = 'courseid = ?' . ($ids == '' ? '' : " AND id {$ids}");
        array_unshift($params, $course->id);
        if ($DB->delete_records_select('grade_categories', $select, $params)) {
            $regrade_course_grades = true;
        }
        $select = 'itemtype = ? AND courseid = ?' . ($ids == '' ? '' : " AND iteminstance {$ids}");
        array_unshift($params, 'category');
        if ($DB->delete_records_select('grade_items', $select, $params)) {
            $regrade_course_grades = true;
        }
        unset($select, $from, $where, $params, $ids, $id);
    }
    // sort grade categories, if necessary
    if ($sortgradeitems) {
        $select = 'courseid = ? AND itemtype = ?';
        $params = array($course->id, 'mod');
        if ($items = $DB->get_records_select('grade_items', $select, $params, 'sortorder')) {
            $categories = array();
            foreach ($items as $item) {
                $categoryid = $item->categoryid;
                $cmid = 0;
                foreach ($modinfo->cms as $cmid => $cm) {
                    if ($item->itemmodule == $cm->modname && $item->iteminstance == $cm->instance) {
                        $cmid = $cm->id;
                        break;
                    }
                }
                if ($cmid) {
                    if (empty($categories[$categoryid])) {
                        $categories[$categoryid] = array();
                    }
                    $categories[$categoryid][$cmid] = $item->sortorder;
                }
            }
            $modinfo_cmids = array_keys($modinfo->cms);
            foreach (array_keys($categories) as $categoryid) {
                // get available cm ids and sortorder numbers
                $cmids = array_keys($categories[$categoryid]);
                $sortorder = array_values($categories[$categoryid]);
                // get course page sort order for each cm
                $cmids = array_flip($cmids);
                foreach (array_keys($cmids) as $cmid) {
                    $cmids[$cmid] = array_search($cmid, $modinfo_cmids);
                }
                // sort cmids according to course page order
                asort($cmids);
                // remove course page order info
                $cmids = array_keys($cmids);
                // assign an available sort order to each cm's grade item
                $select = 'courseid = ? AND itemtype = ? AND itemmodule = ? AND iteminstance = ?';
                foreach ($cmids as $i => $cmid) {
                    $params = array($course->id, 'mod', $modinfo->cms[$cmid]->modname, $modinfo->cms[$cmid]->instance);
                    $DB->set_field_select('grade_items', 'sortorder', $sortorder[$i], $select, $params);
                }
            }
        }
        unset($items, $categories, $cmids, $sortorder, $modinfo_cmids);
    }
    // update activities, if necessary
    if (count($selected_cmids) && (count($selected_settings) || $action == 'delete')) {
        $success = true;
        $fields = array('assign' => array('availablefrom' => 'allowsubmissionsfromdate', 'availableuntil' => 'duedate', 'maxgrade' => 'grade', 'rating' => ''), 'assignment' => array('availablefrom' => 'timeavailable', 'availableuntil' => 'timedue', 'maxgrade' => 'grade', 'rating' => ''), 'attendance' => array('availablefrom' => '', 'availableuntil' => '', 'maxgrade' => 'grade', 'rating' => ''), 'choice' => array('availablefrom' => 'timeopen', 'availableuntil' => 'timeclose', 'maxgrade' => '', 'rating' => ''), 'data' => array('availablefrom' => 'timeavailablefrom', 'availableuntil' => 'timeavailableto', 'maxgrade' => 'scale', 'rating' => 'assessed'), 'feedback' => array('availablefrom' => 'timeopen', 'availableuntil' => 'timeclose', 'maxgrade' => '', 'rating' => ''), 'forum' => array('availablefrom' => 'assesstimestart', 'availableuntil' => 'assesstimefinish', 'maxgrade' => 'scale', 'rating' => 'assessed'), 'glossary' => array('availablefrom' => 'assesstimestart', 'availableuntil' => 'assesstimefinish', 'maxgrade' => 'scale', 'rating' => 'assessed'), 'hotpot' => array('availablefrom' => 'timeopen', 'availableuntil' => 'timeclose', 'maxgrade' => 'grade', 'rating' => ''), 'lesson' => array('availablefrom' => 'available', 'availableuntil' => 'deadline', 'maxgrade' => 'grade', 'rating' => ''), 'questionnaire' => array('availablefrom' => 'opendate', 'availableuntil' => 'closedate', 'maxgrade' => 'grade', 'rating' => ''), 'quiz' => array('availablefrom' => 'timeopen', 'availableuntil' => 'timeclose', 'maxgrade' => 'grade', 'rating' => ''), 'reader' => array('availablefrom' => 'timeopen', 'availableuntil' => 'timeclose', 'maxgrade' => 'maxgrade', 'rating' => ''), 'scorm' => array('availablefrom' => 'timeopen', 'availableuntil' => 'timeclose', 'maxgrade' => 'maxgrade', 'rating' => ''), 'taskchain' => array('availablefrom' => 'timeopen', 'availableuntil' => 'timeclose', 'maxgrade' => 'gradelimit', 'rating' => ''), 'workshop' => array('availablefrom' => 'assessmentstart', 'availableuntil' => 'assessmentend', 'maxgrade' => 'grade ', 'rating' => ''));
        $table_columns = array();
        // make sure mod pix path is set
        if (empty($CFG->modpixpath)) {
            $CFG->modpixpath = $CFG->dirroot . '/mod';
        }
        foreach ($selected_cmids as $cmid => $cm) {
            $updated = false;
            $skipped = false;
            $regrade_item_id = 0;
            $modhaslibfile = file_exists("{$CFG->dirroot}/mod/{$cm->modname}/lib.php");
            // get the $instance of this $cm (include idnumber for grading)
            $instance = $DB->get_record($cm->modname, array('id' => $cm->instance));
            $instance->cmidnumber = $cm->idnumber;
            // get module context
            $modulecontext = context_module::instance($cm->id);
            if ($action == 'delete') {
                if (function_exists('course_delete_module')) {
                    // Moodle >= 2.5
                    course_delete_module($cm->id);
                } else {
                    // Moodle <= 2.4
                    $filepath = $CFG->dirroot . '/mod/' . $cm->modname . '/lib.php';
                    if (!file_exists($filepath)) {
                        $msg = "{$cm->modname} lib.php not found at {$filepath}";
                        echo $OUTPUT->notification($msg);
                    }
                    require_once $filepath;
                    $deleteinstancefunction = $cm->modname . '_delete_instance';
                    if (!function_exists($deleteinstancefunction)) {
                        $msg = "{$cm->modname} delete function not found ({$deleteinstancefunction})";
                        echo $OUTPUT->notification($msg);
                    }
                    // copied from "course/mod.php"
                    if (!$deleteinstancefunction($cm->instance)) {
                        $msg = "Could not delete the {$cm->modname} (instance id={$cm->instance})";
                        echo $OUTPUT->notification($msg);
                    }
                    if (!delete_course_module($cm->id)) {
                        $msg = "Could not delete the {$cm->modname} (coursemodule, id={$cm->id})";
                        echo $OUTPUT->notification($msg);
                    }
                    if (!($sectionid = $DB->get_field('course_sections', 'id', array('course' => $cm->course, 'section' => $cm->sectionnum)))) {
                        $msg = "Could not get section id (course id={$cm->course}, section num={$cm->sectionnum})";
                        echo $OUTPUT->notification($msg);
                    }
                    if (!delete_mod_from_section($cm->id, $sectionid)) {
                        $msg = "Could not delete the {$cm->modname} (id={$cm->id}) from that section (id={$sectionid})";
                        echo $OUTPUT->notification($msg);
                    }
                    add_to_log($cm->course, 'course', 'delete mod', "view.php?id={$cm->course}", "{$cm->modname} {$cm->instance}", $cm->id);
                }
                $rebuild_course_cache = true;
                $updated = true;
            }
            // only check completion/conditions once per $cm
            $conditions_checked = false;
            $completion_updated = false;
            // Note: $selected_settings should only contain anything if $action=='apply'
            foreach ($selected_settings as $setting) {
                switch ($setting) {
                    // activity instance settings
                    case 'availablefrom':
                    case 'availableuntil':
                    case 'availablecutoff':
                    case 'maxgrade':
                    case 'rating':
                        if ($cm->modname == 'taskchain') {
                            $table = 'taskchain_chains';
                            $id = $DB->get_field($table, 'id', array('parenttype' => 0, 'parentid' => $cm->instance));
                        } else {
                            $table = $cm->modname;
                            $id = $cm->instance;
                        }
                        // get list of fields in this $table
                        if (empty($table_columns[$table])) {
                            $table_columns[$table] = $DB->get_columns($table);
                            foreach (array_keys($table_columns[$table]) as $field) {
                                $table_columns[$table][$field] = true;
                            }
                        }
                        // convert setting name to database field name
                        if (isset($fields[$cm->modname][$setting])) {
                            $field = $fields[$cm->modname][$setting];
                        } else {
                            if ($setting == 'availablecutoff') {
                                $field = 'cutoffdate';
                            } else {
                                $field = $setting;
                            }
                        }
                        // update activity instance record, if field exists
                        if (empty($table_columns[$table][$field])) {
                            $skipped = true;
                        } else {
                            if ($DB->set_field($table, $field, ${$setting}, array('id' => $id))) {
                                // $$ is on purpose
                                $updated = true;
                            } else {
                                $success = false;
                            }
                        }
                        break;
                        // course_module settings
                    // course_module settings
                    case 'visible':
                        if ($section_visible[$cm->sectionnum]) {
                            $rebuild_course_cache = true;
                            $field = 'visible';
                        } else {
                            // hidden section - use "visibleold" field
                            // Note: there is no need to rebuild cache
                            $field = 'visibleold';
                        }
                        if ($DB->set_field('course_modules', $field, ${$setting}, array('id' => $cm->id))) {
                            $updated = true;
                        } else {
                            $success = false;
                        }
                        break;
                    case 'indent':
                        switch (true) {
                            case $indent == 0:
                                $set = 'indent = 0';
                                break;
                            case $indent > 0:
                                $set = "indent = (indent + {$indent})";
                                break;
                            case $indent < 0:
                                $set = "indent = (CASE WHEN indent < ABS({$indent}) THEN 0 ELSE indent - ABS({$indent}) END)";
                                break;
                        }
                        if ($DB->execute("UPDATE {$CFG->prefix}course_modules SET {$set} WHERE id = {$cm->id}")) {
                            $rebuild_course_cache = true;
                            $updated = true;
                        } else {
                            $success = false;
                        }
                        break;
                    case 'section':
                        if ($cm->sectionnum == $section) {
                            $skipped = true;
                        } else {
                            // remove cm from old section
                            $params = array('course' => $course->id, 'section' => $cm->sectionnum);
                            if ($sectionid = $DB->get_field('course_sections', 'id', $params)) {
                                $sequence = $DB->get_field('course_sections', 'sequence', $params);
                                if (is_string($sequence)) {
                                    $sequence = explode(',', $sequence);
                                    $sequence = array_filter($sequence);
                                    // remove blanks
                                    $sequence = preg_grep('/^' . $cm->id . '$/', $sequence, PREG_GREP_INVERT);
                                    $sequence = implode(',', $sequence);
                                    $DB->set_field('course_sections', 'sequence', $sequence, $params);
                                }
                                // add cm to target $section
                                if ($position == 1) {
                                    $add_cm_to_sequence = 'array_unshift';
                                    // prepend to start of section
                                } else {
                                    $add_cm_to_sequence = 'array_push';
                                    // append to end of section
                                }
                                $params = array('course' => $course->id, 'section' => $section >= 0 ? $section : $cm->sectionnum);
                                $sectionid = $DB->get_field('course_sections', 'id', $params);
                                $sequence = $DB->get_field('course_sections', 'sequence', $params);
                                if (is_string($sequence)) {
                                    $sequence = explode(',', $sequence);
                                    $sequence = array_filter($sequence);
                                    // remove blanks
                                    $sequence = preg_grep('/^' . $cm->id . '$/', $sequence, PREG_GREP_INVERT);
                                } else {
                                    $sequence = array();
                                    // shouldn't happen !!
                                }
                                $add_cm_to_sequence($sequence, $cm->id);
                                $sequence = implode(',', $sequence);
                                $DB->set_field('course_sections', 'sequence', $sequence, $params);
                                $DB->set_field('course_modules', 'section', $sectionid, array('id' => $cm->id));
                                $updated = true;
                                $rebuild_course_cache = true;
                            }
                        }
                        break;
                        // uploadlimit
                    // uploadlimit
                    case 'uploadlimit':
                        switch ($cm->modname) {
                            case 'assign':
                                // Moodle >= 2.3
                                $table = 'assign_plugin_config';
                                $params = array('assignment' => $cm->instance, 'subtype' => 'assignsubmission', 'plugin' => 'file', 'name' => 'maxsubmissionsizebytes');
                                if ($DB->record_exists($table, $params)) {
                                    if ($DB->set_field($table, 'value', ${$setting}, $params)) {
                                        $updated = true;
                                    } else {
                                        $success = false;
                                    }
                                } else {
                                    $params['value'] = ${$setting};
                                    if ($DB->insert_record($table, $params)) {
                                        $updated = true;
                                    } else {
                                        $success = false;
                                    }
                                }
                                break;
                            case 'assignment':
                                // Moodle <= 2.2
                            // Moodle <= 2.2
                            case 'forum':
                            case 'workshop':
                                if ($DB->set_field($cm->modname, 'maxbytes', ${$setting}, array('id' => $cm->instance))) {
                                    $updated = true;
                                } else {
                                    $success = false;
                                }
                                break;
                                // skip all other modules
                            // skip all other modules
                            default:
                                $skipped = true;
                        }
                        break;
                        // course module settings
                    // course module settings
                    case 'groupmode':
                    case 'groupingid':
                    case 'groupmembersonly':
                        if ($DB->set_field('course_modules', $setting, ${$setting}, array('id' => $cm->id))) {
                            $updated = true;
                            $rebuild_course_cache = true;
                        } else {
                            $success = false;
                        }
                        break;
                        // gradebook settings
                    // gradebook settings
                    case 'gradecat':
                    case 'gradeitemhidden':
                    case 'gradepass':
                        $select = 'courseid = ? AND itemtype = ? AND itemmodule = ? AND iteminstance = ?';
                        $params = array($course->id, 'mod', $cm->modname, $cm->instance);
                        switch ($setting) {
                            case 'gradecat':
                                $field = 'categoryid';
                                break;
                            case 'gradeitemhidden':
                                $field = 'hidden';
                                break;
                            default:
                                $field = $setting;
                        }
                        if ($DB->set_field_select('grade_items', $field, ${$setting}, $select, $params)) {
                            $updated = true;
                            $regrade_item_id = $DB->get_field_select('grade_items', 'id', $select, $params);
                        } else {
                            $success = false;
                        }
                        break;
                        // extra credit
                    // extra credit
                    case 'extracredit':
                        $skipped = true;
                        $select = 'courseid = ? AND itemtype = ? AND itemmodule = ? AND iteminstance = ?';
                        $params = array($course->id, 'mod', $cm->modname, $cm->instance);
                        if ($grade_item = $DB->get_record_select('grade_items', $select, $params)) {
                            $select = 'id = ? AND aggregation IN (?, ?, ?)';
                            $params = array($grade_item->categoryid, GRADE_AGGREGATE_WEIGHTED_MEAN2, GRADE_AGGREGATE_EXTRACREDIT_MEAN, GRADE_AGGREGATE_SUM);
                            if ($grade_category = $DB->get_record_select('grade_categories', $select, $params)) {
                                $skipped = false;
                                if ($DB->set_field('grade_items', 'aggregationcoef', $extracredit, array('id' => $grade_item->id))) {
                                    $updated = true;
                                    $regrade_item_id = $grade_item->id;
                                } else {
                                    $success = false;
                                }
                            }
                        }
                        break;
                        // regrade activity
                    // regrade activity
                    case 'regrade':
                        // Note: the lib.php for this mod was included earlier
                        // if we use just the "update_grades" function,
                        // we cannot know if it is successful or not ...
                        // $update_grades = $cm->modname.'_update_grades';
                        // ... so we use the following functions instead:
                        $get_user_grades = $cm->modname . '_get_user_grades';
                        $grade_item_update = $cm->modname . '_grade_item_update';
                        if (function_exists($get_user_grades) && function_exists($grade_item_update)) {
                            $grades = $get_user_grades($instance);
                            if ($grade_item_update($instance, $grades) == GRADE_UPDATE_OK) {
                                // GRADE_UPDATE_OK = 0
                                $updated = true;
                            } else {
                                $success = false;
                            }
                            $skipped = false;
                        } else {
                            $skipped = true;
                        }
                        break;
                    case 'removeconditions':
                        if ($removeconditions) {
                            if ($dbman->field_exists('course_modules', 'availability')) {
                                // Moodle >= 2.7
                                $DB->set_field('course_modules', 'availability', '', array('id' => $cm->id));
                                $updated = true;
                            } else {
                                // Moodle <= 2.6
                                if ($dbman->field_exists('course_modules', 'availablefrom')) {
                                    $DB->set_field('course_modules', 'availablefrom', 0, array('id' => $cm->id));
                                    $DB->set_field('course_modules', 'availableuntil', 0, array('id' => $cm->id));
                                    $DB->set_field('course_modules', 'showavailability', 0, array('id' => $cm->id));
                                    $updated = true;
                                }
                                if ($dbman->table_exists('course_modules_availability')) {
                                    $DB->delete_records('course_modules_availability', array('coursemoduleid' => $cm->id));
                                    $updated = true;
                                }
                                if ($dbman->table_exists('course_modules_avail_fields')) {
                                    $DB->delete_records('course_modules_avail_fields', array('coursemoduleid' => $cm->id));
                                    $updated = true;
                                }
                            }
                            $rebuild_course_cache = true;
                        }
                        break;
                    case 'conditiondate':
                    case 'conditiongrade':
                    case 'conditionfield':
                    case 'conditiongroup':
                    case 'conditiongrouping':
                    case 'conditioncm':
                    case 'conditionaction':
                        if ($conditions_checked == false) {
                            $conditions_checked = true;
                            $conditions = array_merge($conditiondate, $conditiongrade, $conditionfield, $conditiongroup, $conditiongrouping, $conditioncm);
                            update_course_module_availability($labelmods, $resourcemods, $course, $cm, $conditions, $conditionaction, $updated, $skipped);
                            if ($updated) {
                                $rebuild_course_cache = true;
                            }
                        }
                        break;
                    case 'removecompletion':
                        if ($removecompletion) {
                            $table = 'course_modules';
                            $params = array('id' => $cm->id);
                            $names = array('completion' => 0, 'completionview' => 0, 'completionexpected' => 0, 'completiongradeitemnumber' => null);
                            foreach ($names as $name => $disabled) {
                                $value = $DB->get_field($table, $name, $params);
                                if (isset($value)) {
                                    $value = intval($value);
                                }
                                if ($value === $disabled) {
                                    $skipped = true;
                                } else {
                                    $updated = $DB->set_field($table, $name, $disabled, $params);
                                }
                            }
                            $params = array('id' => $cm->instance);
                            foreach ($completionfields as $name => $field) {
                                if ($field->cmfield) {
                                    continue;
                                    // e.g. completionview/grade
                                }
                                if (array_key_exists($cm->modname, $field->mods)) {
                                    if ($DB->get_field($cm->modname, $name, $params)) {
                                        $updated = $DB->set_field($cm->modname, $name, 0, $params);
                                    } else {
                                        $skipped = true;
                                    }
                                }
                            }
                            if ($updated) {
                                $completion_updated = true;
                            }
                        }
                        break;
                    case 'erasecompletion':
                        if ($erasecompletion) {
                            $completion_updated = true;
                            $updated = true;
                        } else {
                            $skipped = true;
                        }
                        break;
                    case 'completiontracking':
                        update_course_module_completion('course_modules', $cm->id, 'completion', $completiontracking, $updated, $skipped, $completion_updated);
                        break;
                    case 'completiondate':
                        update_course_module_completion('course_modules', $cm->id, $setting, $completiondate, $updated, $skipped, $completion_updated);
                        break;
                    case 'completionview':
                        if (array_key_exists($cm->modname, $completionfields[$setting]->mods)) {
                            update_course_module_completion('course_modules', $cm->id, $setting, $completionview, $updated, $skipped, $completion_updated);
                        }
                        break;
                    case 'completiongrade':
                        if (array_key_exists($cm->modname, $completionfields[$setting]->mods)) {
                            // course_modules.completiongradeitemnumber
                            // see "set_moduleinfo_defaults()" in "course/modlib.php"
                            // null=disabled, 0=enabled (i.e. require grade)
                            $completiongradeitemnumber = $completiongrade ? 0 : null;
                            update_course_module_completion('course_modules', $cm->id, 'completiongradeitemnumber', $completiongradeitemnumber, $updated, $skipped, $completion_updated);
                        }
                        break;
                    case 'competencyrule':
                        $data = (object) array('coursemodule' => $cm->id, 'competencies' => array(), 'competency_rule' => $competencyrule);
                        // see "admin/tool/lp/lib.php"
                        $data = tool_lp_coursemodule_edit_post_actions($data, $course);
                        $updated = true;
                        break;
                    default:
                        if (array_key_exists($setting, $completionfields)) {
                            $field = $completionfields[$setting];
                            if (array_key_exists($cm->modname, $field->mods)) {
                                update_course_module_completion($cm->modname, $cm->instance, $setting, ${$setting}, $updated, $skipped, $completion_updated);
                            }
                        } else {
                            if (substr($setting, 0, 6) == 'filter') {
                                $filter = substr($setting, 6);
                                if (in_array(${$setting}, array(TEXTFILTER_ON, TEXTFILTER_OFF, TEXTFILTER_INHERIT))) {
                                    filter_set_local_state($filter, $modulecontext->id, ${$setting});
                                    $reset_filter_caches = true;
                                    $updated = true;
                                } else {
                                    $skipped = true;
                                }
                            } else {
                                // unexpected setting - shouldn't happen !!
                                echo 'Unknown setting, ' . $setting . ', not processed' . html_writer::empty_tag('br');
                            }
                        }
                }
                // end switch
            }
            // end foreach $selected_settings
            if ($completion_updated) {
                $completion = $completiontracking;
                // if automatic completion (=2) is requested,
                // check that some completion conditions are set
                if ($completion == 2) {
                    $completion = 0;
                    $table = 'course_modules';
                    $params = array('id' => $cm->id);
                    $names = array('completionview' => 0, 'completionexpected' => 0, 'completiongradeitemnumber' => null);
                    foreach ($names as $name => $disabled) {
                        $value = $DB->get_field($table, $name, $params);
                        if (isset($value)) {
                            $value = intval($value);
                        }
                        if ($value !== $disabled) {
                            $completion = $completiontracking;
                        }
                    }
                    foreach ($completionfields as $field) {
                        $name = $field->name;
                        if (property_exists($instance, $name) && $instance->{$name}) {
                            $completion = $completiontracking;
                        }
                    }
                }
                // force completion to be something sensible
                update_course_module_completion('course_modules', $cm->id, 'completion', $completion, $updated, $skipped, $completion_updated);
                // get full $cm record
                if (method_exists($cm, 'get_course_module_record')) {
                    // Moodle >= 2.7
                    $cm = $cm->get_course_module_record(true);
                } else {
                    // Moodle <= 2.6
                    $cm = get_coursemodule_from_id($cm->modname, $cm->id, $cm->course, true);
                }
                // prevent "Cannot find grade item" error in "lib/completionlib.php"
                $params = array('courseid' => $cm->course, 'itemtype' => 'mod', 'itemmodule' => $cm->modname, 'iteminstance' => $cm->instance);
                if (!grade_item::fetch($params)) {
                    $cm->completiongradeitemnumber = null;
                    // disable grade completion
                }
                $completion = new completion_info($course);
                $completion->reset_all_state($cm);
                $rebuild_course_cache = true;
            }
            if ($regrade_item_id) {
                $regrade_course_grades = true;
                $DB->set_field('grade_items', 'needsupdate', 1, array('id' => $regrade_item_id));
                $DB->set_field('grade_items', 'needsupdate', 1, array('courseid' => $course->id, 'itemtype' => 'course'));
            }
            if ($started_list == false) {
                $started_list = true;
                echo '<table border="0" cellpadding="4" cellspacing="4" class="selectedactivitylist"><tbody>' . "\n";
                echo '<tr><th colspan="2">' . get_string('settingsselected', $plugin) . '</th></tr>' . "\n";
                foreach ($selected_settings as $setting) {
                    list($name, $value) = format_setting($setting, ${$setting}, $ratings, $gradecategories, $groupmodes, $groupings, $indentmenu, $sectionmenu, $positionmenu, $uploadlimitmenu, $conditiongradeitemidmenu, $conditioncmidmenu, $conditioncmcompletionmenu, $conditionfieldnamemenu, $conditionfieldoperatormenu, $conditiongroupidmenu, $conditiongroupingidmenu, $conditionactionmenu, $completiontrackingmenu, $completionfields, $competencyrulemenu, $filters, $filtermenu, $filterdefaulton, $filterdefaultoff);
                    echo '<tr><td class="itemname">' . $name . ':</td><td class="itemvalue">' . $value . '</td></tr>' . "\n";
                }
                echo '<tr><th colspan="2">' . get_string('activitiesselected', $plugin) . '</th></tr>' . "\n";
            }
            echo '<tr><td class="itemname">';
            if ($updated) {
                echo '<span class="updated">' . get_string('updated', 'moodle', $cm->modname) . '</span>';
            } else {
                if ($skipped) {
                    echo '<span class="skipped">' . get_string('skipped') . ' ' . $cm->modname . '</span>';
                } else {
                    echo '<span class="failure">' . get_string('fail', 'install') . ' ' . $cm->modname . '</span>';
                }
            }
            echo '</td><td class="itemvalue">';
            $url = $PAGE->theme->pix_url('icon', $cm->modname)->out();
            echo '<img src="' . $url . '" class="icon" title="' . s(get_string('modulename', $cm->modname)) . '"></img> ';
            $name = urldecode($cm->name);
            $name = block_taskchain_navigation::filter_text($name);
            $name = trim(strip_tags($name));
            $name = block_taskchain_navigation::trim_text($name, $cm_namelength, $cm_headlength, $cm_taillength);
            echo $name;
            echo '</td></tr>' . "\n";
        }
    }
    if ($sortgradeitems || $creategradecats || $removegradecats || $reset_filter_caches || $rebuild_course_cache || $regrade_course_grades || isset($success)) {
        if ($started_list == false) {
            $started_list = true;
            echo '<table border="0" cellpadding="4" cellspacing="4" class="selectedactivitylist"><tbody>' . "\n";
        }
        if ($sortgradeitems) {
            echo '<tr><td class="notifymessage" colspan="2">';
            $msg = get_string('sortedgradeitems', $plugin);
            echo $OUTPUT->notification($msg, 'notifysuccess');
            echo '</td></tr>' . "\n";
        }
        if ($creategradecats) {
            echo '<tr><td class="notifymessage" colspan="2">';
            $msg = get_string('createdgradecategories', $plugin);
            echo $OUTPUT->notification($msg, 'notifysuccess');
            echo '</td></tr>' . "\n";
        }
        if ($removegradecats) {
            echo '<tr><td class="notifymessage" colspan="2">';
            $msg = get_string('removedgradecategories', $plugin);
            echo $OUTPUT->notification($msg, 'notifysuccess');
            echo '</td></tr>' . "\n";
        }
        if ($reset_filter_caches) {
            echo '<tr><td class="notifymessage" colspan="2">';
            echo get_string('resettingfiltercache', $plugin) . ' ... ';
            filter_manager::reset_caches();
            //unset($FILTERLIB_PRIVATE->active[$context->id]);
            echo get_string('ok') . '</td></tr>' . "\n";
        }
        if ($rebuild_course_cache) {
            echo '<tr><td class="notifymessage" colspan="2">';
            echo get_string('rebuildingcoursecache', $plugin) . ' ... ';
            rebuild_course_cache($course->id);
            echo get_string('ok') . '</td></tr>' . "\n";
        }
        if ($regrade_course_grades) {
            echo '<tr><td class="notifymessage" colspan="2">';
            echo get_string('recalculatingcoursegrades', $plugin) . ' ... ';
            grade_regrade_final_grades($course->id);
            echo get_string('ok') . '</td></tr>' . "\n";
        }
        if ($success === true) {
            echo '<tr><td class="notifymessage" colspan="2">';
            $msg = get_string('success');
            echo $OUTPUT->notification($msg, 'notifysuccess');
            echo '</td></tr>' . "\n";
        }
        if ($success === false) {
            echo '<tr><td class="notifymessage" colspan="2">';
            $msg = get_string('activityupdatefailure', $plugin);
            echo $OUTPUT->notification($msg, 'notifyproblem');
            echo '</td></tr>' . "\n";
        }
    }
    if ($started_list) {
        $started_list = false;
        echo '</tbody></table>' . "\n";
    }
    echo '<script type="text/javascript">' . "\n";
    echo "//<![CDATA[\n";
    echo "function reset_all_in(elTagName, elNamePrefix, parentTagName, parentClass, parentId, resetValues) {\n";
    echo "    var obj = document.getElementsByTagName(elTagName);\n";
    echo "    obj = filterByParent(obj, function(el) {return findParentNode(el, parentTagName, parentClass, parentId);});\n";
    echo "    for (var i=0; i<obj.length; i++) {\n";
    echo "        var elName = obj[i].name;\n";
    echo "        if (elName && (elNamePrefix=='' || elName.substr(0, elNamePrefix.length)==elNamePrefix)) {\n";
    echo "            switch (obj[i].type) {\n";
    echo "                case 'checkbox':\n";
    echo "                case 'radio':\n";
    echo "                    if (typeof(resetValues)=='string') {\n";
    echo "                        obj[i].checked = (resetValues=='all' ? true : false);\n";
    echo "                    } else {\n";
    echo "                        obj[i].checked = (resetValues[elName] ? true : false);\n";
    echo "                    }\n";
    echo "                    if (obj[i].onclick) {\n";
    echo "                        obj[i].onclick()\n";
    echo "                    }\n";
    echo "                    break;\n";
    echo "                case 'select':\n";
    echo "                case 'select-multiple':\n";
    echo "                    for (var ii=0; ii<obj[i].options.length; ii++) {\n";
    echo "                        if (typeof(resetValues)=='string') {\n";
    echo "                            obj[i].options[ii].selected = (resetValues=='all' ? true : false);\n";
    echo "                        } else {\n";
    echo "                            var elValue = obj[i].options[ii].value;\n";
    echo "                            obj[i].options[ii].selected = (resetValues[elValue] ? true : false);\n";
    echo "                        }\n";
    echo "                    }\n";
    echo "                    break;\n";
    echo "            }\n";
    echo "        }\n";
    echo "    }\n";
    echo "}\n";
    echo "function set_disabled(frm, names, value, sync_checkbox) {\n";
    echo "    var fixed_color = false;\n";
    echo "    if (frm) {\n";
    echo "        var i_max = names.length;\n";
    echo "        for (var i=0; i<i_max; i++) {\n";
    echo "            if (frm.elements[names[i]]) {\n";
    echo "                frm.elements[names[i]].disabled = value;\n";
    echo "                if (sync_checkbox) {\n";
    echo "                    if (frm.elements[names[i]].type=='checkbox') {\n";
    echo "                        frm.elements[names[i]].checked = (! value);\n";
    echo "                    }\n";
    echo "                }\n";
    echo "                if (fixed_color==false) {\n";
    echo "                    fixed_color = true;\n";
    echo "                    var obj = frm.elements[names[i]].parentNode;\n";
    echo "                    if (obj) {\n";
    echo "                        obj.style.color = (value ? '#999999' : 'inherit');\n";
    echo "                    }\n";
    echo "                }\n";
    echo "            }\n";
    echo "        }\n";
    echo "    }\n";
    echo "    return true;\n";
    echo "}\n";
    echo "function init_disabled(frm, names, value) {\n";
    echo "    var obj = document.getElementsByTagName('input');\n";
    echo "    if (obj) {\n";
    echo "        var i_max = obj.length;\n";
    echo "        for (var i=0; i<i_max; i++) {\n";
    echo "            if (obj[i].name && obj[i].name.substr(0, 7)=='select_' && obj[i].onclick) {\n";
    echo "                obj[i].id = 'id_' + obj[i].name;\n";
    echo "                obj[i].onclick();\n";
    echo "            }\n";
    echo "        }\n";
    echo "    }\n";
    echo "    return true;\n";
    echo "}\n";
    echo "function confirm_action(msg, checksettings) {\n";
    echo "    var ok = false;\n";
    echo "    var obj = null;\n";
    echo "    if (obj = document.getElementById('id_sections')) {\n";
    echo "        if (obj.selectedIndex >= 0) {\n";
    echo "            ok = true;\n";
    echo "        }\n";
    echo "    }\n";
    echo "    if (obj = document.getElementById('id_modules')) {\n";
    echo "        if (obj.selectedIndex >= 0) {\n";
    echo "            ok = true;\n";
    echo "        }\n";
    echo "    }\n";
    echo "    if (obj = document.getElementById('id_include')) {\n";
    echo "        if (obj.value) {\n";
    echo "            ok = true;\n";
    echo "        }\n";
    echo "    }\n";
    echo "    if (obj = document.getElementById('id_exclude')) {\n";
    echo "        if (obj.value) {\n";
    echo "            ok = true;\n";
    echo "        }\n";
    echo "    }\n";
    echo "    if (obj = document.getElementById('menuvisibility')) {\n";
    echo "        if (obj.selectedIndex >= 1) {\n";
    echo "            ok = true;\n";
    echo "        }\n";
    echo "    }\n";
    echo "    if (obj = document.getElementById('id_cmids')) {\n";
    echo "        if (obj.selectedIndex >= 0) {\n";
    echo "            ok = true;\n";
    echo "        }\n";
    echo "    }\n";
    echo "    if (ok==false) {\n";
    echo "        alert('" . js(get_string('noactivitiesselected', $plugin)) . "');\n";
    echo "        return ok;\n";
    echo "    }\n";
    echo "    if (checksettings) {\n";
    echo "        ok = false;\n";
    echo "        var settings = new Array('id_select_" . implode("', 'id_select_", $settings) . "');\n";
    echo "        for (var i=0; i<settings.length; i++) {\n";
    echo "            if (obj = document.getElementById(settings[i])) {\n";
    echo "                if (obj.checked) {\n";
    echo "                    ok = true;\n";
    echo "                }\n";
    echo "            }\n";
    echo "        }\n";
    echo "    }\n";
    echo "    if (ok==false) {\n";
    echo "        alert('" . js(get_string('nosettingsselected', $plugin)) . "');\n";
    echo "        return ok;\n";
    echo "    }\n";
    echo "    return confirm(msg);\n";
    echo "}\n";
    echo "if (window.addEventListener) {\n";
    echo "    window.addEventListener('load', init_disabled, false);\n";
    echo "} else if (window.attachEvent) {\n";
    echo "    window.attachEvent('onload', init_disabled)\n";
    echo "} else {\n";
    echo "    window.onload = init_disabled;\n";
    echo "}\n";
    echo "//]]>\n";
    echo '</script>' . "\n";
    echo '<form method="post" action="accesscontrol.php" enctype="multipart/form-data">' . "\n";
    echo '<table border="0" cellpadding="4" cellspacing="4" width="720" style="margin: auto;" class="blockconfigtable">' . "\n";
    echo '<tr>' . "\n";
    echo '<td colspan="2" class="blockdescription">' . nl2br(get_string('accesspagedescription', $plugin)) . '</td>' . "\n";
    echo '<td class="itemselect">';
    echo get_string('select') . ' ';
    echo $OUTPUT->help_icon('selectsettings', $plugin);
    echo '<br />';
    echo '<a href="' . "javascript:reset_all_in('INPUT','select_','TD','itemselect',null,'all');" . '">' . get_string('all') . '</a>';
    echo ' / ';
    echo '<a href="' . "javascript:reset_all_in('INPUT','select_','TD','itemselect',null,'none');" . '">' . get_string('none') . '</a>';
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    // ============================
    // Activity filters
    // ============================
    //
    print_sectionheading(get_string('activityfilters', $plugin), 'activityfilters', false);
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('sectiontags', $plugin) . ':</td>';
    echo '<td class="itemvalue">';
    echo '<input id="id_sectiontags" type="text" name="sectiontags" size="15" value="' . $sectiontags . '" />';
    echo ' ' . $OUTPUT->help_icon('sectiontitletags', $plugin);
    echo '</td>' . "\n";
    echo '<td class="itemselect">&nbsp;</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('sections', $plugin) . ':';
    echo '<div class="smalltext">';
    echo '<a href="' . "javascript:reset_all_in('SELECT','sections','','',null,'all');" . '">' . get_string('all') . '</a>';
    echo ' / ';
    echo '<a href="' . "javascript:reset_all_in('SELECT','sections','','',null,'none');" . '">' . get_string('none') . '</a>';
    echo '</div>';
    echo '</td>' . "\n";
    echo '<td class="itemvalue">' . $sections . '</td>' . "\n";
    echo '<td class="itemselect">&nbsp;</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('activitytypes', $plugin) . ':';
    echo '<div class="smalltext">';
    echo '<a href="' . "javascript:reset_all_in('SELECT','modules','','',null,'all');" . '">' . get_string('all') . '</a>';
    echo ' / ';
    echo '<a href="' . "javascript:reset_all_in('SELECT','modules','','',null,'none');" . '">' . get_string('none') . '</a>';
    echo '</div>';
    echo '</td>' . "\n";
    echo '<td class="itemvalue">' . $modules . '</td>' . "\n";
    echo '<td class="itemselect">&nbsp;</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('activitynamefilters', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo '    <div class="subitem">';
    echo '        <div class="subname">' . get_string('include', $plugin) . ':</div>';
    echo '        <input id="id_include" type="text" name="include" size="15" value="' . $include . '" />';
    echo '    </div>';
    echo '    <div class="subitem">';
    echo '        <div class="subname">' . get_string('exclude', $plugin) . ':</div>';
    echo '        <input id="id_exclude" type="text" name="exclude" size="15" value="' . $exclude . '" />';
    echo '    </div>';
    echo '</td>' . "\n";
    echo '<td class="itemselect">&nbsp;</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('visibility', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($visibilitymenu, 'visibility', $visibility, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">&nbsp;</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('activityids', $plugin) . ':';
    echo '<div class="smalltext">';
    echo '<a href="' . "javascript:reset_all_in('SELECT','cmids','','',null,'all');" . '">' . get_string('all') . '</a>';
    echo ' / ';
    echo '<a href="' . "javascript:reset_all_in('SELECT','cmids','','',null,'none');" . '">' . get_string('none') . '</a>';
    echo '</div>';
    echo '</td>' . "\n";
    echo '<td class="itemvalue">' . $cms . '</td>' . "\n";
    echo '<td class="itemselect">&nbsp;</td>' . "\n";
    echo '</tr>' . "\n";
    // ============================
    // Availability dates
    // ============================
    //
    print_sectionheading(get_string('dates', $plugin), 'dates', true);
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('availablefrom', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    $fromdate['minutes'] = intval($fromdate['minutes']) - intval($fromdate['minutes']) % 5;
    echo html_writer::select($days, 'fromday', intval($fromdate['mday']), '') . ' ';
    echo html_writer::select($months, 'frommonth', intval($fromdate['mon']), '') . ' ';
    echo html_writer::select($years, 'fromyear', intval($fromdate['year']), '') . ' ';
    echo html_writer::select($hours, 'fromhours', intval($fromdate['hours']), '') . ' ';
    echo html_writer::select($minutes, 'fromminutes', intval($fromdate['minutes']), '') . ' ';
    $names = "'menufromday', 'menufrommonth', 'menufromyear', 'menufromhours', 'menufromminutes'";
    $script = "return set_disabled(this.form, new Array({$names}), (this.disabled || this.checked))";
    echo html_writer::checkbox('fromdisable', '1', $fromdisable, get_string('disable'), array('onclick' => $script));
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('fromdisable'), (! this.checked)) && this.form.fromdisable.onclick()";
    $checked = optional_param('select_availablefrom', 0, PARAM_INT);
    echo html_writer::checkbox('select_availablefrom', 1, $checked, '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('availableuntil', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    $untildate['minutes'] = intval($untildate['minutes']) - intval($untildate['minutes']) % 5;
    echo html_writer::select($days, 'untilday', intval($untildate['mday']), '') . ' ';
    echo html_writer::select($months, 'untilmonth', intval($untildate['mon']), '') . ' ';
    echo html_writer::select($years, 'untilyear', intval($untildate['year']), '') . ' ';
    echo html_writer::select($hours, 'untilhours', intval($untildate['hours']), '') . ' ';
    echo html_writer::select($minutes, 'untilminutes', intval($untildate['minutes']), '') . ' ';
    $names = "'menuuntilday', 'menuuntilmonth', 'menuuntilyear', 'menuuntilhours', 'menuuntilminutes'";
    $script = "return set_disabled(this.form, new Array({$names}), (this.disabled || this.checked))";
    echo html_writer::checkbox('untildisable', '1', $untildisable, get_string('disable'), array('onclick' => $script));
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('untildisable'), (! this.checked)) && this.form.untildisable.onclick()";
    $checked = optional_param('select_availableuntil', 0, PARAM_INT);
    echo html_writer::checkbox('select_availableuntil', 1, $checked, '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    if ($modnames = implode(', ', $cutoffdatemods)) {
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('cutoffdate', 'assign') . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        $cutoffdate['minutes'] = intval($cutoffdate['minutes']) - intval($cutoffdate['minutes']) % 5;
        echo html_writer::select($days, 'cutoffday', intval($cutoffdate['mday']), '') . ' ';
        echo html_writer::select($months, 'cutoffmonth', intval($cutoffdate['mon']), '') . ' ';
        echo html_writer::select($years, 'cutoffyear', intval($cutoffdate['year']), '') . ' ';
        echo html_writer::select($hours, 'cutoffhours', intval($cutoffdate['hours']), '') . ' ';
        echo html_writer::select($minutes, 'cutoffminutes', intval($cutoffdate['minutes']), '') . ' ';
        $names = "'menucutoffday', 'menucutoffmonth', 'menucutoffyear', 'menucutoffhours', 'menucutoffminutes'";
        $script = "return set_disabled(this.form, new Array({$names}), (this.disabled || this.checked))";
        echo html_writer::checkbox('cutoffdisable', '1', $cutoffdisable, get_string('disable'), array('onclick' => $script));
        echo html_writer::empty_tag('br') . '(' . get_string('completionfieldactivities', $plugin, $modnames) . ')';
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('cutoffdisable'), (! this.checked)) && this.form.cutoffdisable.onclick()";
        $checked = optional_param('select_availablecutoff', 0, PARAM_INT);
        echo html_writer::checkbox('select_availablecutoff', 1, $checked, '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
    }
    // ============================
    // Grades
    // ============================
    //
    echo '<tr class="sectionheading" id="id_section_dates">' . "\n";
    echo '<th colspan="2">';
    echo get_string('grades');
    echo ' &nbsp; <span class="sortgradeitems">';
    if ($sortgradeitems) {
        echo ' ' . get_string('sortedgradeitems', $plugin);
    } else {
        $href = $CFG->wwwroot . '/blocks/taskchain_navigation/accesscontrol.php?id=' . $block_instance->id . '&sortgradeitems=1&sesskey=' . sesskey();
        $onclick = 'return confirm("' . js(get_string('confirmsortgradeitems', $plugin)) . '")';
        echo '<a href="' . s($href) . '" onclick="' . s($onclick) . '">' . get_string('sortgradeitems', $plugin) . '</a> ';
        echo $OUTPUT->help_icon('sortgradeitems', $plugin);
    }
    echo '</span>';
    echo ' &nbsp; <span class="creategradecategories">';
    if ($creategradecats) {
        echo ' ' . get_string('createdgradecategories', $plugin);
    } else {
        $href = $CFG->wwwroot . '/blocks/taskchain_navigation/accesscontrol.php?id=' . $block_instance->id . '&creategradecats=1&sesskey=' . sesskey();
        $onclick = 'return confirm("' . js(get_string('confirmcreategradecategories', $plugin)) . '")';
        echo '<a href="' . s($href) . '" onclick="' . s($onclick) . '">' . get_string('creategradecategories', $plugin) . '</a> ';
        echo $OUTPUT->help_icon('creategradecategories', $plugin);
    }
    echo '</span>';
    echo ' &nbsp; <span class="removegradecategories">';
    if ($removegradecats) {
        echo ' ' . get_string('removedgradecategories', $plugin);
    } else {
        $href = $CFG->wwwroot . '/blocks/taskchain_navigation/accesscontrol.php?id=' . $block_instance->id . '&removegradecats=1&sesskey=' . sesskey();
        $onclick = 'return confirm("' . js(get_string('confirmremovegradecategories', $plugin)) . '")';
        echo '<a href="' . s($href) . '" onclick="' . s($onclick) . '">' . get_string('removegradecategories', $plugin) . '</a> ';
        echo $OUTPUT->help_icon('removegradecategories', $plugin);
    }
    echo '</span>';
    echo '</th>' . "\n";
    echo '<th class="toggle"></th>' . "\n";
    echo '</tr>' . "\n";
    if ($modnames = implode(', ', $ratingmods)) {
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('rating', 'rating') . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::select($ratings, 'rating', $rating, '') . ' ';
        echo '(' . get_string('completionfieldactivities', $plugin, $modnames) . ')';
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('rating'), (! this.checked))";
        echo html_writer::checkbox('select_rating', 1, optional_param('select_rating', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
    }
    if ($modnames = implode(', ', $gradingmods)) {
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('grade') . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        foreach ($gradingmods as $modname => $modtext) {
            echo "<p>{$modname} - {$modtext}<br />";
            foreach ($gradingareas[$modname] as $areaname => $areatext) {
                echo " == {$areaname} - {$areatext}<br />";
            }
            echo "</p>\n";
        }
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('grading'), (! this.checked))";
        echo html_writer::checkbox('select_grading', 1, optional_param('select_grading', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
    }
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('maximumgrade', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($maxgrades, 'maxgrade', $maxgrade, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('maxgrade'), (! this.checked))";
    echo html_writer::checkbox('select_maxgrade', 1, optional_param('select_maxgrade', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('gradepass', 'grades') . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($gradepassmenu, 'gradepass', $gradepass, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('gradepass'), (! this.checked))";
    echo html_writer::checkbox('select_gradepass', 1, optional_param('select_gradepass', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('gradecategory', 'grades') . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($gradecategories, 'gradecat', $gradecat, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('gradecat'), (! this.checked))";
    echo html_writer::checkbox('select_gradecat', 1, optional_param('select_gradecat', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('gradeitemhidden', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select_yes_no('gradeitemhidden', $gradeitemhidden);
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('gradeitemhidden'), (! this.checked))";
    echo html_writer::checkbox('select_gradeitemhidden', 1, optional_param('select_gradeitemhidden', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('aggregationcoefextra', 'grades') . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select_yes_no('extracredit', $extracredit);
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('extracredit'), (! this.checked))";
    echo html_writer::checkbox('select_extracredit', 1, optional_param('select_extracredit', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('regrade', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select_yes_no('regrade', $regrade);
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('regrade'), (! this.checked))";
    echo html_writer::checkbox('select_regrade', 1, optional_param('select_regrade', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    // ============================
    // Groups
    // ============================
    //
    print_sectionheading(get_string('groups'), 'groups', true);
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('groupmode') . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($groupmodes, 'groupmode', $groupmode, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('groupmode'), (! this.checked))";
    echo html_writer::checkbox('select_groupmode', 1, optional_param('select_groupmode', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    if (count($groupings)) {
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('grouping', 'group') . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::select($groupings, 'groupingid', $groupingid, '');
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('groupingid'), (! this.checked))";
        echo html_writer::checkbox('select_groupingid', 1, optional_param('select_groupingid', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
        if ($strman->string_exists('groupmembersonly', 'group')) {
            echo '<tr>' . "\n";
            echo '<td class="itemname groupmembersonly">' . get_string('groupmembersonly', 'group') . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            echo html_writer::checkbox('groupmembersonly', 1, $groupmembersonly);
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('groupmembersonly'), (! this.checked))";
            echo html_writer::checkbox('select_groupmembersonly', 1, optional_param('select_groupmembersonly', 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
    }
    // ============================
    // Course page
    // ============================
    //
    echo '<tr class="sectionheading" id="id_section_coursepage">' . "\n";
    echo '<th colspan="2">';
    echo get_string('coursepage', $plugin);
    echo ' &nbsp; <span class="sortgradeitems">';
    if ($sortactivities) {
        echo ' ' . get_string('sortedactivities', $plugin);
    } else {
        $href = $CFG->wwwroot . '/blocks/taskchain_navigation/accesscontrol.php?id=' . $block_instance->id . '&sortactivities=1&sesskey=' . sesskey();
        $onclick = 'return confirm("' . get_string('confirmsortactivities', $plugin) . '")';
        echo '<a href="' . s($href) . '" onclick="' . js($onclick) . '">' . get_string('sortactivities', $plugin) . '</a> ';
        echo $OUTPUT->help_icon('sortactivities', $plugin);
    }
    echo '</span>';
    echo '</th>' . "\n";
    echo '<th class="toggle"></th>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('visible') . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($visiblemenu, 'visible', $visible, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('visible'), (! this.checked))";
    echo html_writer::checkbox('select_visible', 1, optional_param('select_visible', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . get_string('indent', $plugin) . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($indentmenu, 'indent', $indent, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('indent'), (! this.checked))";
    echo html_writer::checkbox('select_indent', 1, optional_param('select_indent', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    if ($strman->string_exists('moveto', 'question')) {
        // Moodle >= 2.2
        $moveto = get_string('moveto', 'question');
    } else {
        // Moodle <= 2.1
        $moveto = get_string('movehere');
    }
    echo '<tr>' . "\n";
    echo '<td class="itemname">' . $moveto . ':</td>' . "\n";
    echo '<td class="itemvalue">';
    echo html_writer::select($sectionmenu, 'section', $section, '');
    echo ' ';
    echo html_writer::select($positionmenu, 'position', $position, '');
    echo '</td>' . "\n";
    echo '<td class="itemselect">';
    $script = "return set_disabled(this.form, new Array('section', 'position'), (! this.checked))";
    echo html_writer::checkbox('select_section', 1, optional_param('select_section', 0, PARAM_INT), '', array('onclick' => $script));
    echo '</td>' . "\n";
    echo '</tr>' . "\n";
    // ============================
    // Files and uploads
    // ============================
    //
    if (count($filemods)) {
        print_sectionheading(get_string('fileuploads', 'install'), 'files', true);
        $href = 'http://php.net/manual/' . substr(current_language(), 0, 2) . '/ini.core.php';
        $icon = html_writer::empty_tag('img', array('src' => $PAGE->theme->pix_url('i/info', ''), 'title' => get_string('info')));
        $params = array('onclick' => 'this.target="_blank"');
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('phpuploadlimit', $plugin) . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        if ($limit = ini_get('upload_max_filesize')) {
            $limit = display_size(get_real_size($limit)) . ' upload_max_filesize ';
            echo html_writer::tag('span', $limit, array('class' => 'uploadlimit'));
            echo html_writer::link($href . '#ini.upload-max-filesize', $icon, $params);
            echo html_writer::empty_tag('br');
        }
        if ($limit = ini_get('post_max_size')) {
            $limit = display_size(get_real_size($limit)) . ' post_max_size ';
            echo html_writer::tag('span', $limit, array('class' => 'uploadlimit'));
            echo html_writer::link($href . '#ini.post-max-size', $icon, $params);
        }
        echo '</td>' . "\n";
        echo '<td class="itemselect"></td>' . "\n";
        echo '</tr>' . "\n";
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('siteuploadlimit', $plugin) . ':' . '</td>' . "\n";
        echo '<td class="itemvalue">';
        // Site administration -> Security -> Site policies: Maximum uploaded file size
        if ($siteuploadlimit) {
            $limit = display_size($siteuploadlimit);
        } else {
            $limit = get_string('phpuploadlimit', $plugin);
            $limit = get_string('sameas', $plugin, $limit);
            $limit = html_writer::tag('i', $limit);
        }
        echo html_writer::tag('span', $limit, array('class' => 'uploadlimit'));
        if (has_capability('moodle/course:update', $sitecontext)) {
            $href = new moodle_url('/admin/settings.php', array('section' => 'sitepolicies'));
            $icon = html_writer::empty_tag('img', array('src' => $PAGE->theme->pix_url('i/settings', ''), 'title' => get_string('update')));
            echo html_writer::link($href, $icon, array('onclick' => 'this.target="_blank"'));
        }
        echo '</td>' . "\n";
        echo '<td class="itemselect"></td>' . "\n";
        echo '</tr>' . "\n";
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('courseuploadlimit', $plugin) . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        if ($courseuploadlimit) {
            $limit = display_size($courseuploadlimit);
        } else {
            $limit = get_string('siteuploadlimit', $plugin);
            $limit = get_string('sameas', $plugin, $limit);
            $limit = html_writer::tag('i', $limit);
        }
        echo html_writer::tag('span', $limit, array('class' => 'uploadlimit'));
        if (has_capability('moodle/course:update', $course->context)) {
            $href = new moodle_url('/course/edit.php', array('id' => $course->id));
            $icon = html_writer::empty_tag('img', array('src' => $PAGE->theme->pix_url('i/settings', ''), 'title' => get_string('update')));
            echo html_writer::link($href, $icon, array('onclick' => 'this.target="_blank"'));
        }
        echo '</td>' . "\n";
        echo '<td class="itemselect"></td>' . "\n";
        echo '</tr>' . "\n";
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('pluginuploadlimits', $plugin) . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        foreach ($filemods as $name => $limit) {
            if ($limit) {
                $limit = display_size($limit);
            } else {
                $limit = get_string('courseuploadlimit', $plugin);
                $limit = get_string('sameas', $plugin, $limit);
                $limit = html_writer::tag('i', $limit);
            }
            $limit .= ': ' . get_string('pluginname', $name);
            echo html_writer::tag('span', $limit, array('class' => 'uploadlimit'));
            if ($hassiteconfig) {
                if ($name == 'assign') {
                    $href = $name . 'submission_file';
                } else {
                    $href = 'modsetting' . $name;
                }
                $href = new moodle_url('/admin/settings.php', array('section' => $href));
                $icon = html_writer::empty_tag('img', array('src' => $PAGE->theme->pix_url('i/settings', ''), 'title' => get_string('update')));
                echo html_writer::link($href, $icon, array('onclick' => 'this.target="_blank"'));
            }
            echo html_writer::empty_tag('br');
        }
        echo '</td>' . "\n";
        echo '<td class="itemselect"></td>' . "\n";
        echo '</tr>' . "\n";
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('activityuploadlimit', $plugin) . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::select($uploadlimitmenu, 'uploadlimit', $uploadlimit, '');
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('uploadlimit'), (! this.checked))";
        echo html_writer::checkbox('select_uploadlimit', 1, optional_param('select_uploadlimit', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
    }
    // ============================
    // Active filters
    // ============================
    //
    if (count($filters)) {
        print_sectionheading(get_string('actfilterhdr', 'filters'), 'filters', true);
        foreach ($filters as $filter => $filterinfo) {
            if ($filterinfo->inheritedstate == TEXTFILTER_ON) {
                $filtermenu[TEXTFILTER_INHERIT] = $filterdefaulton;
            } else {
                $filtermenu[TEXTFILTER_INHERIT] = $filterdefaultoff;
            }
            $setting = 'filter' . $filter;
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . filter_get_name($filter) . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            echo html_writer::select($filtermenu, $setting, ${$setting}, '');
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('{$setting}'), (! this.checked))";
            echo html_writer::checkbox('select_' . $setting, 1, optional_param('select_' . $setting, 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
    }
    // ============================
    // Access restrictions (Moodle >= 2.7)
    // Restrict access     (Moodle <= 2.6)
    // ============================
    //
    if ($enableavailability) {
        echo '<tr class="sectionheading" id ="id_section_availability">' . "\n";
        echo '<th colspan="2">' . $str->accessrestrictions . '</th>' . "\n";
        echo '<th class="toggle"></th>' . "\n";
        echo '</tr>' . "\n";
        echo '<tr>' . "\n";
        echo '<td class="itemname removeconditions">' . get_string('removeconditions', $plugin) . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::checkbox('removeconditions', 1, $removeconditions, get_string('removeconditions_help', $plugin));
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('removeconditions'), (! this.checked), true)";
        echo html_writer::checkbox('select_removeconditions', 1, optional_param('select_removeconditions', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
        // =====================
        // condition dates
        // =====================
        //
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . $str->datetitle . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        $names = array();
        $i_max = count($conditiondatedirection);
        for ($i = 0; $i < $i_max; $i++) {
            $conditiondatetime[$i]['minutes'] = intval($conditiondatetime[$i]['minutes']) - intval($conditiondatetime[$i]['minutes']) % 5;
            echo html_writer::start_tag('p');
            echo html_writer::select($conditiondatedirectionmenu, "conditiondatedirection[{$i}]", $conditiondatedirection[$i], '') . ' ';
            echo html_writer::select($days, "conditiondatetimeday[{$i}]", intval($conditiondatetime[$i]['mday']), '') . ' ';
            echo html_writer::select($months, "conditiondatetimemonth[{$i}]", intval($conditiondatetime[$i]['mon']), '') . ' ';
            echo html_writer::select($years, "conditiondatetimeyear[{$i}]", intval($conditiondatetime[$i]['year']), '') . ' ';
            echo html_writer::select($hours, "conditiondatetimehours[{$i}]", intval($conditiondatetime[$i]['hours']), '') . ' ';
            echo html_writer::select($minutes, "conditiondatetimeminutes[{$i}]", intval($conditiondatetime[$i]['minutes']), '') . ' ';
            echo html_writer::end_tag('p');
            $names[] = "conditiondatedirection[{$i}]";
            $names[] = "conditiondatetimeday[{$i}]";
            $names[] = "conditiondatetimemonth[{$i}]";
            $names[] = "conditiondatetimeyear[{$i}]";
            $names[] = "conditiondatetimehours[{$i}]";
            $names[] = "conditiondatetimeminutes[{$i}]";
        }
        $names = implode("', '", $names);
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('{$names}'), (! this.checked))";
        echo html_writer::checkbox('select_conditiondate', 1, optional_param('select_conditiondate', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
        // =====================
        // condition grades
        // =====================
        //
        if (count($conditiongradeitemidmenu)) {
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . $str->gradetitle . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            $names = array();
            $i_max = count($conditiongradeitemid);
            for ($i = 0; $i < $i_max; $i++) {
                echo html_writer::start_tag('p');
                echo html_writer::select($conditiongradeitemidmenu, 'conditiongradeitemid[' . $i . ']', $conditiongradeitemid[$i], '', array('class' => 'conditiongradeitemid')) . ' ';
                echo html_writer::empty_tag('br');
                echo $str->grademin . ' ';
                echo ' <input id="id_conditiongrademin[' . $i . ']" type="text" name="conditiongrademin[' . $i . ']" size="3" value="' . $conditiongrademin[$i] . '" />% ';
                echo html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('spacer'), 'class' => 'spacer', 'width' => '30px'));
                echo $str->grademax . ' ';
                echo ' <input id="id_conditiongrademax[' . $i . ']" type="text" name="conditiongrademax[' . $i . ']" size="3" value="' . $conditiongrademax[$i] . '" />% ';
                echo html_writer::end_tag('p');
                $names[] = 'conditiongradeitemid[' . $i . ']';
                $names[] = 'conditiongrademin[' . $i . ']';
                $names[] = 'conditiongrademax[' . $i . ']';
            }
            $names = implode("', '", $names);
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('{$names}'), (! this.checked))";
            echo html_writer::checkbox('select_conditiongrade', 1, optional_param('select_conditiongrade', 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
        // =====================
        // condition userfields
        // =====================
        //
        if (count($conditionfieldnamemenu)) {
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . $str->userfield . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            $names = array();
            $i_max = count($conditionfieldname);
            for ($i = 0; $i < $i_max; $i++) {
                echo html_writer::start_tag('p');
                echo html_writer::select($conditionfieldnamemenu, 'conditionfieldname[' . $i . ']', $conditionfieldname[$i], '', array('class' => 'conditionfieldname')) . ' ';
                echo html_writer::select($conditionfieldoperatormenu, 'conditionfieldoperator[' . $i . ']', $conditionfieldoperator[$i], '', array('class' => 'conditionfieldoperator')), ' ';
                echo '<input id="id_conditionfieldvalue[' . $i . ']" type="text" name="conditionfieldvalue[' . $i . ']" size="15" value="' . $conditionfieldvalue[$i] . '" />';
                echo html_writer::end_tag('p');
                $names[] = 'conditionfieldname[' . $i . ']';
                $names[] = 'conditionfieldoperator[' . $i . ']';
                $names[] = 'conditionfieldvalue[' . $i . ']';
            }
            $names = implode("', '", $names);
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('{$names}'), (! this.checked))";
            echo html_writer::checkbox('select_conditionfield', 1, optional_param('select_conditionfield', 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
        // =====================
        // condition groups
        // =====================
        //
        if (count($conditiongroupidmenu)) {
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . get_string('group') . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            $names = array();
            $i_max = count($conditiongroupid);
            for ($i = 0; $i < $i_max; $i++) {
                echo html_writer::start_tag('p');
                echo html_writer::select($conditiongroupidmenu, 'conditiongroupid[' . $i . ']', $conditiongroupid[$i], '', array('class' => 'conditiongroupid'));
                echo html_writer::end_tag('p');
                $names[] = 'conditiongroupid[' . $i . ']';
            }
            $names = implode("', '", $names);
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('{$names}'), (! this.checked))";
            echo html_writer::checkbox('select_conditiongroup', 1, optional_param('select_conditiongroup', 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
        // =====================
        // condition groupings
        // =====================
        //
        if (count($conditiongroupingidmenu)) {
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . get_string('grouping', 'group') . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            $names = array();
            $i_max = count($conditiongroupingid);
            for ($i = 0; $i < $i_max; $i++) {
                echo html_writer::start_tag('p');
                echo html_writer::select($conditiongroupingidmenu, 'conditiongroupingid[' . $i . ']', $conditiongroupingid[$i], '', array('class' => 'conditiongroupingid'));
                echo html_writer::end_tag('p');
                $names[] = 'conditiongroupingid[' . $i . ']';
            }
            $names = implode("', '", $names);
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('{$names}'), (! this.checked))";
            echo html_writer::checkbox('select_conditiongrouping', 1, optional_param('select_conditiongrouping', 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
        // =====================
        // conditions completion
        // of other activities
        // =====================
        //
        if (count($conditioncmidmenu)) {
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . $str->activitycompletion . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            $names = array();
            $i_max = count($conditioncmid);
            for ($i = 0; $i < $i_max; $i++) {
                echo html_writer::start_tag('p');
                echo html_writer::select($conditioncmidmenu, 'conditioncmid[' . $i . ']', $conditioncmid[$i], '', array('class' => 'conditioncmid'));
                echo html_writer::empty_tag('br');
                echo html_writer::checkbox('conditioncmungraded[' . $i . ']', 1, $conditioncmungraded[$i], $str->conditioncmungraded, array('class' => 'conditioncmungraded'));
                echo html_writer::empty_tag('br');
                echo html_writer::checkbox('conditioncmresources[' . $i . ']', 1, $conditioncmresources[$i], $str->conditioncmresources, array('class' => 'conditioncmresources'));
                echo html_writer::empty_tag('br');
                echo html_writer::checkbox('conditioncmlabels[' . $i . ']', 1, $conditioncmlabels[$i], $str->conditioncmlabels, array('class' => 'conditioncmlabels'));
                echo html_writer::empty_tag('br');
                echo html_writer::select($conditioncmcompletionmenu, 'conditioncmcompletion[' . $i . ']', $conditioncmcompletion[$i], '', array('class' => 'conditioncmcompletion'));
                echo html_writer::end_tag('p');
                $names[] = 'conditioncmid[' . $i . ']';
                $names[] = 'conditioncmungraded[' . $i . ']';
                $names[] = 'conditioncmresources[' . $i . ']';
                $names[] = 'conditioncmlabels[' . $i . ']';
                $names[] = 'conditioncmcompletion[' . $i . ']';
            }
            $names = implode("', '", $names);
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('{$names}'), (! this.checked))";
            echo html_writer::checkbox('select_conditioncm', 1, optional_param('select_conditioncm', 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
        // =====================
        // conditions actions
        // =====================
        //
        if (count($conditionactionmenu)) {
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . $str->showavailability . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            $names = array();
            $i_max = count($conditionaction);
            for ($i = 0; $i < $i_max; $i++) {
                echo html_writer::start_tag('p');
                echo html_writer::select($conditionactionmenu, 'conditionaction[' . $i . ']', $conditionaction[$i], '', array('class' => 'conditionaction'));
                echo html_writer::end_tag('p');
                $names[] = 'conditionaction[' . $i . ']';
            }
            $names = implode("', '", $names);
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $script = "return set_disabled(this.form, new Array('{$names}'), (! this.checked))";
            echo html_writer::checkbox('select_conditionaction', 1, optional_param('select_conditionaction', 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
    }
    // ============================
    // Activity completion
    // ============================
    //
    if ($enablecompletion) {
        print_sectionheading(get_string('activitycompletion', 'completion'), 'completion', true);
        echo '<tr>' . "\n";
        echo '<td class="itemname removecompletion">' . get_string('removecompletion', $plugin) . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::checkbox('removecompletion', 1, $removecompletion, get_string('removecompletion_help', $plugin));
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('removecompletion'), (! this.checked), true)";
        echo html_writer::checkbox('select_removecompletion', 1, optional_param('select_removecompletion', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
        echo '<tr>' . "\n";
        echo '<td class="itemname erasecompletion">' . get_string('erasecompletion', $plugin) . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::checkbox('erasecompletion', 1, $erasecompletion, get_string('erasecompletion_help', $plugin));
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('erasecompletion'), (! this.checked), true)";
        echo html_writer::checkbox('select_erasecompletion', 1, optional_param('select_erasecompletion', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
        // =====================
        // completion type
        // none/manual/automatic
        // =====================
        //
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('completion', 'completion') . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::select($completiontrackingmenu, 'completiontracking', $completiontracking, '');
        echo html_writer::empty_tag('br') . '(' . get_string('usedbyall', $plugin) . ')';
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('completiontracking'), (! this.checked))";
        echo html_writer::checkbox('select_completiontracking', 1, optional_param('select_completiontracking', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
        // =====================
        // require view
        // =====================
        //
        //echo '<tr>'."\n";
        //echo '<td class="itemname">'.get_string('completionview', 'completion').':</td>'."\n";
        //echo '<td class="itemvalue">';
        //echo html_writer::checkbox('completionview', 1, $completionview, get_string('completionview_desc', 'completion'));
        //echo '</td>'."\n";
        //echo '<td class="itemselect">';
        //$script = "return set_disabled(this.form, new Array('completionview'), (! this.checked), true)";
        //echo html_writer::checkbox('select_completionview', 1, optional_param('select_completionview', 0, PARAM_INT), '', array('onclick' => $script));
        //echo '</td>'."\n";
        //echo '</tr>'."\n";
        // =====================
        // require grade
        // =====================
        //
        //echo '<tr>'."\n";
        //echo '<td class="itemname">'.get_string('completionusegrade', 'completion').':</td>'."\n";
        //echo '<td class="itemvalue">';
        //echo html_writer::checkbox('completiongrade', 1, $completiongrade, get_string('completionusegrade_desc', 'completion'));
        //echo '</td>'."\n";
        //echo '<td class="itemselect">';
        //$script = "return set_disabled(this.form, new Array('completiongrade'), (! this.checked), true)";
        //echo html_writer::checkbox('select_completiongrade', 1, optional_param('select_completiongrade', 0, PARAM_INT), '', array('onclick' => $script));
        //echo '</td>'."\n";
        //echo '</tr>'."\n";
        // =====================
        // completion date
        // =====================
        //
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('completionexpected', 'completion') . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::select_time('days', 'completionday', $completiondate, 1) . ' ';
        echo html_writer::select_time('months', 'completionmonth', $completiondate, 1) . ' ';
        echo html_writer::select_time('years', 'completionyear', $completiondate, 1);
        echo html_writer::empty_tag('br') . '(' . get_string('usedbyall', $plugin) . ')';
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('completionday', 'completionmonth', 'completionyear'), (! this.checked))";
        echo html_writer::checkbox('select_completiondate', 1, optional_param('select_completiondate', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
        // =====================
        // activity-specific
        // completion settings
        // =====================
        //
        foreach ($completionfields as $name => $field) {
            $text = $field->text;
            $desc = $field->desc;
            $type = $field->type;
            if ($text == $desc) {
                $desc = '';
            }
            if (empty($field->params['name'])) {
                $fieldname = $name;
            } else {
                $fieldname = $field->params['name'];
            }
            if ($modnames = implode(', ', $field->mods)) {
                $modnames = get_string('completionfieldactivities', $plugin, $modnames);
                $modnames = html_writer::tag('span', "({$modnames})", array('class' => 'completionfieldmodnames'));
                if ($desc) {
                    $modnames = html_writer::empty_tag('br') . $modnames;
                }
            }
            echo '<tr>' . "\n";
            echo '<td class="itemname">' . $text . ':</td>' . "\n";
            echo '<td class="itemvalue">';
            switch ($type) {
                case 'checkbox':
                    echo html_writer::checkbox($name, 1, ${$name}, ' ' . $desc . $modnames, $field->params);
                    break;
                case 'duration':
                    $options = implode('', $field->options);
                    echo $desc . ' ' . html_writer::empty_tag('input', $field->params['number']) . ' ' . html_writer::tag('select', $options, $field->params['unit']) . ' ' . $modnames;
                    break;
                case 'select':
                    $options = implode('', $field->options);
                    echo $desc . ' ' . html_writer::tag('select', $options, $field->params) . $modnames;
                    break;
                case 'textbox':
                    echo $desc . ' ' . html_writer::empty_tag('input', $field->params) . ' ' . $modnames;
                    break;
            }
            echo '</td>' . "\n";
            echo '<td class="itemselect">';
            $fieldnames = "'{$fieldname}'";
            if ($type == 'duration') {
                $fieldnames .= ",'" . $fieldname . "_unit'";
            }
            $script = $type == 'checkbox' ? 'true' : 'false';
            // sync_checkbox
            $script = "return set_disabled(this.form, new Array({$fieldnames}), (! this.checked), {$script})";
            echo html_writer::checkbox('select_' . $name, 1, optional_param('select_' . $name, 0, PARAM_INT), '', array('onclick' => $script));
            echo '</td>' . "\n";
            echo '</tr>' . "\n";
        }
    }
    // ============================
    // Activity competency
    // ============================
    //
    if ($enablecompetency) {
        print_sectionheading(get_string('competencies', 'competency'), 'competency', true);
        echo '<tr>' . "\n";
        echo '<td class="itemname">' . get_string('uponcoursemodulecompletion', 'tool_lp') . ':</td>' . "\n";
        echo '<td class="itemvalue">';
        echo html_writer::select($competencyrulemenu, 'competencyrule', $competencyrule, '');
        echo html_writer::empty_tag('br') . '(' . get_string('usedbyall', $plugin) . ')';
        echo '</td>' . "\n";
        echo '<td class="itemselect">';
        $script = "return set_disabled(this.form, new Array('competencyrule'), (! this.checked))";
        echo html_writer::checkbox('select_competencyrule', 1, optional_param('select_competencyrule', 0, PARAM_INT), '', array('onclick' => $script));
        echo '</td>' . "\n";
        echo '</tr>' . "\n";
    }
    // ============================
    // Actions
    // ============================
    //
    print_sectionheading(get_string('actions'), 'actions', false);
    echo '<tr>' . "\n";
    echo '<td class="itemname">&nbsp;</td>' . "\n";
    echo '<td class="itemvalue">' . "\n";
    $btn = get_string('applysettings', $plugin);
    $msg = js(get_string('confirmapply', $plugin));
    echo '<input type="submit" name="apply" value="' . $btn . '" onclick="return confirm_action(' . "'{$msg}'" . ', true)" />' . "\n";
    echo ' &nbsp; &nbsp; ' . "\n";
    echo '<input type="submit" name="cancel" value="' . get_string('cancel') . '" />' . "\n";
    echo ' &nbsp; &nbsp; ' . "\n";
    $btn = get_string('delete');
    $msg = js(get_string('confirmdelete', $plugin));
    echo '<input type="submit" name="delete" value="' . $btn . '" onclick="return confirm_action(' . "'{$msg}'" . ')" />' . "\n";
    echo '<input type="hidden" name="id" value="' . $block_instance->id . '" />' . "\n";
    echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />' . "\n";
    echo '</td><td></td>' . "\n";
    echo '</tr>' . "\n";
    echo '</table>' . "\n";
    echo '</form>' . "\n";
}
Example #2
0
/**
 * This file keeps track of upgrades to the certificate module
 *
 * @package    mod_certificate
 * @copyright  Mark Nelson <*****@*****.**>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
function xmldb_certificate_upgrade($oldversion = 0)
{
    global $CFG, $THEME, $DB;
    $dbman = $DB->get_manager();
    // ===== 1.9.0 or older upgrade line ======//
    if ($oldversion < 2007061300) {
        // Add new fields to certificate table
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('emailothers');
        $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'emailteachers');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('printhours');
        $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'gradefmt');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('lockgrade');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'printhours');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('requiredgrade');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'lockgrade');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Rename field save to savecert
        $field = new xmldb_field('save');
        if ($dbman->field_exists($table, $field)) {
            $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'emailothers');
            // Launch rename field savecert
            $dbman->rename_field($table, $field, 'savecert');
        } else {
            $field = new xmldb_field('savecert');
            $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'emailothers');
            $dbman->add_field($table, $field);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2007061300, 'certificate');
    }
    if ($oldversion < 2007061301) {
        $table = new xmldb_table('certificate_linked_modules');
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
        $table->add_field('certificate_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
        $table->add_field('linkid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'certificate_id');
        $table->add_field('linkgrade', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'linkid');
        $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'linkgrade');
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'), null, null);
        $table->add_index('certificate_id', XMLDB_INDEX_NOTUNIQUE, array('certificate_id'));
        $table->add_index('linkid', XMLDB_INDEX_NOTUNIQUE, array('linkid'));
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2007061301, 'certificate');
    }
    if ($oldversion < 2007102800) {
        // Add new fields to certificate table
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('reportcert');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'savecert');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        $table = new xmldb_table('certificate_issues');
        $field = new xmldb_field('reportgrade');
        $field->set_attributes(XMLDB_TYPE_CHAR, '10', null, null, null, null, 'certdate');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2007102800, 'certificate');
    }
    if ($oldversion < 2007102806) {
        // Add new fields to certificate table
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('printoutcome');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'gradefmt');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2007102806, 'certificate');
    }
    if ($oldversion < 2008080904) {
        // Add new fields to certificate table if they dont already exist
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('intro');
        $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'name');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2008080904, 'certificate');
    }
    //===== 2.0 or older upgrade line ======//
    // Note, fresh 1.9 installs add the version 2009080900, so they miss this when upgrading from 1.9 -> 2.0.
    if ($oldversion < 2009062900) {
        // Add new field to certificate table
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'intro');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        $field = new xmldb_field('orientation', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, ' ', 'certificatetype');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        $field = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'reportcert');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Set default orientation accordingly
        $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'portrait'));
        $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'letter_portrait'));
        $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'unicode_portrait'));
        $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'landscape'));
        $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'letter_landscape'));
        $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'unicode_landscape'));
        // Update all the certificate types
        $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'landscape'));
        $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'portrait'));
        $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_landscape'));
        $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_portrait'));
        $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_landscape'));
        $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_portrait'));
        // savepoint reached
        upgrade_mod_savepoint(true, 2009062900, 'certificate');
    }
    if ($oldversion < 2011030105) {
        // Define field id to be added to certificate
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, 0, 'intro');
        // Conditionally launch add field id
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2011030105, 'certificate');
    }
    // The Moodle 2.0 CVS certificate version sets it to 2011110101, if the user performed an upgrade
    // then this upgrade will take care of several issues, if it's a fresh install then nothing is done.
    if ($oldversion < 2011110102) {
        require_once $CFG->libdir . '/conditionlib.php';
        $table = new xmldb_table('certificate');
        // It is possible for these fields not to be added, ever, it is included in the upgrade
        // process but fresh certificate 1.9 install from CVS MOODLE_19_STABLE set the Moodle version
        // to 2009080900, which means it missed all the earlier code written for upgrading to 2.0.
        $reissuefield = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'reportcert');
        $orientationfield = new xmldb_field('orientation', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, ' ', 'certificatetype');
        // Have to check, may be added during earlier upgrade, or may be missing due to not being included in install.xml
        if (!$dbman->field_exists($table, $reissuefield)) {
            $dbman->add_field($table, $reissuefield);
        }
        if (!$dbman->field_exists($table, $orientationfield)) {
            $dbman->add_field($table, $orientationfield);
        }
        // Fresh 2.0 installs won't have this table, but upgrades from 1.9 will
        if ($dbman->table_exists('certificate_linked_modules')) {
            // No longer need lock grade, or required grade, but first need to
            // convert so that the restrictions are still in place for Moodle 2.0
            if ($certs = $DB->get_records('certificate')) {
                foreach ($certs as $cert) {
                    if ($cert->lockgrade == 0) {
                        // Can skip this certificate, no course grade required
                        continue;
                    }
                    if (!($cm = get_coursemodule_from_instance('certificate', $cert->id))) {
                        // Not valid skip it
                        continue;
                    }
                    if (!($gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'itemtype' => 'course')))) {
                        // Not valid skip it
                        continue;
                    }
                    $condition_info = new condition_info($cm, CONDITION_MISSING_EVERYTHING);
                    $condition_info->add_grade_condition($gradeitem->id, $cert->requiredgrade, '110');
                }
            }
            // Fresh installs won't have this table, but upgrades will
            // Lock grade and required grade field are not needed anymore
            if ($dbman->field_exists($table, 'lockgrade')) {
                $field = new xmldb_field('lockgrade');
                $dbman->drop_field($table, $field);
            }
            if ($dbman->field_exists($table, 'requiredgrade')) {
                $field = new xmldb_field('requiredgrade');
                $dbman->drop_field($table, $field);
            }
            // Now we need to loop through the restrictions in the certificate_linked_modules
            // table and convert it into the new Moodle 2.0 restrictions
            if ($certlinks = $DB->get_records('certificate_linked_modules')) {
                foreach ($certlinks as $link) {
                    // If the link id is '-1' then the setting applies to the time spent in the course and is not
                    // related to a module, meaning we can skip it for this section
                    if ($link->linkid == '-1') {
                        continue;
                    }
                    // Get the course module
                    if (!($cm = get_coursemodule_from_instance('certificate', $link->certificate_id))) {
                        // Not valid skip it
                        continue;
                    }
                    // Get grade item for module specified - is there an API function for this ??
                    $sql = "SELECT gi.id\n                            FROM {course_modules} cm\n                            INNER JOIN {modules} m\n                            ON cm.module = m.id\n                            INNER JOIN {grade_items} gi\n                            ON m.name = gi.itemmodule\n                            WHERE cm.id = :cmid\n                            AND cm.course = :courseid\n                            AND cm.instance = gi.iteminstance";
                    if (!($gradeitem = $DB->get_record_sql($sql, array('cmid' => $link->linkid, 'courseid' => $cm->course)))) {
                        // Not valid skip it
                        continue;
                    }
                    $condition_info = new condition_info($cm, CONDITION_MISSING_EVERYTHING);
                    $condition_info->add_grade_condition($gradeitem->id, $link->linkgrade, '110', true);
                }
            }
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2011110102, 'certificate');
    }
    // Note - the date has not changed as it has been set in the future, so I am incrementing
    // last digits. Actual date - 15/09/11
    if ($oldversion < 2011110103) {
        // New orientation field needs a value in order to view the cert, otherwise you get
        // an issue with FPDF and invalid orientation. This should be done during the upgrade,
        // but due to version number issues it is possible it was not executed, so do it now.
        $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'portrait'));
        $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'letter_portrait'));
        $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'unicode_portrait'));
        $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'landscape'));
        $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'letter_landscape'));
        $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'unicode_landscape'));
        // If the certificate type does not match any of the orientations in the above then set to 'L'
        $sql = "UPDATE {certificate}\n                SET orientation = 'L'\n                WHERE orientation = ''";
        $DB->execute($sql);
        // Update all the certificate types
        $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'landscape'));
        $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'portrait'));
        $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_landscape'));
        $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_portrait'));
        $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_landscape'));
        $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_portrait'));
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2011110103, 'certificate');
    }
    if ($oldversion < 2012022001) {
        // CONTRIB-3470 - certdate remaining 0 on issued certificates, need to update
        $sql = "UPDATE {certificate_issues}\n                SET certdate = timecreated\n                WHERE certdate = 0";
        $DB->execute($sql);
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2012022001, 'certificate');
    }
    if ($oldversion < 2012060901) {
        // Editing this table
        $table = new xmldb_table('certificate');
        // Get rid of the reissue cert column, this was a hack introduced later
        // in 1.9 when the bug was brought up that grades were not refreshing
        // since they were being stored in the issues table.
        // The certificate will now always return the current grade, student name
        // and course name.
        $field = new xmldb_field('reissuecert');
        if ($dbman->field_exists($table, $field)) {
            $dbman->drop_field($table, $field);
        }
        // The poor certificate_issues table is going to have a lot of
        // duplicates, we don't need that now, just keep the latest one
        $sql = "SELECT MAX(id) id1, MAX(id) as id2\n                FROM {certificate_issues}\n                GROUP BY certificateid, userid";
        if ($arrids = $DB->get_records_sql_menu($sql)) {
            $idstokeep = implode(",", $arrids);
            $sql = "DELETE\n                    FROM {certificate_issues}\n                    WHERE id NOT IN ({$idstokeep})";
            $DB->execute($sql);
        }
        // Going to be editing this table
        $table = new xmldb_table('certificate_issues');
        // Conditionally remove columns no longer needed
        $field = new xmldb_field('studentname');
        if ($dbman->field_exists($table, $field)) {
            $dbman->drop_field($table, $field);
        }
        $field = new xmldb_field('classname');
        if ($dbman->field_exists($table, $field)) {
            $dbman->drop_field($table, $field);
        }
        $field = new xmldb_field('certdate');
        if ($dbman->field_exists($table, $field)) {
            $dbman->drop_field($table, $field);
        }
        $field = new xmldb_field('reportgrade');
        if ($dbman->field_exists($table, $field)) {
            $dbman->drop_field($table, $field);
        }
        $field = new xmldb_field('mailed');
        if ($dbman->field_exists($table, $field)) {
            $dbman->drop_field($table, $field);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2012060901, 'certificate');
    }
    if ($oldversion < 2012072501) {
        // Add a column to store the required grade
        $table = new xmldb_table('certificate');
        $requiredtimefield = new xmldb_field('requiredtime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'delivery');
        if (!$dbman->field_exists($table, $requiredtimefield)) {
            $dbman->add_field($table, $requiredtimefield);
        }
        // If this table still exists, then the install was from a 1.9 version
        if ($dbman->table_exists('certificate_linked_modules')) {
            // Now we need to loop through the restrictions in the certificate_linked_modules
            // table and check if there were any required time conditions
            if ($certlinks = $DB->get_records('certificate_linked_modules')) {
                foreach ($certlinks as $link) {
                    // If the link id is '-1' then the setting applies to the time spent in the course
                    if ($link->linkid == '-1') {
                        // Make sure the certificate exists
                        if ($certificate = $DB->get_record('certificate', array('id' => $link->certificate_id))) {
                            $certificate->requiredtime = $link->linkgrade;
                            $DB->update_record('certificate', $certificate);
                        }
                    }
                }
            }
            // We can now get rid of this table
            $table = new xmldb_table('certificate_linked_modules');
            $dbman->drop_table($table);
        }
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2012072501, 'certificate');
    }
    if ($oldversion < 2012082401) {
        $table = new xmldb_table('certificate');
        // Change length of the fields that store images, so longer image names can be stored
        $field = new xmldb_field('borderstyle', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0);
        $dbman->change_field_precision($table, $field);
        $field = new xmldb_field('printwmark', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0);
        $dbman->change_field_precision($table, $field);
        $field = new xmldb_field('printsignature', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0);
        $dbman->change_field_precision($table, $field);
        $field = new xmldb_field('printseal', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0);
        $dbman->change_field_precision($table, $field);
        // Change length of fields that are unnecessarily large
        $field = new xmldb_field('printnumber', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0);
        $dbman->change_field_precision($table, $field);
        $field = new xmldb_field('printhours', XMLDB_TYPE_CHAR, '255', null, false, 0, 0);
        $dbman->change_field_precision($table, $field);
        $field = new xmldb_field('emailteachers', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0);
        $dbman->change_field_precision($table, $field);
        $field = new xmldb_field('savecert', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0);
        $dbman->change_field_precision($table, $field);
        $field = new xmldb_field('reportcert', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0);
        $dbman->change_field_precision($table, $field);
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2012082401, 'certificate');
    }
    if ($oldversion < 2012090901) {
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, 0, 0, 'printseal');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Set the time created to the time modified
        $sql = "UPDATE {certificate}\n                SET timecreated = timemodified";
        $DB->execute($sql);
        // Certificate savepoint reached
        upgrade_mod_savepoint(true, 2012090901, 'certificate');
    }
    if ($oldversion < 2014041802) {
        // Fix previous upgrades.
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('borderstyle', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0');
        $dbman->change_field_default($table, $field);
        $field = new xmldb_field('printwmark', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0');
        $dbman->change_field_default($table, $field);
        $field = new xmldb_field('printhours', XMLDB_TYPE_CHAR, '255', null, false, 0, null);
        $dbman->change_field_default($table, $field);
        $field = new xmldb_field('printsignature', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0');
        $dbman->change_field_default($table, $field);
        $field = new xmldb_field('printseal', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0');
        $dbman->change_field_default($table, $field);
        // Certificate savepoint reached.
        upgrade_mod_savepoint(true, 2014041802, 'certificate');
    }
    return true;
}
Example #3
0
/**
 * Prints a section full of activity modules
 */
function print_section($course, $section, $mods, $modnamesused, $absolute = false, $width = "100%", $hidecompletion = false)
{
    global $CFG, $USER, $DB, $PAGE, $OUTPUT;
    static $initialised;
    static $groupbuttons;
    static $groupbuttonslink;
    static $isediting;
    static $ismoving;
    static $strmovehere;
    static $strmovefull;
    static $strunreadpostsone;
    static $groupings;
    static $modulenames;
    if (!isset($initialised)) {
        $groupbuttons = ($course->groupmode or !$course->groupmodeforce);
        $groupbuttonslink = !$course->groupmodeforce;
        $isediting = $PAGE->user_is_editing();
        $ismoving = $isediting && ismoving($course->id);
        if ($ismoving) {
            $strmovehere = get_string("movehere");
            $strmovefull = strip_tags(get_string("movefull", "", "'{$USER->activitycopyname}'"));
        }
        $modulenames = array();
        $initialised = true;
    }
    $modinfo = get_fast_modinfo($course);
    $completioninfo = new completion_info($course);
    //Accessibility: replace table with list <ul>, but don't output empty list.
    if (!empty($section->sequence)) {
        // Fix bug #5027, don't want style=\"width:$width\".
        echo "<ul class=\"section img-text\">\n";
        $sectionmods = explode(",", $section->sequence);
        foreach ($sectionmods as $modnumber) {
            if (empty($mods[$modnumber])) {
                continue;
            }
            /**
             * @var cm_info
             */
            $mod = $mods[$modnumber];
            if ($ismoving and $mod->id == $USER->activitycopy) {
                // do not display moving mod
                continue;
            }
            if (isset($modinfo->cms[$modnumber])) {
                // We can continue (because it will not be displayed at all)
                // if:
                // 1) The activity is not visible to users
                // and
                // 2a) The 'showavailability' option is not set (if that is set,
                //     we need to display the activity so we can show
                //     availability info)
                // or
                // 2b) The 'availableinfo' is empty, i.e. the activity was
                //     hidden in a way that leaves no info, such as using the
                //     eye icon.
                if (!$modinfo->cms[$modnumber]->uservisible && (empty($modinfo->cms[$modnumber]->showavailability) || empty($modinfo->cms[$modnumber]->availableinfo))) {
                    // visibility shortcut
                    continue;
                }
            } else {
                if (!file_exists("{$CFG->dirroot}/mod/{$mod->modname}/lib.php")) {
                    // module not installed
                    continue;
                }
                if (!coursemodule_visible_for_user($mod) && empty($mod->showavailability)) {
                    // full visibility check
                    continue;
                }
            }
            if (!isset($modulenames[$mod->modname])) {
                $modulenames[$mod->modname] = get_string('modulename', $mod->modname);
            }
            $modulename = $modulenames[$mod->modname];
            // In some cases the activity is visible to user, but it is
            // dimmed. This is done if viewhiddenactivities is true and if:
            // 1. the activity is not visible, or
            // 2. the activity has dates set which do not include current, or
            // 3. the activity has any other conditions set (regardless of whether
            //    current user meets them)
            $canviewhidden = has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $mod->id));
            $accessiblebutdim = false;
            if ($canviewhidden) {
                $accessiblebutdim = !$mod->visible;
                if (!empty($CFG->enableavailability)) {
                    $accessiblebutdim = $accessiblebutdim || $mod->availablefrom > time() || $mod->availableuntil && $mod->availableuntil < time() || count($mod->conditionsgrade) > 0 || count($mod->conditionscompletion) > 0;
                }
            }
            $liclasses = array();
            $liclasses[] = 'activity';
            $liclasses[] = $mod->modname;
            $liclasses[] = 'modtype_' . $mod->modname;
            $extraclasses = $mod->get_extra_classes();
            if ($extraclasses) {
                $liclasses = array_merge($liclasses, explode(' ', $extraclasses));
            }
            echo html_writer::start_tag('li', array('class' => join(' ', $liclasses), 'id' => 'module-' . $modnumber));
            if ($ismoving) {
                echo '<a title="' . $strmovefull . '"' . ' href="' . $CFG->wwwroot . '/course/mod.php?moveto=' . $mod->id . '&amp;sesskey=' . sesskey() . '">' . '<img class="movetarget" src="' . $OUTPUT->pix_url('movehere') . '" ' . ' alt="' . $strmovehere . '" /></a><br />
                     ';
            }
            $classes = array('mod-indent');
            if (!empty($mod->indent)) {
                $classes[] = 'mod-indent-' . $mod->indent;
                if ($mod->indent > 15) {
                    $classes[] = 'mod-indent-huge';
                }
            }
            echo html_writer::start_tag('div', array('class' => join(' ', $classes)));
            // Get data about this course-module
            list($content, $instancename) = get_print_section_cm_text($modinfo->cms[$modnumber], $course);
            //Accessibility: for files get description via icon, this is very ugly hack!
            $altname = '';
            $altname = $mod->modfullname;
            if (!empty($customicon)) {
                $archetype = plugin_supports('mod', $mod->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
                if ($archetype == MOD_ARCHETYPE_RESOURCE) {
                    $mimetype = mimeinfo_from_icon('type', $customicon);
                    $altname = get_mimetype_description($mimetype);
                }
            }
            // Avoid unnecessary duplication: if e.g. a forum name already
            // includes the word forum (or Forum, etc) then it is unhelpful
            // to include that in the accessible description that is added.
            if (false !== strpos(textlib::strtolower($instancename), textlib::strtolower($altname))) {
                $altname = '';
            }
            // File type after name, for alphabetic lists (screen reader).
            if ($altname) {
                $altname = get_accesshide(' ' . $altname);
            }
            // We may be displaying this just in order to show information
            // about visibility, without the actual link
            $contentpart = '';
            if ($mod->uservisible) {
                // Nope - in this case the link is fully working for user
                $linkclasses = '';
                $textclasses = '';
                if ($accessiblebutdim) {
                    $linkclasses .= ' dimmed';
                    $textclasses .= ' dimmed_text';
                    $accesstext = '<span class="accesshide">' . get_string('hiddenfromstudents') . ': </span>';
                } else {
                    $accesstext = '';
                }
                if ($linkclasses) {
                    $linkcss = 'class="' . trim($linkclasses) . '" ';
                } else {
                    $linkcss = '';
                }
                if ($textclasses) {
                    $textcss = 'class="' . trim($textclasses) . '" ';
                } else {
                    $textcss = '';
                }
                // Get on-click attribute value if specified
                $onclick = $mod->get_on_click();
                if ($onclick) {
                    $onclick = ' onclick="' . $onclick . '"';
                }
                if ($url = $mod->get_url()) {
                    // Display link itself
                    echo '<a ' . $linkcss . $mod->extra . $onclick . ' href="' . $url . '"><img src="' . $mod->get_icon_url() . '" class="activityicon" alt="' . $modulename . '" /> ' . $accesstext . '<span class="instancename">' . $instancename . $altname . '</span></a>';
                    // If specified, display extra content after link
                    if ($content) {
                        $contentpart = '<div class="' . trim('contentafterlink' . $textclasses) . '">' . $content . '</div>';
                    }
                } else {
                    // No link, so display only content
                    $contentpart = '<div ' . $textcss . $mod->extra . '>' . $accesstext . $content . '</div>';
                }
                if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
                    if (!isset($groupings)) {
                        $groupings = groups_get_all_groupings($course->id);
                    }
                    echo " <span class=\"groupinglabel\">(" . format_string($groupings[$mod->groupingid]->name) . ')</span>';
                }
            } else {
                $textclasses = $extraclasses;
                $textclasses .= ' dimmed_text';
                if ($textclasses) {
                    $textcss = 'class="' . trim($textclasses) . '" ';
                } else {
                    $textcss = '';
                }
                $accesstext = '<span class="accesshide">' . get_string('notavailableyet', 'condition') . ': </span>';
                if ($url = $mod->get_url()) {
                    // Display greyed-out text of link
                    echo '<div ' . $textcss . $mod->extra . ' >' . '<img src="' . $mod->get_icon_url() . '" class="activityicon" alt="' . $modulename . '" /> <span>' . $instancename . $altname . '</span></div>';
                    // Do not display content after link when it is greyed out like this.
                } else {
                    // No link, so display only content (also greyed)
                    $contentpart = '<div ' . $textcss . $mod->extra . '>' . $accesstext . $content . '</div>';
                }
            }
            // Module can put text after the link (e.g. forum unread)
            echo $mod->get_after_link();
            // If there is content but NO link (eg label), then display the
            // content here (BEFORE any icons). In this case cons must be
            // displayed after the content so that it makes more sense visually
            // and for accessibility reasons, e.g. if you have a one-line label
            // it should work similarly (at least in terms of ordering) to an
            // activity.
            if (empty($url)) {
                echo $contentpart;
            }
            if ($isediting) {
                if ($groupbuttons and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
                    if (!($mod->groupmodelink = $groupbuttonslink)) {
                        $mod->groupmode = $course->groupmode;
                    }
                } else {
                    $mod->groupmode = false;
                }
                echo '&nbsp;&nbsp;';
                echo make_editing_buttons($mod, $absolute, true, $mod->indent, $section->section);
                echo $mod->get_after_edit_icons();
            }
            // Completion
            $completion = $hidecompletion ? COMPLETION_TRACKING_NONE : $completioninfo->is_enabled($mod);
            if ($completion != COMPLETION_TRACKING_NONE && isloggedin() && !isguestuser() && $mod->uservisible) {
                $completiondata = $completioninfo->get_data($mod, true);
                $completionicon = '';
                if ($isediting) {
                    switch ($completion) {
                        case COMPLETION_TRACKING_MANUAL:
                            $completionicon = 'manual-enabled';
                            break;
                        case COMPLETION_TRACKING_AUTOMATIC:
                            $completionicon = 'auto-enabled';
                            break;
                        default:
                            // wtf
                    }
                } else {
                    if ($completion == COMPLETION_TRACKING_MANUAL) {
                        switch ($completiondata->completionstate) {
                            case COMPLETION_INCOMPLETE:
                                $completionicon = 'manual-n';
                                break;
                            case COMPLETION_COMPLETE:
                                $completionicon = 'manual-y';
                                break;
                        }
                    } else {
                        // Automatic
                        switch ($completiondata->completionstate) {
                            case COMPLETION_INCOMPLETE:
                                $completionicon = 'auto-n';
                                break;
                            case COMPLETION_COMPLETE:
                                $completionicon = 'auto-y';
                                break;
                            case COMPLETION_COMPLETE_PASS:
                                $completionicon = 'auto-pass';
                                break;
                            case COMPLETION_COMPLETE_FAIL:
                                $completionicon = 'auto-fail';
                                break;
                        }
                    }
                }
                if ($completionicon) {
                    $imgsrc = $OUTPUT->pix_url('i/completion-' . $completionicon);
                    $imgalt = s(get_string('completion-alt-' . $completionicon, 'completion', $mod->name));
                    if ($completion == COMPLETION_TRACKING_MANUAL && !$isediting) {
                        $imgtitle = s(get_string('completion-title-' . $completionicon, 'completion', $mod->name));
                        $newstate = $completiondata->completionstate == COMPLETION_COMPLETE ? COMPLETION_INCOMPLETE : COMPLETION_COMPLETE;
                        // In manual mode the icon is a toggle form...
                        // If this completion state is used by the
                        // conditional activities system, we need to turn
                        // off the JS.
                        if (!empty($CFG->enableavailability) && condition_info::completion_value_used_as_condition($course, $mod)) {
                            $extraclass = ' preventjs';
                        } else {
                            $extraclass = '';
                        }
                        echo "\n<form class='togglecompletion{$extraclass}' method='post' action='" . $CFG->wwwroot . "/course/togglecompletion.php'><div>\n<input type='hidden' name='id' value='{$mod->id}' />\n<input type='hidden' name='modulename' value='" . s($mod->name) . "' />\n<input type='hidden' name='sesskey' value='" . sesskey() . "' />\n<input type='hidden' name='completionstate' value='{$newstate}' />\n<input type='image' src='{$imgsrc}' alt='{$imgalt}' title='{$imgtitle}' />\n</div></form>";
                    } else {
                        // In auto mode, or when editing, the icon is just an image
                        echo "<span class='autocompletion'>";
                        echo "<img src='{$imgsrc}' alt='{$imgalt}' title='{$imgalt}' /></span>";
                    }
                }
            }
            // If there is content AND a link, then display the content here
            // (AFTER any icons). Otherwise it was displayed before
            if (!empty($url)) {
                echo $contentpart;
            }
            // Show availability information (for someone who isn't allowed to
            // see the activity itself, or for staff)
            if (!$mod->uservisible) {
                echo '<div class="availabilityinfo">' . $mod->availableinfo . '</div>';
            } else {
                if ($canviewhidden && !empty($CFG->enableavailability)) {
                    $ci = new condition_info($mod);
                    $fullinfo = $ci->get_full_information();
                    if ($fullinfo) {
                        echo '<div class="availabilityinfo">' . get_string($mod->showavailability ? 'userrestriction_visible' : 'userrestriction_hidden', 'condition', $fullinfo) . '</div>';
                    }
                }
            }
            echo html_writer::end_tag('div');
            echo html_writer::end_tag('li') . "\n";
        }
    } elseif ($ismoving) {
        echo "<ul class=\"section\">\n";
    }
    if ($ismoving) {
        echo '<li><a title="' . $strmovefull . '"' . ' href="' . $CFG->wwwroot . '/course/mod.php?movetosection=' . $section->id . '&amp;sesskey=' . sesskey() . '">' . '<img class="movetarget" src="' . $OUTPUT->pix_url('movehere') . '" ' . ' alt="' . $strmovehere . '" /></a></li>
             ';
    }
    if (!empty($section->sequence) || $ismoving) {
        echo "</ul><!--class='section'-->\n\n";
    }
}
Example #4
0
    /**
     * If dynamic data for this course-module is not yet available, gets it.
     *
     * This function is automatically called when requesting any course_modinfo property
     * that can be modified by modules (have a set_xxx method).
     *
     * Dynamic data is data which does not come directly from the cache but is calculated at
     * runtime based on the current user. Primarily this concerns whether the user can access
     * the module or not.
     *
     * As part of this function, the module's _cm_info_dynamic function from its lib.php will
     * be called (if it exists).
     * @return void
     */
    private function obtain_dynamic_data() {
        global $CFG;
        $userid = $this->modinfo->get_user_id();
        if ($this->state >= self::STATE_BUILDING_DYNAMIC || $userid == -1) {
            return;
        }
        $this->state = self::STATE_BUILDING_DYNAMIC;

        if (!empty($CFG->enableavailability)) {
            require_once($CFG->libdir. '/conditionlib.php');
            // Get availability information
            $ci = new condition_info($this);
            // Note that the modinfo currently available only includes minimal details (basic data)
            // but we know that this function does not need anything more than basic data.
            $this->available = $ci->is_available($this->availableinfo, true,
                    $userid, $this->modinfo);

            // Check parent section
            $parentsection = $this->modinfo->get_section_info($this->sectionnum);
            if (!$parentsection->available) {
                // Do not store info from section here, as that is already
                // presented from the section (if appropriate) - just change
                // the flag
                $this->available = false;
            }
        } else {
            $this->available = true;
        }

        // Update visible state for current user
        $this->update_user_visible();

        // Let module make dynamic changes at this point
        $this->call_mod_function('cm_info_dynamic');
        $this->state = self::STATE_DYNAMIC;
    }
function link_to_gdoc($name, $link, $type = null, $modtype = 'url')
{
    global $COURSE, $DB, $CFG, $USER;
    require_once "{$CFG->dirroot}/mod/{$modtype}/lib.php";
    //add
    $fromform = new stdClass();
    $newform = new stdClass();
    $mform = new MoodleQuickForm(null, 'POST', 'nothing');
    $module = $DB->get_record("modules", array('name' => $modtype));
    $course = $COURSE;
    $cw = get_course_section(0, $course->id);
    $cm = null;
    // fields for mdl_url
    $fromform->course = $course->id;
    $fromform->name = $name;
    $fromform->introformat = 0;
    $fromform->introeditor = 0;
    $fromform->externalurl = $link;
    /*    if ($type !== 'dir') {
            $fromform->display          = 6;
            $fromform->displayoptions = 'a:2:{s:10:"popupwidth";i:1024;s:11:"popupheight";i:768;}';
        } else {
    */
    $fromform->display = 0;
    $fromform->popupwidth = 1024;
    $fromform->popupheight = 768;
    $fromform->popupwidth = null;
    $fromform->popupheight = null;
    $fromform->displayoptions = 'a:1:{s:10:"printintro";i:0;}';
    //    }
    // fields for mdl_course_module
    $fromform->module = $module->id;
    $fromform->instance = '';
    $fromform->section = 0;
    // The section number itself - relative!!! (section column in course_sections)
    $fromform->idnumber = null;
    $fromform->score = 0;
    $fromform->indent = 0;
    $fromform->visible = 1;
    $fromform->visibleold = 1;
    $fromform->groupmode = $course->groupmode;
    $fromform->groupingid = 0;
    $fromform->groupmembersonly = 0;
    $fromform->completion = 0;
    $fromform->completionview = 0;
    $fromform->completionexpected = 0;
    $fromform->availablefrom = 0;
    $fromform->availableuntil = 0;
    $fromform->showavailability = 0;
    $fromform->showdescription = 0;
    $fromform->conditiongradegroup = array();
    $fromform->conditionfieldgroup = array();
    // fields for mdl_course_sections
    $fromform->summaryformat = 0;
    $fromform->modulename = clean_param($module->name, PARAM_SAFEDIR);
    // For safety
    //	$fromform->add              = 'resource';
    //	$fromform->type             = $type == 'dir' ? 'collection' : 'file';
    //	$fromform->return           = 0; //must be false if this is an add, go back to course view on cancel
    //    $fromform->coursemodule 	= '';
    //	$fromform->popup			= 'resizable=1,scrollbars=1,directories=1,location=1,menubar=1,toolbar=1,status=1,width=1024,height=768';
    //	require_login($course->id); // needed to setup proper $COURSE
    $context = get_context_instance(CONTEXT_COURSE, $course->id);
    require_capability('moodle/course:manageactivities', $context);
    if (!empty($course->groupmodeforce) or !isset($fromform->groupmode)) {
        $fromform->groupmode = 0;
        // do not set groupmode
    }
    if (!course_allowed_module($course, $fromform->modulename)) {
        print_error('moduledisable', '', '', $fromform->modulename);
    }
    // first add course_module record because we need the context
    $newcm = new stdClass();
    $newcm->course = $course->id;
    $newcm->module = $fromform->module;
    $newcm->instance = 0;
    // not known yet, will be updated later (this is similar to restore code)
    $newcm->visible = $fromform->visible;
    $newcm->groupmode = $fromform->groupmode;
    $newcm->groupingid = $fromform->groupingid;
    $newcm->groupmembersonly = $fromform->groupmembersonly;
    $completion = new completion_info($course);
    if ($completion->is_enabled()) {
        $newcm->completion = $fromform->completion;
        $newcm->completiongradeitemnumber = $fromform->completiongradeitemnumber;
        $newcm->completionview = $fromform->completionview;
        $newcm->completionexpected = $fromform->completionexpected;
    }
    if (!empty($CFG->enableavailability)) {
        $newcm->availablefrom = $fromform->availablefrom;
        $newcm->availableuntil = $fromform->availableuntil;
        $newcm->showavailability = $fromform->showavailability;
    }
    if (isset($fromform->showdescription)) {
        $newcm->showdescription = $fromform->showdescription;
    } else {
        $newcm->showdescription = 0;
    }
    if (!($fromform->coursemodule = add_course_module($newcm))) {
        print_error('cannotaddcoursemodule');
    }
    if (plugin_supports('mod', $fromform->modulename, FEATURE_MOD_INTRO, true)) {
        $draftid_editor = file_get_submitted_draft_itemid('introeditor');
        file_prepare_draft_area($draftid_editor, null, null, null, null);
        $fromform->introeditor = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => $draftid_editor);
        // TODO: add better default
    }
    if (plugin_supports('mod', $fromform->modulename, FEATURE_MOD_INTRO, true)) {
        $introeditor = $fromform->introeditor;
        unset($fromform->introeditor);
        $fromform->intro = $introeditor['text'];
        $fromform->introformat = $introeditor['format'];
    }
    $addinstancefunction = $fromform->modulename . "_add_instance";
    $updateinstancefunction = $fromform->modulename . "_update_instance";
    $returnfromfunc = $addinstancefunction($fromform, $mform);
    //	$returnfromfunc = url_add_instance($fromform, $mform);
    if (!$returnfromfunc or !is_number($returnfromfunc)) {
        // undo everything we can
        $modcontext = get_context_instance(CONTEXT_MODULE, $fromform->coursemodule);
        delete_context(CONTEXT_MODULE, $fromform->coursemodule);
        $DB->delete_records('course_modules', array('id' => $fromform->coursemodule));
        if (!is_number($returnfromfunc)) {
            print_error('invalidfunction', '', course_get_url($course, $cw->section));
        } else {
            print_error('cannotaddnewmodule', '', course_get_url($course, $cw->section), $fromform->modulename);
        }
    }
    $fromform->instance = $returnfromfunc;
    $DB->set_field('course_modules', 'instance', $returnfromfunc, array('id' => $fromform->coursemodule));
    // update embedded links and save files
    $modcontext = get_context_instance(CONTEXT_MODULE, $fromform->coursemodule);
    if (!empty($introeditor)) {
        $fromform->intro = file_save_draft_area_files($introeditor['itemid'], $modcontext->id, 'mod_' . $fromform->modulename, 'intro', 0, array('subdirs' => true), $introeditor['text']);
        $DB->set_field($fromform->modulename, 'intro', $fromform->intro, array('id' => $fromform->instance));
    }
    // course_modules and course_sections each contain a reference
    // to each other, so we have to update one of them twice.
    $sectionid = add_mod_to_section($fromform);
    $DB->set_field('course_modules', 'section', $sectionid, array('id' => $fromform->coursemodule));
    // make sure visibility is set correctly (in particular in calendar)
    set_coursemodule_visible($fromform->coursemodule, $fromform->visible);
    if (isset($fromform->cmidnumber)) {
        //label
        // set cm idnumber
        set_coursemodule_idnumber($fromform->coursemodule, $fromform->cmidnumber);
    }
    // Set up conditions
    if ($CFG->enableavailability) {
        condition_info::update_cm_from_form((object) array('id' => $fromform->coursemodule), $fromform, false);
    }
    $eventname = 'mod_created';
    add_to_log($course->id, "course", "add mod", "../mod/{$fromform->modulename}/view.php?id={$fromform->coursemodule}", "{$fromform->modulename} {$fromform->instance}");
    add_to_log($course->id, $fromform->modulename, "add", "view.php?id={$fromform->coursemodule}", "{$fromform->instance}", $fromform->coursemodule);
    // Trigger mod_created/mod_updated event with information about this module.
    $eventdata = new stdClass();
    $eventdata->modulename = $fromform->modulename;
    $eventdata->name = $fromform->name;
    $eventdata->cmid = $fromform->coursemodule;
    $eventdata->courseid = $course->id;
    $eventdata->userid = $USER->id;
    events_trigger($eventname, $eventdata);
    rebuild_course_cache($course->id);
    return 1;
}
Example #6
0
 /**
  * If dynamic data for this course-module is not yet available, gets it.
  *
  * This function is automatically called when constructing course_modinfo, so users don't
  * need to call it.
  *
  * Dynamic data is data which does not come directly from the cache but is calculated at
  * runtime based on the current user. Primarily this concerns whether the user can access
  * the module or not.
  *
  * As part of this function, the module's _cm_info_dynamic function from its lib.php will
  * be called (if it exists).
  * @return void
  */
 public function obtain_dynamic_data()
 {
     global $CFG;
     if ($this->state >= self::STATE_DYNAMIC) {
         return;
     }
     $userid = $this->modinfo->get_user_id();
     if (!empty($CFG->enableavailability)) {
         // Get availability information
         $ci = new condition_info($this);
         // Note that the modinfo currently available only includes minimal details (basic data)
         // so passing it to this function is a bit dangerous as it would cause infinite
         // recursion if it tried to get dynamic data, however we know that this function only
         // uses basic data.
         $this->available = $ci->is_available($this->availableinfo, true, $userid, $this->modinfo);
     } else {
         $this->available = true;
     }
     // Update visible state for current user
     $this->update_user_visible();
     // Let module make dynamic changes at this point
     $this->call_mod_function('cm_info_dynamic');
     $this->state = self::STATE_DYNAMIC;
 }
 public function definition_after_data()
 {
     global $CFG, $DB;
     $mform = $this->_form;
     $course = $this->_customdata['course'];
     $context = context_course::instance($course->id);
     if (!empty($CFG->enableavailability)) {
         $mform->addElement('header', 'availabilityconditions', get_string('availabilityconditions', 'condition'));
         $mform->setExpanded('availabilityconditions', false);
         // String used by conditions more than once
         $strcondnone = get_string('none', 'condition');
         // Grouping conditions - only if grouping is enabled at site level
         if (!empty($CFG->enablegroupmembersonly)) {
             $options = array();
             if ($groupings = $DB->get_records('groupings', array('courseid' => $course->id))) {
                 foreach ($groupings as $grouping) {
                     $options[$grouping->id] = format_string($grouping->name, true, array('context' => $context));
                 }
             }
             collatorlib::asort($options);
             $options = array(0 => get_string('none')) + $options;
             $mform->addElement('select', 'groupingid', get_string('groupingsection', 'group'), $options);
             $mform->addHelpButton('groupingid', 'groupingsection', 'group');
         }
         // Available from/to defaults to midnight because then the display
         // will be nicer where it tells users when they can access it (it
         // shows only the date and not time).
         $date = usergetdate(time());
         $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
         // Date and time conditions.
         $mform->addElement('date_time_selector', 'availablefrom', get_string('availablefrom', 'condition'), array('optional' => true, 'defaulttime' => $midnight));
         $mform->addElement('date_time_selector', 'availableuntil', get_string('availableuntil', 'condition'), array('optional' => true, 'defaulttime' => $midnight));
         // Conditions based on grades
         $gradeoptions = array();
         $items = grade_item::fetch_all(array('courseid' => $course->id));
         $items = $items ? $items : array();
         foreach ($items as $id => $item) {
             $gradeoptions[$id] = $item->get_name();
         }
         asort($gradeoptions);
         $gradeoptions = array(0 => $strcondnone) + $gradeoptions;
         $grouparray = array();
         $grouparray[] = $mform->createElement('select', 'conditiongradeitemid', '', $gradeoptions);
         $grouparray[] = $mform->createElement('static', '', '', ' ' . get_string('grade_atleast', 'condition') . ' ');
         $grouparray[] = $mform->createElement('text', 'conditiongrademin', '', array('size' => 3));
         $grouparray[] = $mform->createElement('static', '', '', '% ' . get_string('grade_upto', 'condition') . ' ');
         $grouparray[] = $mform->createElement('text', 'conditiongrademax', '', array('size' => 3));
         $grouparray[] = $mform->createElement('static', '', '', '%');
         $group = $mform->createElement('group', 'conditiongradegroup', get_string('gradecondition', 'condition'), $grouparray);
         // Get full version (including condition info) of section object
         $ci = new condition_info_section($this->_customdata['cs']);
         $fullcs = $ci->get_full_section();
         $count = count($fullcs->conditionsgrade) + 1;
         // Grade conditions
         $this->repeat_elements(array($group), $count, array('conditiongradegroup[conditiongrademin]' => array('type' => PARAM_RAW), 'conditiongradegroup[conditiongrademax]' => array('type' => PARAM_RAW)), 'conditiongraderepeats', 'conditiongradeadds', 2, get_string('addgrades', 'condition'), true);
         $mform->addHelpButton('conditiongradegroup[0]', 'gradecondition', 'condition');
         // Conditions based on user fields
         $operators = condition_info::get_condition_user_field_operators();
         $useroptions = condition_info::get_condition_user_fields(array('context' => $context));
         asort($useroptions);
         $useroptions = array(0 => $strcondnone) + $useroptions;
         $grouparray = array();
         $grouparray[] =& $mform->createElement('select', 'conditionfield', '', $useroptions);
         $grouparray[] =& $mform->createElement('select', 'conditionfieldoperator', '', $operators);
         $grouparray[] =& $mform->createElement('text', 'conditionfieldvalue');
         $group = $mform->createElement('group', 'conditionfieldgroup', get_string('userfield', 'condition'), $grouparray);
         $fieldcount = count($fullcs->conditionsfield) + 1;
         $this->repeat_elements(array($group), $fieldcount, array('conditionfieldgroup[conditionfieldvalue]' => array('type' => PARAM_RAW)), 'conditionfieldrepeats', 'conditionfieldadds', 2, get_string('adduserfields', 'condition'), true);
         $mform->addHelpButton('conditionfieldgroup[0]', 'userfield', 'condition');
         // Conditions based on completion
         $completion = new completion_info($course);
         if ($completion->is_enabled()) {
             $completionoptions = array();
             $modinfo = get_fast_modinfo($course);
             foreach ($modinfo->cms as $id => $cm) {
                 // Add each course-module if it:
                 // (a) has completion turned on
                 // (b) does not belong to current course-section
                 if ($cm->completion && $fullcs->id != $cm->section) {
                     $completionoptions[$id] = $cm->name;
                 }
             }
             asort($completionoptions);
             $completionoptions = array(0 => $strcondnone) + $completionoptions;
             $completionvalues = array(COMPLETION_COMPLETE => get_string('completion_complete', 'condition'), COMPLETION_INCOMPLETE => get_string('completion_incomplete', 'condition'), COMPLETION_COMPLETE_PASS => get_string('completion_pass', 'condition'), COMPLETION_COMPLETE_FAIL => get_string('completion_fail', 'condition'));
             $grouparray = array();
             $grouparray[] = $mform->createElement('select', 'conditionsourcecmid', '', $completionoptions);
             $grouparray[] = $mform->createElement('select', 'conditionrequiredcompletion', '', $completionvalues);
             $group = $mform->createElement('group', 'conditioncompletiongroup', get_string('completioncondition', 'condition'), $grouparray);
             $count = count($fullcs->conditionscompletion) + 1;
             $this->repeat_elements(array($group), $count, array(), 'conditioncompletionrepeats', 'conditioncompletionadds', 2, get_string('addcompletions', 'condition'), true);
             $mform->addHelpButton('conditioncompletiongroup[0]', 'completionconditionsection', 'condition');
         }
         // Availability conditions - set up form values
         if (!empty($CFG->enableavailability)) {
             $num = 0;
             foreach ($fullcs->conditionsgrade as $gradeitemid => $minmax) {
                 $groupelements = $mform->getElement('conditiongradegroup[' . $num . ']')->getElements();
                 $groupelements[0]->setValue($gradeitemid);
                 $groupelements[2]->setValue(is_null($minmax->min) ? '' : format_float($minmax->min, 5, true, true));
                 $groupelements[4]->setValue(is_null($minmax->max) ? '' : format_float($minmax->max, 5, true, true));
                 $num++;
             }
             $num = 0;
             foreach ($fullcs->conditionsfield as $fieldid => $data) {
                 $groupelements = $mform->getElement('conditionfieldgroup[' . $num . ']')->getElements();
                 $groupelements[0]->setValue($fieldid);
                 $groupelements[1]->setValue(is_null($data->operator) ? '' : $data->operator);
                 $groupelements[2]->setValue(is_null($data->value) ? '' : $data->value);
                 $num++;
             }
             if ($completion->is_enabled()) {
                 $num = 0;
                 foreach ($fullcs->conditionscompletion as $othercmid => $state) {
                     $groupelements = $mform->getElement('conditioncompletiongroup[' . $num . ']')->getElements();
                     $groupelements[0]->setValue($othercmid);
                     $groupelements[1]->setValue($state);
                     $num++;
                 }
             }
         }
         // Do we display availability info to students?
         $showhide = array(CONDITION_STUDENTVIEW_SHOW => get_string('showavailabilitysection_show', 'condition'), CONDITION_STUDENTVIEW_HIDE => get_string('showavailabilitysection_hide', 'condition'));
         $mform->addElement('select', 'showavailability', get_string('showavailabilitysection', 'condition'), $showhide);
     }
     $this->add_action_buttons();
 }
Example #8
0
 public function inspect_get_cached_user_profile_field($userid, $fieldid) {
     return parent::get_cached_user_profile_field($userid, $fieldid);
 }
             $DB->set_field($fromform->modulename, 'intro', $fromform->intro, array('id' => $fromform->instance));
         }
         // course_modules and course_sections each contain a reference
         // to each other, so we have to update one of them twice.
         $sectionid = add_mod_to_section($fromform);
         $DB->set_field('course_modules', 'section', $sectionid, array('id' => $fromform->coursemodule));
         // make sure visibility is set correctly (in particular in calendar)
         set_coursemodule_visible($fromform->coursemodule, $fromform->visible);
         if (isset($fromform->cmidnumber)) {
             //label
             // set cm idnumber - uniqueness is already verified by form validation
             set_coursemodule_idnumber($fromform->coursemodule, $fromform->cmidnumber);
         }
         // Set up conditions
         if ($CFG->enableavailability) {
             condition_info::update_cm_from_form((object) array('id' => $fromform->coursemodule), $fromform, false);
         }
         // Trigger mod_created event with information about this module.
         $eventdata = new stdClass();
         $eventdata->modulename = $fromform->modulename;
         $eventdata->name = $fromform->name;
         $eventdata->cmid = $fromform->coursemodule;
         $eventdata->courseid = $course->id;
         $eventdata->userid = $USER->id;
         events_trigger('mod_created', $eventdata);
         add_to_log($course->id, "course", "add mod", "../mod/{$fromform->modulename}/view.php?id={$fromform->coursemodule}", "{$fromform->modulename} {$fromform->instance}");
         add_to_log($course->id, $fromform->modulename, "add", "view.php?id={$fromform->coursemodule}", "{$fromform->instance}", $fromform->coursemodule);
     } else {
         print_error('invaliddata');
     }
 }
Example #10
0
 function get_course_mods($id, $username = '')
 {
     global $CFG, $DB;
     $username = utf8_decode($username);
     $username = strtolower($username);
     if ($username) {
         $user = get_complete_user_data('username', $username);
     }
     $sections = get_all_sections($id);
     $forum = forum_get_course_forum($id, 'news');
     $news_forum_id = $forum->id;
     get_all_mods($id, $mods, $modnames, $modnamesplural, $modnamesused);
     $context = get_context_instance(CONTEXT_COURSE, $id);
     $e = array();
     foreach ($sections as $section) {
         if (!$section->visible) {
             continue;
         }
         $sectionmods = explode(",", $section->sequence);
         foreach ($sectionmods as $modnumber) {
             if (empty($mods[$modnumber])) {
                 continue;
             }
             $mod = $mods[$modnumber];
             $resource['completion_info'] = '';
             if ($username) {
                 $cm = get_coursemodule_from_id(false, $mod->id);
                 if (!coursemodule_visible_for_user($cm, $user->id)) {
                     if (!$mod->showavailability) {
                         // Mod not visible, and no completion info to show
                         continue;
                     }
                     $resource['available'] = 0;
                     $ci = new condition_info($mod);
                     $resource['completion_info'] = $ci->get_full_information();
                 } else {
                     $resource['available'] = 1;
                 }
             } else {
                 $resource['available'] = 1;
             }
             $e[$section->section]['section'] = $section->section;
             $e[$section->section]['name'] = $section->name;
             $e[$section->section]['summary'] = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $context->id, 'course', 'section', $section->id);
             $e[$section->section]['summary'] = str_replace('pluginfile.php', '/auth/joomdle/pluginfile_joomdle.php', $e[$section->section]['summary']);
             $resource['id'] = $mod->id;
             $resource['name'] = $mod->name;
             $resource['mod'] = $mod->modname;
             // Format for mod->icon is: f/type-24
             $type = substr($mod->icon, 2);
             $parts = explode('-', $type);
             $type = $parts[0];
             $resource['type'] = $type;
             //In forum, type is unused, so we use it for forum type: news/general
             if ($mod->modname == 'forum') {
                 $cm = get_coursemodule_from_id('forum', $mod->id);
                 if ($cm->instance == $news_forum_id) {
                     $resource['type'] = 'news';
                 }
             }
             $e[$section->section]['mods'][] = $resource;
         }
     }
     return $e;
 }
Example #11
0
/**
 * This function checks that the current user is logged in and has the
 * required privileges
 *
 * This function checks that the current user is logged in, and optionally
 * whether they are allowed to be in a particular course and view a particular
 * course module.
 * If they are not logged in, then it redirects them to the site login unless
 * $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which
 * case they are automatically logged in as guests.
 * If $courseid is given and the user is not enrolled in that course then the
 * user is redirected to the course enrolment page.
 * If $cm is given and the coursemodule is hidden and the user is not a teacher
 * in the course then the user is redirected to the course home page.
 *
 * @uses $CFG
 * @uses $SESSION
 * @uses $USER
 * @uses $FULLME
 * @uses SITEID
 * @uses $COURSE
 * @param mixed $courseorid id of the course or course object
 * @param bool $autologinguest
 * @param object $cm course module object
 * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to
 *             true. Used to avoid (=false) some scripts (file.php...) to set that variable,
 *             in order to keep redirects working properly. MDL-14495
 */
function require_login($courseorid = 0, $autologinguest = true, $cm = null, $setwantsurltome = true)
{
    global $CFG, $SESSION, $USER, $COURSE, $FULLME, $PAGE, $SITE, $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));
                if (!$course) {
                    throw new moodle_exception('invalidcourseid');
                }
            }
        }
        $PAGE->set_course($course);
    } else {
        // If $PAGE->course, and hence $PAGE->context, have not already been set
        // up properly, set them up now.
        $PAGE->set_course($PAGE->course);
    }
    /// If the user is not even logged in yet then make sure they are
    if (!isloggedin()) {
        //NOTE: $USER->site check was obsoleted by session test cookie,
        //      $USER->confirmed test is in login/index.php
        if ($setwantsurltome) {
            $SESSION->wantsurl = $FULLME;
        }
        if (!empty($_SERVER['HTTP_REFERER'])) {
            $SESSION->fromurl = $_SERVER['HTTP_REFERER'];
        }
        if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests) and ($COURSE->id == SITEID or $COURSE->guest)) {
            $loginguest = true;
        } else {
            $loginguest = false;
        }
        redirect(get_login_url($loginguest));
        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()) {
            $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)) {
        $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 checking script parameters.
    sesskey();
    // Check that the user has agreed to a site policy if there is one
    if (!empty($CFG->sitepolicy)) {
        if (!$USER->policyagreed) {
            $SESSION->wantsurl = $FULLME;
            redirect($CFG->wwwroot . '/user/policy.php');
        }
    }
    // Fetch the system context, we are going to use it a lot.
    $sysctx = get_context_instance(CONTEXT_SYSTEM);
    /// If the site is currently under maintenance, then print a message
    if (!has_capability('moodle/site:config', $sysctx)) {
        if (file_exists($CFG->dataroot . '/' . SITEID . '/maintenance.html')) {
            print_maintenance_message();
            exit;
        }
    }
    /// groupmembersonly access control
    if (!empty($CFG->enablegroupings) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) {
        if (isguestuser() or !groups_has_membership($cm)) {
            print_error('groupmembersonlyerror', 'group', $CFG->wwwroot . '/course/view.php?id=' . $cm->course);
        }
    }
    // Fetch the course context, and prefetch its child contexts
    if (!isset($COURSE->context)) {
        if (!($COURSE->context = get_context_instance(CONTEXT_COURSE, $COURSE->id))) {
            print_error('nocontext');
        }
    }
    if (!empty($cm) && !isset($cm->context)) {
        if (!($cm->context = get_context_instance(CONTEXT_MODULE, $cm->id))) {
            print_error('nocontext');
        }
    }
    // Conditional activity access control
    if (!empty($CFG->enableavailability) and $cm) {
        // We cache conditional access in session
        if (!isset($SESSION->conditionaccessok)) {
            $SESSION->conditionaccessok = array();
        }
        // If you have been allowed into the module once then you are allowed
        // in for rest of session, no need to do conditional checks
        if (!array_key_exists($cm->id, $SESSION->conditionaccessok)) {
            // Get condition info (does a query for the availability table)
            require_once $CFG->libdir . '/conditionlib.php';
            $ci = new condition_info($cm, CONDITION_MISSING_EXTRATABLE);
            // Check condition for user (this will do a query if the availability
            // information depends on grade or completion information)
            if ($ci->is_available($junk) || has_capability('moodle/course:viewhiddenactivities', $cm->context)) {
                $SESSION->conditionaccessok[$cm->id] = true;
            } else {
                print_error('activityiscurrentlyhidden');
            }
        }
    }
    if ($COURSE->id == SITEID) {
        /// Eliminate hidden site activities straight away
        if (!empty($cm) && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cm->context)) {
            redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden'));
        }
        user_accesstime_log($COURSE->id);
        /// Access granted, update lastaccess times
        return;
    } else {
        /// Check if the user can be in a particular course
        if (empty($USER->access['rsw'][$COURSE->context->path])) {
            //
            // MDL-13900 - If the course or the parent category are hidden
            // and the user hasn't the 'course:viewhiddencourses' capability, prevent access
            //
            if (!($COURSE->visible && course_parent_visible($COURSE)) && !has_capability('moodle/course:viewhiddencourses', $COURSE->context)) {
                print_header_simple();
                notice(get_string('coursehidden'), $CFG->wwwroot . '/');
            }
        }
        /// Non-guests who don't currently have access, check if they can be allowed in as a guest
        if ($USER->username != 'guest' and !has_capability('moodle/course:view', $COURSE->context)) {
            if ($COURSE->guest == 1) {
                // Temporarily assign them guest role for this context, if it fails later user is asked to enrol
                $USER->access = load_temp_role($COURSE->context, $CFG->guestroleid, $USER->access);
            }
        }
        /// If the user is a guest then treat them according to the course policy about guests
        if (has_capability('moodle/legacy:guest', $COURSE->context, NULL, false)) {
            if (has_capability('moodle/site:doanything', $sysctx)) {
                // administrators must be able to access any course - even if somebody gives them guest access
                user_accesstime_log($COURSE->id);
                /// Access granted, update lastaccess times
                return;
            }
            switch ($COURSE->guest) {
                /// Check course policy about guest access
                case 1:
                    /// Guests always allowed
                    if (!has_capability('moodle/course:view', $COURSE->context)) {
                        // Prohibited by capability
                        print_header_simple();
                        notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), get_login_url());
                    }
                    if (!empty($cm) and !$cm->visible) {
                        // Not allowed to see module, send to course page
                        redirect($CFG->wwwroot . '/course/view.php?id=' . $cm->course, get_string('activityiscurrentlyhidden'));
                    }
                    user_accesstime_log($COURSE->id);
                    /// Access granted, update lastaccess times
                    return;
                    // User is allowed to see this course
                    break;
                case 2:
                    /// Guests allowed with key
                    if (!empty($USER->enrolkey[$COURSE->id])) {
                        // Set by enrol/manual/enrol.php
                        user_accesstime_log($COURSE->id);
                        /// Access granted, update lastaccess times
                        return true;
                    }
                    //  otherwise drop through to logic below (--> enrol.php)
                    break;
                default:
                    /// Guests not allowed
                    $strloggedinasguest = get_string('loggedinasguest');
                    print_header_simple('', '', build_navigation(array(array('name' => $strloggedinasguest, 'link' => null, 'type' => 'misc'))));
                    if (empty($USER->access['rsw'][$COURSE->context->path])) {
                        // Normal guest
                        notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), get_login_url());
                    } else {
                        notify(get_string('guestsnotallowed', '', format_string($COURSE->fullname)));
                        echo '<div class="notifyproblem">' . switchroles_form($COURSE->id) . '</div>';
                        print_footer($COURSE);
                        exit;
                    }
                    break;
            }
            /// For non-guests, check if they have course view access
        } else {
            if (has_capability('moodle/course:view', $COURSE->context)) {
                if (session_is_loggedinas()) {
                    // Make sure the REAL person can also access this course
                    $realuser = session_get_realuser();
                    if (!has_capability('moodle/course:view', $COURSE->context, $realuser->id)) {
                        print_header_simple();
                        notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/');
                    }
                }
                /// Make sure they can read this activity too, if specified
                if (!empty($cm) && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cm->context)) {
                    redirect($CFG->wwwroot . '/course/view.php?id=' . $cm->course, get_string('activityiscurrentlyhidden'));
                }
                user_accesstime_log($COURSE->id);
                /// Access granted, update lastaccess times
                return;
                // User is allowed to see this course
            }
        }
        /// Currently not enrolled in the course, so see if they want to enrol
        $SESSION->wantsurl = $FULLME;
        redirect($CFG->wwwroot . '/course/enrol.php?id=' . $COURSE->id);
        die;
    }
}
 /**
  * Checks whether a user can be subscribed to the forum, regardless of
  * subscription option. Includes a variety of other checks. [These are
  * supposed to be the same as checks done when building the list of people
  * for email.]
  * @param int $userid User ID or 0 for current
  * @return bool True if user can be subscribed
  */
 private function can_be_subscribed($userid = 0)
 {
     global $USER;
     $userid = mod_forumng_utils::get_real_userid($userid);
     $cm = $this->get_course_module();
     $course = $this->get_course();
     $context = $this->get_context();
     // Guests cannot subscribe
     if (!isloggedin() || isguestuser($userid)) {
         return false;
     }
     // Get from cache if possible
     if (!isset($this->cache->can_be_subscribed)) {
         $this->cache->can_be_subscribed = array();
     }
     if (array_key_exists($userid, $this->cache->can_be_subscribed)) {
         return $this->cache->can_be_subscribed[$userid];
     }
     // This is not a loop, just so I can use break
     do {
         // Check user can see forum
         if (!has_capability('mod/forumng:viewdiscussion', $context, $userid)) {
             $result = false;
             break;
         }
         // For current user, can take shortcut
         if ($userid == $USER->id) {
             if (empty($cm->uservisible)) {
                 $uservisible = false;
             } else {
                 $uservisible = true;
             }
             if (!$uservisible) {
                 $result = false;
                 break;
             }
         } else {
             $visible = $cm->visible;
             // Note: It is pretty terrible that this code is placed here.
             // Shouldn't there be a function in cm_info to do this? :(
             // Unfortunately I didn't think of that when redesigning
             // cm_info, it can only work for current user.
             $conditioninfo = new condition_info($cm);
             $visible = $visible && $conditioninfo->is_available($crap, false, $userid);
             if (!$visible && !has_capability('moodle/site:viewhiddenactivities', $context, $userid)) {
                 $result = false;
                 break;
             }
             if ($cm->groupmembersonly && !has_capability('moodle/site:accessallgroups', $context, $userid)) {
                 // If the forum is restricted to group members only, then
                 // limit it to people within groups on the course - or
                 // groups in the grouping, if one is selected
                 $groupobjs = groups_get_all_groups($course->id, $userid, $cm->groupingid, 'g.id');
                 if (!$groupobjs || count($groupobjs) == 0) {
                     $result = false;
                     break;
                 }
             }
         }
         $result = true;
         break;
     } while (false);
     $this->cache->can_be_subscribed[$userid] = $result;
     return $result;
 }
Example #13
0
 /**
  * Adds all the standard elements to a form to edit the settings for an activity module.
  */
 function standard_coursemodule_elements()
 {
     global $COURSE, $CFG, $DB;
     $mform =& $this->_form;
     $outcomesused = false;
     if ($this->_features->outcomes) {
         if ($outcomes = grade_outcome::fetch_all_available($COURSE->id)) {
             $outcomesused = true;
             $mform->addElement('header', 'modoutcomes', get_string('outcomes', 'grades'));
             foreach ($outcomes as $outcome) {
                 $mform->addElement('advcheckbox', 'outcome_' . $outcome->id, $outcome->get_name());
             }
         }
     }
     $mform->addElement('header', 'modstandardelshdr', get_string('modstandardels', 'form'));
     if ($this->_features->groups) {
         $options = array(NOGROUPS => get_string('groupsnone'), SEPARATEGROUPS => get_string('groupsseparate'), VISIBLEGROUPS => get_string('groupsvisible'));
         $mform->addElement('select', 'groupmode', get_string('groupmode'), $options, NOGROUPS);
         $mform->setHelpButton('groupmode', array('groupmode', get_string('groupmode')));
     }
     if (!empty($CFG->enablegroupings)) {
         if ($this->_features->groupings or $this->_features->groupmembersonly) {
             //groupings selector - used for normal grouping mode or also when restricting access with groupmembersonly
             $options = array();
             $options[0] = get_string('none');
             if ($groupings = $DB->get_records('groupings', array('courseid' => $COURSE->id))) {
                 foreach ($groupings as $grouping) {
                     $options[$grouping->id] = format_string($grouping->name);
                 }
             }
             $mform->addElement('select', 'groupingid', get_string('grouping', 'group'), $options);
             $mform->setHelpButton('groupingid', array('grouping', get_string('grouping', 'group')));
             $mform->setAdvanced('groupingid');
         }
         if ($this->_features->groupmembersonly) {
             $mform->addElement('checkbox', 'groupmembersonly', get_string('groupmembersonly', 'group'));
             $mform->setHelpButton('groupmembersonly', array('groupmembersonly', get_string('groupmembersonly', 'group')));
             $mform->setAdvanced('groupmembersonly');
         }
     }
     $mform->addElement('modvisible', 'visible', get_string('visible'));
     if ($this->_features->idnumber) {
         $mform->addElement('text', 'cmidnumber', get_string('idnumbermod'));
         $mform->setHelpButton('cmidnumber', array('cmidnumber', get_string('idnumbermod')), true);
     }
     if ($this->_features->gradecat) {
         $categories = grade_get_categories_menu($COURSE->id, $outcomesused);
         $mform->addElement('select', 'gradecat', get_string('gradecategory', 'grades'), $categories);
     }
     if (!empty($CFG->enableavailability)) {
         // Conditional availability
         $mform->addElement('header', '', get_string('availabilityconditions', 'condition'));
         $mform->addElement('date_selector', 'availablefrom', get_string('availablefrom', 'condition'), array('optional' => true));
         $mform->setHelpButton('availablefrom', array('conditiondates', get_string('help_conditiondates', 'condition'), 'condition'));
         $mform->addElement('date_selector', 'availableuntil', get_string('availableuntil', 'condition'), array('optional' => true));
         $mform->setHelpButton('availableuntil', array('conditiondates', get_string('help_conditiondates', 'condition'), 'condition'));
         // Conditions based on grades
         $gradeoptions = array();
         $items = grade_item::fetch_all(array('courseid' => $COURSE->id));
         $items = $items ? $items : array();
         foreach ($items as $id => $item) {
             // Do not include grades for current item
             if (!empty($this->_cm) && $this->_cm->instance == $item->iteminstance && $this->_cm->modname == $item->itemmodule && $item->itemtype == 'mod') {
                 continue;
             }
             $gradeoptions[$id] = $item->get_name();
         }
         asort($gradeoptions);
         $gradeoptions = array(0 => get_string('none', 'condition')) + $gradeoptions;
         $grouparray = array();
         $grouparray[] =& $mform->createElement('select', 'conditiongradeitemid', '', $gradeoptions);
         $grouparray[] =& $mform->createElement('static', '', '', ' ' . get_string('grade_atleast', 'condition') . ' ');
         $grouparray[] =& $mform->createElement('text', 'conditiongrademin', '', array('size' => 3));
         $grouparray[] =& $mform->createElement('static', '', '', '% ' . get_string('grade_upto', 'condition') . ' ');
         $grouparray[] =& $mform->createElement('text', 'conditiongrademax', '', array('size' => 3));
         $grouparray[] =& $mform->createElement('static', '', '', '%');
         $mform->setType('conditiongrademin', PARAM_FLOAT);
         $mform->setType('conditiongrademax', PARAM_FLOAT);
         $group = $mform->createElement('group', 'conditiongradegroup', get_string('gradecondition', 'condition'), $grouparray);
         // Get version with condition info and store it so we don't ask
         // twice
         if (!empty($this->_cm)) {
             $ci = new condition_info($this->_cm, CONDITION_MISSING_EXTRATABLE);
             $this->_cm = $ci->get_full_course_module();
             $count = count($this->_cm->conditionsgrade) + 1;
         } else {
             $count = 1;
         }
         $this->repeat_elements(array($group), $count, array(), 'conditiongraderepeats', 'conditiongradeadds', 2, get_string('addgrades', 'condition'), true);
         $mform->setHelpButton('conditiongradegroup[0]', array('gradecondition', get_string('help_gradecondition', 'condition'), 'condition'));
         // Conditions based on completion
         $completion = new completion_info($COURSE);
         if ($completion->is_enabled()) {
             $completionoptions = array();
             $modinfo = get_fast_modinfo($COURSE);
             foreach ($modinfo->cms as $id => $cm) {
                 // Add each course-module if it:
                 // (a) has completion turned on
                 // (b) is not the same as current course-module
                 if ($cm->completion && (empty($this->_cm) || $this->_cm->id != $id)) {
                     $completionoptions[$id] = $cm->name;
                 }
             }
             asort($completionoptions);
             $completionoptions = array(0 => get_string('none', 'condition')) + $completionoptions;
             $completionvalues = array(COMPLETION_COMPLETE => get_string('completion_complete', 'condition'), COMPLETION_INCOMPLETE => get_string('completion_incomplete', 'condition'), COMPLETION_COMPLETE_PASS => get_string('completion_pass', 'condition'), COMPLETION_COMPLETE_FAIL => get_string('completion_fail', 'condition'));
             $grouparray = array();
             $grouparray[] =& $mform->createElement('select', 'conditionsourcecmid', '', $completionoptions);
             $grouparray[] =& $mform->createElement('select', 'conditionrequiredcompletion', '', $completionvalues);
             $group = $mform->createElement('group', 'conditioncompletiongroup', get_string('completioncondition', 'condition'), $grouparray);
             $count = empty($this->_cm) ? 1 : count($this->_cm->conditionscompletion) + 1;
             $this->repeat_elements(array($group), $count, array(), 'conditioncompletionrepeats', 'conditioncompletionadds', 2, get_string('addcompletions', 'condition'), true);
             $mform->setHelpButton('conditioncompletiongroup[0]', array('completioncondition', get_string('help_completioncondition', 'condition'), 'condition'));
         }
         // Do we display availability info to students?
         $mform->addElement('select', 'showavailability', get_string('showavailability', 'condition'), array(CONDITION_STUDENTVIEW_SHOW => get_string('showavailability_show', 'condition'), CONDITION_STUDENTVIEW_HIDE => get_string('showavailability_hide', 'condition')));
         $mform->setDefault('showavailability', CONDITION_STUDENTVIEW_SHOW);
         $mform->setHelpButton('showavailability', array('showavailability', get_string('help_showavailability', 'condition'), 'condition'));
     }
     // Conditional activities: completion tracking section
     if (!isset($completion)) {
         $completion = new completion_info($COURSE);
     }
     if ($completion->is_enabled()) {
         $mform->addElement('header', '', get_string('activitycompletion', 'completion'));
         // Unlock button for if people have completed it (will
         // be removed in definition_after_data if they haven't)
         $mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion'));
         $mform->registerNoSubmitButton('unlockcompletion');
         $mform->addElement('hidden', 'completionunlocked', 0);
         $mform->addElement('select', 'completion', get_string('completion', 'completion'), array(COMPLETION_TRACKING_NONE => get_string('completion_none', 'completion'), COMPLETION_TRACKING_MANUAL => get_string('completion_manual', 'completion')));
         $mform->setHelpButton('completion', array('completion', get_string('help_completion', 'completion'), 'completion'));
         $mform->setDefault('completion', $this->_features->defaultcompletion ? COMPLETION_TRACKING_MANUAL : COMPLETION_TRACKING_NONE);
         // Automatic completion once you view it
         $gotcompletionoptions = false;
         if (plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_TRACKS_VIEWS, false)) {
             $mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'), get_string('completionview_text', 'completion'));
             $mform->setHelpButton('completionview', array('completionview', get_string('help_completionview', 'completion'), 'completion'));
             $mform->disabledIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
             $gotcompletionoptions = true;
         }
         // Automatic completion once it's graded
         if (plugin_supports('mod', $this->_modname, FEATURE_GRADE_HAS_GRADE, false)) {
             $mform->addElement('checkbox', 'completionusegrade', get_string('completionusegrade', 'completion'), get_string('completionusegrade_text', 'completion'));
             $mform->setHelpButton('completionusegrade', array('completionusegrade', get_string('help_completionusegrade', 'completion'), 'completion'));
             $mform->disabledIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
             $gotcompletionoptions = true;
         }
         // Automatic completion according to module-specific rules
         $this->_customcompletionelements = $this->add_completion_rules();
         foreach ($this->_customcompletionelements as $element) {
             $mform->disabledIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
         }
         $gotcompletionoptions = $gotcompletionoptions || count($this->_customcompletionelements) > 0;
         // Automatic option only appears if possible
         if ($gotcompletionoptions) {
             $mform->getElement('completion')->addOption(get_string('completion_automatic', 'completion'), COMPLETION_TRACKING_AUTOMATIC);
         }
         // Completion expected at particular date? (For progress tracking)
         $mform->addElement('date_selector', 'completionexpected', get_string('completionexpected', 'completion'), array('optional' => true));
         $mform->setHelpButton('completionexpected', array('completionexpected', get_string('help_completionexpected', 'completion'), 'completion'));
         $mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
     }
     $this->standard_hidden_coursemodule_elements();
 }
 /**
  * Created to accomodate forumng on shared activities
  * where the shared activites course does not hold cm information
  * in the course table's modinfo field
  * @param $course
  * @param $cmid
  * @return $modinfo
  */
 private function get_fast_modinfo($course, $cmid)
 {
     global $CFG;
     if (class_exists('ouflags')) {
         require_once $CFG->dirroot . '/course/format/sharedactv/sharedactv.php';
         if (sharedactv_is_magic_course($course)) {
             // get_fast_modinfo will only ever return a minimal object, so build own
             $modinfo = new object();
             $modinfo->courseid = $course->id;
             $modinfo->userid = 0;
             $modinfo->sections = array();
             $modinfo->instances = array();
             $modinfo->groups = null;
             if (!($cm = get_coursemodule_from_id('forumng', $cmid, $course->id))) {
                 throw new forum_exception('Could not find the forum course module.');
             }
             if (!empty($CFG->enableavailability)) {
                 $cm->conditionscompletion = array();
                 $cm->conditionsgrade = array();
                 // Unfortunately the next call really wants to call
                 // get_fast_modinfo, but that would be recursive, so we fake up a
                 // modinfo for it already
                 if (empty($minimalmodinfo)) {
                     $minimalmodinfo = new stdClass();
                     $minimalmodinfo->cms = array();
                     $minimalcm = new stdClass();
                     $minimalcm->id = $cmid;
                     $minimalcm->name = 'forumng';
                     $minimalmodinfo->cms[$cmid] = $minimalcm;
                 }
                 // Get availability information
                 $ci = new condition_info($cm);
                 $cm->available = $ci->is_available($cm->availableinfo, true, 0, $minimalmodinfo);
             } else {
                 $cm->available = true;
             }
             $cm->uservisible = true;
             $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
             if ((!$cm->visible or !$cm->available) and !has_capability('moodle/course:viewhiddenactivities', $modcontext, 0)) {
                 $cm->uservisible = false;
             } else {
                 if (!empty($CFG->enablegroupings) and !empty($cm->groupmembersonly) and !has_capability('moodle/site:accessallgroups', $modcontext, 0)) {
                     if (is_null($modinfo->groups)) {
                         $modinfo->groups = groups_get_user_groups($course->id, 0);
                     }
                     if (empty($modinfo->groups[$cm->groupingid])) {
                         $cm->uservisible = false;
                     }
                 }
             }
             $modinfo->cms = array($cmid => $cm);
         } else {
             $modinfo = get_fast_modinfo($course);
         }
     } else {
         $modinfo = get_fast_modinfo($course);
     }
     return $modinfo;
 }
Example #15
0
     *
     * @param condition_info_base $ci Condition info
     * @param object $fromform Data from form
     * @param bool $wipefirst If true, wipes existing conditions
     */
    protected static function update_from_form(condition_info_base $ci, $fromform, $wipefirst)
    {
        if ($wipefirst) {
            $ci->wipe_conditions();
        }
        foreach ($fromform->conditiongradegroup as $record) {
            if ($record['conditiongradeitemid']) {
                $ci->add_grade_condition($record['conditiongradeitemid'], unformat_float($record['conditiongrademin']), unformat_float($record['conditiongrademax']));
            }
        }
        foreach ($fromform->conditionfieldgroup as $record) {
            if ($record['conditionfield']) {
                $ci->add_user_field_condition($record['conditionfield'], $record['conditionfieldoperator'], $record['conditionfieldvalue']);
            }
        }
        if (isset($fromform->conditioncompletiongroup)) {
            foreach ($fromform->conditioncompletiongroup as $record) {
                if ($record['conditionsourcecmid']) {
                    $ci->add_completion_condition($record['conditionsourcecmid'], $record['conditionrequiredcompletion']);
                }
            }
        }
    }
}
condition_info::init_global_cache();
 function test_is_available()
 {
     global $DB, $USER;
     $courseid = $this->make_course();
     // No conditions
     $cmid = $this->make_course_module($courseid);
     $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING);
     $this->assertTrue($ci->is_available($text, false, 0));
     $this->assertEqual('', $text);
     // Time (from)
     $time = time() + 100;
     $cmid = $this->make_course_module($courseid, array('availablefrom' => $time));
     $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING);
     $this->assertFalse($ci->is_available($text));
     $this->assert(new PatternExpectation('/' . preg_quote(userdate($time, get_string('strftimedate', 'langconfig'))) . '/'), $text);
     $time = time() - 100;
     $cmid = $this->make_course_module($courseid, array('availablefrom' => $time));
     $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING);
     $this->assertTrue($ci->is_available($text));
     $this->assertEqual('', $text);
     $this->assert(new PatternExpectation('/' . preg_quote(userdate($time, get_string('strftimedate', 'langconfig'))) . '/'), $ci->get_full_information());
     // Time (until)
     $cmid = $this->make_course_module($courseid, array('availableuntil' => time() - 100));
     $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING);
     $this->assertFalse($ci->is_available($text));
     $this->assertEqual('', $text);
     // Completion
     $oldid = $cmid;
     $cmid = $this->make_course_module($courseid);
     $this->make_section($courseid, array($oldid, $cmid));
     $oldcm = $DB->get_record('course_modules', array('id' => $oldid));
     $oldcm->completion = COMPLETION_TRACKING_MANUAL;
     $DB->update_record('course_modules', $oldcm);
     $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING);
     $ci->add_completion_condition($oldid, COMPLETION_COMPLETE);
     $this->assertFalse($ci->is_available($text, false));
     $this->assertEqual(get_string('requires_completion_1', 'condition', 'xxx'), $text);
     $completion = new completion_info($DB->get_record('course', array('id' => $courseid)));
     $completion->update_state($oldcm, COMPLETION_COMPLETE);
     completion_info::wipe_session_cache();
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text));
     $this->assertFalse($ci->is_available($text, false, $USER->id + 1));
     completion_info::wipe_session_cache();
     condition_info::wipe_session_cache();
     $completion = new completion_info($DB->get_record('course', array('id' => $courseid)));
     $completion->update_state($oldcm, COMPLETION_INCOMPLETE);
     $this->assertFalse($ci->is_available($text));
     $ci->wipe_conditions();
     $ci->add_completion_condition($oldid, COMPLETION_INCOMPLETE);
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text));
     $this->assertTrue($ci->is_available($text, false, $USER->id + 1));
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text, true));
     // Grade
     $ci->wipe_conditions();
     // Add a fake grade item
     $gradeitemid = $DB->insert_record('grade_items', (object) array('courseid' => $courseid, 'itemname' => 'frog'));
     // Add a condition on a value existing...
     $ci->add_grade_condition($gradeitemid, null, null, true);
     $this->assertFalse($ci->is_available($text));
     $this->assertEqual(get_string('requires_grade_any', 'condition', 'frog'), $text);
     // Fake it existing
     $DB->insert_record('grade_grades', (object) array('itemid' => $gradeitemid, 'userid' => $USER->id, 'finalgrade' => 3.78));
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text));
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text, true));
     // Now require that user gets more than 3.78001
     $ci->wipe_conditions();
     $ci->add_grade_condition($gradeitemid, 3.78001, null, true);
     condition_info::wipe_session_cache();
     $this->assertFalse($ci->is_available($text));
     $this->assertEqual(get_string('requires_grade_min', 'condition', 'frog'), $text);
     // ...just on 3.78...
     $ci->wipe_conditions();
     $ci->add_grade_condition($gradeitemid, 3.78, null, true);
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text));
     // ...less than 3.78
     $ci->wipe_conditions();
     $ci->add_grade_condition($gradeitemid, null, 3.78, true);
     condition_info::wipe_session_cache();
     $this->assertFalse($ci->is_available($text));
     $this->assertEqual(get_string('requires_grade_max', 'condition', 'frog'), $text);
     // ...less than 3.78001
     $ci->wipe_conditions();
     $ci->add_grade_condition($gradeitemid, null, 3.78001, true);
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text));
     // ...in a range that includes it
     $ci->wipe_conditions();
     $ci->add_grade_condition($gradeitemid, 3, 4, true);
     condition_info::wipe_session_cache();
     $this->assertTrue($ci->is_available($text));
     // ...in a range that doesn't include it
     $ci->wipe_conditions();
     $ci->add_grade_condition($gradeitemid, 4, 5, true);
     condition_info::wipe_session_cache();
     $this->assertFalse($ci->is_available($text));
     $this->assertEqual(get_string('requires_grade_range', 'condition', 'frog'), $text);
 }
Example #17
0
 function get_course_mods($id, $username = '')
 {
     global $CFG, $DB;
     $username = utf8_decode($username);
     $username = strtolower($username);
     if ($username) {
         $user = get_complete_user_data('username', $username);
     }
     $modinfo = get_fast_modinfo($id);
     $sections = $modinfo->get_section_info_all();
     $forum = forum_get_course_forum($id, 'news');
     $news_forum_id = $forum->id;
     $mods = get_fast_modinfo($id)->get_cms();
     $modnames = get_module_types_names();
     $modnamesplural = get_module_types_names(true);
     $modnamesused = get_fast_modinfo($id)->get_used_module_names();
     $rawmods = get_course_mods($id);
     $context = context_course::instance($id);
     // Kludge to use username param to get non visible sections and modules
     $username_orig = $username;
     if ($username_orig == 'joomdle_get_not_visible') {
         $username = '';
     }
     $e = array();
     foreach ($sections as $section) {
         if ($username_orig != 'joomdle_get_not_visible') {
             if (!$section->visible) {
                 continue;
             }
         }
         $sectionmods = explode(",", $section->sequence);
         foreach ($sectionmods as $modnumber) {
             if (empty($mods[$modnumber])) {
                 continue;
             }
             $mod = $mods[$modnumber];
             if ($username_orig != 'joomdle_get_not_visible') {
                 if (!$mod->visible) {
                     continue;
                 }
             }
             $resource['completion_info'] = '';
             if ($username) {
                 $cm = get_coursemodule_from_id(false, $mod->id);
                 if (!\core_availability\info_module::is_user_visible($cm, $user->id)) {
                     if (empty($mod->availableinfo)) {
                         // Mod not visible, and no completion info to show
                         continue;
                     }
                     $resource['available'] = 0;
                     $ci = new condition_info($mod);
                     $resource['completion_info'] = $ci->get_full_information();
                 } else {
                     $resource['available'] = 1;
                 }
             } else {
                 $resource['available'] = 1;
             }
             $e[$section->section]['section'] = $section->section;
             $e[$section->section]['name'] = $section->name;
             $e[$section->section]['summary'] = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $context->id, 'course', 'section', $section->id);
             $e[$section->section]['summary'] = str_replace('pluginfile.php', '/auth/joomdle/pluginfile_joomdle.php', $e[$section->section]['summary']);
             $resource['id'] = $mod->id;
             $resource['name'] = $mod->name;
             $resource['mod'] = $mod->modname;
             // Get content
             $resource['content'] = '';
             $modname = $mod->modname;
             $functionname = $modname . "_get_coursemodule_info";
             if (file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) {
                 include_once "{$CFG->dirroot}/mod/{$modname}/lib.php";
                 if ($hasfunction = function_exists($functionname)) {
                     if ($info = $functionname($rawmods[$modnumber])) {
                         $resource['content'] = $info->content;
                     }
                 }
             }
             // Format for mod->icon is: f/type-24
             $type = substr($mod->icon, 2);
             $parts = explode('-', $type);
             $type = $parts[0];
             $resource['type'] = $type;
             //In forum, type is unused, so we use it for forum type: news/general
             if ($mod->modname == 'forum') {
                 $cm = get_coursemodule_from_id('forum', $mod->id);
                 if ($cm->instance == $news_forum_id) {
                     $resource['type'] = 'news';
                 }
             }
             /*
             				if ($mod->modname == 'resource')
                             {
                                 // Get display options for resource
                                 $params = array ($mod->instance);
                                 $query = "SELECT display from  {$CFG->prefix}resource where id = ?";
                                 $record = $DB->get_record_sql ($query, $params);
                                 
                                 $resource['display'] = $record->display;
                             }
                             else $resource['display'] = 0;
             */
             $resource['display'] = $this->get_display($mod->modname, $mod->instance);
             $e[$section->section]['mods'][] = $resource;
         }
     }
     return $e;
 }
 /**
  * Tests the is_available function for modules. This does not test all the
  * conditions and stuff, because it only needs to check that the system
  * connects through to the real availability API. Also tests
  * get_full_information function.
  */
 public function test_is_available()
 {
     // Create course.
     $generator = $this->getDataGenerator();
     $course = $generator->create_course();
     // Create activity with no restrictions and one with date restriction.
     $page1 = $generator->get_plugin_generator('mod_page')->create_instance(array('course' => $course));
     $time = time() + 100;
     $avail = '{"op":"|","show":true,"c":[{"type":"date","d":">=","t":' . $time . '}]}';
     $page2 = $generator->get_plugin_generator('mod_page')->create_instance(array('course' => $course, 'availability' => $avail));
     // No conditions.
     $ci = new condition_info((object) array('id' => $page1->cmid), CONDITION_MISSING_EVERYTHING);
     $this->assertDebuggingCalled();
     $this->assertTrue($ci->is_available($text, false, 0));
     $this->assertDebuggingCalled();
     $this->assertEquals('', $text);
     // Date condition.
     $ci = new condition_info((object) array('id' => $page2->cmid), CONDITION_MISSING_EVERYTHING);
     $this->assertDebuggingCalled();
     $this->assertFalse($ci->is_available($text));
     $this->assertDebuggingCalled();
     $expectedtime = userdate($time, get_string('strftimedate', 'langconfig'));
     $this->assertContains($expectedtime, $text);
     // Full information display.
     $text = $ci->get_full_information();
     $this->assertDebuggingCalled();
     $expectedtime = userdate($time, get_string('strftimedate', 'langconfig'));
     $this->assertContains($expectedtime, $text);
 }
Example #19
0
 /**
  * Renders HTML to show course module availability information (for someone who isn't allowed
  * to see the activity itself, or for staff)
  *
  * @param cm_info $mod
  * @param array $displayoptions
  * @return string
  */
 public function course_section_cm_availability(cm_info $mod, $displayoptions = array())
 {
     global $CFG;
     if (!$mod->uservisible) {
         // this is a student who is not allowed to see the module but might be allowed
         // to see availability info (i.e. "Available from ...")
         if (!empty($mod->showavailability) && !empty($mod->availableinfo)) {
             $output = html_writer::tag('div', $mod->availableinfo, array('class' => 'availabilityinfo'));
         }
         return $output;
     }
     // this is a teacher who is allowed to see module but still should see the
     // information that module is not available to all/some students
     $modcontext = context_module::instance($mod->id);
     $canviewhidden = has_capability('moodle/course:viewhiddenactivities', $modcontext);
     if ($canviewhidden && !empty($CFG->enableavailability)) {
         // Don't add availability information if user is not editing and activity is hidden.
         if ($mod->visible || $this->page->user_is_editing()) {
             $hidinfoclass = '';
             if (!$mod->visible) {
                 $hidinfoclass = 'hide';
             }
             $ci = new condition_info($mod);
             $fullinfo = $ci->get_full_information();
             if ($fullinfo) {
                 return '<div class="availabilityinfo ' . $hidinfoclass . '">' . get_string($mod->showavailability ? 'userrestriction_visible' : 'userrestriction_hidden', 'condition', $fullinfo) . '</div>';
             }
         }
     }
     return '';
 }
 /**
  * Tests grade_report_user::inject_rowspans()
  *
  * inject_rowspans() returns the count of the number of elements, sets maxdepth on the
  *  report object and sets the rowspan property on any element that has children.
  */
 public function test_inject_rowspans()
 {
     global $CFG, $USER, $DB;
     parent::setUp();
     $this->resetAfterTest(true);
     $CFG->enableavailability = 1;
     $CFG->enablecompletion = 1;
     // Create a course.
     $course = $this->getDataGenerator()->create_course();
     $coursecategory = grade_category::fetch_course_category($course->id);
     $coursecontext = context_course::instance($course->id);
     // Create and enrol test users.
     $student = $this->getDataGenerator()->create_user(array('username' => 'Student Sam'));
     $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
     $this->getDataGenerator()->enrol_user($student->id, $course->id, $role->id);
     $teacher = $this->getDataGenerator()->create_user(array('username' => 'Teacher T'));
     $role = $DB->get_record('role', array('shortname' => 'editingteacher'), '*', MUST_EXIST);
     $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $role->id);
     // An array so we can test with both users in a loop.
     $users = array($student, $teacher);
     // Make the student the current user.
     $this->setUser($student);
     // Test an empty course.
     $report = $this->create_report($course, $student, $coursecontext);
     // a lead column that spans all children + course grade item = 2
     $this->assertEquals(2, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(2, $report->gtree->top_element['rowspan']);
     $this->assertEquals(2, $report->maxdepth);
     // Only elements with children should have rowspan set.
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) {
         $this->fail('Elements without children should not have rowspan set');
     }
     // Add 2 activities.
     $data1 = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forum1 = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forum1cm = get_coursemodule_from_id('forum', $forum1->cmid);
     // Switch the stdClass instance for a grade item instance so grade_item::set_parent() is available.
     $forum1 = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum1->id, 'courseid' => $course->id));
     $report = $this->create_report($course, $student, $coursecontext);
     // Lead column + course + (2 x activity) = 4
     $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(4, $report->gtree->top_element['rowspan']);
     // Lead column + 1 level (course + 2 activities) = 2
     $this->assertEquals(2, $report->maxdepth);
     // Only elements with children should have rowspan set.
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) {
         $this->fail('Elements without children should not have rowspan set');
     }
     // Hide the forum activity.
     set_coursemodule_visible($forum1cm->id, 0);
     foreach ($users as $user) {
         $this->setUser($user);
         $message = 'Testing with ' . $user->username;
         accesslib_clear_all_caches_for_unit_testing();
         $report = $this->create_report($course, $user, $coursecontext);
         // Lead column + course + (2 x activity) = 4 (element count isn't affected by hiding)
         $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element), $message);
         $this->assertEquals(4, $report->gtree->top_element['rowspan'], $message);
         // Lead column -> 1 level containing the course + 2 activities = 2
         $this->assertEquals(2, $report->maxdepth, $message);
     }
     // Unhide the forum activity.
     set_coursemodule_visible($forum1cm->id, 1);
     // Create a category and put the forum in it.
     $params = new stdClass();
     $params->courseid = $course->id;
     $params->fullname = 'unittestcategory';
     $params->parent = $coursecategory->id;
     $gradecategory = new grade_category($params, false);
     $gradecategory->insert();
     $forum1->set_parent($gradecategory->id);
     $report = $this->create_report($course, $student, $coursecontext);
     // Lead column + course + (category + category grade item) + (2 x activity) = 6
     $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element));
     $this->assertEquals(6, $report->gtree->top_element['rowspan']);
     // Lead column -> the category -> the forum activity = 3
     $this->assertEquals(3, $report->maxdepth);
     // Check rowspan on the category. The category itself + category grade item + forum = 3
     $this->assertEquals(3, $report->gtree->top_element['children'][4]['rowspan']);
     // check the forum doesn't have rowspan set
     if (array_key_exists('rowspan', $report->gtree->top_element['children'][4]['children'][3])) {
         $this->fail('The forum has no children so should not have rowspan set');
     }
     // Conditional activity tests.
     $DB->insert_record('course_modules_availability', (object) array('coursemoduleid' => $forum1cm->id, 'gradeitemid' => 37, 'grademin' => 5.5));
     $cm = (object) array('id' => $forum1cm->id);
     $test = new condition_info($cm, CONDITION_MISSING_EVERYTHING);
     $fullcm = $test->get_full_course_module();
     foreach ($users as $user) {
         $this->setUser($user);
         $message = 'Testing with ' . $user->username;
         accesslib_clear_all_caches_for_unit_testing();
         $report = $this->create_report($course, $user, $coursecontext);
         // Lead column + course + (category + category grade item) + (2 x activity) = 6
         $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element), $message);
         $this->assertEquals(6, $report->gtree->top_element['rowspan'], $message);
         // Lead column -> the category -> the forum activity = 3
         $this->assertEquals(3, $report->maxdepth, $message);
     }
 }
Example #21
0
 /**
  * Utility function called by modedit.php; updates the 
  * course_modules_availability table based on the module form data.
  *
  * @param object $cm Course-module with as much data as necessary, min id
  * @param object $fromform
  * @param bool $wipefirst Defaults to true
  */
 public static function update_cm_from_form($cm, $fromform, $wipefirst = true)
 {
     $ci = new condition_info($cm, CONDITION_MISSING_EVERYTHING, false);
     if ($wipefirst) {
         $ci->wipe_conditions();
     }
     foreach ($fromform->conditiongradegroup as $record) {
         if ($record['conditiongradeitemid']) {
             $ci->add_grade_condition($record['conditiongradeitemid'], $record['conditiongrademin'], $record['conditiongrademax']);
         }
     }
     if (isset($fromform->conditioncompletiongroup)) {
         foreach ($fromform->conditioncompletiongroup as $record) {
             if ($record['conditionsourcecmid']) {
                 $ci->add_completion_condition($record['conditionsourcecmid'], $record['conditionrequiredcompletion']);
             }
         }
     }
 }
Example #22
0
/**
 * Returns reference to full info about modules in course (including visibility).
 * Cached and as fast as possible (0 or 1 db query).
 *
 * @global object
 * @global object
 * @global object
 * @uses CONTEXT_MODULE
 * @uses MAX_MODINFO_CACHE_SIZE
 * @param mixed $course object or 'reset' string to reset caches, modinfo may be updated in db
 * @param int $userid Defaults to current user id
 * @return mixed courseinfo object or nothing if resetting
 */
function &get_fast_modinfo(&$course, $userid = 0)
{
    global $CFG, $USER, $DB;
    require_once $CFG->dirroot . '/course/lib.php';
    if (!empty($CFG->enableavailability)) {
        require_once $CFG->libdir . '/conditionlib.php';
    }
    static $cache = array();
    if ($course === 'reset') {
        $cache = array();
        $nothing = null;
        return $nothing;
        // we must return some reference
    }
    if (empty($userid)) {
        $userid = $USER->id;
    }
    if (array_key_exists($course->id, $cache) and $cache[$course->id]->userid == $userid) {
        return $cache[$course->id];
    }
    if (empty($course->modinfo)) {
        // no modinfo yet - load it
        rebuild_course_cache($course->id);
        $course->modinfo = $DB->get_field('course', 'modinfo', array('id' => $course->id));
    }
    $modinfo = new object();
    $modinfo->courseid = $course->id;
    $modinfo->userid = $userid;
    $modinfo->sections = array();
    $modinfo->cms = array();
    $modinfo->instances = array();
    $modinfo->groups = null;
    // loaded only when really needed - the only one db query
    $info = unserialize($course->modinfo);
    if (!is_array($info)) {
        // hmm, something is wrong - lets try to fix it
        rebuild_course_cache($course->id);
        $course->modinfo = $DB->get_field('course', 'modinfo', array('id' => $course->id));
        $info = unserialize($course->modinfo);
        if (!is_array($info)) {
            return $modinfo;
        }
    }
    if ($info) {
        // detect if upgrade required
        $first = reset($info);
        if (!isset($first->id)) {
            rebuild_course_cache($course->id);
            $course->modinfo = $DB->get_field('course', 'modinfo', array('id' => $course->id));
            $info = unserialize($course->modinfo);
            if (!is_array($info)) {
                return $modinfo;
            }
        }
    }
    $modlurals = array();
    // If we haven't already preloaded contexts for the course, do it now
    preload_course_contexts($course->id);
    foreach ($info as $mod) {
        if (empty($mod->name)) {
            // something is wrong here
            continue;
        }
        // reconstruct minimalistic $cm
        $cm = new object();
        $cm->id = $mod->cm;
        $cm->instance = $mod->id;
        $cm->course = $course->id;
        $cm->modname = $mod->mod;
        $cm->name = urldecode($mod->name);
        $cm->visible = $mod->visible;
        $cm->sectionnum = $mod->section;
        $cm->groupmode = $mod->groupmode;
        $cm->groupingid = $mod->groupingid;
        $cm->groupmembersonly = $mod->groupmembersonly;
        $cm->indent = $mod->indent;
        $cm->completion = $mod->completion;
        $cm->extra = isset($mod->extra) ? urldecode($mod->extra) : '';
        $cm->icon = isset($mod->icon) ? $mod->icon : '';
        $cm->uservisible = true;
        if (!empty($CFG->enableavailability)) {
            // We must have completion information from modinfo. If it's not
            // there, cache needs rebuilding
            if (!isset($mod->availablefrom)) {
                debugging('enableavailability option was changed; rebuilding ' . 'cache for course ' . $course->id);
                rebuild_course_cache($course->id, true);
                // Re-enter this routine to do it all properly
                return get_fast_modinfo($course, $userid);
            }
            $cm->availablefrom = $mod->availablefrom;
            $cm->availableuntil = $mod->availableuntil;
            $cm->showavailability = $mod->showavailability;
            $cm->conditionscompletion = $mod->conditionscompletion;
            $cm->conditionsgrade = $mod->conditionsgrade;
        }
        // preload long names plurals and also check module is installed properly
        if (!isset($modlurals[$cm->modname])) {
            if (!file_exists("{$CFG->dirroot}/mod/{$cm->modname}/lib.php")) {
                continue;
            }
            $modlurals[$cm->modname] = get_string('modulenameplural', $cm->modname);
        }
        $cm->modplural = $modlurals[$cm->modname];
        $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
        if (!empty($CFG->enableavailability)) {
            // Unfortunately the next call really wants to call
            // get_fast_modinfo, but that would be recursive, so we fake up a
            // modinfo for it already
            if (empty($minimalmodinfo)) {
                $minimalmodinfo = new stdClass();
                $minimalmodinfo->cms = array();
                foreach ($info as $mod) {
                    $minimalcm = new stdClass();
                    $minimalcm->id = $mod->cm;
                    $minimalcm->name = urldecode($mod->name);
                    $minimalmodinfo->cms[$minimalcm->id] = $minimalcm;
                }
            }
            // Get availability information
            $ci = new condition_info($cm);
            $cm->available = $ci->is_available($cm->availableinfo, true, $userid, $minimalmodinfo);
        } else {
            $cm->available = true;
        }
        if ((!$cm->visible or !$cm->available) and !has_capability('moodle/course:viewhiddenactivities', $modcontext, $userid)) {
            $cm->uservisible = false;
        } else {
            if (!empty($CFG->enablegroupings) and !empty($cm->groupmembersonly) and !has_capability('moodle/site:accessallgroups', $modcontext, $userid)) {
                if (is_null($modinfo->groups)) {
                    $modinfo->groups = groups_get_user_groups($course->id, $userid);
                }
                if (empty($modinfo->groups[$cm->groupingid])) {
                    $cm->uservisible = false;
                }
            }
        }
        if (!isset($modinfo->instances[$cm->modname])) {
            $modinfo->instances[$cm->modname] = array();
        }
        $modinfo->instances[$cm->modname][$cm->instance] =& $cm;
        $modinfo->cms[$cm->id] =& $cm;
        // reconstruct sections
        if (!isset($modinfo->sections[$cm->sectionnum])) {
            $modinfo->sections[$cm->sectionnum] = array();
        }
        $modinfo->sections[$cm->sectionnum][] = $cm->id;
        unset($cm);
    }
    unset($cache[$course->id]);
    // prevent potential reference problems when switching users
    $cache[$course->id] = $modinfo;
    // Ensure cache does not use too much RAM
    if (count($cache) > MAX_MODINFO_CACHE_SIZE) {
        reset($cache);
        $key = key($cache);
        unset($cache[$key]);
    }
    return $cache[$course->id];
}
Example #23
0
 /**
  * Adds all the standard elements to a form to edit the settings for an activity module.
  */
 function standard_coursemodule_elements()
 {
     global $COURSE, $CFG, $DB;
     $mform =& $this->_form;
     $this->_outcomesused = false;
     if ($this->_features->outcomes) {
         if ($outcomes = grade_outcome::fetch_all_available($COURSE->id)) {
             $this->_outcomesused = true;
             $mform->addElement('header', 'modoutcomes', get_string('outcomes', 'grades'));
             foreach ($outcomes as $outcome) {
                 $mform->addElement('advcheckbox', 'outcome_' . $outcome->id, $outcome->get_name());
             }
         }
     }
     if ($this->_features->rating) {
         require_once $CFG->dirroot . '/rating/lib.php';
         $rm = new rating_manager();
         $mform->addElement('header', 'modstandardratings', get_string('ratings', 'rating'));
         $permission = CAP_ALLOW;
         $rolenamestring = null;
         if (!empty($this->_cm)) {
             $context = context_module::instance($this->_cm->id);
             $rolenames = get_role_names_with_caps_in_context($context, array('moodle/rating:rate', 'mod/' . $this->_cm->modname . ':rate'));
             $rolenamestring = implode(', ', $rolenames);
         } else {
             $rolenamestring = get_string('capabilitychecknotavailable', 'rating');
         }
         $mform->addElement('static', 'rolewarning', get_string('rolewarning', 'rating'), $rolenamestring);
         $mform->addHelpButton('rolewarning', 'rolewarning', 'rating');
         $mform->addElement('select', 'assessed', get_string('aggregatetype', 'rating'), $rm->get_aggregate_types());
         $mform->setDefault('assessed', 0);
         $mform->addHelpButton('assessed', 'aggregatetype', 'rating');
         $mform->addElement('modgrade', 'scale', get_string('scale'), false);
         $mform->disabledIf('scale', 'assessed', 'eq', 0);
         $mform->addElement('checkbox', 'ratingtime', get_string('ratingtime', 'rating'));
         $mform->disabledIf('ratingtime', 'assessed', 'eq', 0);
         $mform->addElement('date_time_selector', 'assesstimestart', get_string('from'));
         $mform->disabledIf('assesstimestart', 'assessed', 'eq', 0);
         $mform->disabledIf('assesstimestart', 'ratingtime');
         $mform->addElement('date_time_selector', 'assesstimefinish', get_string('to'));
         $mform->disabledIf('assesstimefinish', 'assessed', 'eq', 0);
         $mform->disabledIf('assesstimefinish', 'ratingtime');
     }
     //doing this here means splitting up the grade related settings on the lesson settings page
     //$this->standard_grading_coursemodule_elements();
     $mform->addElement('header', 'modstandardelshdr', get_string('modstandardels', 'form'));
     if ($this->_features->groups) {
         $options = array(NOGROUPS => get_string('groupsnone'), SEPARATEGROUPS => get_string('groupsseparate'), VISIBLEGROUPS => get_string('groupsvisible'));
         $mform->addElement('select', 'groupmode', get_string('groupmode', 'group'), $options, NOGROUPS);
         $mform->addHelpButton('groupmode', 'groupmode', 'group');
     }
     if ($this->_features->groupings or $this->_features->groupmembersonly) {
         //groupings selector - used for normal grouping mode or also when restricting access with groupmembersonly
         $options = array();
         $options[0] = get_string('none');
         if ($groupings = $DB->get_records('groupings', array('courseid' => $COURSE->id))) {
             foreach ($groupings as $grouping) {
                 $options[$grouping->id] = format_string($grouping->name);
             }
         }
         $mform->addElement('select', 'groupingid', get_string('grouping', 'group'), $options);
         $mform->addHelpButton('groupingid', 'grouping', 'group');
         $mform->setAdvanced('groupingid');
     }
     if ($this->_features->groupmembersonly) {
         $mform->addElement('checkbox', 'groupmembersonly', get_string('groupmembersonly', 'group'));
         $mform->addHelpButton('groupmembersonly', 'groupmembersonly', 'group');
         $mform->setAdvanced('groupmembersonly');
     }
     $mform->addElement('modvisible', 'visible', get_string('visible'));
     if (!empty($this->_cm)) {
         $context = context_module::instance($this->_cm->id);
         if (!has_capability('moodle/course:activityvisibility', $context)) {
             $mform->hardFreeze('visible');
         }
     }
     if ($this->_features->idnumber) {
         $mform->addElement('text', 'cmidnumber', get_string('idnumbermod'));
         $mform->addHelpButton('cmidnumber', 'idnumbermod');
     }
     if (!empty($CFG->enableavailability)) {
         // String used by conditions
         $strnone = get_string('none', 'condition');
         // Conditional availability
         // Available from/to defaults to midnight because then the display
         // will be nicer where it tells users when they can access it (it
         // shows only the date and not time).
         $date = usergetdate(time());
         $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
         // From/until controls
         $mform->addElement('header', 'availabilityconditionsheader', get_string('availabilityconditions', 'condition'));
         $mform->addElement('date_time_selector', 'availablefrom', get_string('availablefrom', 'condition'), array('optional' => true, 'defaulttime' => $midnight));
         $mform->addHelpButton('availablefrom', 'availablefrom', 'condition');
         $mform->addElement('date_time_selector', 'availableuntil', get_string('availableuntil', 'condition'), array('optional' => true, 'defaulttime' => $midnight));
         // Conditions based on grades
         $gradeoptions = array();
         $items = grade_item::fetch_all(array('courseid' => $COURSE->id));
         $items = $items ? $items : array();
         foreach ($items as $id => $item) {
             // Do not include grades for current item
             if (!empty($this->_cm) && $this->_cm->instance == $item->iteminstance && $this->_cm->modname == $item->itemmodule && $item->itemtype == 'mod') {
                 continue;
             }
             $gradeoptions[$id] = $item->get_name();
         }
         asort($gradeoptions);
         $gradeoptions = array(0 => $strnone) + $gradeoptions;
         $grouparray = array();
         $grouparray[] =& $mform->createElement('select', 'conditiongradeitemid', '', $gradeoptions);
         $grouparray[] =& $mform->createElement('static', '', '', ' ' . get_string('grade_atleast', 'condition') . ' ');
         $grouparray[] =& $mform->createElement('text', 'conditiongrademin', '', array('size' => 3));
         $grouparray[] =& $mform->createElement('static', '', '', '% ' . get_string('grade_upto', 'condition') . ' ');
         $grouparray[] =& $mform->createElement('text', 'conditiongrademax', '', array('size' => 3));
         $grouparray[] =& $mform->createElement('static', '', '', '%');
         $group = $mform->createElement('group', 'conditiongradegroup', get_string('gradecondition', 'condition'), $grouparray);
         // Get version with condition info and store it so we don't ask
         // twice
         if (!empty($this->_cm)) {
             $ci = new condition_info($this->_cm, CONDITION_MISSING_EXTRATABLE);
             $this->_cm = $ci->get_full_course_module();
             $count = count($this->_cm->conditionsgrade) + 1;
             $fieldcount = count($this->_cm->conditionsfield) + 1;
         } else {
             $count = 1;
             $fieldcount = 1;
         }
         $this->repeat_elements(array($group), $count, array(), 'conditiongraderepeats', 'conditiongradeadds', 2, get_string('addgrades', 'condition'), true);
         $mform->addHelpButton('conditiongradegroup[0]', 'gradecondition', 'condition');
         // Conditions based on user fields
         $operators = condition_info::get_condition_user_field_operators();
         $useroptions = condition_info::get_condition_user_fields();
         asort($useroptions);
         $useroptions = array(0 => $strnone) + $useroptions;
         $grouparray = array();
         $grouparray[] =& $mform->createElement('select', 'conditionfield', '', $useroptions);
         $grouparray[] =& $mform->createElement('select', 'conditionfieldoperator', '', $operators);
         $grouparray[] =& $mform->createElement('text', 'conditionfieldvalue');
         $mform->setType('conditionfieldvalue', PARAM_RAW);
         $group = $mform->createElement('group', 'conditionfieldgroup', get_string('userfield', 'condition'), $grouparray);
         $this->repeat_elements(array($group), $fieldcount, array(), 'conditionfieldrepeats', 'conditionfieldadds', 2, get_string('adduserfields', 'condition'), true);
         $mform->addHelpButton('conditionfieldgroup[0]', 'userfield', 'condition');
         // Conditions based on completion
         $completion = new completion_info($COURSE);
         if ($completion->is_enabled()) {
             $completionoptions = array();
             $modinfo = get_fast_modinfo($COURSE);
             foreach ($modinfo->cms as $id => $cm) {
                 // Add each course-module if it:
                 // (a) has completion turned on
                 // (b) is not the same as current course-module
                 if ($cm->completion && (empty($this->_cm) || $this->_cm->id != $id)) {
                     $completionoptions[$id] = $cm->name;
                 }
             }
             asort($completionoptions);
             $completionoptions = array(0 => $strnone) + $completionoptions;
             $completionvalues = array(COMPLETION_COMPLETE => get_string('completion_complete', 'condition'), COMPLETION_INCOMPLETE => get_string('completion_incomplete', 'condition'), COMPLETION_COMPLETE_PASS => get_string('completion_pass', 'condition'), COMPLETION_COMPLETE_FAIL => get_string('completion_fail', 'condition'));
             $grouparray = array();
             $grouparray[] =& $mform->createElement('select', 'conditionsourcecmid', '', $completionoptions);
             $grouparray[] =& $mform->createElement('select', 'conditionrequiredcompletion', '', $completionvalues);
             $group = $mform->createElement('group', 'conditioncompletiongroup', get_string('completioncondition', 'condition'), $grouparray);
             $count = empty($this->_cm) ? 1 : count($this->_cm->conditionscompletion) + 1;
             $this->repeat_elements(array($group), $count, array(), 'conditioncompletionrepeats', 'conditioncompletionadds', 2, get_string('addcompletions', 'condition'), true);
             $mform->addHelpButton('conditioncompletiongroup[0]', 'completioncondition', 'condition');
         }
         // Do we display availability info to students?
         $mform->addElement('select', 'showavailability', get_string('showavailability', 'condition'), array(CONDITION_STUDENTVIEW_SHOW => get_string('showavailability_show', 'condition'), CONDITION_STUDENTVIEW_HIDE => get_string('showavailability_hide', 'condition')));
         $mform->setDefault('showavailability', CONDITION_STUDENTVIEW_SHOW);
     }
     // Conditional activities: completion tracking section
     if (!isset($completion)) {
         $completion = new completion_info($COURSE);
     }
     if ($completion->is_enabled()) {
         $mform->addElement('header', 'activitycompletionheader', get_string('activitycompletion', 'completion'));
         // Unlock button for if people have completed it (will
         // be removed in definition_after_data if they haven't)
         $mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion'));
         $mform->registerNoSubmitButton('unlockcompletion');
         $mform->addElement('hidden', 'completionunlocked', 0);
         $mform->setType('completionunlocked', PARAM_INT);
         $mform->addElement('select', 'completion', get_string('completion', 'completion'), array(COMPLETION_TRACKING_NONE => get_string('completion_none', 'completion'), COMPLETION_TRACKING_MANUAL => get_string('completion_manual', 'completion')));
         $mform->setDefault('completion', $this->_features->defaultcompletion ? COMPLETION_TRACKING_MANUAL : COMPLETION_TRACKING_NONE);
         $mform->addHelpButton('completion', 'completion', 'completion');
         // Automatic completion once you view it
         $gotcompletionoptions = false;
         if (plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_TRACKS_VIEWS, false)) {
             $mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'), get_string('completionview_desc', 'completion'));
             $mform->disabledIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
             $gotcompletionoptions = true;
         }
         // Automatic completion once it's graded
         if (plugin_supports('mod', $this->_modname, FEATURE_GRADE_HAS_GRADE, false)) {
             $mform->addElement('checkbox', 'completionusegrade', get_string('completionusegrade', 'completion'), get_string('completionusegrade_desc', 'completion'));
             $mform->disabledIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
             $mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion');
             $gotcompletionoptions = true;
         }
         // Automatic completion according to module-specific rules
         $this->_customcompletionelements = $this->add_completion_rules();
         foreach ($this->_customcompletionelements as $element) {
             $mform->disabledIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
         }
         $gotcompletionoptions = $gotcompletionoptions || count($this->_customcompletionelements) > 0;
         // Automatic option only appears if possible
         if ($gotcompletionoptions) {
             $mform->getElement('completion')->addOption(get_string('completion_automatic', 'completion'), COMPLETION_TRACKING_AUTOMATIC);
         }
         // Completion expected at particular date? (For progress tracking)
         $mform->addElement('date_selector', 'completionexpected', get_string('completionexpected', 'completion'), array('optional' => true));
         $mform->addHelpButton('completionexpected', 'completionexpected', 'completion');
         $mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
     }
     $this->standard_hidden_coursemodule_elements();
 }
 public function test_cm_info_properties()
 {
     global $DB, $CFG;
     $this->resetAfterTest();
     $oldcfgenableavailability = $CFG->enableavailability;
     $oldcfgenablecompletion = $CFG->enablecompletion;
     set_config('enableavailability', 1);
     set_config('enablecompletion', 1);
     $this->setAdminUser();
     // Generate the course and pre-requisite module.
     $course = $this->getDataGenerator()->create_course(array('format' => 'topics', 'numsections' => 3, 'enablecompletion' => 1, 'groupmode' => SEPARATEGROUPS, 'forcegroupmode' => 0), array('createsections' => true));
     $coursecontext = context_course::instance($course->id);
     $prereqforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), array('completion' => 1));
     // Generate the module and add availability conditions.
     $conditionscompletion = array($prereqforum->cmid => COMPLETION_COMPLETE);
     $conditionsgrade = array(666 => (object) array('min' => 0.4, 'max' => null, 'name' => '!missing'));
     $conditionsfield = array('email' => (object) array('fieldname' => 'email', 'operator' => 'contains', 'value' => 'test'));
     $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id), array('idnumber' => 123, 'groupmode' => VISIBLEGROUPS, 'availablefrom' => time() + 3600, 'availableuntil' => time() + 5 * 3600));
     $ci = new condition_info((object) array('id' => $assign->cmid), CONDITION_MISSING_EVERYTHING);
     foreach ($conditionscompletion as $cmid => $requiredcompletion) {
         $ci->add_completion_condition($cmid, $requiredcompletion);
     }
     foreach ($conditionsgrade as $gradeid => $conditiongrade) {
         $ci->add_grade_condition($gradeid, $conditiongrade->min, $conditiongrade->max, true);
     }
     foreach ($conditionsfield as $conditionfield) {
         $ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value);
     }
     // Direct access to condition_info functions does not reset course cache, do it manually.
     rebuild_course_cache($course->id, true);
     // Retrieve all related records from DB.
     $assigndb = $DB->get_record('assign', array('id' => $assign->id));
     $moduletypedb = $DB->get_record('modules', array('name' => 'assign'));
     $moduledb = $DB->get_record('course_modules', array('module' => $moduletypedb->id, 'instance' => $assign->id));
     $sectiondb = $DB->get_record('course_sections', array('id' => $moduledb->section));
     $modnamessingular = get_module_types_names(false);
     $modnamesplural = get_module_types_names(true);
     // Create and enrol a student.
     $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
     $student = $this->getDataGenerator()->create_user();
     role_assign($studentrole->id, $student->id, $coursecontext);
     $enrolplugin = enrol_get_plugin('manual');
     $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
     $enrolplugin->enrol_user($enrolinstance, $student->id);
     $this->setUser($student);
     // Emulate data used in building course cache to receive the same instance of cached_cm_info as was used in building modinfo.
     $rawmods = get_course_mods($course->id);
     $cachedcminfo = assign_get_coursemodule_info($rawmods[$moduledb->id]);
     // Get modinfo.
     $modinfo = get_fast_modinfo($course->id);
     $cm = $modinfo->instances['assign'][$assign->id];
     $this->assertEquals($moduledb->id, $cm->id);
     $this->assertEquals($assigndb->id, $cm->instance);
     $this->assertEquals($moduledb->course, $cm->course);
     $this->assertEquals($moduledb->idnumber, $cm->idnumber);
     $this->assertEquals($moduledb->added, $cm->added);
     $this->assertEquals($moduledb->visible, $cm->visible);
     $this->assertEquals($moduledb->visibleold, $cm->visibleold);
     $this->assertEquals($moduledb->groupmode, $cm->groupmode);
     $this->assertEquals(VISIBLEGROUPS, $cm->groupmode);
     $this->assertEquals($moduledb->groupingid, $cm->groupingid);
     $this->assertEquals($moduledb->groupmembersonly, $cm->groupmembersonly);
     $this->assertEquals($course->groupmodeforce, $cm->coursegroupmodeforce);
     $this->assertEquals($course->groupmode, $cm->coursegroupmode);
     $this->assertEquals(SEPARATEGROUPS, $cm->coursegroupmode);
     $this->assertEquals($course->groupmodeforce ? $course->groupmode : $moduledb->groupmode, $cm->effectivegroupmode);
     // (since mod_assign supports groups).
     $this->assertEquals(VISIBLEGROUPS, $cm->effectivegroupmode);
     $this->assertEquals($moduledb->indent, $cm->indent);
     $this->assertEquals($moduledb->completion, $cm->completion);
     $this->assertEquals($moduledb->completiongradeitemnumber, $cm->completiongradeitemnumber);
     $this->assertEquals($moduledb->completionview, $cm->completionview);
     $this->assertEquals($moduledb->completionexpected, $cm->completionexpected);
     $this->assertEquals($moduledb->availablefrom, $cm->availablefrom);
     $this->assertEquals($moduledb->availableuntil, $cm->availableuntil);
     $this->assertEquals($moduledb->showavailability, $cm->showavailability);
     $this->assertEquals($moduledb->showdescription, $cm->showdescription);
     $this->assertEquals(null, $cm->extra);
     // Deprecated field. Used in module types that don't return cached_cm_info.
     $this->assertEquals($cachedcminfo->icon, $cm->icon);
     $this->assertEquals($cachedcminfo->iconcomponent, $cm->iconcomponent);
     $this->assertEquals('assign', $cm->modname);
     $this->assertEquals($moduledb->module, $cm->module);
     $this->assertEquals($cachedcminfo->name, $cm->name);
     $this->assertEquals($sectiondb->section, $cm->sectionnum);
     $this->assertEquals($moduledb->section, $cm->section);
     $this->assertEquals($conditionscompletion, $cm->conditionscompletion);
     $this->assertEquals($conditionsgrade, $cm->conditionsgrade);
     $this->assertEquals($conditionsfield, $cm->conditionsfield);
     $this->assertEquals(context_module::instance($moduledb->id), $cm->context);
     $this->assertEquals($modnamessingular['assign'], $cm->modfullname);
     $this->assertEquals($modnamesplural['assign'], $cm->modplural);
     $this->assertEquals(new moodle_url('/mod/assign/view.php', array('id' => $moduledb->id)), $cm->url);
     $this->assertEquals($cachedcminfo->customdata, $cm->customdata);
     // Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type).
     $this->assertNotEmpty($cm->availableinfo);
     // Lists all unmet availability conditions.
     $this->assertEquals(0, $cm->uservisible);
     $this->assertEquals('', $cm->extraclasses);
     $this->assertEquals('', $cm->onclick);
     $this->assertEquals(null, $cm->afterlink);
     $this->assertEquals(null, $cm->afterediticons);
     $this->assertEquals('', $cm->content);
     // Attempt to access and set non-existing field.
     $this->assertTrue(empty($modinfo->somefield));
     $this->assertFalse(isset($modinfo->somefield));
     $cm->somefield;
     $this->assertDebuggingCalled();
     $cm->somefield = 'Some value';
     $this->assertDebuggingCalled();
     $this->assertEmpty($cm->somefield);
     $this->assertDebuggingCalled();
     // Attempt to overwrite an existing field.
     $prevvalue = $cm->name;
     $this->assertNotEmpty($cm->name);
     $this->assertFalse(empty($cm->name));
     $this->assertTrue(isset($cm->name));
     $cm->name = 'Illegal overwriting';
     $this->assertDebuggingCalled();
     $this->assertEquals($prevvalue, $cm->name);
     $this->assertDebuggingNotCalled();
     // Restore settings.
     set_config('enableavailability', $oldcfgenableavailability);
     set_config('enablecompletion', $oldcfgenablecompletion);
 }
Example #25
0
/**
 * For a given course, returns an array of course activity objects
 * Each item in the array contains he following properties:
 */
function get_array_of_activities($courseid)
{
    //  cm - course module id
    //  mod - name of the module (eg forum)
    //  section - the number of the section (eg week or topic)
    //  name - the name of the instance
    //  visible - is the instance visible or not
    //  groupingid - grouping id
    //  groupmembersonly - is this instance visible to group members only
    //  extra - contains extra string to include in any link
    global $CFG, $DB;
    if (!empty($CFG->enableavailability)) {
        require_once $CFG->libdir . '/conditionlib.php';
    }
    $course = $DB->get_record('course', array('id' => $courseid));
    if (empty($course)) {
        throw new moodle_exception('courseidnotfound');
    }
    $mod = array();
    $rawmods = get_course_mods($courseid);
    if (empty($rawmods)) {
        return $mod;
        // always return array
    }
    if ($sections = $DB->get_records('course_sections', array('course' => $courseid), 'section ASC', 'id,section,sequence')) {
        // First check and correct obvious mismatches between course_sections.sequence and course_modules.section.
        if ($errormessages = course_integrity_check($courseid, $rawmods, $sections)) {
            debugging(join('<br>', $errormessages));
            $rawmods = get_course_mods($courseid);
            $sections = $DB->get_records('course_sections', array('course' => $courseid), 'section ASC', 'id,section,sequence');
        }
        // Build array of activities.
        foreach ($sections as $section) {
            if (!empty($section->sequence)) {
                $sequence = explode(",", $section->sequence);
                foreach ($sequence as $seq) {
                    if (empty($rawmods[$seq])) {
                        continue;
                    }
                    $mod[$seq] = new stdClass();
                    $mod[$seq]->id = $rawmods[$seq]->instance;
                    $mod[$seq]->cm = $rawmods[$seq]->id;
                    $mod[$seq]->mod = $rawmods[$seq]->modname;
                    // Oh dear. Inconsistent names left here for backward compatibility.
                    $mod[$seq]->section = $section->section;
                    $mod[$seq]->sectionid = $rawmods[$seq]->section;
                    $mod[$seq]->module = $rawmods[$seq]->module;
                    $mod[$seq]->added = $rawmods[$seq]->added;
                    $mod[$seq]->score = $rawmods[$seq]->score;
                    $mod[$seq]->idnumber = $rawmods[$seq]->idnumber;
                    $mod[$seq]->visible = $rawmods[$seq]->visible;
                    $mod[$seq]->visibleold = $rawmods[$seq]->visibleold;
                    $mod[$seq]->groupmode = $rawmods[$seq]->groupmode;
                    $mod[$seq]->groupingid = $rawmods[$seq]->groupingid;
                    $mod[$seq]->groupmembersonly = $rawmods[$seq]->groupmembersonly;
                    $mod[$seq]->indent = $rawmods[$seq]->indent;
                    $mod[$seq]->completion = $rawmods[$seq]->completion;
                    $mod[$seq]->extra = "";
                    $mod[$seq]->completiongradeitemnumber = $rawmods[$seq]->completiongradeitemnumber;
                    $mod[$seq]->completionview = $rawmods[$seq]->completionview;
                    $mod[$seq]->completionexpected = $rawmods[$seq]->completionexpected;
                    $mod[$seq]->availablefrom = $rawmods[$seq]->availablefrom;
                    $mod[$seq]->availableuntil = $rawmods[$seq]->availableuntil;
                    $mod[$seq]->showavailability = $rawmods[$seq]->showavailability;
                    $mod[$seq]->showdescription = $rawmods[$seq]->showdescription;
                    if (!empty($CFG->enableavailability)) {
                        condition_info::fill_availability_conditions($rawmods[$seq]);
                        $mod[$seq]->conditionscompletion = $rawmods[$seq]->conditionscompletion;
                        $mod[$seq]->conditionsgrade = $rawmods[$seq]->conditionsgrade;
                        $mod[$seq]->conditionsfield = $rawmods[$seq]->conditionsfield;
                    }
                    $modname = $mod[$seq]->mod;
                    $functionname = $modname . "_get_coursemodule_info";
                    if (!file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) {
                        continue;
                    }
                    include_once "{$CFG->dirroot}/mod/{$modname}/lib.php";
                    if ($hasfunction = function_exists($functionname)) {
                        if ($info = $functionname($rawmods[$seq])) {
                            if (!empty($info->icon)) {
                                $mod[$seq]->icon = $info->icon;
                            }
                            if (!empty($info->iconcomponent)) {
                                $mod[$seq]->iconcomponent = $info->iconcomponent;
                            }
                            if (!empty($info->name)) {
                                $mod[$seq]->name = $info->name;
                            }
                            if ($info instanceof cached_cm_info) {
                                // When using cached_cm_info you can include three new fields
                                // that aren't available for legacy code
                                if (!empty($info->content)) {
                                    $mod[$seq]->content = $info->content;
                                }
                                if (!empty($info->extraclasses)) {
                                    $mod[$seq]->extraclasses = $info->extraclasses;
                                }
                                if (!empty($info->iconurl)) {
                                    // Convert URL to string as it's easier to store. Also serialized object contains \0 byte and can not be written to Postgres DB.
                                    $url = new moodle_url($info->iconurl);
                                    $mod[$seq]->iconurl = $url->out(false);
                                }
                                if (!empty($info->onclick)) {
                                    $mod[$seq]->onclick = $info->onclick;
                                }
                                if (!empty($info->customdata)) {
                                    $mod[$seq]->customdata = $info->customdata;
                                }
                            } else {
                                // When using a stdclass, the (horrible) deprecated ->extra field
                                // is available for BC
                                if (!empty($info->extra)) {
                                    $mod[$seq]->extra = $info->extra;
                                }
                            }
                        }
                    }
                    // When there is no modname_get_coursemodule_info function,
                    // but showdescriptions is enabled, then we use the 'intro'
                    // and 'introformat' fields in the module table
                    if (!$hasfunction && $rawmods[$seq]->showdescription) {
                        if ($modvalues = $DB->get_record($rawmods[$seq]->modname, array('id' => $rawmods[$seq]->instance), 'name, intro, introformat')) {
                            // Set content from intro and introformat. Filters are disabled
                            // because we  filter it with format_text at display time
                            $mod[$seq]->content = format_module_intro($rawmods[$seq]->modname, $modvalues, $rawmods[$seq]->id, false);
                            // To save making another query just below, put name in here
                            $mod[$seq]->name = $modvalues->name;
                        }
                    }
                    if (!isset($mod[$seq]->name)) {
                        $mod[$seq]->name = $DB->get_field($rawmods[$seq]->modname, "name", array("id" => $rawmods[$seq]->instance));
                    }
                    // Minimise the database size by unsetting default options when they are
                    // 'empty'. This list corresponds to code in the cm_info constructor.
                    foreach (array('idnumber', 'groupmode', 'groupingid', 'groupmembersonly', 'indent', 'completion', 'extra', 'extraclasses', 'iconurl', 'onclick', 'content', 'icon', 'iconcomponent', 'customdata', 'showavailability', 'availablefrom', 'availableuntil', 'conditionscompletion', 'conditionsgrade', 'completionview', 'completionexpected', 'score', 'showdescription') as $property) {
                        if (property_exists($mod[$seq], $property) && empty($mod[$seq]->{$property})) {
                            unset($mod[$seq]->{$property});
                        }
                    }
                    // Special case: this value is usually set to null, but may be 0
                    if (property_exists($mod[$seq], 'completiongradeitemnumber') && is_null($mod[$seq]->completiongradeitemnumber)) {
                        unset($mod[$seq]->completiongradeitemnumber);
                    }
                }
            }
        }
    }
    return $mod;
}
/**
 * Add course module.
 *
 * The function does not check user capabilities.
 * The function creates course module, module instance, add the module to the correct section.
 * It also trigger common action that need to be done after adding/updating a module.
 *
 * @param object $moduleinfo the moudle data
 * @param object $course the course of the module
 * @param object $mform this is required by an existing hack to deal with files during MODULENAME_add_instance()
 * @return object the updated module info
 */
function local_ltiprovider_add_moduleinfo($moduleinfo, $course, $mform = null)
{
    global $DB, $CFG;
    $moduleinfo->course = $course->id;
    $moduleinfo = local_ltiprovider_set_moduleinfo_defaults($moduleinfo);
    if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) {
        $moduleinfo->groupmode = 0;
        // Do not set groupmode.
    }
    if (!course_allowed_module($course, $moduleinfo->modulename)) {
        print_error('moduledisable', '', '', $moduleinfo->modulename);
    }
    // First add course_module record because we need the context.
    $newcm = new stdClass();
    $newcm->course = $course->id;
    $newcm->module = $moduleinfo->module;
    $newcm->instance = 0;
    // Not known yet, will be updated later (this is similar to restore code).
    $newcm->visible = $moduleinfo->visible;
    $newcm->visibleold = $moduleinfo->visible;
    $newcm->groupmode = $moduleinfo->groupmode;
    $newcm->groupingid = $moduleinfo->groupingid;
    $newcm->groupmembersonly = $moduleinfo->groupmembersonly;
    $completion = new completion_info($course);
    if ($completion->is_enabled()) {
        $newcm->completion = $moduleinfo->completion;
        $newcm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber;
        $newcm->completionview = $moduleinfo->completionview;
        $newcm->completionexpected = $moduleinfo->completionexpected;
    }
    if (!empty($CFG->enableavailability)) {
        $newcm->availablefrom = $moduleinfo->availablefrom;
        $newcm->availableuntil = $moduleinfo->availableuntil;
        $newcm->showavailability = $moduleinfo->showavailability;
    }
    if (isset($moduleinfo->showdescription)) {
        $newcm->showdescription = $moduleinfo->showdescription;
    } else {
        $newcm->showdescription = 0;
    }
    if (!($moduleinfo->coursemodule = add_course_module($newcm))) {
        print_error('cannotaddcoursemodule');
    }
    if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) {
        $introeditor = $moduleinfo->introeditor;
        unset($moduleinfo->introeditor);
        $moduleinfo->intro = $introeditor['text'];
        $moduleinfo->introformat = $introeditor['format'];
    }
    $addinstancefunction = $moduleinfo->modulename . "_add_instance";
    $returnfromfunc = $addinstancefunction($moduleinfo, $mform);
    if (!$returnfromfunc or !is_number($returnfromfunc)) {
        // Undo everything we can.
        $modcontext = context_module::instance($moduleinfo->coursemodule);
        delete_context(CONTEXT_MODULE, $moduleinfo->coursemodule);
        $DB->delete_records('course_modules', array('id' => $moduleinfo->coursemodule));
        if (!is_number($returnfromfunc)) {
            print_error('invalidfunction', '', course_get_url($course, $cw->section));
        } else {
            print_error('cannotaddnewmodule', '', course_get_url($course, $cw->section), $moduleinfo->modulename);
        }
    }
    $moduleinfo->instance = $returnfromfunc;
    $DB->set_field('course_modules', 'instance', $returnfromfunc, array('id' => $moduleinfo->coursemodule));
    // Update embedded links and save files.
    $modcontext = context_module::instance($moduleinfo->coursemodule);
    if (!empty($introeditor)) {
        $moduleinfo->intro = file_save_draft_area_files($introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $introeditor['text']);
        $DB->set_field($moduleinfo->modulename, 'intro', $moduleinfo->intro, array('id' => $moduleinfo->instance));
    }
    // Course_modules and course_sections each contain a reference to each other.
    // So we have to update one of them twice.
    $sectionid = course_add_cm_to_section($course, $moduleinfo->coursemodule, $moduleinfo->section);
    // Make sure visibility is set correctly (in particular in calendar).
    // Note: allow them to set it even without moodle/course:activityvisibility.
    set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible);
    if (isset($moduleinfo->cmidnumber)) {
        // Label.
        // Set cm idnumber - uniqueness is already verified by form validation.
        set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber);
    }
    // Set up conditions.
    if ($CFG->enableavailability) {
        condition_info::update_cm_from_form((object) array('id' => $moduleinfo->coursemodule), $moduleinfo, false);
    }
    $eventname = 'mod_created';
    add_to_log($course->id, "course", "add mod", "../mod/{$moduleinfo->modulename}/view.php?id={$moduleinfo->coursemodule}", "{$moduleinfo->modulename} {$moduleinfo->instance}");
    add_to_log($course->id, $moduleinfo->modulename, "add", "view.php?id={$moduleinfo->coursemodule}", "{$moduleinfo->instance}", $moduleinfo->coursemodule);
    $moduleinfo = local_ltiprovider_edit_module_post_actions($moduleinfo, $course, 'mod_created');
    return $moduleinfo;
}
/**
 * Prints a section full of activity modules
 * @Overrides course/lib.php=>print_section
 */
function ss_print_section($course, $section, $mods, $modnamesused, $absolute=false, $width="100%", $hidecompletion=false) {
	#print_r($mods);
	
	global $CFG, $USER, $DB, $PAGE, $OUTPUT;

    static $initialised;

    static $groupbuttons;
    static $groupbuttonslink;
    static $isediting;
    static $ismoving;
    static $strmovehere;
    static $strmovefull;
    static $strunreadpostsone;
    static $usetracking;
    static $groupings;

    if (!isset($initialised)) {
        $groupbuttons     = ($course->groupmode or (!$course->groupmodeforce));
        $groupbuttonslink = (!$course->groupmodeforce);
        $isediting        = $PAGE->user_is_editing();
        $ismoving         = $isediting && ismoving($course->id);
        if ($ismoving) {
            $strmovehere  = get_string("movehere");
            $strmovefull  = strip_tags(get_string("movefull", "", "'$USER->activitycopyname'"));
        }
        include_once($CFG->dirroot.'/mod/forum/lib.php');
        if ($usetracking = forum_tp_can_track_forums()) {
            $strunreadpostsone = get_string('unreadpostsone', 'forum');
        }
        $initialised = true;
    }

    $labelformatoptions = new stdClass();
    $labelformatoptions->noclean = true;
    $labelformatoptions->overflowdiv = true;

/// Casting $course->modinfo to string prevents one notice when the field is null
    $modinfo = get_fast_modinfo($course);
    $completioninfo = new completion_info($course);

    //Accessibility: replace table with list <ul>, but don't output empty list.
    if (!empty($section->sequence)) {

        // Fix bug #5027, don't want style=\"width:$width\".
        echo "<ul class=\"section img-text\">\n";
        $sectionmods = explode(",", $section->sequence);

        foreach ($sectionmods as $modnumber) {
            if (empty($mods[$modnumber])) {
                continue;
            }

            $mod = $mods[$modnumber];
            
            if ($ismoving and $mod->id == $USER->activitycopy) {
                // do not display moving mod
                continue;
            }

            if (isset($modinfo->cms[$modnumber])) {
                // We can continue (because it will not be displayed at all)
                // if:
                // 1) The activity is not visible to users
                // and
                // 2a) The 'showavailability' option is not set (if that is set,
                //     we need to display the activity so we can show
                //     availability info)
                // or
                // 2b) The 'availableinfo' is empty, i.e. the activity was
                //     hidden in a way that leaves no info, such as using the
                //     eye icon.
                if (!$modinfo->cms[$modnumber]->uservisible &&
                    (empty($modinfo->cms[$modnumber]->showavailability) ||
                      empty($modinfo->cms[$modnumber]->availableinfo))) {
                    // visibility shortcut
                    continue;
                }
            } else {
                if (!file_exists("$CFG->dirroot/mod/$mod->modname/lib.php")) {
                    // module not installed
                    continue;
                }
                if (!coursemodule_visible_for_user($mod) &&
                    empty($mod->showavailability)) {
                    // full visibility check
                    continue;
                }
            }

            // In some cases the activity is visible to user, but it is
            // dimmed. This is done if viewhiddenactivities is true and if:
            // 1. the activity is not visible, or
            // 2. the activity has dates set which do not include current, or
            // 3. the activity has any other conditions set (regardless of whether
            //    current user meets them)
            $canviewhidden = has_capability(
                'moodle/course:viewhiddenactivities',
                get_context_instance(CONTEXT_MODULE, $mod->id));
            $accessiblebutdim = false;
            if ($canviewhidden) {
                $accessiblebutdim = !$mod->visible;
                if (!empty($CFG->enableavailability)) {
                    $accessiblebutdim = $accessiblebutdim ||
                        $mod->availablefrom > time() ||
                        ($mod->availableuntil && $mod->availableuntil < time()) ||
                        count($mod->conditionsgrade) > 0 ||
                        count($mod->conditionscompletion) > 0;
                }
            }

            $liclasses = array();
            $liclasses[] = 'activity';
            $liclasses[] = $mod->modname;
            $liclasses[] = 'modtype_'.$mod->modname;
            
            
            echo html_writer::start_tag('li', array('class'=>join(' ', $liclasses), 'id'=>'module-'.$modnumber));
            if ($ismoving) {
                echo '<a title="'.$strmovefull.'"'.
                     ' href="'.$CFG->wwwroot.'/course/mod.php?moveto='.$mod->id.'&amp;sesskey='.sesskey().'">'.
                     '<img class="movetarget" src="'.$OUTPUT->pix_url('movehere') . '" '.
                     ' alt="'.$strmovehere.'" /></a><br />
                     ';
            }

            $classes = array('mod-indent');
            if (!empty($mod->indent)) {
                $classes[] = 'mod-indent-'.$mod->indent;
                if ($mod->indent > 15) {
                    $classes[] = 'mod-indent-huge';
                }
            }
            echo html_writer::start_tag('div', array('class'=>join(' ', $classes)));

            $extra = '';
            if (!empty($modinfo->cms[$modnumber]->extra)) {
                $extra = $modinfo->cms[$modnumber]->extra;
            }
            
            if ($mod->modname == "label") {
                if ($accessiblebutdim || !$mod->uservisible) {
                    echo '<div class="dimmed_text"><span class="accesshide">'.
                        get_string('hiddenfromstudents').'</span>';
                } else {
                    echo '<div>';
                }
                echo format_text($extra, FORMAT_HTML, $labelformatoptions);
                echo "</div>";
                if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
                    if (!isset($groupings)) {
                        $groupings = groups_get_all_groupings($course->id);
                    }
                    echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
                }

            } else { // Normal activity
                $instancename = format_string($modinfo->cms[$modnumber]->name, true,  $course->id);
              #  echo format_string($modinfo->cms[$modnumber]->intro, true,  $course->id);
              #  echo format_string($modinfo->cms[$modnumber]->name, true,  $course->id);
              #  print_r($modinfo->cms[$modnumber]);

                $customicon = $modinfo->cms[$modnumber]->icon;
                if (!empty($customicon)) {
                    if (substr($customicon, 0, 4) === 'mod/') {
                        list($modname, $iconname) = explode('/', substr($customicon, 4), 2);
                        $icon = $OUTPUT->pix_url($iconname, $modname);
                    } else {
                        $icon = $OUTPUT->pix_url($customicon);
                    }
                } else {
                    $icon = $OUTPUT->pix_url('icon', $mod->modname);
                }

                //Accessibility: for files get description via icon, this is very ugly hack!
                $altname = '';
                $altname = $mod->modfullname;
                if (!empty($customicon)) {
                    $archetype = plugin_supports('mod', $mod->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
                    if ($archetype == MOD_ARCHETYPE_RESOURCE) {
                        $mimetype = mimeinfo_from_icon('type', $customicon);
                        $altname = get_mimetype_description($mimetype);
                    }
                }
                // Avoid unnecessary duplication.
                if (false !== stripos($instancename, $altname)) {
                    $altname = '';
                }
                // File type after name, for alphabetic lists (screen reader).
                if ($altname) {
                    $altname = get_accesshide(' '.$altname);
                }

                // We may be displaying this just in order to show information
                // about visibility, without the actual link
                if ($mod->uservisible) {
                    // Display normal module link
                    if (!$accessiblebutdim) {
                        $linkcss = '';
                        $accesstext  ='';
                    } else {
                        $linkcss = ' class="dimmed" ';
                        $accesstext = '<span class="accesshide">'.
                            get_string('hiddenfromstudents').': </span>';
                    }

                    echo '<a '.$linkcss.' '.$extra.
                         ' href="'.$CFG->wwwroot.'/mod/'.$mod->modname.'/view.php?id='.$mod->id.'">'.
                         '<img src="'.$icon.'" class="activityicon" alt="'.get_string('modulename',$mod->modname).'" /> '.
                         $accesstext.'<span class="instancename">'.$instancename.$altname.'</span></a>';

                    if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
                        if (!isset($groupings)) {
                            $groupings = groups_get_all_groupings($course->id);
                        }
                        echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
                    }
                } else {
                    // Display greyed-out text of link
                    echo '<span class="dimmed_text" '.$extra.' ><span class="accesshide">'.
                        get_string('notavailableyet','condition').': </span>'.
                        '<img src="'.$icon.'" class="activityicon" alt="'.get_string('modulename', $mod->modname).'" /> <span>'.
                        $instancename.$altname.'</span></span>';
                }
            }
            if ($usetracking && $mod->modname == 'forum') {
                if ($unread = forum_tp_count_forum_unread_posts($mod, $course)) {
                    echo '<span class="unread"> <a href="'.$CFG->wwwroot.'/mod/forum/view.php?id='.$mod->id.'">';
                    if ($unread == 1) {
                        echo $strunreadpostsone;
                    } else {
                        print_string('unreadpostsnumber', 'forum', $unread);
                    }
                    echo '</a></span>';
                }
            }

            if ($isediting) {
                if ($groupbuttons and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
                    if (! $mod->groupmodelink = $groupbuttonslink) {
                        $mod->groupmode = $course->groupmode;
                    }

                } else {
                    $mod->groupmode = false;
                }
                echo '&nbsp;&nbsp;';
                echo make_editing_buttons($mod, $absolute, true, $mod->indent, $section->section);
                hook_make_edit_icon_button($mod, $OUTPUT);
                
            }

            // Completion
            $completion = $hidecompletion
                ? COMPLETION_TRACKING_NONE
                : $completioninfo->is_enabled($mod);
            if ($completion!=COMPLETION_TRACKING_NONE && isloggedin() &&
                !isguestuser() && $mod->uservisible) {
                $completiondata = $completioninfo->get_data($mod,true);
                $completionicon = '';
                if ($isediting) {
                    switch ($completion) {
                        case COMPLETION_TRACKING_MANUAL :
                            $completionicon = 'manual-enabled'; break;
                        case COMPLETION_TRACKING_AUTOMATIC :
                            $completionicon = 'auto-enabled'; break;
                        default: // wtf
                    }
                } else if ($completion==COMPLETION_TRACKING_MANUAL) {
                    switch($completiondata->completionstate) {
                        case COMPLETION_INCOMPLETE:
                            $completionicon = 'manual-n'; break;
                        case COMPLETION_COMPLETE:
                            $completionicon = 'manual-y'; break;
                    }
                } else { // Automatic
                    switch($completiondata->completionstate) {
                        case COMPLETION_INCOMPLETE:
                            $completionicon = 'auto-n'; break;
                        case COMPLETION_COMPLETE:
                            $completionicon = 'auto-y'; break;
                        case COMPLETION_COMPLETE_PASS:
                            $completionicon = 'auto-pass'; break;
                        case COMPLETION_COMPLETE_FAIL:
                            $completionicon = 'auto-fail'; break;
                    }
                }
                if ($completionicon) {
                    $imgsrc = $OUTPUT->pix_url('i/completion-'.$completionicon);
                    $imgalt = s(get_string('completion-alt-'.$completionicon, 'completion'));
                    if ($completion == COMPLETION_TRACKING_MANUAL && !$isediting) {
                        $imgtitle = s(get_string('completion-title-'.$completionicon, 'completion'));
                        $newstate =
                            $completiondata->completionstate==COMPLETION_COMPLETE
                            ? COMPLETION_INCOMPLETE
                            : COMPLETION_COMPLETE;
                        // In manual mode the icon is a toggle form...

                        // If this completion state is used by the
                        // conditional activities system, we need to turn
                        // off the JS.
                        if (!empty($CFG->enableavailability) &&
                            condition_info::completion_value_used_as_condition($course, $mod)) {
                            $extraclass = ' preventjs';
                        } else {
                            $extraclass = '';
                        }
                        echo "
<form class='togglecompletion$extraclass' method='post' action='togglecompletion.php'><div>
<input type='hidden' name='id' value='{$mod->id}' />
<input type='hidden' name='sesskey' value='".sesskey()."' />
<input type='hidden' name='completionstate' value='$newstate' />
<input type='image' src='$imgsrc' alt='$imgalt' title='$imgtitle' />
</div></form>";
                    } else {
                        // In auto mode, or when editing, the icon is just an image
                        echo "<span class='autocompletion'>";
                        echo "<img src='$imgsrc' alt='$imgalt' title='$imgalt' /></span>";
                    }
                }
            }

            // Show availability information (for someone who isn't allowed to
            // see the activity itself, or for staff)
            if (!$mod->uservisible) {
                echo '<div class="availabilityinfo">'.$mod->availableinfo.'</div>';
            } else if ($canviewhidden && !empty($CFG->enableavailability)) {
                $ci = new condition_info($mod);
                $fullinfo = $ci->get_full_information();
                if($fullinfo) {
                    echo '<div class="availabilityinfo">'.get_string($mod->showavailability
                        ? 'userrestriction_visible'
                        : 'userrestriction_hidden','condition',
                        $fullinfo).'</div>';
                }
            }

            echo hook_show_activity_intro($mod);
            echo html_writer::end_tag('div');
            echo html_writer::end_tag('li')."\n";
        }

    } elseif ($ismoving) {
        echo "<ul class=\"section\">\n";
    }

    if ($ismoving) {
        echo '<li><a title="'.$strmovefull.'"'.
             ' href="'.$CFG->wwwroot.'/course/mod.php?movetosection='.$section->id.'&amp;sesskey='.sesskey().'">'.
             '<img class="movetarget" src="'.$OUTPUT->pix_url('movehere') . '" '.
             ' alt="'.$strmovehere.'" /></a></li>
             ';
    }
    if (!empty($section->sequence) || $ismoving) {
        echo "</ul><!--class='section'-->\n\n";
    }
}
Example #28
0
/**
 * Update the module info.
 * This function doesn't check the user capabilities. It updates the course module and the module instance.
 * Then execute common action to create/update module process (trigger event, rebuild cache, save plagiarism settings...).
 *
 * @param object $cm course module
 * @param object $moduleinfo module info
 * @param object $course course of the module
 * @param object $mform - the mform is required by some specific module in the function MODULE_update_instance(). This is due to a hack in this function.
 * @return array list of course module and module info.
 */
function update_moduleinfo($cm, $moduleinfo, $course, $mform = null)
{
    global $DB, $CFG;
    // Attempt to include module library before we make any changes to DB.
    include_modulelib($moduleinfo->modulename);
    $moduleinfo->course = $course->id;
    $moduleinfo = set_moduleinfo_defaults($moduleinfo);
    if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) {
        $moduleinfo->groupmode = $cm->groupmode;
        // Keep original.
    }
    // Update course module first.
    $cm->groupmode = $moduleinfo->groupmode;
    if (isset($moduleinfo->groupingid)) {
        $cm->groupingid = $moduleinfo->groupingid;
    }
    if (isset($moduleinfo->groupmembersonly)) {
        $cm->groupmembersonly = $moduleinfo->groupmembersonly;
    }
    $completion = new completion_info($course);
    if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) {
        // Update completion settings.
        $cm->completion = $moduleinfo->completion;
        $cm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber;
        $cm->completionview = $moduleinfo->completionview;
        $cm->completionexpected = $moduleinfo->completionexpected;
    }
    if (!empty($CFG->enableavailability)) {
        $cm->availablefrom = $moduleinfo->availablefrom;
        $cm->availableuntil = $moduleinfo->availableuntil;
        $cm->showavailability = $moduleinfo->showavailability;
        condition_info::update_cm_from_form($cm, $moduleinfo, true);
    }
    if (isset($moduleinfo->showdescription)) {
        $cm->showdescription = $moduleinfo->showdescription;
    } else {
        $cm->showdescription = 0;
    }
    $DB->update_record('course_modules', $cm);
    $modcontext = context_module::instance($moduleinfo->coursemodule);
    // Update embedded links and save files.
    if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) {
        $moduleinfo->intro = file_save_draft_area_files($moduleinfo->introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $moduleinfo->introeditor['text']);
        $moduleinfo->introformat = $moduleinfo->introeditor['format'];
        unset($moduleinfo->introeditor);
    }
    $updateinstancefunction = $moduleinfo->modulename . "_update_instance";
    if (!$updateinstancefunction($moduleinfo, $mform)) {
        print_error('cannotupdatemod', '', course_get_url($course, $cw->section), $moduleinfo->modulename);
    }
    // Make sure visibility is set correctly (in particular in calendar).
    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
        set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible);
    }
    if (isset($moduleinfo->cmidnumber)) {
        // Label.
        // Set cm idnumber - uniqueness is already verified by form validation.
        set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber);
    }
    // Now that module is fully updated, also update completion data if required.
    // (this will wipe all user completion data and recalculate it)
    if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) {
        $completion->reset_all_state($cm);
    }
    // Trigger event based on the action we did.
    $event = \core\event\course_module_updated::create(array('courseid' => $course->id, 'context' => $modcontext, 'objectid' => $moduleinfo->coursemodule, 'other' => array('modulename' => $moduleinfo->modulename, 'name' => $moduleinfo->name, 'instanceid' => $moduleinfo->instance)));
    $event->trigger();
    add_to_log($course->id, $moduleinfo->modulename, "update", "view.php?id={$moduleinfo->coursemodule}", "{$moduleinfo->instance}", $moduleinfo->coursemodule);
    $moduleinfo = edit_module_post_actions($moduleinfo, $course);
    return array($cm, $moduleinfo);
}
Example #29
0
/**
 * Determine whether a course module is visible within a course,
 * this is different from instance_is_visible() - faster and visibility for user
 *
 * @global object
 * @global object
 * @uses DEBUG_DEVELOPER
 * @uses CONTEXT_MODULE
 * @uses CONDITION_MISSING_EXTRATABLE
 * @param object $cm object
 * @param int $userid empty means current user
 * @return bool Success
 */
function coursemodule_visible_for_user($cm, $userid = 0)
{
    global $USER, $CFG;
    if (empty($cm->id)) {
        debugging("Incorrect course module parameter!", DEBUG_DEVELOPER);
        return false;
    }
    if (empty($userid)) {
        $userid = $USER->id;
    }
    if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $cm->id), $userid)) {
        return false;
    }
    if ($CFG->enableavailability) {
        require_once $CFG->libdir . '/conditionlib.php';
        $ci = new condition_info($cm, CONDITION_MISSING_EXTRATABLE);
        if (!$ci->is_available($cm->availableinfo, false, $userid) and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $cm->id), $userid)) {
            return false;
        }
    }
    return groups_course_module_visible($cm, $userid);
}
 /**
  * Validate that the version 1 plugin deletes appropriate associations when
  * deleting a course
  */
 public function test_version1importdeletecoursedeletesassociations()
 {
     global $DB, $CFG, $USER;
     require_once $CFG->dirroot . '/user/lib.php';
     require_once $CFG->dirroot . '/lib/gradelib.php';
     require_once $CFG->dirroot . '/group/lib.php';
     require_once $CFG->dirroot . '/lib/conditionlib.php';
     require_once $CFG->dirroot . '/lib/enrollib.php';
     require_once $CFG->dirroot . '/tag/lib.php';
     require_once $CFG->dirroot . '/lib/questionlib.php';
     // Setup.
     $initialnumcontexts = $DB->count_records('context', array('contextlevel' => CONTEXT_COURSE));
     $DB->delete_records('block_instances');
     // Set up the course with one section, including default blocks.
     set_config('defaultblocks_topics', 'search_forums');
     set_config('maxsections', 10, 'moodlecourse');
     $this->run_core_course_import(array('shortname' => 'deleteassociationsshortname', 'numsections' => 1));
     // Create a user record.
     $record = new stdClass();
     $record->username = '******';
     $record->password = '******';
     $userid = user_create_user($record);
     // Create a course-level role.
     $courseid = $DB->get_field('course', 'id', array('shortname' => 'deleteassociationsshortname'));
     $coursecontext = context_course::instance($courseid);
     $roleid = create_role('deleterole', 'deleterole', 'deleterole');
     set_role_contextlevels($roleid, array(CONTEXT_COURSE));
     $enrol = new stdClass();
     $enrol->enrol = 'manual';
     $enrol->courseid = $courseid;
     $enrol->status = ENROL_INSTANCE_ENABLED;
     if (!$DB->record_exists('enrol', (array) $enrol)) {
         $DB->insert_record('enrol', $enrol);
     }
     // Assign the user to the course-level role.
     enrol_try_internal_enrol($courseid, $userid, $roleid);
     // Create a grade item.
     $gradeitem = new grade_item(array('courseid' => $courseid, 'itemtype' => 'manual', 'itemname' => 'testitem'), false);
     $gradeitem->insert();
     $gradegrade = new grade_grade(array('itemid' => $gradeitem->id, 'userid' => $userid), false);
     // Assign the user a grade.
     $gradegrade->insert();
     // Create a grade outcome.
     $gradeoutcome = new grade_outcome(array('courseid' => $courseid, 'shortname' => 'bogusshortname', 'fullname' => 'bogusfullname'));
     $gradeoutcome->insert();
     // Create a grade scale.
     $gradescale = new grade_scale(array('courseid' => $courseid, 'name' => 'bogusname', 'userid' => $userid, 'scale' => 'bogusscale', 'description' => 'bogusdescription'));
     $gradescale->insert();
     // Set a grade setting value.
     grade_set_setting($courseid, 'bogus', 'bogus');
     // Set up a grade letter.
     $gradeletter = new stdClass();
     $gradeletter->contextid = $coursecontext->id;
     $gradeletter->lowerboundary = 80;
     $gradeletter->letter = 'A';
     $DB->insert_record('grade_letters', $gradeletter);
     // Set up a forum instance.
     $forum = new stdClass();
     $forum->course = $courseid;
     $forum->intro = 'intro';
     $forum->id = $DB->insert_record('forum', $forum);
     // Add it as a course module.
     $forum->module = $DB->get_field('modules', 'id', array('name' => 'forum'));
     $forum->instance = $forum->id;
     $cmid = add_course_module($forum);
     // Set up a completion record.
     $completion = new stdClass();
     $completion->coursemoduleid = $cmid;
     $completion->completionstate = 0;
     $completion->userid = 9999;
     $completion->timemodified = time();
     $DB->insert_record('course_modules_completion', $completion);
     // Set up a completion condition.
     $forum->id = $cmid;
     $ci = new condition_info($forum, CONDITION_MISSING_EVERYTHING, false);
     $ci->add_completion_condition($cmid, COMPLETION_ENABLED);
     // Set the blocks position.
     $instances = $DB->get_records('block_instances', array('parentcontextid' => $coursecontext->id));
     $page = new stdClass();
     $page->context = $coursecontext;
     $page->pagetype = 'course-view-*';
     $page->subpage = false;
     foreach ($instances as $instance) {
         blocks_set_visibility($instance, $page, 1);
     }
     // Create a group.
     $group = new stdClass();
     $group->name = 'testgroup';
     $group->courseid = $courseid;
     $groupid = groups_create_group($group);
     // Add the user to the group.
     groups_add_member($groupid, $userid);
     // Create a grouping containing our group.
     $grouping = new stdClass();
     $grouping->name = 'testgrouping';
     $grouping->courseid = $courseid;
     $groupingid = groups_create_grouping($grouping);
     groups_assign_grouping($groupingid, $groupid);
     // Set up a user tag.
     tag_set('course', $courseid, array('testtag'));
     // Add a course-level log.
     add_to_log($courseid, 'bogus', 'bogus');
     // Set up the default course question category.
     $newcategory = question_make_default_categories(array($coursecontext));
     // Create a test question.
     $question = new stdClass();
     $question->qtype = 'truefalse';
     $form = new stdClass();
     $form->category = $newcategory->id;
     $form->name = 'testquestion';
     $form->correctanswer = 1;
     $form->feedbacktrue = array('text' => 'bogustext', 'format' => FORMAT_HTML);
     $form->feedbackfalse = array('text' => 'bogustext', 'format' => FORMAT_HTML);
     $question = question_bank::get_qtype('truefalse')->save_question($question, $form);
     if (function_exists('course_set_display')) {
         // Set a "course display" setting.
         course_set_display($courseid, 1);
     }
     // Make a bogus backup record.
     $backupcourse = new stdClass();
     $backupcourse->courseid = $courseid;
     $DB->insert_record('backup_courses', $backupcourse);
     // Add a user lastaccess record.
     $lastaccess = new stdClass();
     $lastaccess->userid = $userid;
     $lastaccess->courseid = $courseid;
     $DB->insert_record('user_lastaccess', $lastaccess);
     // Make a bogus backup log record.
     $log = new stdClass();
     $log->backupid = $courseid;
     $log->timecreated = time();
     $log->loglevel = 1;
     $log->message = 'bogus';
     $DB->insert_record('backup_logs', $log);
     // Get initial counts.
     $initialnumcourse = $DB->count_records('course');
     $initialnumroleassignments = $DB->count_records('role_assignments');
     $initialnumuserenrolments = $DB->count_records('user_enrolments');
     $initialnumgradeitems = $DB->count_records('grade_items');
     $initialnumgradegrades = $DB->count_records('grade_grades');
     $initialnumgradeoutcomes = $DB->count_records('grade_outcomes');
     $initialnumgradeoutcomescourses = $DB->count_records('grade_outcomes_courses');
     $initialnumscale = $DB->count_records('scale');
     $initialnumgradesettings = $DB->count_records('grade_settings');
     $initialnumgradeletters = $DB->count_records('grade_letters');
     $initialnumforum = $DB->count_records('forum');
     $initialnumcoursemodules = $DB->count_records('course_modules');
     $initialnumcoursemodulescompletion = $DB->count_records('course_modules_completion');
     $initialnumcoursemodulesavailability = $DB->count_records('course_modules_availability');
     $initialnumblockinstances = $DB->count_records('block_instances');
     $initialnumblockpositions = $DB->count_records('block_positions');
     $initialnumgroups = $DB->count_records('groups');
     $initialnumgroupsmembers = $DB->count_records('groups_members');
     $initialnumgroupings = $DB->count_records('groupings');
     $initialnumgroupingsgroups = $DB->count_records('groupings_groups');
     $initialnumtaginstance = $DB->count_records('tag_instance');
     $initialnumcoursesections = $DB->count_records('course_sections');
     $initialnumquestioncategories = $DB->count_records('question_categories');
     $initialnumquestion = $DB->count_records('question');
     if (self::$coursedisplay) {
         $initialnumcoursedisplay = $DB->count_records('course_display');
     }
     $initialnumbackupcourses = $DB->count_records('backup_courses');
     $initialnumuserlastaccess = $DB->count_records('user_lastaccess');
     $initialnumbackuplogs = $DB->count_records('backup_logs');
     // Delete the course.
     $data = array('action' => 'delete', 'shortname' => 'deleteassociationsshortname');
     $this->run_core_course_import($data, false);
     // Validate the result.
     $this->assertEquals($DB->count_records('course'), $initialnumcourse - 1);
     $this->assertEquals($DB->count_records('role_assignments'), $initialnumroleassignments - 1);
     $this->assertEquals($DB->count_records('user_enrolments'), $initialnumuserenrolments - 1);
     $this->assertEquals($DB->count_records('grade_items'), $initialnumgradeitems - 2);
     $this->assertEquals($DB->count_records('grade_grades'), $initialnumgradegrades - 1);
     $this->assertEquals($DB->count_records('grade_outcomes'), $initialnumgradeoutcomes - 1);
     $this->assertEquals($DB->count_records('grade_outcomes_courses'), $initialnumgradeoutcomescourses - 1);
     $this->assertEquals($DB->count_records('scale'), $initialnumscale - 1);
     $this->assertEquals($DB->count_records('grade_settings'), $initialnumgradesettings - 1);
     $this->assertEquals($DB->count_records('grade_letters'), $initialnumgradeletters - 1);
     $this->assertEquals($DB->count_records('forum'), $initialnumforum - 1);
     $this->assertEquals($DB->count_records('course_modules'), $initialnumcoursemodules - 1);
     /*
      Uncomment the two lines below when this fix is available: http://tracker.moodle.org/browse/MDL-32988
      $this->assertEquals($DB->count_records('course_modules_completion'), $initialnumcourse_modules_completion - 1);
      $this->assertEquals($DB->count_records('course_modules_availability'), $initialnumcourse_modules_availability - 1);
     */
     $this->assertEquals($initialnumblockinstances - 4, $DB->count_records('block_instances'));
     $this->assertEquals($DB->count_records('block_positions'), 0);
     $this->assertEquals($DB->count_records('groups'), $initialnumgroups - 1);
     $this->assertEquals($DB->count_records('groups_members'), $initialnumgroupsmembers - 1);
     $this->assertEquals($DB->count_records('groupings'), $initialnumgroupings - 1);
     $this->assertEquals($DB->count_records('groupings_groups'), $initialnumgroupingsgroups - 1);
     $this->assertEquals($DB->count_records('log', array('course' => $courseid)), 0);
     $this->assertEquals($DB->count_records('tag_instance'), $initialnumtaginstance - 1);
     $this->assertEquals($DB->count_records('course_sections'), $initialnumcoursesections - 1);
     $this->assertEquals($DB->count_records('question_categories'), $initialnumquestioncategories - 1);
     $this->assertEquals($DB->count_records('question'), $initialnumquestion - 1);
     if (self::$coursedisplay) {
         $this->assertEquals($DB->count_records('course_display'), $initialnumcoursedisplay - 1);
     }
     $this->assertEquals($DB->count_records('backup_courses'), $initialnumbackupcourses - 1);
     $this->assertEquals($DB->count_records('user_lastaccess'), $initialnumuserlastaccess - 1);
 }