function definition() { global $CFG; $mform =& $this->_form; //$mform->addElement('html', get_string('unplagexplain', 'plagiarism_unplag')); $mform->addElement('checkbox', 'unplag_use', get_string('useunplag', 'plagiarism_unplag')); $mform->addElement('text', 'unplag_client_id', get_string('unplag_client_id', 'plagiarism_unplag')); $mform->addHelpButton('unplag_client_id', 'unplag_client_id', 'plagiarism_unplag'); $mform->addRule('unplag_client_id', null, 'required', null, 'client'); $mform->setType('unplag_client_id', PARAM_TEXT); $mform->addElement('text', 'unplag_api_secret', get_string('unplag_api_secret', 'plagiarism_unplag')); $mform->addHelpButton('unplag_api_secret', 'unplag_api_secret', 'plagiarism_unplag'); $mform->addRule('unplag_api_secret', null, 'required', null, 'client'); $mform->setType('unplag_api_secret', PARAM_TEXT); $mform->addElement('text', 'unplag_lang', get_string('unplag_lang', 'plagiarism_unplag')); $mform->addHelpButton('unplag_lang', 'unplag_lang', 'plagiarism_unplag'); $mform->addRule('unplag_lang', null, 'required', null, 'client'); $mform->setDefault('unplag_lang', 'en-US'); $mform->setType('unplag_lang', PARAM_TEXT); $mform->addElement('textarea', 'unplag_student_disclosure', get_string('studentdisclosure', 'plagiarism_unplag'), 'wrap="virtual" rows="6" cols="50"'); $mform->addHelpButton('unplag_student_disclosure', 'studentdisclosure', 'plagiarism_unplag'); $mform->setDefault('unplag_student_disclosure', get_string('studentdisclosuredefault', 'plagiarism_unplag')); $mform->setType('unplag_student_disclosure', PARAM_TEXT); $mods = core_component::get_plugin_list('mod'); foreach ($mods as $mod => $modname) { if (plugin_supports('mod', $mod, FEATURE_PLAGIARISM)) { $modstring = 'unplag_enable_mod_' . $mod; $mform->addElement('checkbox', $modstring, get_string('unplag_enableplugin', 'plagiarism_unplag', $mod)); } } $this->add_action_buttons(true); }
/** * Constructor - instantiates one object of this class */ public function __construct($name, $blockid, $moduleid = null, $plan = null) { global $DB; // Check blockid exists if (!($block = $DB->get_record('block_instances', array('id' => $blockid)))) { throw new backup_task_exception('block_task_block_instance_not_found', $blockid); } $this->blockid = $blockid; $this->blockname = $block->blockname; $this->contextid = get_context_instance(CONTEXT_BLOCK, $this->blockid)->id; $this->moduleid = $moduleid; $this->modulename = null; $this->parentcontextid = null; // If moduleid passed, check exists, supports moodle2 format and save info // Check moduleid exists if (!empty($moduleid)) { if (!($coursemodule = get_coursemodule_from_id(false, $moduleid))) { throw new backup_task_exception('block_task_coursemodule_not_found', $moduleid); } // Check activity supports this moodle2 backup format if (!plugin_supports('mod', $coursemodule->modname, FEATURE_BACKUP_MOODLE2)) { throw new backup_task_exception('block_task_activity_lacks_moodle2_backup_support', $coursemodule->modname); } $this->moduleid = $moduleid; $this->modulename = $coursemodule->modname; $this->parentcontextid = get_context_instance(CONTEXT_MODULE, $this->moduleid)->id; } parent::__construct($name, $plan); }
protected function definition() { global $CFG; $mform =& $this->_form; $mform->addElement('html', get_string('compilatioexplain', 'plagiarism_compilatio')); $mform->addElement('checkbox', 'compilatio_use', get_string('usecompilatio', 'plagiarism_compilatio')); $mform->addElement('text', 'compilatio_api', get_string('compilatio_api', 'plagiarism_compilatio')); $mform->addHelpButton('compilatio_api', 'compilatio_api', 'plagiarism_compilatio'); $mform->addRule('compilatio_api', null, 'required', null, 'client'); $mform->setDefault('compilatio_api', 'http://service.compilatio.net/webservices/CompilatioUserClient2.wsdl'); $mform->addElement('passwordunmask', 'compilatio_password', get_string('compilatio_password', 'plagiarism_compilatio')); $mform->addHelpButton('compilatio_password', 'compilatio_password', 'plagiarism_compilatio'); $mform->addRule('compilatio_password', null, 'required', null, 'client'); $mform->addElement('textarea', 'compilatio_student_disclosure', get_string('studentdisclosure', 'plagiarism_compilatio'), 'wrap="virtual" rows="6" cols="50"'); $mform->addHelpButton('compilatio_student_disclosure', 'studentdisclosure', 'plagiarism_compilatio'); $mform->setDefault('compilatio_student_disclosure', get_string('studentdisclosuredefault', 'plagiarism_compilatio')); $mods = get_plugin_list('mod'); foreach ($mods as $mod => $modname) { if (plugin_supports('mod', $mod, FEATURE_PLAGIARISM)) { $modstring = 'compilatio_enable_mod_' . $mod; $mform->addElement('checkbox', $modstring, get_string('compilatio_enableplugin', 'plagiarism_compilatio', get_string('pluginname', 'mod_' . $mod))); } } $this->add_action_buttons(true); }
/** * Defines forms elements * @see: https://docs.moodle.org/dev/lib/formslib.php_Form_Definition */ public function definition() { $mform = $this->_form; $modinfo = $this->_customdata; //let's create an array of those plugins that support the completion features $supportedmods = array(); foreach ($modinfo->get_used_module_names() as $modtype => $modname) { if (plugin_supports('mod', $modtype, FEATURE_COMPLETION_TRACKS_VIEWS, 0)) { $supportedmods[$modtype] = $modname; } } foreach ($modinfo->get_section_info_all() as $sectid => $sectinfo) { //skip the first section because in snap we turn it into a menu if (!$sectid) { continue; } //skip the section if the id is greater than what is allowed by the course //if($sectid > $course->numsections) continue; //skip the section if not visible or not avilable //if(!$sectinfo->visible || !$sectinfo->available) continue; //skip section if it doesn't have any modules if (empty($modinfo->sections[$sectid])) { continue; } //add the section name as a header $mform->addElement('html', '<h3 class="section-header">' . $sectinfo->name . '</h3>'); //iterate the modules within the section foreach ($modinfo->sections[$sectid] as $modid) { //completion = completion //completionexpected $mod = $modinfo->cms[$modid]; //if this is a subheader, then add it if ($mod->modname == 'subheader') { $mform->addElement('html', '<div class="subheader">' . $mod->name . '</div>'); continue; } //check to see if this plugin supports completion tracking if (!isset($supportedmods[$mod->modname])) { continue; } //create the html for the module icon $icon = html_writer::empty_tag('img', array('src' => $mod->get_icon_url(), 'class' => 'icon', 'alt' => ' ', 'role' => 'presentation')); $mform->addElement('advcheckbox', 'mod_' . $modid, false, $icon . ' ' . $mod->name, null, array('0', $modid)); //if completion is already set, then check the checkbox if ($mod->completion) { $mform->setDefault('mod_' . $modid, true); } } } //add the action buttons $this->add_action_buttons(); }
function get_content() { global $CFG, $DB, $OUTPUT; if ($this->content !== NULL) { return $this->content; } $this->content = new stdClass(); $this->content->items = array(); $this->content->icons = array(); $this->content->footer = ''; $course = $this->page->course; require_once $CFG->dirroot . '/course/lib.php'; $modinfo = get_fast_modinfo($course); $modfullnames = array(); $archetypes = array(); foreach ($modinfo->cms as $cm) { // Exclude activities which are not visible or have no link (=label) if (!$cm->uservisible or !$cm->has_view()) { continue; } if (array_key_exists($cm->modname, $modfullnames)) { continue; } if (!array_key_exists($cm->modname, $archetypes)) { $archetypes[$cm->modname] = plugin_supports('mod', $cm->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); } if ($archetypes[$cm->modname] == MOD_ARCHETYPE_RESOURCE) { if (!array_key_exists('resources', $modfullnames)) { $modfullnames['resources'] = get_string('resources'); } } else { $modfullnames[$cm->modname] = $cm->modplural; } } core_collator::asort($modfullnames); foreach ($modfullnames as $modname => $modfullname) { if ($modname === 'resources') { $icon = $OUTPUT->pix_icon('icon', '', 'mod_page', array('class' => 'icon')); $this->content->items[] = '<a href="' . $CFG->wwwroot . '/course/resources.php?id=' . $course->id . '">' . $icon . $modfullname . '</a>'; } else { $icon = '<img src="' . $OUTPUT->pix_url('icon', $modname) . '" class="icon" alt="" />'; $this->content->items[] = '<a href="' . $CFG->wwwroot . '/mod/' . $modname . '/index.php?id=' . $course->id . '">' . $icon . $modfullname . '</a>'; } } return $this->content; }
/** * Constructor - instantiates one object of this class * * @param string $name the task identifier * @param int $moduleid course module id (id in course_modules table) * @param backup_plan|null $plan the backup plan instance this task is part of */ public function __construct($name, $moduleid, $plan = null) { // Check moduleid exists if (!($coursemodule = get_coursemodule_from_id(false, $moduleid))) { throw new backup_task_exception('activity_task_coursemodule_not_found', $moduleid); } // Check activity supports this moodle2 backup format if (!plugin_supports('mod', $coursemodule->modname, FEATURE_BACKUP_MOODLE2)) { throw new backup_task_exception('activity_task_activity_lacks_moodle2_backup_support', $coursemodule->modname); } $this->moduleid = $moduleid; $this->sectionid = $coursemodule->section; $this->modulename = $coursemodule->modname; $this->activityid = $coursemodule->instance; $this->contextid = context_module::instance($this->moduleid)->id; parent::__construct($name, $plan); }
public function definition() { $mform =& $this->_form; $mform->addElement('html', get_string('urkundexplain', 'plagiarism_urkund')); $mform->addElement('checkbox', 'urkund_use', get_string('useurkund', 'plagiarism_urkund')); $mform->addElement('text', 'urkund_api', get_string('urkund_api', 'plagiarism_urkund')); $mform->addHelpButton('urkund_api', 'urkund_api', 'plagiarism_urkund'); $mform->addRule('urkund_api', null, 'required', null, 'client'); $mform->setDefault('urkund_api', 'https://secure.urkund.com/api/submissions'); $mform->setType('urkund_api', PARAM_URL); $mform->addElement('text', 'urkund_username', get_string('urkund_username', 'plagiarism_urkund')); $mform->addHelpButton('urkund_username', 'urkund_username', 'plagiarism_urkund'); $mform->addRule('urkund_username', null, 'required', null, 'client'); $mform->setType('urkund_username', PARAM_TEXT); $mform->addElement('passwordunmask', 'urkund_password', get_string('urkund_password', 'plagiarism_urkund')); $mform->addHelpButton('urkund_password', 'urkund_password', 'plagiarism_urkund'); $mform->addRule('urkund_password', null, 'required', null, 'client'); $mform->setType('urkund_password', PARAM_TEXT); $mform->addElement('text', 'urkund_lang', get_string('urkund_lang', 'plagiarism_urkund')); $mform->addHelpButton('urkund_lang', 'urkund_lang', 'plagiarism_urkund'); $mform->addRule('urkund_lang', null, 'required', null, 'client'); $mform->setDefault('urkund_lang', 'en-US'); $mform->setType('urkund_lang', PARAM_TEXT); $mform->addElement('textarea', 'urkund_student_disclosure', get_string('studentdisclosure', 'plagiarism_urkund'), 'wrap="virtual" rows="6" cols="50"'); $mform->addHelpButton('urkund_student_disclosure', 'studentdisclosure', 'plagiarism_urkund'); $mform->setDefault('urkund_student_disclosure', get_string('studentdisclosuredefault', 'plagiarism_urkund')); $mform->setType('urkund_student_disclosure', PARAM_TEXT); $mform->addElement('checkbox', 'urkund_optout', get_string('urkund_enableoptout', 'plagiarism_urkund'), '<br/>' . get_string('urkund_enableoptoutdesc', 'plagiarism_urkund')); $mform->setDefault('urkund_optout', true); $mform->addElement('text', 'urkund_wordcount', get_string('wordcount', 'plagiarism_urkund')); $mform->addHelpButton('urkund_wordcount', 'wordcount', 'plagiarism_urkund'); $mform->setType('urkund_wordcount', PARAM_INT); $mform->addRule('urkund_wordcount', null, 'required', null, 'client'); $mform->setDefault('urkund_wordcount', '50'); $mods = core_component::get_plugin_list('mod'); foreach ($mods as $mod => $modname) { if (plugin_supports('mod', $mod, FEATURE_PLAGIARISM)) { $modstring = 'urkund_enable_mod_' . $mod; $mform->addElement('checkbox', $modstring, get_string('urkund_enableplugin', 'plagiarism_urkund', $mod)); if ($modname == 'assign') { $mform->setDefault($modstring, 1); } } } $this->add_action_buttons(true); }
function get_content() { global $CFG, $DB, $OUTPUT; if ($this->content !== NULL) { return $this->content; } $this->content = new stdClass(); $this->content->items = array(); $this->content->icons = array(); $this->content->footer = ''; $course = $this->page->course; require_once $CFG->dirroot . '/course/lib.php'; $modinfo = get_fast_modinfo($course); $modfullnames = array(); $archetypes = array(); foreach ($modinfo->cms as $cm) { if (!$cm->uservisible or $cm->modname === 'label') { continue; } if (array_key_exists($cm->modname, $modfullnames)) { continue; } if (!array_key_exists($cm->modname, $archetypes)) { $archetypes[$cm->modname] = plugin_supports('mod', $cm->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); } if ($archetypes[$cm->modname] == MOD_ARCHETYPE_RESOURCE) { if (!array_key_exists('resources', $modfullnames)) { $modfullnames['resources'] = get_string('resources'); } } else { $modfullnames[$cm->modname] = $cm->modplural; } } textlib_get_instance()->asort($modfullnames); foreach ($modfullnames as $modname => $modfullname) { if ($modname === 'resources') { $icon = '<img src="' . $OUTPUT->pix_url('f/html') . '" class="icon" alt="" /> '; $this->content->items[] = '<a href="' . $CFG->wwwroot . '/course/resources.php?id=' . $course->id . '">' . $icon . $modfullname . '</a>'; } else { $icon = '<img src="' . $OUTPUT->pix_url('icon', $modname) . '" class="icon" alt="" /> '; $this->content->items[] = '<a href="' . $CFG->wwwroot . '/mod/' . $modname . '/index.php?id=' . $course->id . '">' . $icon . $modfullname . '</a>'; } } return $this->content; }
/** * Returns the list of all editing actions that current user can perform on the module * * @param cm_info $mod The module to produce editing buttons for * @param int $indent The current indenting (default -1 means no move left-right actions) * @param int $sr The section to link back to (used for creating the links) * @return array array of action_link or pix_icon objects */ function course_get_cm_edit_actions_reduced(cm_info $mod, $indent = -1, $sr = null) { global $COURSE, $SITE; static $str; $coursecontext = context_course::instance($mod->course); $modcontext = context_module::instance($mod->id); $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign'); $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport'); //No permission to edit anything. if (!has_any_capability($editcaps, $modcontext) and !has_all_capabilities($dupecaps, $coursecontext)) { return array(); } $hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext); if (!isset($str)) { $str = get_strings(array('delete', 'move', 'moveright', 'moveleft', 'editsettings', 'duplicate', 'hide', 'show'), 'moodle'); $str->assign = get_string('assignroles', 'role'); $str->groupsnone = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone")); $str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate")); $str->groupsvisible = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible")); } $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey())); if ($sr !== null) { $baseurl->param('sr', $sr); } $actions = array(); // Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php) // Note that restoring on front page is never allowed. if ($mod->course != SITEID && has_all_capabilities($dupecaps, $coursecontext) && plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2)) { $actions['duplicate'] = new action_menu_link_secondary(new moodle_url($baseurl, array('duplicate' => $mod->id)), new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->duplicate, array('class' => 'editing_duplicate', 'data-action' => 'duplicate', 'data-sr' => $sr)); } // Delete. if ($hasmanageactivities) { $actions['delete'] = new action_menu_link_secondary(new moodle_url($baseurl, array('delete' => $mod->id)), new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->delete, array('class' => 'editing_delete', 'data-action' => 'delete')); } return $actions; }
/** * Create enrolment instances. * * This has to be called after creation of roles * and before adding of role assignments. * * @param mixed $data * @return void */ public function process_enrol($data) { global $DB; $data = (object)$data; $oldid = $data->id; // We'll need this later $restoretype = plugin_supports('enrol', $data->enrol, ENROL_RESTORE_TYPE, null); if ($restoretype !== ENROL_RESTORE_EXACT and $restoretype !== ENROL_RESTORE_NOUSERS) { // TODO: add complex restore support via custom class debugging("Skipping '{$data->enrol}' enrolment plugin. Will be implemented before 2.0 release", DEBUG_DEVELOPER); $this->set_mapping('enrol', $oldid, 0); return; } // Perform various checks to decide what to do with the enrol plugin if (!array_key_exists($data->enrol, enrol_get_plugins(false))) { // TODO: decide if we want to switch to manual enrol - we need UI for this debugging("Enrol plugin data can not be restored because it is not installed"); $this->set_mapping('enrol', $oldid, 0); return; } if (!enrol_is_enabled($data->enrol)) { // TODO: decide if we want to switch to manual enrol - we need UI for this debugging("Enrol plugin data can not be restored because it is not enabled"); $this->set_mapping('enrol', $oldid, 0); return; } // map standard fields - plugin has to process custom fields from own restore class $data->roleid = $this->get_mappingid('role', $data->roleid); //TODO: should we move the enrol start and end date here? // always add instance, if the course does not support multiple instances it just returns NULL $enrol = enrol_get_plugin($data->enrol); $courserec = $DB->get_record('course', array('id' => $this->get_courseid())); // Requires object, uses only id!! if ($newitemid = $enrol->add_instance($courserec, (array)$data)) { // ok } else { if ($instances = $DB->get_records('enrol', array('courseid'=>$courserec->id, 'enrol'=>$data->enrol))) { // most probably plugin that supports only one instance $newitemid = key($instances); } else { debugging('Can not create new enrol instance or reuse existing'); $newitemid = 0; } } if ($restoretype === ENROL_RESTORE_NOUSERS) { // plugin requests to prevent restore of any users $newitemid = 0; } $this->set_mapping('enrol', $oldid, $newitemid); }
/** * Calculates the completion state for an activity and user. * * Internal function. Not private, so we can unit-test it. * * @param stdClass|cm_info $cm Activity * @param int $userid ID of user * @param stdClass $current Previous completion information from database * @return mixed */ public function internal_get_state($cm, $userid, $current) { global $USER, $DB, $CFG; // Get user ID if (!$userid) { $userid = $USER->id; } // Check viewed if ($cm->completionview == COMPLETION_VIEW_REQUIRED && $current->viewed == COMPLETION_NOT_VIEWED) { return COMPLETION_INCOMPLETE; } // Modname hopefully is provided in $cm but just in case it isn't, let's grab it if (!isset($cm->modname)) { $cm->modname = $DB->get_field('modules', 'name', array('id' => $cm->module)); } $newstate = COMPLETION_COMPLETE; // Check grade if (!is_null($cm->completiongradeitemnumber)) { require_once $CFG->libdir . '/gradelib.php'; $item = grade_item::fetch(array('courseid' => $cm->course, 'itemtype' => 'mod', 'itemmodule' => $cm->modname, 'iteminstance' => $cm->instance, 'itemnumber' => $cm->completiongradeitemnumber)); if ($item) { // Fetch 'grades' (will be one or none) $grades = grade_grade::fetch_users_grades($item, array($userid), false); if (empty($grades)) { // No grade for user return COMPLETION_INCOMPLETE; } if (count($grades) > 1) { $this->internal_systemerror("Unexpected result: multiple grades for\n item '{$item->id}', user '{$userid}'"); } $newstate = self::internal_get_grade_state($item, reset($grades)); if ($newstate == COMPLETION_INCOMPLETE) { return COMPLETION_INCOMPLETE; } } else { $this->internal_systemerror("Cannot find grade item for '{$cm->modname}'\n cm '{$cm->id}' matching number '{$cm->completiongradeitemnumber}'"); } } if (plugin_supports('mod', $cm->modname, FEATURE_COMPLETION_HAS_RULES)) { $function = $cm->modname . '_get_completion_state'; if (!function_exists($function)) { $this->internal_systemerror("Module {$cm->modname} claims to support\n FEATURE_COMPLETION_HAS_RULES but does not have required\n {$cm->modname}_get_completion_state function"); } if (!$function($this->course, $cm, $userid, COMPLETION_AND)) { return COMPLETION_INCOMPLETE; } } return $newstate; }
/** * Is the user allowed to add this type of module to this course? * @param object $course the course settings. Only $course->id is used. * @param string $modname the module name. E.g. 'forum' or 'quiz'. * @return bool whether the current user is allowed to add this type of module to this course. */ function course_allowed_module($course, $modname) { global $DB; if (is_numeric($modname)) { throw new coding_exception('Function course_allowed_module no longer supports numeric module ids. Please update your code to pass the module name.'); } $capability = 'mod/' . $modname . ':addinstance'; if (!get_capability_info($capability)) { // Debug warning that the capability does not exist, but no more than once per page. static $warned = array(); $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); if (!isset($warned[$modname]) && $archetype !== MOD_ARCHETYPE_SYSTEM) { debugging('The module ' . $modname . ' does not define the standard capability ' . $capability, DEBUG_DEVELOPER); $warned[$modname] = 1; } // If the capability does not exist, the module can always be added. return true; } $coursecontext = context_course::instance($course->id); return has_capability($capability, $coursecontext); }
/** * Get the activities supported by the format. * * Here we ignore the modules that do not have a page of their own, like the label. * * @return array array($module => $name of the module). */ public static function get_supported_activities() { $availabletypes = get_module_types_names(); foreach ($availabletypes as $module => $name) { if (plugin_supports('mod', $module, FEATURE_NO_VIEW_LINK, false)) { unset($availabletypes[$module]); } } return $availabletypes; }
/** * 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->addHelpButton('scale', 'modgrade', 'grades'); $mform->setDefault('scale', $CFG->gradepointdefault); $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')); $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->setType('cmidnumber', PARAM_RAW); $mform->addHelpButton('cmidnumber', 'idnumbermod'); } 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) { // Groupings selector - used to select grouping for groups in activity. $options = array(); if ($groupings = $DB->get_records('groupings', array('courseid' => $COURSE->id))) { foreach ($groupings as $grouping) { $options[$grouping->id] = format_string($grouping->name); } } core_collator::asort($options); $options = array(0 => get_string('none')) + $options; $mform->addElement('select', 'groupingid', get_string('grouping', 'group'), $options); $mform->addHelpButton('groupingid', 'grouping', 'group'); } if (!empty($CFG->enableavailability)) { // Add special button to end of previous section if groups/groupings // are enabled. if ($this->_features->groups || $this->_features->groupings) { $mform->addElement('static', 'restrictgroupbutton', '', html_writer::tag('button', get_string('restrictbygroup', 'availability'), array('id' => 'restrictbygroup', 'disabled' => 'disabled'))); } // Availability field. This is just a textarea; the user interface // interaction is all implemented in JavaScript. $mform->addElement('header', 'availabilityconditionsheader', get_string('restrictaccess', 'availability')); // Note: This field cannot be named 'availability' because that // conflicts with fields in existing modules (such as assign). // So it uses a long name that will not conflict. $mform->addElement('textarea', 'availabilityconditionsjson', get_string('accessrestrictions', 'availability')); // The _cm variable may not be a proper cm_info, so get one from modinfo. if ($this->_cm) { $modinfo = get_fast_modinfo($COURSE); $cm = $modinfo->get_cm($this->_cm->id); } else { $cm = null; } \core_availability\frontend::include_all_javascript($COURSE, $cm); } // 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); $trackingdefault = COMPLETION_TRACKING_NONE; // If system and activity default is on, set it. if ($CFG->completiondefault && $this->_features->defaultcompletion) { $trackingdefault = COMPLETION_TRACKING_MANUAL; } $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', $trackingdefault); $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; // If using the rating system, there is no grade unless ratings are enabled. if ($this->_features->rating) { $mform->disabledIf('completionusegrade', 'assessed', 'eq', 0); } } // 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(); }
/** * 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.'&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 ' '; 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.'&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"; } }
/** * Loads an array of current module choices * * @return bool always return true */ public function load_choices() { if (is_array($this->choices)) { return true; } $this->choices = array(); global $CFG, $DB; $records = $DB->get_records('modules', array('visible' => 1), 'name'); foreach ($records as $record) { // Exclude modules if the code doesn't exist if (file_exists("{$CFG->dirroot}/mod/{$record->name}/lib.php")) { // Also exclude system modules (if specified) if (!($this->excludesystem && plugin_supports('mod', $record->name, FEATURE_MOD_ARCHETYPE) === MOD_ARCHETYPE_SYSTEM)) { $this->choices[$record->id] = $record->name; } } } return true; }
private function get_course_activities() { // A copy of block_activity_modules. $course = $this->page->course; $modinfo = get_fast_modinfo($course); $course = course_get_format($course)->get_course(); $modfullnames = array(); $archetypes = array(); foreach ($modinfo->get_section_info_all() as $section => $thissection) { if (!empty($course->numsections) and $section > $course->numsections or empty($modinfo->sections[$section])) { // This is a stealth section or is empty. continue; } foreach ($modinfo->sections[$thissection->section] as $modnumber) { $cm = $modinfo->cms[$modnumber]; // Exclude activities which are not visible or have no link (=label). if (!$cm->uservisible or !$cm->has_view()) { continue; } if (array_key_exists($cm->modname, $modfullnames)) { continue; } if (!array_key_exists($cm->modname, $archetypes)) { $archetypes[$cm->modname] = plugin_supports('mod', $cm->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); } if ($archetypes[$cm->modname] == MOD_ARCHETYPE_RESOURCE) { if (!array_key_exists('resources', $modfullnames)) { $modfullnames['resources'] = get_string('resources'); } } else { $modfullnames[$cm->modname] = $cm->modplural; } } } \core_collator::asort($modfullnames); return $modfullnames; }
private function register_link_encoders() { $encoders = array(); // Add the course encoder $encoders['backup_course_task'] = 'encode_content_links'; // Add the module ones. Each module supporting moodle2 backups MUST have it $mods = get_plugin_list('mod'); foreach ($mods as $mod => $moddir) { if (plugin_supports('mod', $mod, FEATURE_BACKUP_MOODLE2)) { $encoders['backup_' . $mod . '_activity_task'] = 'encode_content_links'; } } // Add the block encoders $blocks = get_plugin_list('block'); foreach ($blocks as $block => $blockdir) { if (class_exists('backup_' . $block . '_block_task')) { $encoders['backup_' . $block . '_block_task'] = 'encode_content_links'; } } // Add the course format encodes // TODO: Same than blocks, need to know how courseformats are going to handle backup // (1.9 was based in backuplib function, see code) // Add local encodes // TODO: Any interest? 1.9 never had that. return $encoders; }
$section = $DB->get_record('course_sections', array('id' => $cm->section, 'course' => $cm->course)); require_login($course); require_sesskey(); require_capability('moodle/course:manageactivities', $context); // Require both target import caps to be able to duplicate, see make_editing_buttons() require_capability('moodle/backup:backuptargetimport', $context); require_capability('moodle/restore:restoretargetimport', $context); $PAGE->set_title(get_string('duplicate')); $PAGE->set_heading($course->fullname); $PAGE->set_url(new moodle_url('/course/modduplicate.php', array('cmid' => $cm->id, 'courseid' => $course->id))); $PAGE->set_pagelayout('incourse'); $output = $PAGE->get_renderer('core', 'backup'); $a = new stdClass(); $a->modtype = get_string('modulename', $cm->modname); $a->modname = format_string($cm->name); if (!plugin_supports('mod', $cm->modname, FEATURE_BACKUP_MOODLE2)) { $url = course_get_url($course, $cm->sectionnum, array('sr' => $sectionreturn)); print_error('duplicatenosupport', 'error', $url, $a); } // backup the activity $bc = new backup_controller(backup::TYPE_1ACTIVITY, $cm->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id); $backupid = $bc->get_backupid(); $backupbasepath = $bc->get_plan()->get_basepath(); $bc->execute_plan(); $bc->destroy(); // restore the backup immediately $rc = new restore_controller($backupid, $courseid, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_CURRENT_ADDING); if (!$rc->execute_precheck()) { $precheckresults = $rc->get_precheck_results(); if (is_array($precheckresults) && !empty($precheckresults['errors'])) { if (empty($CFG->keeptempdirectoriesonbackup)) {
/** * Test a specific type of module. * * @param string $modulename - the module name to test */ private function update_specific_module_test($modulename) { global $DB, $CFG; $this->resetAfterTest(true); $this->setAdminUser(); // Warnings: you'll need to change this line if ever you come to test a module not following Moodle standard. require_once $CFG->dirroot . '/mod/' . $modulename . '/lib.php'; // Enable avaibility. // If not enabled all conditional fields will be ignored. set_config('enableavailability', 1); // Enable course completion. // If not enabled all completion settings will be ignored. set_config('enablecompletion', COMPLETION_ENABLED); // Enable forum RSS feeds. set_config('enablerssfeeds', 1); set_config('forum_enablerssfeeds', 1); $course = $this->getDataGenerator()->create_course(array('numsections' => 1, 'enablecompletion' => COMPLETION_ENABLED), array('createsections' => true)); $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id)); // Create assign module instance for testing gradeitem. $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $instance = $generator->create_instance($params); $assigncm = get_coursemodule_from_instance('assign', $instance->id); // Create the test forum to update. $initvalues = new stdClass(); $initvalues->introformat = FORMAT_HTML; $initvalues->course = $course->id; $forum = self::getDataGenerator()->create_module('forum', $initvalues); // Retrieve course module. $cm = get_coursemodule_from_instance('forum', $forum->id); // Module test values. $moduleinfo = new stdClass(); // Always mandatory generic values to any module. $moduleinfo->coursemodule = $cm->id; $moduleinfo->modulename = $modulename; $moduleinfo->course = $course->id; $moduleinfo->groupingid = $grouping->id; $moduleinfo->visible = true; // Sometimes optional generic values for some modules. $moduleinfo->name = 'My test module'; $moduleinfo->showdescription = 1; // standard boolean require_once $CFG->libdir . '/gradelib.php'; $gradecats = grade_get_categories_menu($moduleinfo->course, false); $gradecatid = current(array_keys($gradecats)); // Retrieve the first key of $gradecats $moduleinfo->gradecat = $gradecatid; $moduleinfo->groupmode = VISIBLEGROUPS; $moduleinfo->cmidnumber = 'idnumber_XXX'; // Completion common to all module. $moduleinfo->completion = COMPLETION_TRACKING_AUTOMATIC; $moduleinfo->completionview = COMPLETION_VIEW_REQUIRED; $moduleinfo->completiongradeitemnumber = 1; $moduleinfo->completionexpected = time() + 7 * 24 * 3600; $moduleinfo->completionunlocked = 1; // Conditional activity. $coursegradeitem = grade_item::fetch_course_item($moduleinfo->course); //the activity will become available only when the user reach some grade into the course itself. $moduleinfo->availability = json_encode(\core_availability\tree::get_root_json(array(\availability_date\condition::get_json('>=', time()), \availability_date\condition::get_json('<', time() + 7 * 24 * 3600), \availability_grade\condition::get_json($coursegradeitem->id, 10, 80), \availability_profile\condition::get_json(false, 'email', 'contains', '@'), \availability_completion\condition::get_json($assigncm->id, COMPLETION_COMPLETE)), '&')); // Grading and Advanced grading. require_once $CFG->dirroot . '/rating/lib.php'; $moduleinfo->assessed = RATING_AGGREGATE_AVERAGE; $moduleinfo->scale = 10; // Note: it could be minus (for specific course scale). It is a signed number. $moduleinfo->assesstimestart = time(); $moduleinfo->assesstimefinish = time() + 7 * 24 * 3600; // RSS. $moduleinfo->rsstype = 2; $moduleinfo->rssarticles = 10; // Optional intro editor (depends of module). $draftid_editor = 0; file_prepare_draft_area($draftid_editor, null, null, null, null); $moduleinfo->introeditor = array('text' => 'This is a module', 'format' => FORMAT_HTML, 'itemid' => $draftid_editor); // Following is the advanced grading method area called 'submissions' for the 'assign' module. if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) { $moduleinfo->grade = 100; } // Plagiarism form values. // No plagiarism plugin installed by default. Use this space to make your own test. // Values specific to the module. $modulesetvalues = $modulename . '_update_set_values'; $this->{$modulesetvalues}($moduleinfo); // Create the module. $result = update_module($moduleinfo); // Retrieve the module info. $dbmodinstance = $DB->get_record($moduleinfo->modulename, array('id' => $result->instance)); $dbcm = get_coursemodule_from_instance($moduleinfo->modulename, $result->instance); // Retrieve the grade item. $gradeitem = $DB->get_record('grade_items', array('courseid' => $moduleinfo->course, 'iteminstance' => $dbmodinstance->id, 'itemmodule' => $moduleinfo->modulename)); // Compare the values common to all module instances. $this->assertEquals($moduleinfo->modulename, $dbcm->modname); $this->assertEquals($moduleinfo->course, $dbcm->course); $this->assertEquals($moduleinfo->groupingid, $dbcm->groupingid); $this->assertEquals($moduleinfo->visible, $dbcm->visible); $this->assertEquals($moduleinfo->completion, $dbcm->completion); $this->assertEquals($moduleinfo->completionview, $dbcm->completionview); $this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber); $this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected); $this->assertEquals($moduleinfo->availability, $dbcm->availability); $this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription); $this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode); $this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber); $this->assertEquals($moduleinfo->gradecat, $gradeitem->categoryid); // Optional grade testing. if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) { $this->assertEquals($moduleinfo->grade, $dbmodinstance->grade); } // Some optional (but quite common) to some module. $this->assertEquals($moduleinfo->name, $dbmodinstance->name); $this->assertEquals($moduleinfo->intro, $dbmodinstance->intro); $this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat); // Test specific to the module. $modulerunasserts = $modulename . '_update_run_asserts'; $this->{$modulerunasserts}($moduleinfo, $dbmodinstance); return $moduleinfo; }
// ======================================================================================================================== } else { if (strpos($component, 'mod_') === 0) { $modname = substr($component, 4); if (!file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) { send_file_not_found(); } require_once "{$CFG->dirroot}/mod/{$modname}/lib.php"; if ($context->contextlevel == CONTEXT_MODULE) { if ($cm->modname !== $modname) { // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } } if ($filearea === 'intro') { if (!plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)) { send_file_not_found(); } require_course_login($course, true, $cm); // all users may access it $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'mod_' . $modname, 'intro', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } $lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400; // finally send the file send_stored_file($file, $lifetime, 0); } $filefunction = $component . '_pluginfile'; $filefunctionold = $modname . '_pluginfile';
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; }
/** * Does an activity module use the question bank? * * @param string $modname The name of the module (without mod_ prefix). * @return bool true if the module uses questions. */ function question_module_uses_questions($modname) { if (plugin_supports('mod', $modname, FEATURE_USES_QUESTIONS)) { return true; } $component = 'mod_' . $modname; if (component_callback_exists($component, 'question_pluginfile')) { debugging("{$component} uses questions but doesn't declare FEATURE_USES_QUESTIONS", DEBUG_DEVELOPER); return true; } return false; }
require_once "{$CFG->libdir}/resourcelib.php"; $id = required_param('id', PARAM_INT); // course id $course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST); $PAGE->set_pagelayout('course'); require_course_login($course, true); // get list of all resource-like modules $allmodules = $DB->get_records('modules', array('visible' => 1)); $modules = array(); foreach ($allmodules as $key => $module) { $modname = $module->name; $libfile = "{$CFG->dirroot}/mod/{$modname}/lib.php"; if (!file_exists($libfile)) { continue; } $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); if ($archetype != MOD_ARCHETYPE_RESOURCE) { continue; } $modules[$modname] = get_string('modulename', $modname); //some hacky nasic logging add_to_log($course->id, $modname, 'view all', "index.php?id={$course->id}", ''); } $strresources = get_string('resources'); $strsectionname = get_string('sectionname', 'format_' . $course->format); $strname = get_string('name'); $strintro = get_string('moduleintro'); $strlastmodified = get_string('lastmodified'); $PAGE->set_url('/course/resources.php', array('id' => $course->id)); $PAGE->set_title($course->shortname . ': ' . $strresources); $PAGE->set_heading($course->fullname);
/** * Include the grading.xml only if the module supports advanced grading */ protected function execute_condition() { return plugin_supports('mod', $this->get_task()->get_modulename(), FEATURE_ADVANCED_GRADING, false); }
/** * This function delegates file serving to individual plugins * * @param string $relativepath * @param bool $forcedownload * @param null|string $preview the preview mode, defaults to serving the original file * @todo MDL-31088 file serving improments */ function file_pluginfile($relativepath, $forcedownload, $preview = null) { global $DB, $CFG, $USER; // relative path must start with '/' if (!$relativepath) { print_error('invalidargorconf'); } else { if ($relativepath[0] != '/') { print_error('pathdoesnotstartslash'); } } // extract relative path components $args = explode('/', ltrim($relativepath, '/')); if (count($args) < 3) { // always at least context, component and filearea print_error('invalidarguments'); } $contextid = (int) array_shift($args); $component = clean_param(array_shift($args), PARAM_COMPONENT); $filearea = clean_param(array_shift($args), PARAM_AREA); list($context, $course, $cm) = get_context_info_array($contextid); $fs = get_file_storage(); // ======================================================================================================================== if ($component === 'blog') { // Blog file serving if ($context->contextlevel != CONTEXT_SYSTEM) { send_file_not_found(); } if ($filearea !== 'attachment' and $filearea !== 'post') { send_file_not_found(); } if (empty($CFG->enableblogs)) { print_error('siteblogdisable', 'blog'); } $entryid = (int) array_shift($args); if (!($entry = $DB->get_record('post', array('module' => 'blog', 'id' => $entryid)))) { send_file_not_found(); } if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) { require_login(); if (isguestuser()) { print_error('noguest'); } if ($CFG->bloglevel == BLOG_USER_LEVEL) { if ($USER->id != $entry->userid) { send_file_not_found(); } } } if ($entry->publishstate === 'public') { if ($CFG->forcelogin) { require_login(); } } else { if ($entry->publishstate === 'site') { require_login(); //ok } else { if ($entry->publishstate === 'draft') { require_login(); if ($USER->id != $entry->userid) { send_file_not_found(); } } } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $entryid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 10 * 60, 0, true, array('preview' => $preview)); // download MUST be forced - security! // ======================================================================================================================== } else { if ($component === 'grade') { if (($filearea === 'outcome' or $filearea === 'scale') and $context->contextlevel == CONTEXT_SYSTEM) { // Global gradebook files if ($CFG->forcelogin) { require_login(); } $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'feedback' and $context->contextlevel == CONTEXT_COURSE) { //TODO: nobody implemented this yet in grade edit form!! send_file_not_found(); if ($CFG->forcelogin || $course->id != SITEID) { require_login($course); } $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } // ======================================================================================================================== } else { if ($component === 'tag') { if ($filearea === 'description' and $context->contextlevel == CONTEXT_SYSTEM) { // All tag descriptions are going to be public but we still need to respect forcelogin if ($CFG->forcelogin) { require_login(); } $fullpath = "/{$context->id}/tag/description/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'badges') { require_once $CFG->libdir . '/badgeslib.php'; $badgeid = (int) array_shift($args); $badge = new badge($badgeid); $filename = array_pop($args); if ($filearea === 'badgeimage') { if ($filename !== 'f1' && $filename !== 'f2') { send_file_not_found(); } if (!($file = $fs->get_file($context->id, 'badges', 'badgeimage', $badge->id, '/', $filename . '.png'))) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'userbadge' and $context->contextlevel == CONTEXT_USER) { if (!($file = $fs->get_file($context->id, 'badges', 'userbadge', $badge->id, '/', $filename . '.png'))) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview)); } } // ======================================================================================================================== } else { if ($component === 'calendar') { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_SYSTEM) { // All events here are public the one requirement is that we respect forcelogin if ($CFG->forcelogin) { require_login(); } // Get the event if from the args array $eventid = array_shift($args); // Load the event from the database if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'eventtype' => 'site')))) { send_file_not_found(); } // Get the file and serve if successful $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_USER) { // Must be logged in, if they are not then they obviously can't be this user require_login(); // Don't want guests here, potentially saves a DB call if (isguestuser()) { send_file_not_found(); } // Get the event if from the args array $eventid = array_shift($args); // Load the event from the database - user id must match if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'userid' => $USER->id, 'eventtype' => 'user')))) { send_file_not_found(); } // Get the file and serve if successful $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); } else { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_COURSE) { // Respect forcelogin and require login unless this is the site.... it probably // should NEVER be the site if ($CFG->forcelogin || $course->id != SITEID) { require_login($course); } // Must be able to at least view the course. This does not apply to the front page. if ($course->id != SITEID && !is_enrolled($context) && !is_viewing($context)) { //TODO: hmm, do we really want to block guests here? send_file_not_found(); } // Get the event id $eventid = array_shift($args); // Load the event from the database we need to check whether it is // a) valid course event // b) a group event // Group events use the course context (there is no group context) if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'courseid' => $course->id)))) { send_file_not_found(); } // If its a group event require either membership of view all groups capability if ($event->eventtype === 'group') { if (!has_capability('moodle/site:accessallgroups', $context) && !groups_is_member($event->groupid, $USER->id)) { send_file_not_found(); } } else { if ($event->eventtype === 'course' || $event->eventtype === 'site') { // Ok. Please note that the event type 'site' still uses a course context. } else { // Some other type. send_file_not_found(); } } // If we get this far we can serve the file $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } // ======================================================================================================================== } else { if ($component === 'user') { if ($filearea === 'icon' and $context->contextlevel == CONTEXT_USER) { if (count($args) == 1) { $themename = theme_config::DEFAULT_THEME; $filename = array_shift($args); } else { $themename = array_shift($args); $filename = array_shift($args); } // fix file name automatically if ($filename !== 'f1' and $filename !== 'f2' and $filename !== 'f3') { $filename = 'f1'; } if ((!empty($CFG->forcelogin) and !isloggedin()) || !empty($CFG->forceloginforprofileimage) && (!isloggedin() || isguestuser())) { // protect images if login required and not logged in; // also if login is required for profile images and is not logged in or guest // do not use require_login() because it is expensive and not suitable here anyway $theme = theme_config::load($themename); redirect($theme->pix_url('u/' . $filename, 'moodle')); // intentionally not cached } if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.png'))) { if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.jpg'))) { if ($filename === 'f3') { // f3 512x512px was introduced in 2.3, there might be only the smaller version. if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.png'))) { $file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.jpg'); } } } } if (!$file) { // bad reference - try to prevent future retries as hard as possible! if ($user = $DB->get_record('user', array('id' => $context->instanceid), 'id, picture')) { if ($user->picture > 0) { $DB->set_field('user', 'picture', 0, array('id' => $user->id)); } } // no redirect here because it is not cached $theme = theme_config::load($themename); $imagefile = $theme->resolve_image_location('u/' . $filename, 'moodle', null); send_file($imagefile, basename($imagefile), 60 * 60 * 24 * 14); } $options = array('preview' => $preview); if (empty($CFG->forcelogin) && empty($CFG->forceloginforprofileimage)) { // Profile images should be cache-able by both browsers and proxies according // to $CFG->forcelogin and $CFG->forceloginforprofileimage. $options['cacheability'] = 'public'; } send_stored_file($file, 60 * 60 * 24 * 365, 0, false, $options); // enable long caching, there are many images on each page } else { if ($filearea === 'private' and $context->contextlevel == CONTEXT_USER) { require_login(); if (isguestuser()) { send_file_not_found(); } if ($USER->id !== $context->instanceid) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'profile' and $context->contextlevel == CONTEXT_USER) { if ($CFG->forcelogin) { require_login(); } $userid = $context->instanceid; if ($USER->id == $userid) { // always can access own } else { if (!empty($CFG->forceloginforprofiles)) { require_login(); if (isguestuser()) { send_file_not_found(); } // we allow access to site profile of all course contacts (usually teachers) if (!has_coursecontact_role($userid) && !has_capability('moodle/user:viewdetails', $context)) { send_file_not_found(); } $canview = false; if (has_capability('moodle/user:viewdetails', $context)) { $canview = true; } else { $courses = enrol_get_my_courses(); } while (!$canview && count($courses) > 0) { $course = array_shift($courses); if (has_capability('moodle/user:viewdetails', context_course::instance($course->id))) { $canview = true; } } } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'profile' and $context->contextlevel == CONTEXT_COURSE) { $userid = (int) array_shift($args); $usercontext = context_user::instance($userid); if ($CFG->forcelogin) { require_login(); } if (!empty($CFG->forceloginforprofiles)) { require_login(); if (isguestuser()) { print_error('noguest'); } //TODO: review this logic of user profile access prevention if (!has_coursecontact_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) { print_error('usernotavailable'); } if (!has_capability('moodle/user:viewdetails', $context) && !has_capability('moodle/user:viewdetails', $usercontext)) { print_error('cannotviewprofile'); } if (!is_enrolled($context, $userid)) { print_error('notenrolledprofile'); } if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { print_error('groupnotamember'); } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($usercontext->id, 'user', 'profile', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'backup' and $context->contextlevel == CONTEXT_USER) { require_login(); if (isguestuser()) { send_file_not_found(); } $userid = $context->instanceid; if ($USER->id != $userid) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'user', 'backup', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { send_file_not_found(); } } } } } // ======================================================================================================================== } else { if ($component === 'coursecat') { if ($context->contextlevel != CONTEXT_COURSECAT) { send_file_not_found(); } if ($filearea === 'description') { if ($CFG->forcelogin) { // no login necessary - unless login forced everywhere require_login(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'coursecat', 'description', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'course') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } if ($filearea === 'summary' || $filearea === 'overviewfiles') { if ($CFG->forcelogin) { require_login(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'course', $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'section') { if ($CFG->forcelogin) { require_login($course); } else { if ($course->id != SITEID) { require_login($course); } } $sectionid = (int) array_shift($args); if (!($section = $DB->get_record('course_sections', array('id' => $sectionid, 'course' => $course->id)))) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'course', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } else { if ($component === 'cohort') { $cohortid = (int) array_shift($args); $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST); $cohortcontext = context::instance_by_id($cohort->contextid); // The context in the file URL must be either cohort context or context of the course underneath the cohort's context. if ($context->id != $cohort->contextid && ($context->contextlevel != CONTEXT_COURSE || !in_array($cohort->contextid, $context->get_parent_context_ids()))) { send_file_not_found(); } // User is able to access cohort if they have view cap on cohort level or // the cohort is visible and they have view cap on course level. $canview = has_capability('moodle/cohort:view', $cohortcontext) || $cohort->visible && has_capability('moodle/cohort:view', $context); if ($filearea === 'description' && $canview) { $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (($file = $fs->get_file($cohortcontext->id, 'cohort', 'description', $cohort->id, $filepath, $filename)) && !$file->is_directory()) { \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } } send_file_not_found(); } else { if ($component === 'group') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } require_course_login($course, true, null, false); $groupid = (int) array_shift($args); $group = $DB->get_record('groups', array('id' => $groupid, 'courseid' => $course->id), '*', MUST_EXIST); if ($course->groupmodeforce and $course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context) and !groups_is_member($group->id, $USER->id)) { // do not allow access to separate group info if not member or teacher send_file_not_found(); } if ($filearea === 'description') { require_login($course); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'group', 'description', $group->id, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'icon') { $filename = array_pop($args); if ($filename !== 'f1' and $filename !== 'f2') { send_file_not_found(); } if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.png'))) { if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.jpg'))) { send_file_not_found(); } } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, false, array('preview' => $preview)); } else { send_file_not_found(); } } } else { if ($component === 'grouping') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } require_login($course); $groupingid = (int) array_shift($args); // note: everybody has access to grouping desc images for now if ($filearea === 'description') { $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'grouping', 'description', $groupingid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'backup') { if ($filearea === 'course' and $context->contextlevel == CONTEXT_COURSE) { require_login($course); require_capability('moodle/backup:downloadfile', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'course', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'section' and $context->contextlevel == CONTEXT_COURSE) { require_login($course); require_capability('moodle/backup:downloadfile', $context); $sectionid = (int) array_shift($args); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'activity' and $context->contextlevel == CONTEXT_MODULE) { require_login($course, false, $cm); require_capability('moodle/backup:downloadfile', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'activity', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'automated' and $context->contextlevel == CONTEXT_COURSE) { // Backup files that were generated by the automated backup systems. require_login($course); require_capability('moodle/site:config', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'automated', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } } // ======================================================================================================================== } else { if ($component === 'question') { require_once $CFG->libdir . '/questionlib.php'; question_pluginfile($course, $context, 'question', $filearea, $args, $forcedownload); send_file_not_found(); // ======================================================================================================================== } else { if ($component === 'grading') { if ($filearea === 'description') { // files embedded into the form definition description if ($context->contextlevel == CONTEXT_SYSTEM) { require_login(); } else { if ($context->contextlevel >= CONTEXT_COURSE) { require_login($course, false, $cm); } else { send_file_not_found(); } } $formid = (int) array_shift($args); $sql = "SELECT ga.id\n FROM {grading_areas} ga\n JOIN {grading_definitions} gd ON (gd.areaid = ga.id)\n WHERE gd.id = ? AND ga.contextid = ?"; $areaid = $DB->get_field_sql($sql, array($formid, $context->id), IGNORE_MISSING); if (!$areaid) { send_file_not_found(); } $fullpath = "/{$context->id}/{$component}/{$filearea}/{$formid}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } // ======================================================================================================================== } else { if (strpos($component, 'mod_') === 0) { $modname = substr($component, 4); if (!file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) { send_file_not_found(); } require_once "{$CFG->dirroot}/mod/{$modname}/lib.php"; if ($context->contextlevel == CONTEXT_MODULE) { if ($cm->modname !== $modname) { // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } } if ($filearea === 'intro') { if (!plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)) { send_file_not_found(); } require_course_login($course, true, $cm); // all users may access it $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'mod_' . $modname, 'intro', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } // finally send the file send_stored_file($file, null, 0, false, array('preview' => $preview)); } $filefunction = $component . '_pluginfile'; $filefunctionold = $modname . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } else { if (function_exists($filefunctionold)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunctionold($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } } send_file_not_found(); // ======================================================================================================================== } else { if (strpos($component, 'block_') === 0) { $blockname = substr($component, 6); // note: no more class methods in blocks please, that is .... if (!file_exists("{$CFG->dirroot}/blocks/{$blockname}/lib.php")) { send_file_not_found(); } require_once "{$CFG->dirroot}/blocks/{$blockname}/lib.php"; if ($context->contextlevel == CONTEXT_BLOCK) { $birecord = $DB->get_record('block_instances', array('id' => $context->instanceid), '*', MUST_EXIST); if ($birecord->blockname !== $blockname) { // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } if ($context->get_course_context(false)) { // If block is in course context, then check if user has capability to access course. require_course_login($course); } else { if ($CFG->forcelogin) { // If user is logged out, bp record will not be visible, even if the user would have access if logged in. require_login(); } } $bprecord = $DB->get_record('block_positions', array('contextid' => $context->id, 'blockinstanceid' => $context->instanceid)); // User can't access file, if block is hidden or doesn't have block:view capability if ($bprecord && !$bprecord->visible || !has_capability('moodle/block:view', $context)) { send_file_not_found(); } } else { $birecord = null; } $filefunction = $component . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $birecord, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } send_file_not_found(); // ======================================================================================================================== } else { if (strpos($component, '_') === false) { // all core subsystems have to be specified above, no more guessing here! send_file_not_found(); } else { // try to serve general plugin file in arbitrary context $dir = core_component::get_component_directory($component); if (!file_exists("{$dir}/lib.php")) { send_file_not_found(); } include_once "{$dir}/lib.php"; $filefunction = $component . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } send_file_not_found(); } } } } } } } } } } } } } } } } } }
/** * Duplicate a module on the course. * * @param object $course The course * @param object $cm The course module to duplicate * @throws moodle_exception if the plugin doesn't support duplication * @return Object containing: * - fullcontent: The HTML markup for the created CM * - cmid: The CMID of the newly created CM * - redirect: Whether to trigger a redirect following this change */ function mod_duplicate_activity($course, $cm, $sr = null) { global $CFG, $USER, $PAGE, $DB; require_once $CFG->dirroot . '/backup/util/includes/backup_includes.php'; require_once $CFG->dirroot . '/backup/util/includes/restore_includes.php'; require_once $CFG->libdir . '/filelib.php'; $a = new stdClass(); $a->modtype = get_string('modulename', $cm->modname); $a->modname = format_string($cm->name); if (!plugin_supports('mod', $cm->modname, FEATURE_BACKUP_MOODLE2)) { throw new moodle_exception('duplicatenosupport', 'error'); } // backup the activity $bc = new backup_controller(backup::TYPE_1ACTIVITY, $cm->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id); $backupid = $bc->get_backupid(); $backupbasepath = $bc->get_plan()->get_basepath(); $bc->execute_plan(); $bc->destroy(); // restore the backup immediately $rc = new restore_controller($backupid, $course->id, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_CURRENT_ADDING); $cmcontext = context_module::instance($cm->id); if (!$rc->execute_precheck()) { $precheckresults = $rc->get_precheck_results(); if (is_array($precheckresults) && !empty($precheckresults['errors'])) { if (empty($CFG->keeptempdirectoriesonbackup)) { fulldelete($backupbasepath); } } } $rc->execute_plan(); // now a bit hacky part follows - we try to get the cmid of the newly // restored copy of the module $newcmid = null; $tasks = $rc->get_plan()->get_tasks(); foreach ($tasks as $task) { error_log("Looking at a task"); if (is_subclass_of($task, 'restore_activity_task')) { error_log("Looking at a restore_activity_task task"); if ($task->get_old_contextid() == $cmcontext->id) { error_log("Contexts match"); $newcmid = $task->get_moduleid(); break; } } } // if we know the cmid of the new course module, let us move it // right below the original one. otherwise it will stay at the // end of the section if ($newcmid) { $info = get_fast_modinfo($course); $newcm = $info->get_cm($newcmid); $section = $DB->get_record('course_sections', array('id' => $cm->section, 'course' => $cm->course)); moveto_module($newcm, $section, $cm); moveto_module($cm, $section, $newcm); // Trigger course module created event. We can trigger the event only if we know the newcmid. $event = \core\event\course_module_created::create_from_cm($newcm); $event->trigger(); } rebuild_course_cache($cm->course); $rc->destroy(); if (empty($CFG->keeptempdirectoriesonbackup)) { fulldelete($backupbasepath); } $resp = new stdClass(); if ($newcm) { $courserenderer = $PAGE->get_renderer('core', 'course'); $completioninfo = new completion_info($course); $modulehtml = $courserenderer->course_section_cm($course, $completioninfo, $newcm, null, array()); $resp->fullcontent = $courserenderer->course_section_cm_list_item($course, $completioninfo, $newcm, $sr); $resp->cmid = $newcm->id; } else { // Trigger a redirect $resp->redirect = true; } return $resp; }
function theme_bcu_get_course_activities() { global $CFG, $PAGE, $OUTPUT; // A copy of block_activity_modules. $course = $PAGE->course; $content = new stdClass(); $modinfo = get_fast_modinfo($course); $modfullnames = array(); $archetypes = array(); foreach ($modinfo->cms as $cm) { // Exclude activities which are not visible or have no link (=label). if (!$cm->uservisible or !$cm->has_view()) { continue; } if (array_key_exists($cm->modname, $modfullnames)) { continue; } if (!array_key_exists($cm->modname, $archetypes)) { $archetypes[$cm->modname] = plugin_supports('mod', $cm->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); } if ($archetypes[$cm->modname] == MOD_ARCHETYPE_RESOURCE) { if (!array_key_exists('resources', $modfullnames)) { $modfullnames['resources'] = get_string('resources'); } } else { $modfullnames[$cm->modname] = $cm->modplural; } } core_collator::asort($modfullnames); return $modfullnames; }
/** * Generate the list of modules for the given course. * * @param stdClass $course The course to get modules for */ protected function get_course_modules($course) { global $CFG; $mods = $modnames = $modnamesplural = $modnamesused = array(); // This function is included when we include course/lib.php at the top // of this file get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused); $resources = array(); $activities = array(); foreach ($modnames as $modname => $modnamestr) { if (!course_allowed_module($course, $modname)) { continue; } $libfile = "{$CFG->dirroot}/mod/{$modname}/lib.php"; if (!file_exists($libfile)) { continue; } include_once $libfile; $gettypesfunc = $modname . '_get_types'; if (function_exists($gettypesfunc)) { $types = $gettypesfunc(); foreach ($types as $type) { if (!isset($type->modclass) || !isset($type->typestr)) { debugging('Incorrect activity type in ' . $modname); continue; } if ($type->modclass == MOD_CLASS_RESOURCE) { $resources[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr; } else { $activities[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr; } } } else { $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); if ($archetype == MOD_ARCHETYPE_RESOURCE) { $resources[$modname] = $modnamestr; } else { // all other archetypes are considered activity $activities[$modname] = $modnamestr; } } } return array($resources, $activities); }
/** * Create the coursemodule to hold the file/content that has been uploaded */ protected function create_course_module() { if (!course_allowed_module($this->course, $this->module->name)) { throw new coding_exception("The module {$this->module->name} is not allowed to be added to this course"); } $this->cm = new stdClass(); $this->cm->course = $this->course->id; $this->cm->section = $this->section; $this->cm->module = $this->module->id; $this->cm->modulename = $this->module->name; $this->cm->instance = 0; // This will be filled in after we create the instance. $this->cm->visible = 1; $this->cm->groupmode = $this->course->groupmode; $this->cm->groupingid = $this->course->defaultgroupingid; if (!($this->cm->id = add_course_module($this->cm))) { throw new coding_exception("Unable to create the course module"); } // The following are used inside some few core functions, so may as well set them here. $this->cm->coursemodule = $this->cm->id; $groupbuttons = ($this->course->groupmode or !$this->course->groupmodeforce); if ($groupbuttons and plugin_supports('mod', $this->module->name, FEATURE_GROUPS, 0)) { $this->cm->groupmodelink = !$this->course->groupmodeforce; } else { $this->cm->groupmodelink = false; $this->cm->groupmode = false; } }