/** * Add course module. * * The function does not check user capabilities. * The function creates course module, module instance, add the module to the correct section. * It also trigger common action that need to be done after adding/updating a module. * * @param object $moduleinfo the moudle data * @param object $course the course of the module * @param object $mform this is required by an existing hack to deal with files during MODULENAME_add_instance() * @return object the updated module info */ function add_moduleinfo($moduleinfo, $course, $mform = null) { global $DB, $CFG; // Attempt to include module library before we make any changes to DB. include_modulelib($moduleinfo->modulename); $moduleinfo->course = $course->id; $moduleinfo = set_moduleinfo_defaults($moduleinfo); if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) { $moduleinfo->groupmode = 0; // Do not set groupmode. } // First add course_module record because we need the context. $newcm = new stdClass(); $newcm->course = $course->id; $newcm->module = $moduleinfo->module; $newcm->instance = 0; // Not known yet, will be updated later (this is similar to restore code). $newcm->visible = $moduleinfo->visible; $newcm->visibleold = $moduleinfo->visible; if (isset($moduleinfo->cmidnumber)) { $newcm->idnumber = $moduleinfo->cmidnumber; } $newcm->groupmode = $moduleinfo->groupmode; $newcm->groupingid = $moduleinfo->groupingid; $newcm->groupmembersonly = $moduleinfo->groupmembersonly; $completion = new completion_info($course); if ($completion->is_enabled()) { $newcm->completion = $moduleinfo->completion; $newcm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber; $newcm->completionview = $moduleinfo->completionview; $newcm->completionexpected = $moduleinfo->completionexpected; } if (!empty($CFG->enableavailability)) { $newcm->availablefrom = $moduleinfo->availablefrom; $newcm->availableuntil = $moduleinfo->availableuntil; $newcm->showavailability = $moduleinfo->showavailability; } if (isset($moduleinfo->showdescription)) { $newcm->showdescription = $moduleinfo->showdescription; } else { $newcm->showdescription = 0; } if (!($moduleinfo->coursemodule = add_course_module($newcm))) { print_error('cannotaddcoursemodule'); } if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true) && isset($moduleinfo->introeditor)) { $introeditor = $moduleinfo->introeditor; unset($moduleinfo->introeditor); $moduleinfo->intro = $introeditor['text']; $moduleinfo->introformat = $introeditor['format']; } $addinstancefunction = $moduleinfo->modulename . "_add_instance"; $returnfromfunc = $addinstancefunction($moduleinfo, $mform); if (!$returnfromfunc or !is_number($returnfromfunc)) { // Undo everything we can. $modcontext = context_module::instance($moduleinfo->coursemodule); context_helper::delete_instance(CONTEXT_MODULE, $moduleinfo->coursemodule); $DB->delete_records('course_modules', array('id' => $moduleinfo->coursemodule)); if (!is_number($returnfromfunc)) { print_error('invalidfunction', '', course_get_url($course, $moduleinfo->section)); } else { print_error('cannotaddnewmodule', '', course_get_url($course, $moduleinfo->section), $moduleinfo->modulename); } } $moduleinfo->instance = $returnfromfunc; $DB->set_field('course_modules', 'instance', $returnfromfunc, array('id' => $moduleinfo->coursemodule)); // Update embedded links and save files. $modcontext = context_module::instance($moduleinfo->coursemodule); if (!empty($introeditor)) { $moduleinfo->intro = file_save_draft_area_files($introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $introeditor['text']); $DB->set_field($moduleinfo->modulename, 'intro', $moduleinfo->intro, array('id' => $moduleinfo->instance)); } // Course_modules and course_sections each contain a reference to each other. // So we have to update one of them twice. $sectionid = course_add_cm_to_section($course, $moduleinfo->coursemodule, $moduleinfo->section); // Set up conditions. if ($CFG->enableavailability) { condition_info::update_cm_from_form((object) array('id' => $moduleinfo->coursemodule), $moduleinfo, false); } // Trigger event based on the action we did. $event = \core\event\course_module_created::create(array('courseid' => $course->id, 'context' => $modcontext, 'objectid' => $moduleinfo->coursemodule, 'other' => array('modulename' => $moduleinfo->modulename, 'name' => $moduleinfo->name, 'instanceid' => $moduleinfo->instance))); $event->trigger(); add_to_log($course->id, $moduleinfo->modulename, "add", "view.php?id={$moduleinfo->coursemodule}", "{$moduleinfo->instance}", $moduleinfo->coursemodule); $moduleinfo = edit_module_post_actions($moduleinfo, $course); return $moduleinfo; }
/** * Tests for event validations related to course module creation. */ public function test_course_module_created_event_exceptions() { $this->resetAfterTest(); // Generate data. $modinfo = $this->create_specific_module_test('assign'); $context = context_module::instance($modinfo->coursemodule); // Test not setting instanceid. try { $event = \core\event\course_module_created::create(array('courseid' => $modinfo->course, 'context' => $context, 'objectid' => $modinfo->coursemodule, 'other' => array('modulename' => 'assign', 'name' => 'My assignment'))); $this->fail("Event validation should not allow \\core\\event\\course_module_created to be triggered without\n other['instanceid']"); } catch (coding_exception $e) { $this->assertContains("The 'instanceid' value must be set in other.", $e->getMessage()); } // Test not setting modulename. try { $event = \core\event\course_module_created::create(array('courseid' => $modinfo->course, 'context' => $context, 'objectid' => $modinfo->coursemodule, 'other' => array('instanceid' => $modinfo->instance, 'name' => 'My assignment'))); $this->fail("Event validation should not allow \\core\\event\\course_module_created to be triggered without\n other['modulename']"); } catch (coding_exception $e) { $this->assertContains("The 'modulename' value must be set in other.", $e->getMessage()); } // Test not setting name. try { $event = \core\event\course_module_created::create(array('courseid' => $modinfo->course, 'context' => $context, 'objectid' => $modinfo->coursemodule, 'other' => array('modulename' => 'assign', 'instanceid' => $modinfo->instance))); $this->fail("Event validation should not allow \\core\\event\\course_module_created to be triggered without\n other['name']"); } catch (coding_exception $e) { $this->assertContains("The 'name' value must be set in other.", $e->getMessage()); } }
/** * Called after the mod has set itself up, to finish off any course module settings * (set instance id, add to correct section, set visibility, etc.) and send the response * * @param int $instanceid id returned by the mod when it was created */ protected function finish_setup_course_module($instanceid) { global $DB, $USER; if (!$instanceid) { // Something has gone wrong - undo everything we can. course_delete_module($this->cm->id); throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name); } // Note the section visibility $visible = get_fast_modinfo($this->course)->get_section_info($this->section)->visible; $DB->set_field('course_modules', 'instance', $instanceid, array('id' => $this->cm->id)); // Rebuild the course cache after update action rebuild_course_cache($this->course->id, true); $sectionid = course_add_cm_to_section($this->course, $this->cm->id, $this->section); set_coursemodule_visible($this->cm->id, $visible); if (!$visible) { $DB->set_field('course_modules', 'visibleold', 1, array('id' => $this->cm->id)); } // retrieve the final info about this module. $info = get_fast_modinfo($this->course); if (!isset($info->cms[$this->cm->id])) { // The course module has not been properly created in the course - undo everything. course_delete_module($this->cm->id); throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name); } $mod = $info->get_cm($this->cm->id); // Trigger course module created event. $event = \core\event\course_module_created::create(array('courseid' => $this->course->id, 'context' => context_module::instance($mod->id), 'objectid' => $mod->id, 'other' => array('modulename' => $mod->modname, 'name' => $mod->name, 'instanceid' => $instanceid))); $event->trigger(); add_to_log($this->course->id, $mod->modname, "add", "view.php?id={$mod->id}", "{$instanceid}", $mod->id); $this->send_response($mod); }