function ma_show_execute($modids) { $message = ""; foreach ($modids as $modid) { if (!set_coursemodule_visible($modid, 1)) { $message .= "Could not show module {$modid}, "; } } return $message; }
/** * Adding this test here as get_areas_user_accesses process is the same, results just depend on the context level. * * @return void */ public function test_search_user_accesses() { global $DB; $this->resetAfterTest(); $frontpage = $DB->get_record('course', array('id' => SITEID)); $course1 = $this->getDataGenerator()->create_course(); $course1ctx = context_course::instance($course1->id); $course2 = $this->getDataGenerator()->create_course(); $course2ctx = context_course::instance($course2->id); $teacher = $this->getDataGenerator()->create_user(); $teacherctx = context_user::instance($teacher->id); $student = $this->getDataGenerator()->create_user(); $studentctx = context_user::instance($student->id); $noaccess = $this->getDataGenerator()->create_user(); $noaccessctx = context_user::instance($noaccess->id); $this->getDataGenerator()->enrol_user($teacher->id, $course1->id, 'teacher'); $this->getDataGenerator()->enrol_user($student->id, $course1->id, 'student'); $frontpageforum = $this->getDataGenerator()->create_module('forum', array('course' => $frontpage->id)); $forum1 = $this->getDataGenerator()->create_module('forum', array('course' => $course1->id)); $forum2 = $this->getDataGenerator()->create_module('forum', array('course' => $course1->id)); $forum3 = $this->getDataGenerator()->create_module('forum', array('course' => $course2->id)); $frontpageforumcontext = context_module::instance($frontpageforum->cmid); $context1 = context_module::instance($forum1->cmid); $context2 = context_module::instance($forum2->cmid); $context3 = context_module::instance($forum3->cmid); $search = testable_core_search::instance(); $mockareaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area'); $search->add_core_search_areas(); $search->add_search_area($mockareaid, new core_mocksearch\search\mock_search_area()); $this->setAdminUser(); $this->assertTrue($search->get_areas_user_accesses()); $sitectx = \context_course::instance(SITEID); $systemctxid = \context_system::instance()->id; // Can access the frontpage ones. $this->setUser($noaccess); $contexts = $search->get_areas_user_accesses(); $this->assertEquals(array($frontpageforumcontext->id => $frontpageforumcontext->id), $contexts[$this->forumpostareaid]); $this->assertEquals(array($sitectx->id => $sitectx->id), $contexts[$this->mycoursesareaid]); $mockctxs = array($noaccessctx->id => $noaccessctx->id, $systemctxid => $systemctxid); $this->assertEquals($mockctxs, $contexts[$mockareaid]); $this->setUser($teacher); $contexts = $search->get_areas_user_accesses(); $frontpageandcourse1 = array($frontpageforumcontext->id => $frontpageforumcontext->id, $context1->id => $context1->id, $context2->id => $context2->id); $this->assertEquals($frontpageandcourse1, $contexts[$this->forumpostareaid]); $this->assertEquals(array($sitectx->id => $sitectx->id, $course1ctx->id => $course1ctx->id), $contexts[$this->mycoursesareaid]); $mockctxs = array($teacherctx->id => $teacherctx->id, $systemctxid => $systemctxid); $this->assertEquals($mockctxs, $contexts[$mockareaid]); $this->setUser($student); $contexts = $search->get_areas_user_accesses(); $this->assertEquals($frontpageandcourse1, $contexts[$this->forumpostareaid]); $this->assertEquals(array($sitectx->id => $sitectx->id, $course1ctx->id => $course1ctx->id), $contexts[$this->mycoursesareaid]); $mockctxs = array($studentctx->id => $studentctx->id, $systemctxid => $systemctxid); $this->assertEquals($mockctxs, $contexts[$mockareaid]); // Hide the activity. set_coursemodule_visible($forum2->cmid, 0); $contexts = $search->get_areas_user_accesses(); $this->assertEquals(array($frontpageforumcontext->id => $frontpageforumcontext->id, $context1->id => $context1->id), $contexts[$this->forumpostareaid]); // Now test course limited searches. set_coursemodule_visible($forum2->cmid, 1); $this->getDataGenerator()->enrol_user($student->id, $course2->id, 'student'); $contexts = $search->get_areas_user_accesses(); $allcontexts = array($frontpageforumcontext->id => $frontpageforumcontext->id, $context1->id => $context1->id, $context2->id => $context2->id, $context3->id => $context3->id); $this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]); $this->assertEquals(array($sitectx->id => $sitectx->id, $course1ctx->id => $course1ctx->id, $course2ctx->id => $course2ctx->id), $contexts[$this->mycoursesareaid]); $contexts = $search->get_areas_user_accesses(array($course1->id, $course2->id)); $allcontexts = array($context1->id => $context1->id, $context2->id => $context2->id, $context3->id => $context3->id); $this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]); $this->assertEquals(array($course1ctx->id => $course1ctx->id, $course2ctx->id => $course2ctx->id), $contexts[$this->mycoursesareaid]); $contexts = $search->get_areas_user_accesses(array($course2->id)); $allcontexts = array($context3->id => $context3->id); $this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]); $this->assertEquals(array($course2ctx->id => $course2ctx->id), $contexts[$this->mycoursesareaid]); $contexts = $search->get_areas_user_accesses(array($course1->id)); $allcontexts = array($context1->id => $context1->id, $context2->id => $context2->id); $this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]); $this->assertEquals(array($course1ctx->id => $course1ctx->id), $contexts[$this->mycoursesareaid]); }
case 'move': require_capability('moodle/course:movesections', $coursecontext); move_section_to($course, $id, $value); // See if format wants to do something about it $response = course_get_format($course)->ajax_section_move(); if ($response !== null) { echo json_encode($response); } break; } break; case 'resource': switch ($field) { case 'visible': require_capability('moodle/course:activityvisibility', $modcontext); set_coursemodule_visible($cm->id, $value); \core\event\course_module_updated::create_from_cm($cm, $modcontext)->trigger(); break; case 'duplicate': require_capability('moodle/course:manageactivities', $modcontext); require_capability('moodle/backup:backuptargetimport', $modcontext); require_capability('moodle/restore:restoretargetimport', $modcontext); if (!course_allowed_module($course, $cm->modname)) { throw new moodle_exception('No permission to create that activity'); } $sr = optional_param('sr', null, PARAM_INT); $result = mod_duplicate_activity($course, $cm, $sr); echo json_encode($result); break; case 'groupmode': require_capability('moodle/course:manageactivities', $modcontext);
/** * Move the module object $mod to the specified $section * If $beforemod exists then that is the module * before which $modid should be inserted * All parameters are objects */ function moveto_module($mod, $section, $beforemod = NULL) { global $DB, $OUTPUT; /// Remove original module from original section if (!delete_mod_from_section($mod->id, $mod->section)) { echo $OUTPUT->notification("Could not delete module from existing section"); } /// Update module itself if necessary if ($mod->section != $section->id) { $mod->section = $section->id; $DB->update_record("course_modules", $mod); // if moving to a hidden section then hide module if (!$section->visible) { set_coursemodule_visible($mod->id, 0); } } /// Add the module into the new section $mod->course = $section->course; $mod->section = $section->section; // need relative reference $mod->coursemodule = $mod->id; if (!add_mod_to_section($mod, $beforemod)) { return false; } return true; }
/** * Tests grade_report::blank_hidden_total_and_adjust_bounds() */ public function test_blank_hidden_total_and_adjust_bounds() { global $DB; $this->resetAfterTest(true); $student = $this->getDataGenerator()->create_user(); $this->setUser($student); // Create a course and two activities. // One activity will be hidden. $course = $this->getDataGenerator()->create_course(); $coursegradeitem = grade_item::fetch_course_item($course->id); $coursecontext = context_course::instance($course->id); $data = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id)); $datacm = get_coursemodule_from_id('data', $data->cmid); $forum = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id)); $forumcm = get_coursemodule_from_id('forum', $forum->cmid); // Insert student grades for the two activities. $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'data', 'iteminstance' => $data->id, 'courseid' => $course->id)); $datagrade = 50; $grade_grade = new grade_grade(); $grade_grade->itemid = $gi->id; $grade_grade->userid = $student->id; $grade_grade->rawgrade = $datagrade; $grade_grade->finalgrade = $datagrade; $grade_grade->rawgrademax = 100; $grade_grade->rawgrademin = 0; $grade_grade->timecreated = time(); $grade_grade->timemodified = time(); $grade_grade->insert(); $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum->id, 'courseid' => $course->id)); $forumgrade = 70; $grade_grade = new grade_grade(); $grade_grade->itemid = $gi->id; $grade_grade->userid = $student->id; $grade_grade->rawgrade = $forumgrade; $grade_grade->finalgrade = $forumgrade; $grade_grade->rawgrademax = 100; $grade_grade->rawgrademin = 0; $grade_grade->timecreated = time(); $grade_grade->timemodified = time(); $grade_grade->insert(); // Hide the database activity. set_coursemodule_visible($datacm->id, 0); $gpr = new grade_plugin_return(array('type' => 'report', 'courseid' => $course->id)); $report = new grade_report_test($course->id, $gpr, $coursecontext, $student); // Should return the supplied student total grade regardless of hiding. $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN); $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade); $this->assertEquals(array('grade' => $datagrade + $forumgrade, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result); // Should blank the student total as course grade depends on a hidden item. $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN); $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade); $this->assertEquals(array('grade' => null, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result); // Should return the course total minus the hidden database activity grade. $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN); $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade); $this->assertEquals(array('grade' => floatval($forumgrade), 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result); // Note: we cannot simply hide modules and call $report->blank_hidden_total() again. // It stores grades in a static variable so $report->blank_hidden_total() will return incorrect totals // In practice this isn't a problem. Grade visibility isn't altered mid-request outside of the unit tests. // Add a second course to test: // 1) How a course with no visible activities behaves. // 2) That $report->blank_hidden_total() correctly moves on to the new course. $course = $this->getDataGenerator()->create_course(); $coursegradeitem = grade_item::fetch_course_item($course->id); $coursecontext = context_course::instance($course->id); $data = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id)); $datacm = get_coursemodule_from_id('data', $data->cmid); $forum = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id)); $forumcm = get_coursemodule_from_id('forum', $forum->cmid); $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'data', 'iteminstance' => $data->id, 'courseid' => $course->id)); $datagrade = 50; $grade_grade = new grade_grade(); $grade_grade->itemid = $gi->id; $grade_grade->userid = $student->id; $grade_grade->rawgrade = $datagrade; $grade_grade->finalgrade = $datagrade; $grade_grade->rawgrademax = 100; $grade_grade->rawgrademin = 0; $grade_grade->timecreated = time(); $grade_grade->timemodified = time(); $grade_grade->insert(); $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum->id, 'courseid' => $course->id)); $forumgrade = 70; $grade_grade = new grade_grade(); $grade_grade->itemid = $gi->id; $grade_grade->userid = $student->id; $grade_grade->rawgrade = $forumgrade; $grade_grade->finalgrade = $forumgrade; $grade_grade->rawgrademax = 100; $grade_grade->rawgrademin = 0; $grade_grade->timecreated = time(); $grade_grade->timemodified = time(); $grade_grade->insert(); // Hide both activities. set_coursemodule_visible($datacm->id, 0); set_coursemodule_visible($forumcm->id, 0); $gpr = new grade_plugin_return(array('type' => 'report', 'courseid' => $course->id)); $report = new grade_report_test($course->id, $gpr, $coursecontext, $student); // Should return the supplied student total grade regardless of hiding. $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN); $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade); $this->assertEquals(array('grade' => $datagrade + $forumgrade, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result); // Should blank the student total as course grade depends on a hidden item. $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN); $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade); $this->assertEquals(array('grade' => null, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result); // Should return the course total minus the hidden activity grades. // They are both hidden so should return null. $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN); $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade); $this->assertEquals(array('grade' => null, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result); }
/** * Move the module object $mod to the specified $section * If $beforemod exists then that is the module * before which $modid should be inserted * * @param stdClass|cm_info $mod * @param stdClass|section_info $section * @param int|stdClass $beforemod id or object with field id corresponding to the module * before which the module needs to be included. Null for inserting in the * end of the section * @return int new value for module visibility (0 or 1) */ function moveto_module($mod, $section, $beforemod = NULL) { global $OUTPUT, $DB; // Current module visibility state - return value of this function. $modvisible = $mod->visible; // Remove original module from original section. if (!delete_mod_from_section($mod->id, $mod->section)) { echo $OUTPUT->notification("Could not delete module from existing section"); } // If moving to a hidden section then hide module. if ($mod->section != $section->id) { if (!$section->visible && $mod->visible) { // Module was visible but must become hidden after moving to hidden section. $modvisible = 0; set_coursemodule_visible($mod->id, 0); // Set visibleold to 1 so module will be visible when section is made visible. $DB->set_field('course_modules', 'visibleold', 1, array('id' => $mod->id)); } if ($section->visible && !$mod->visible) { // Hidden module was moved to the visible section, restore the module visibility from visibleold. set_coursemodule_visible($mod->id, $mod->visibleold); $modvisible = $mod->visibleold; } } // Add the module into the new section. course_add_cm_to_section($section->course, $mod->id, $section->section, $beforemod); return $modvisible; }
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; }
/** * Test get_course_module_by_instance */ public function test_get_course_module_by_instance() { global $DB; $this->resetAfterTest(true); $this->setAdminUser(); $course = self::getDataGenerator()->create_course(); $record = array('course' => $course->id, 'name' => 'First Chat'); $options = array('idnumber' => 'ABC', 'visible' => 0); // Hidden activity. $chat = self::getDataGenerator()->create_module('chat', $record, $options); // Test admin user can see the complete hidden activity. $result = core_course_external::get_course_module_by_instance('chat', $chat->id); $result = external_api::clean_returnvalue(core_course_external::get_course_module_by_instance_returns(), $result); $this->assertCount(0, $result['warnings']); // Test we retrieve all the fields. $this->assertCount(22, $result['cm']); $this->assertEquals($record['name'], $result['cm']['name']); $this->assertEquals($options['idnumber'], $result['cm']['idnumber']); $student = $this->getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); self::getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); $this->setUser($student); // The user shouldn't be able to see the activity. try { core_course_external::get_course_module_by_instance('chat', $chat->id); $this->fail('Exception expected due to invalid permissions.'); } catch (moodle_exception $e) { $this->assertEquals('requireloginerror', $e->errorcode); } // Make module visible. set_coursemodule_visible($chat->cmid, 1); // Test student user. $result = core_course_external::get_course_module_by_instance('chat', $chat->id); $result = external_api::clean_returnvalue(core_course_external::get_course_module_by_instance_returns(), $result); $this->assertCount(0, $result['warnings']); // Test we retrieve only the few files we can see. $this->assertCount(11, $result['cm']); $this->assertEquals($chat->cmid, $result['cm']['id']); $this->assertEquals($course->id, $result['cm']['course']); $this->assertEquals('chat', $result['cm']['modname']); $this->assertEquals($chat->id, $result['cm']['instance']); // Try with an invalid module name. try { core_course_external::get_course_module_by_instance('abc', $chat->id); $this->fail('Exception expected due to invalid module name.'); } catch (dml_read_exception $e) { $this->assertEquals('dmlreadexception', $e->errorcode); } }
function moveto_module($mod, $section, $beforemod = NULL) { /// All parameters are objects /// Move the module object $mod to the specified $section /// If $beforemod exists then that is the module /// before which $modid should be inserted /// Remove original module from original section if (!delete_mod_from_section($mod->id, $mod->section)) { notify("Could not delete module from existing section"); } /// Update module itself if necessary if ($mod->section != $section->id) { $mod->section = $section->id; if (!update_record("course_modules", $mod)) { return false; } // if moving to a hidden section then hide module if (!$section->visible) { set_coursemodule_visible($mod->id, 0); } } /// Add the module into the new section $mod->course = $section->course; $mod->section = $section->section; // need relative reference $mod->coursemodule = $mod->id; if (!add_mod_to_section($mod, $beforemod)) { return false; } return true; }
/** * Document accesses. * * @return void */ public function test_posts_access() { global $DB; // Returns the instance as long as the area is supported. $searcharea = \core_search\manager::get_search_area($this->forumpostareaid); $user1 = self::getDataGenerator()->create_user(); $user2 = self::getDataGenerator()->create_user(); $course1 = self::getDataGenerator()->create_course(); $course2 = self::getDataGenerator()->create_course(); $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher'); $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student'); $record = new stdClass(); $record->course = $course1->id; // Available for both student and teacher. $forum1 = self::getDataGenerator()->create_module('forum', $record); // Teacher only. $forum2 = self::getDataGenerator()->create_module('forum', $record); set_coursemodule_visible($forum2->cmid, 0); // Create discussion1. $record = new stdClass(); $record->course = $course1->id; $record->userid = $user1->id; $record->forum = $forum1->id; $record->message = 'discussion'; $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); // Create post1 in discussion1. $record = new stdClass(); $record->discussion = $discussion1->id; $record->parent = $discussion1->firstpost; $record->userid = $user2->id; $record->message = 'post1'; $discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); // Create discussion2 only visible to teacher. $record = new stdClass(); $record->course = $course1->id; $record->userid = $user1->id; $record->forum = $forum2->id; $record->message = 'discussion'; $discussion2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); // Create post2 in discussion2. $record = new stdClass(); $record->discussion = $discussion2->id; $record->parent = $discussion2->firstpost; $record->userid = $user1->id; $record->message = 'post2'; $discussion2reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); $this->setUser($user2); $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($discussion1reply1->id)); $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($discussion2reply1->id)); }
/** * Update the module info. * This function doesn't check the user capabilities. It updates the course module and the module instance. * Then execute common action to create/update module process (trigger event, rebuild cache, save plagiarism settings...). * * @param object $cm course module * @param object $moduleinfo module info * @param object $course course of the module * @param object $mform - the mform is required by some specific module in the function MODULE_update_instance(). This is due to a hack in this function. * @return array list of course module and module info. */ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) { global $DB, $CFG; // Attempt to include module library before we make any changes to DB. include_modulelib($moduleinfo->modulename); $moduleinfo->course = $course->id; $moduleinfo = set_moduleinfo_defaults($moduleinfo); if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) { $moduleinfo->groupmode = $cm->groupmode; // Keep original. } // Update course module first. $cm->groupmode = $moduleinfo->groupmode; if (isset($moduleinfo->groupingid)) { $cm->groupingid = $moduleinfo->groupingid; } if (isset($moduleinfo->groupmembersonly)) { $cm->groupmembersonly = $moduleinfo->groupmembersonly; } $completion = new completion_info($course); if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) { // Update completion settings. $cm->completion = $moduleinfo->completion; $cm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber; $cm->completionview = $moduleinfo->completionview; $cm->completionexpected = $moduleinfo->completionexpected; } if (!empty($CFG->enableavailability)) { $cm->availablefrom = $moduleinfo->availablefrom; $cm->availableuntil = $moduleinfo->availableuntil; $cm->showavailability = $moduleinfo->showavailability; condition_info::update_cm_from_form($cm, $moduleinfo, true); } if (isset($moduleinfo->showdescription)) { $cm->showdescription = $moduleinfo->showdescription; } else { $cm->showdescription = 0; } $DB->update_record('course_modules', $cm); $modcontext = context_module::instance($moduleinfo->coursemodule); // Update embedded links and save files. if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) { $moduleinfo->intro = file_save_draft_area_files($moduleinfo->introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $moduleinfo->introeditor['text']); $moduleinfo->introformat = $moduleinfo->introeditor['format']; unset($moduleinfo->introeditor); } $updateinstancefunction = $moduleinfo->modulename . "_update_instance"; if (!$updateinstancefunction($moduleinfo, $mform)) { print_error('cannotupdatemod', '', course_get_url($course, $cw->section), $moduleinfo->modulename); } // Make sure visibility is set correctly (in particular in calendar). if (has_capability('moodle/course:activityvisibility', $modcontext)) { set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible); } if (isset($moduleinfo->cmidnumber)) { // Label. // Set cm idnumber - uniqueness is already verified by form validation. set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber); } // Now that module is fully updated, also update completion data if required. // (this will wipe all user completion data and recalculate it) if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) { $completion->reset_all_state($cm); } // Trigger event based on the action we did. $event = \core\event\course_module_updated::create(array('courseid' => $course->id, 'context' => $modcontext, 'objectid' => $moduleinfo->coursemodule, 'other' => array('modulename' => $moduleinfo->modulename, 'name' => $moduleinfo->name, 'instanceid' => $moduleinfo->instance))); $event->trigger(); add_to_log($course->id, $moduleinfo->modulename, "update", "view.php?id={$moduleinfo->coursemodule}", "{$moduleinfo->instance}", $moduleinfo->coursemodule); $moduleinfo = edit_module_post_actions($moduleinfo, $course); return array($cm, $moduleinfo); }
/** * Add course module. * * The function does not check user capabilities. * The function creates course module, module instance, add the module to the correct section. * It also trigger common action that need to be done after adding/updating a module. * * @param object $moduleinfo the moudle data * @param object $course the course of the module * @param object $mform this is required by an existing hack to deal with files during MODULENAME_add_instance() * @return object the updated module info */ function local_ltiprovider_add_moduleinfo($moduleinfo, $course, $mform = null) { global $DB, $CFG; $moduleinfo->course = $course->id; $moduleinfo = local_ltiprovider_set_moduleinfo_defaults($moduleinfo); if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) { $moduleinfo->groupmode = 0; // Do not set groupmode. } if (!course_allowed_module($course, $moduleinfo->modulename)) { print_error('moduledisable', '', '', $moduleinfo->modulename); } // First add course_module record because we need the context. $newcm = new stdClass(); $newcm->course = $course->id; $newcm->module = $moduleinfo->module; $newcm->instance = 0; // Not known yet, will be updated later (this is similar to restore code). $newcm->visible = $moduleinfo->visible; $newcm->visibleold = $moduleinfo->visible; $newcm->groupmode = $moduleinfo->groupmode; $newcm->groupingid = $moduleinfo->groupingid; $newcm->groupmembersonly = $moduleinfo->groupmembersonly; $completion = new completion_info($course); if ($completion->is_enabled()) { $newcm->completion = $moduleinfo->completion; $newcm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber; $newcm->completionview = $moduleinfo->completionview; $newcm->completionexpected = $moduleinfo->completionexpected; } if (!empty($CFG->enableavailability)) { $newcm->availablefrom = $moduleinfo->availablefrom; $newcm->availableuntil = $moduleinfo->availableuntil; $newcm->showavailability = $moduleinfo->showavailability; } if (isset($moduleinfo->showdescription)) { $newcm->showdescription = $moduleinfo->showdescription; } else { $newcm->showdescription = 0; } if (!($moduleinfo->coursemodule = add_course_module($newcm))) { print_error('cannotaddcoursemodule'); } if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) { $introeditor = $moduleinfo->introeditor; unset($moduleinfo->introeditor); $moduleinfo->intro = $introeditor['text']; $moduleinfo->introformat = $introeditor['format']; } $addinstancefunction = $moduleinfo->modulename . "_add_instance"; $returnfromfunc = $addinstancefunction($moduleinfo, $mform); if (!$returnfromfunc or !is_number($returnfromfunc)) { // Undo everything we can. $modcontext = context_module::instance($moduleinfo->coursemodule); delete_context(CONTEXT_MODULE, $moduleinfo->coursemodule); $DB->delete_records('course_modules', array('id' => $moduleinfo->coursemodule)); if (!is_number($returnfromfunc)) { print_error('invalidfunction', '', course_get_url($course, $cw->section)); } else { print_error('cannotaddnewmodule', '', course_get_url($course, $cw->section), $moduleinfo->modulename); } } $moduleinfo->instance = $returnfromfunc; $DB->set_field('course_modules', 'instance', $returnfromfunc, array('id' => $moduleinfo->coursemodule)); // Update embedded links and save files. $modcontext = context_module::instance($moduleinfo->coursemodule); if (!empty($introeditor)) { $moduleinfo->intro = file_save_draft_area_files($introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $introeditor['text']); $DB->set_field($moduleinfo->modulename, 'intro', $moduleinfo->intro, array('id' => $moduleinfo->instance)); } // Course_modules and course_sections each contain a reference to each other. // So we have to update one of them twice. $sectionid = course_add_cm_to_section($course, $moduleinfo->coursemodule, $moduleinfo->section); // Make sure visibility is set correctly (in particular in calendar). // Note: allow them to set it even without moodle/course:activityvisibility. set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible); if (isset($moduleinfo->cmidnumber)) { // Label. // Set cm idnumber - uniqueness is already verified by form validation. set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber); } // Set up conditions. if ($CFG->enableavailability) { condition_info::update_cm_from_form((object) array('id' => $moduleinfo->coursemodule), $moduleinfo, false); } $eventname = 'mod_created'; add_to_log($course->id, "course", "add mod", "../mod/{$moduleinfo->modulename}/view.php?id={$moduleinfo->coursemodule}", "{$moduleinfo->modulename} {$moduleinfo->instance}"); add_to_log($course->id, $moduleinfo->modulename, "add", "view.php?id={$moduleinfo->coursemodule}", "{$moduleinfo->instance}", $moduleinfo->coursemodule); $moduleinfo = local_ltiprovider_edit_module_post_actions($moduleinfo, $course, 'mod_created'); return $moduleinfo; }
function RWSAUQuiz() { global $CFG; global $DB; global $RWSLB; global $RWSUID; RWSCMAuth(); RWSCRAuth(); RWSCMUSvc(); RWSCMMaint(); $r_pm = RWSGSOpt("quizid", PARAM_ALPHANUM); if ($r_pm === false || strlen($r_pm) == 0) { RWSSErr("2067"); } $r_qzmi = intval($r_pm); $r_cmod = RWSCMUQuiz($r_qzmi); $r_sfl = RWSGSOpt("sfile", RWSPRF); if ($r_sfl === false) { $r_sn = RWSGSOpt("sname", PARAM_FILE); $r_sd = RWSGSOpt("sdata", PARAM_NOTAGS); $r_ecd = true; } else { $r_sn = $r_sfl->filename; $r_sd = $r_sfl->filedata; $r_ecd = false; } $r_imp = false; if ($r_sd !== false && strlen($r_sd) > 0) { if ($r_sn === false || strlen($r_sn) == 0) { RWSSErr("2075"); } $r_sn = clean_filename($r_sn); $r_imp = true; } $r_cid = $r_cmod->course; $r_crs = RWSCMUCourse($r_cid, true); $r_mr = $DB->get_record("modules", array("id" => $r_cmod->module)); if ($r_mr === false) { RWSSErr("2043"); } $r_qiz = $DB->get_record($r_mr->name, array("id" => $r_cmod->instance)); if ($r_qiz === false) { RWSSErr("2044"); } $r_ren = false; $r_pm = RWSGSOpt("rename", PARAM_TEXT); if ($r_pm !== false && strlen($r_pm) > 0) { $r_ren = trim(clean_text(strip_tags($r_pm, "<lang><span>"))); $r_qiz->name = $r_ren; } if ($r_ren === false) { if ($r_sd === false || strlen($r_sd) == 0) { RWSSErr("2080"); } } $r_sec = $DB->get_record("course_sections", array("id" => $r_cmod->section)); if ($r_sec === false) { RWSSErr("2079"); } $r_qiz->coursemodule = $r_cmod->id; $r_qiz->section = $r_sec->section; $r_qiz->visible = $r_cmod->visible; $r_qiz->cmidnumber = $r_cmod->idnumber; $r_qiz->groupmode = groups_get_activity_groupmode($r_cmod); $r_qiz->groupingid = $r_cmod->groupingid; $r_qiz->groupmembersonly = $r_cmod->groupmembersonly; $r_qiz->course = $r_cid; $r_qiz->module = $r_mr->id; $r_qiz->modulename = $r_mr->name; $r_qiz->instance = $r_cmod->instance; if (respondusws_floatcompare($CFG->version, 2011120500.0, 2) >= 0) { $r_qiz->showdescription = 0; } $r_cpl = new completion_info($r_crs); if ($r_cpl->is_enabled()) { $r_qiz->completion = $r_cmod->completion; $r_qiz->completionview = $r_cmod->completionview; $r_qiz->completionexpected = $r_cmod->completionexpected; $r_qiz->completionusegrade = is_null($r_cmod->completiongradeitemnumber) ? 0 : 1; } if ($CFG->enableavailability) { $r_qiz->availablefrom = $r_cmod->availablefrom; $r_qiz->availableuntil = $r_cmod->availableuntil; if ($r_qiz->availableuntil) { $r_qiz->availableuntil = strtotime("23:59:59", $r_qiz->availableuntil); } $r_qiz->showavailability = $r_cmod->showavailability; } $r_its = grade_item::fetch_all(array('itemtype' => 'mod', 'itemmodule' => $r_qiz->modulename, 'iteminstance' => $r_qiz->instance, 'courseid' => $r_cid)); if ($r_its) { foreach ($r_its as $r_it) { if (!empty($r_it->outcomeid)) { $r_qiz->{'outcome_' . $r_it->outcomeid} = 1; } } $r_gc = false; foreach ($r_its as $r_it) { if ($r_gc === false) { $r_gc = $r_it->categoryid; continue; } if ($r_gc != $r_it->categoryid) { $r_gc = false; break; } } if ($r_gc !== false) { $r_qiz->gradecat = $r_gc; } } if ($r_imp) { RWSIQSet($r_qiz, $r_sn, $r_sd, $r_ecd); } $DB->update_record("course_modules", $r_qiz); if (is_null($r_qiz->quizpassword) && !is_null($r_qiz->password)) { $r_qiz->quizpassword = $r_qiz->password; } $r_res = quiz_update_instance($r_qiz); if (!$r_res || is_string($r_res)) { RWSSErr("2081"); } RWSSLBSet($r_qiz); set_coursemodule_visible($r_qzmi, $r_qiz->visible); if (isset($r_qiz->cmidnumber)) { set_coursemodule_idnumber($r_qzmi, $r_qiz->cmidnumber); } RWSUQGrades($r_qiz); if ($r_cpl->is_enabled() && !empty($r_qiz->completionunlocked)) { $r_cpl->reset_all_state($r_qiz); } if (respondusws_floatcompare($CFG->version, 2014051200, 2) >= 0) { $r_qiz->modname = $r_qiz->modulename; $r_qiz->id = $r_qiz->coursemodule; \core\event\course_module_updated::create_from_cm($r_qiz)->trigger(); } else { $r_evt = new stdClass(); $r_evt->modulename = $r_qiz->modulename; $r_evt->name = $r_qiz->name; $r_evt->cmid = $r_qiz->coursemodule; $r_evt->courseid = $r_qiz->course; $r_evt->userid = $RWSUID; events_trigger("mod_updated", $r_evt); } rebuild_course_cache($r_cid); grade_regrade_final_grades($r_cid); if ($RWSLB->mex || $RWSLB->bex) { if ($RWSLB->mok) { if ($RWSLB->perr) { RWSSWarn("3003"); } } else { if ($RWSLB->bok) { if ($RWSLB->perr) { RWSSWarn("3003"); } } else { RWSSWarn("3001"); } } } else { RWSSWarn("3000"); } RWSSStat("1004"); }
/** * Test get_calendar_events */ public function test_get_calendar_events() { global $DB, $USER; $this->resetAfterTest(true); $this->setAdminUser(); // Create a few stuff to test with. $user = $this->getDataGenerator()->create_user(); $course = $this->getDataGenerator()->create_course(); $record = new stdClass(); $record->courseid = $course->id; $group = $this->getDataGenerator()->create_group($record); $beforecount = $DB->count_records('event'); // Let's create a few events. $siteevent = $this->create_calendar_event('site', $USER->id, 'site'); // This event will have description with an inline fake image. $draftidfile = file_get_unused_draft_itemid(); $usercontext = context_course::instance($course->id); $filerecord = array('contextid' => $usercontext->id, 'component' => 'user', 'filearea' => 'draft', 'itemid' => $draftidfile, 'filepath' => '/', 'filename' => 'fakeimage.png'); $fs = get_file_storage(); $fs->create_file_from_string($filerecord, 'img contents'); $record = new stdClass(); $record->courseid = $course->id; $record->description = array('format' => FORMAT_HTML, 'text' => 'Text with img <img src="@@PLUGINFILE@@/fakeimage.png">', 'itemid' => $draftidfile); $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record); $userevent = $this->create_calendar_event('user', $USER->id); $record = new stdClass(); $record->courseid = $course->id; $record->groupid = $group->id; $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record); $paramevents = array('eventids' => array($siteevent->id), 'courseids' => array($course->id), 'groupids' => array($group->id)); $options = array('siteevents' => true, 'userevents' => true); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); // Check to see if we got all events. $this->assertEquals(5, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + 7 * WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(5, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); // Expect the same URL in the description of two different events (because they are repeated). $coursecontext = context_course::instance($course->id); $expectedurl = "webservice/pluginfile.php/{$coursecontext->id}/calendar/event_description/{$courseevent->id}/fakeimage.png"; $withdescription = 0; foreach ($events['events'] as $event) { if (!empty($event['description'])) { $withdescription++; $this->assertContains($expectedurl, $event['description']); } } $this->assertEquals(2, $withdescription); // Let's play around with caps. $this->setUser($user); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(2, count($events['events'])); // site, user. $this->assertEquals(2, count($events['warnings'])); // course, group. $role = $DB->get_record('role', array('shortname' => 'student')); $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(4, count($events['events'])); // site, user, both course events. $this->assertEquals(1, count($events['warnings'])); // group. $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(3, count($events['events'])); // site, user, one course event. $this->assertEquals(1, count($events['warnings'])); // group. groups_add_member($group, $user); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('courseids' => array($course->id), 'groupids' => array($group->id)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('groupids' => array($group->id, 23)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(3, count($events['events'])); // site, user, group. $this->assertEquals(1, count($events['warnings'])); $paramevents = array('courseids' => array(23)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(2, count($events['events'])); // site, user. $this->assertEquals(1, count($events['warnings'])); $paramevents = array(); $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(0, count($events['events'])); // nothing returned. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('eventids' => array($siteevent->id, $groupevent->id)); $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(2, count($events['events'])); // site, group. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('eventids' => array($siteevent->id)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(1, count($events['events'])); // site. $this->assertEquals(0, count($events['warnings'])); // Try getting a course event by its id. $paramevents = array('eventids' => array($courseevent->id)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(1, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); // Now, create an activity event. $this->setAdminUser(); $nexttime = time() + DAYSECS; $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime)); $this->setUser($user); $paramevents = array('courseids' => array($course->id)); $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertCount(5, $events['events']); // Hide the assignment. set_coursemodule_visible($assign->cmid, 0); // Empty all the caches that may be affected by this change. accesslib_clear_all_caches_for_unit_testing(); course_modinfo::clear_instance_cache(); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); // Expect one less. $this->assertCount(4, $events['events']); }
/** * Tests grade_report_user::inject_rowspans() * * inject_rowspans() returns the count of the number of elements, sets maxdepth on the * report object and sets the rowspan property on any element that has children. */ public function test_inject_rowspans() { global $CFG, $USER, $DB; parent::setUp(); $this->resetAfterTest(true); $CFG->enableavailability = 1; $CFG->enablecompletion = 1; // Create a course. $course = $this->getDataGenerator()->create_course(); $coursecategory = grade_category::fetch_course_category($course->id); $coursecontext = context_course::instance($course->id); // Create and enrol test users. $student = $this->getDataGenerator()->create_user(array('username' => 'Student Sam')); $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); $this->getDataGenerator()->enrol_user($student->id, $course->id, $role->id); $teacher = $this->getDataGenerator()->create_user(array('username' => 'Teacher T')); $role = $DB->get_record('role', array('shortname' => 'editingteacher'), '*', MUST_EXIST); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $role->id); // An array so we can test with both users in a loop. $users = array($student, $teacher); // Make the student the current user. $this->setUser($student); // Test an empty course. $report = $this->create_report($course, $student, $coursecontext); // a lead column that spans all children + course grade item = 2 $this->assertEquals(2, $report->inject_rowspans($report->gtree->top_element)); $this->assertEquals(2, $report->gtree->top_element['rowspan']); $this->assertEquals(2, $report->maxdepth); // Only elements with children should have rowspan set. if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) { $this->fail('Elements without children should not have rowspan set'); } // Add 2 activities. $data1 = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id)); $forum1 = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id)); $forum1cm = get_coursemodule_from_id('forum', $forum1->cmid); // Switch the stdClass instance for a grade item instance so grade_item::set_parent() is available. $forum1 = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum1->id, 'courseid' => $course->id)); $report = $this->create_report($course, $student, $coursecontext); // Lead column + course + (2 x activity) = 4 $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element)); $this->assertEquals(4, $report->gtree->top_element['rowspan']); // Lead column + 1 level (course + 2 activities) = 2 $this->assertEquals(2, $report->maxdepth); // Only elements with children should have rowspan set. if (array_key_exists('rowspan', $report->gtree->top_element['children'][1])) { $this->fail('Elements without children should not have rowspan set'); } // Hide the forum activity. set_coursemodule_visible($forum1cm->id, 0); foreach ($users as $user) { $this->setUser($user); $message = 'Testing with ' . $user->username; accesslib_clear_all_caches_for_unit_testing(); $report = $this->create_report($course, $user, $coursecontext); // Lead column + course + (2 x activity) = 4 (element count isn't affected by hiding) $this->assertEquals(4, $report->inject_rowspans($report->gtree->top_element), $message); $this->assertEquals(4, $report->gtree->top_element['rowspan'], $message); // Lead column -> 1 level containing the course + 2 activities = 2 $this->assertEquals(2, $report->maxdepth, $message); } // Unhide the forum activity. set_coursemodule_visible($forum1cm->id, 1); // Create a category and put the forum in it. $params = new stdClass(); $params->courseid = $course->id; $params->fullname = 'unittestcategory'; $params->parent = $coursecategory->id; $gradecategory = new grade_category($params, false); $gradecategory->insert(); $forum1->set_parent($gradecategory->id); $report = $this->create_report($course, $student, $coursecontext); // Lead column + course + (category + category grade item) + (2 x activity) = 6 $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element)); $this->assertEquals(6, $report->gtree->top_element['rowspan']); // Lead column -> the category -> the forum activity = 3 $this->assertEquals(3, $report->maxdepth); // Check rowspan on the category. The category itself + category grade item + forum = 3 $this->assertEquals(3, $report->gtree->top_element['children'][4]['rowspan']); // check the forum doesn't have rowspan set if (array_key_exists('rowspan', $report->gtree->top_element['children'][4]['children'][3])) { $this->fail('The forum has no children so should not have rowspan set'); } // Conditional activity tests. $DB->insert_record('course_modules_availability', (object) array('coursemoduleid' => $forum1cm->id, 'gradeitemid' => 37, 'grademin' => 5.5)); $cm = (object) array('id' => $forum1cm->id); $test = new condition_info($cm, CONDITION_MISSING_EVERYTHING); $fullcm = $test->get_full_course_module(); foreach ($users as $user) { $this->setUser($user); $message = 'Testing with ' . $user->username; accesslib_clear_all_caches_for_unit_testing(); $report = $this->create_report($course, $user, $coursecontext); // Lead column + course + (category + category grade item) + (2 x activity) = 6 $this->assertEquals(6, $report->inject_rowspans($report->gtree->top_element), $message); $this->assertEquals(6, $report->gtree->top_element['rowspan'], $message); // Lead column -> the category -> the forum activity = 3 $this->assertEquals(3, $report->maxdepth, $message); } }
/** * Tests searching across a whole course in cases of grouped and non-grouped * forums and users. */ public function test_coursewide_search() { global $DB, $CFG; require_once $CFG->dirroot . '/course/lib.php'; $this->check_skip(); $this->resetAfterTest(); // Create a couple of courses for testing. $generator = $this->getDataGenerator(); $course1 = $generator->create_course(); $course2 = $generator->create_course(); // Create some groups in course 1. $group1 = $generator->create_group(array('courseid' => $course1->id)); $group2 = $generator->create_group(array('courseid' => $course1->id)); // Create two forums in course 1 and one in course 2. $forum1n = $generator->create_module('forumng', array('course' => $course1->id)); $forum1g = $generator->create_module('forumng', array('course' => $course1->id, 'groupmode' => SEPARATEGROUPS)); $forum2 = $generator->create_module('forumng', array('course' => $course2->id)); // Create two students on the course. One belongs to groups, the other doesn't. $student1 = $generator->create_user(); $student2 = $generator->create_user(); $studentroleid = $DB->get_field('role', 'id', array('shortname' => 'student')); $generator->enrol_user($student1->id, $course1->id, $studentroleid); $generator->enrol_user($student2->id, $course1->id, $studentroleid); $generator->enrol_user($student1->id, $course2->id, $studentroleid); groups_add_member($group1, $student1); // Add two discussions in forum 1N. $forumgen = $generator->get_plugin_generator('mod_forumng'); $params = array('course' => $course1->id, 'forum' => $forum1n->id, 'userid' => $student1->id); $params['subject'] = 'D1 Apples'; $forumgen->create_discussion($params); $params['subject'] = 'D2 Oranges'; $forumgen->create_discussion($params); // Add a discussion to each group in forum 1G. $params['forum'] = $forum1g->id; $params['groupid'] = $group1->id; $params['subject'] = 'D3 Apples'; $forumgen->create_discussion($params); $params['groupid'] = $group2->id; $params['subject'] = 'D4 Oranges'; $forumgen->create_discussion($params); // Add two discussions in forum 2. $params = array('course' => $course2->id, 'forum' => $forum2->id, 'userid' => $student1->id); $params['subject'] = 'D5 Apples'; $forumgen->create_discussion($params); $params['subject'] = 'D6 Oranges'; $forumgen->create_discussion($params); // Do a coursewide search for 'apples' on course 1 as student 1. $this->setUser($student1); $this->assertEquals(array('D1 Apples', 'D3 Apples'), $this->coursewide_search($course1, 'apples')); // Coursewide search for 'oranges' (doesn't have the group result. $this->assertEquals(array('D2 Oranges'), $this->coursewide_search($course1, 'oranges')); // Coursewide search for 'apples' on course 2. $this->assertEquals(array('D5 Apples'), $this->coursewide_search($course2, 'apples')); // Try as student2 (not in group). $this->setUser($student2); $this->assertEquals(array('D1 Apples'), $this->coursewide_search($course1, 'apples')); // Check it works if we hide one of the forums. set_coursemodule_visible($forum1n->cmid, false); $this->assertEquals(array(), $this->coursewide_search($course1, 'apples')); // Try as admin user (also not in group). $this->setAdminUser(); $this->assertEquals(array('D2 Oranges', 'D4 Oranges'), $this->coursewide_search($course1, 'oranges')); }
/** * Purpose: add a Moodle page resource to a course * * @author Andrew Zoltay * date 2011-04-27 * @global $CFG - configuration settings for CACE * @global object $DB Moodle database object * @global $CACE_CFG - configuration settings for CACE * @param int $courseid * @param object $pagedata */ function cace_add_page_resource($course, $pagedata) { global $CFG, $DB, $CACE_CFG, $USER; require_once "{$CFG->dirroot}/mod/page/lib.php"; try { // Create a new course module for the page. $newcm = new stdClass(); $newcm->course = $course->id; $newcm->module = $pagedata->module; $newcm->instance = 0; // Don't have this value yet, but will update later. $newcm->visible = $pagedata->visible; $newcm->groupmode = $pagedata->groupmode; $newcm->groupingid = $pagedata->groupingid; $newcm->groupmembersonly = $pagedata->groupmembersonly; $pagedata->coursemodule = add_course_module($newcm); // This is lame, but need to create a dummy object for page_add_instance() // useless $mform parameter that isn't used in the function. $dummyform = new stdClass(); // Create the page instance. $pageid = page_add_instance($pagedata, $dummyform); $pagedata->instance = $pageid; // Update course_modules table with new instance. $DB->set_field('course_modules', 'instance', $pageid, array('id' => $pagedata->coursemodule)); // Add the module to the correct section of the course // 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($pagedata->course, $pagedata->coursemodule, $pagedata->section); $DB->set_field('course_modules', 'section', $sectionid, array('id' => $pagedata->coursemodule)); set_coursemodule_visible($pagedata->coursemodule, $pagedata->visible); // Trigger mod_created event with information about the new module. // Use the new events system to log the creation of a resource. $eventdata = clone $pagedata; $eventdata->modname = $pagedata->modulename; $eventdata->name = $pagedata->name; $eventdata->id = $pagedata->coursemodule; $eventdata->courseid = $course->id; $eventdata->userid = $CACE_CFG->admin_user; // Use Admin account for event data. $event = \core\event\course_module_created::create_from_cm($eventdata); $event->trigger(); return true; } catch (Exception $e) { return false; } }
/** * Run periodically to check for vpl visibility update * * @uses $CFG * @return boolean **/ function vpl_cron() { global $DB; $rebuilds = array(); $now = time(); $sql = 'SELECT id, startdate, duedate, course, name FROM {vpl} WHERE startdate > ? and startdate <= ? and (duedate > ? or duedate = 0)'; $parms = array($now - 2 * 3600, $now, $now); $vpls = $DB->get_records_sql($sql, $parms); foreach ($vpls as $instance) { if (!instance_is_visible(VPL, $instance)) { $vpl = new mod_vpl(null, $instance->id); echo 'Setting visible "' . s($vpl->get_printable_name()) . '"'; $cm = $vpl->get_course_module(); $rebuilds[$cm->id] = $cm; } } foreach ($rebuilds as $cmid => $cm) { set_coursemodule_visible($cm->id, true); rebuild_course_cache($cm->course); } return true; }
/** * Test to confirm that subscriptions for enrolled users who don't have CM access, are deactivated. */ public function test_cm_access() { // Enrol the user as a student but grant to ability to subscribe. Students cannot view hidden activities. $context = \context_course::instance($this->course->id); assign_capability('tool/monitor:subscribe', CAP_ALLOW, $this->studentrole->id, $context); $this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->studentrole->id); // Generate a course module. $book = $this->getDataGenerator()->create_module('book', array('course' => $this->course->id)); // And add a subscription to it. $sub = new stdClass(); $sub->courseid = $this->course->id; $sub->userid = $this->user->id; $sub->ruleid = $this->rule->id; $sub->cmid = $book->cmid; $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor'); $this->subscription = $monitorgenerator->create_subscription($sub); // The subscription should be active to start with. Pass in the id only to refetch the data. $this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription)); // Run the task. $task = new \tool_monitor\task\check_subscriptions(); $task->execute(); // The subscription should still be active. Pass in the id only to refetch the data. $this->reload_subscription(); $this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription)); // Make the course module invisible, which should in turn make the subscription inactive. set_coursemodule_visible($book->cmid, false); // Run the task. $task = new \tool_monitor\task\check_subscriptions(); $task->execute(); // The subscription should NOT be active. Pass in the id only to refetch the data. $this->reload_subscription(); $this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription)); // Make the course module visible again. set_coursemodule_visible($book->cmid, true); // Run the task. $task = new \tool_monitor\task\check_subscriptions(); $task->execute(); // The subscription should be active. Pass in the id only to refetch the data. $this->reload_subscription(); $this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription)); }
/** * Move the module object $mod to the specified $section * If $beforemod exists then that is the module * before which $modid should be inserted * All parameters are objects */ function moveto_module($mod, $section, $beforemod = NULL) { global $OUTPUT, $DB; /// Remove original module from original section if (!delete_mod_from_section($mod->id, $mod->section)) { echo $OUTPUT->notification("Could not delete module from existing section"); } // if moving to a hidden section then hide module if ($mod->section != $section->id) { if (!$section->visible && $mod->visible) { // Set this in the object because it is sent as a response to ajax calls. $mod->visible = 0; set_coursemodule_visible($mod->id, 0); // Set visibleold to 1 so module will be visible when section is made visible. $DB->set_field('course_modules', 'visibleold', 1, array('id' => $mod->id)); } if ($section->visible && !$mod->visible) { set_coursemodule_visible($mod->id, $mod->visibleold); // Set this in the object because it is sent as a response to ajax calls. $mod->visible = $mod->visibleold; } } /// Add the module into the new section course_add_cm_to_section($section->course, $mod->id, $section->section, $beforemod); return true; }
/** * Tests moving a module between hidden/visible sections and * verifies that the course/module visiblity seettings are * retained. */ public function test_moveto_module_between_hidden_sections() { global $DB; $this->resetAfterTest(true); $course = $this->getDataGenerator()->create_course(array('numsections' => 4), array('createsections' => true)); $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id)); $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); // Set the page as hidden set_coursemodule_visible($page->cmid, 0); // Set sections 3 as hidden. set_section_visible($course->id, 3, 0); $modinfo = get_fast_modinfo($course); $hiddensection = $modinfo->get_section_info(3); // New section is definitely not visible: $this->assertEquals($hiddensection->visible, 0); $forumcm = $modinfo->cms[$forum->cmid]; $pagecm = $modinfo->cms[$page->cmid]; // Move the forum and the page to a hidden section, make sure moveto_module returns 0 as new visibility state. $this->assertEquals(0, moveto_module($forumcm, $hiddensection)); $this->assertEquals(0, moveto_module($pagecm, $hiddensection)); $modinfo = get_fast_modinfo($course); // Verify that forum and page have been moved to the hidden section and quiz has not. $this->assertContains($forum->cmid, $modinfo->sections[3]); $this->assertContains($page->cmid, $modinfo->sections[3]); $this->assertNotContains($quiz->cmid, $modinfo->sections[3]); // Verify that forum has been made invisible. $forumcm = $modinfo->cms[$forum->cmid]; $this->assertEquals($forumcm->visible, 0); // Verify that old state has been retained. $this->assertEquals($forumcm->visibleold, 1); // Verify that page has stayed invisible. $pagecm = $modinfo->cms[$page->cmid]; $this->assertEquals($pagecm->visible, 0); // Verify that old state has been retained. $this->assertEquals($pagecm->visibleold, 0); // Verify that quiz has been unaffected. $quizcm = $modinfo->cms[$quiz->cmid]; $this->assertEquals($quizcm->visible, 1); // Move forum and page back to visible section. // Make sure the visibility is restored to the original value (visible for forum and hidden for page). $visiblesection = $modinfo->get_section_info(2); $this->assertEquals(1, moveto_module($forumcm, $visiblesection)); $this->assertEquals(0, moveto_module($pagecm, $visiblesection)); $modinfo = get_fast_modinfo($course); // Double check that forum has been made visible. $forumcm = $modinfo->cms[$forum->cmid]; $this->assertEquals($forumcm->visible, 1); // Double check that page has stayed invisible. $pagecm = $modinfo->cms[$page->cmid]; $this->assertEquals($pagecm->visible, 0); // Move the page in the same section (this is what mod duplicate does). // Visibility of page remains 0. $this->assertEquals(0, moveto_module($pagecm, $visiblesection, $forumcm)); // Double check that the the page is still hidden. $modinfo = get_fast_modinfo($course); $pagecm = $modinfo->cms[$page->cmid]; $this->assertEquals($pagecm->visible, 0); }
$quizdata->id = $DB->insert_record("quiz", $quizdata); $quizdata->instance = $quizdata->id; if (!($quizdata->coursemodule = add_course_module($quizdata))) { error("Could not add a new course module"); } if (!($sectionid = add_mod_to_section($quizdata))) { error("Could not add the new course module to that section"); } if (!$DB->set_field("course_modules", "section", $sectionid, array("id" => $quizdata->coursemodule))) { error("Could not update the course module with the correct section"); } if (!isset($quizdata->visible)) { // We get the section's visible field status $quizdata->visible = $DB->get_field("course_sections", "visible", "id", $sectionid); } set_coursemodule_visible($quizdata->coursemodule, $quizdata->visible); // Trigger mod_updated event with information about this module. $eventdata = new stdClass(); $eventdata->modulename = $quizdata->modulename; $eventdata->name = $quizdata->name; $eventdata->cmid = $quizdata->coursemodule; $eventdata->courseid = $courseid; $eventdata->userid = $USER->id; events_trigger('mod_updated', $eventdata); rebuild_course_cache($courseid); $quizbook[$quizzestoadd_['id']] = $quizdata->instance; //Set section name if ($sectionchoosing == 1) { $DB->set_field("course_sections", "summary", $currentsection, array("course" => $courseid, "section" => $sectionnum)); } if ($needtoaddsection) {
/** * 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. delete_course_module($this->cm->id); throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name); } $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); $this->course->modinfo = null; // Otherwise we will just get the old version back again. $sectionid = course_add_cm_to_section($this->course, $this->cm->id, $this->section); set_coursemodule_visible($this->cm->id, true); // 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. delete_course_module($this->cm->id); throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name); } $mod = $info->cms[$this->cm->id]; $mod->groupmodelink = $this->cm->groupmodelink; $mod->groupmode = $this->cm->groupmode; // Trigger mod_created event with information about this module. $eventdata = new stdClass(); $eventdata->modulename = $mod->modname; $eventdata->name = $mod->name; $eventdata->cmid = $mod->id; $eventdata->courseid = $this->course->id; $eventdata->userid = $USER->id; events_trigger('mod_created', $eventdata); add_to_log($this->course->id, "course", "add mod", "../mod/{$mod->modname}/view.php?id={$mod->id}", "{$mod->modname} {$instanceid}"); add_to_log($this->course->id, $mod->modname, "add", "view.php?id={$mod->id}", "{$instanceid}", $mod->id); $this->send_response($mod); }
/** * Update the module info. * This function doesn't check the user capabilities. It updates the course module and the module instance. * Then execute common action to create/update module process (trigger event, rebuild cache, save plagiarism settings...). * * @param object $cm course module * @param object $moduleinfo module info * @param object $course course of the module * @param object $mform - the mform is required by some specific module in the function MODULE_update_instance(). This is due to a hack in this function. * @return array list of course module and module info. */ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) { global $DB, $CFG; // Attempt to include module library before we make any changes to DB. include_modulelib($moduleinfo->modulename); $moduleinfo->course = $course->id; $moduleinfo = set_moduleinfo_defaults($moduleinfo); if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) { $moduleinfo->groupmode = $cm->groupmode; // Keep original. } // Update course module first. $cm->groupmode = $moduleinfo->groupmode; if (isset($moduleinfo->groupingid)) { $cm->groupingid = $moduleinfo->groupingid; } $completion = new completion_info($course); if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) { // Update completion settings. $cm->completion = $moduleinfo->completion; $cm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber; $cm->completionview = $moduleinfo->completionview; $cm->completionexpected = $moduleinfo->completionexpected; } if (!empty($CFG->enableavailability)) { // This code is used both when submitting the form, which uses a long // name to avoid clashes, and by unit test code which uses the real // name in the table. if (property_exists($moduleinfo, 'availabilityconditionsjson')) { if ($moduleinfo->availabilityconditionsjson !== '') { $cm->availability = $moduleinfo->availabilityconditionsjson; } else { $cm->availability = null; } } else { if (property_exists($moduleinfo, 'availability')) { $cm->availability = $moduleinfo->availability; } } } if (isset($moduleinfo->showdescription)) { $cm->showdescription = $moduleinfo->showdescription; } else { $cm->showdescription = 0; } $DB->update_record('course_modules', $cm); $modcontext = context_module::instance($moduleinfo->coursemodule); // Update embedded links and save files. if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) { $moduleinfo->intro = file_save_draft_area_files($moduleinfo->introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $moduleinfo->introeditor['text']); $moduleinfo->introformat = $moduleinfo->introeditor['format']; unset($moduleinfo->introeditor); } $updateinstancefunction = $moduleinfo->modulename . "_update_instance"; if (!$updateinstancefunction($moduleinfo, $mform)) { print_error('cannotupdatemod', '', course_get_url($course, $cw->section), $moduleinfo->modulename); } // Make sure visibility is set correctly (in particular in calendar). if (has_capability('moodle/course:activityvisibility', $modcontext)) { set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible); } if (isset($moduleinfo->cmidnumber)) { // Label. // Set cm idnumber - uniqueness is already verified by form validation. set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber); } // Now that module is fully updated, also update completion data if required. // (this will wipe all user completion data and recalculate it) if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) { $completion->reset_all_state($cm); } $cm->name = $moduleinfo->name; \core\event\course_module_updated::create_from_cm($cm, $modcontext)->trigger(); $moduleinfo = edit_module_post_actions($moduleinfo, $course); return array($cm, $moduleinfo); }
/** * Create a duplicate course module record so we can create the upgraded * setask module alongside the old setaskment module. * * @param stdClass $cm The old course module record * @param int $moduleid The id of the new setask module * @param int $newinstanceid The id of the new instance of the setask module * @return mixed stdClass|bool The new course module record or FALSE */ private function duplicate_course_module(stdClass $cm, $moduleid, $newinstanceid) { global $DB, $CFG; $newcm = new stdClass(); $newcm->course = $cm->course; $newcm->module = $moduleid; $newcm->instance = $newinstanceid; $newcm->visible = $cm->visible; $newcm->section = $cm->section; $newcm->score = $cm->score; $newcm->indent = $cm->indent; $newcm->groupmode = $cm->groupmode; $newcm->groupingid = $cm->groupingid; $newcm->completion = $cm->completion; $newcm->completiongradeitemnumber = $cm->completiongradeitemnumber; $newcm->completionview = $cm->completionview; $newcm->completionexpected = $cm->completionexpected; if (!empty($CFG->enableavailability)) { $newcm->availability = $cm->availability; } $newcm->showdescription = $cm->showdescription; $newcmid = add_course_module($newcm); $newcm = get_coursemodule_from_id('', $newcmid, $cm->course); if (!$newcm) { return false; } $section = $DB->get_record("course_sections", array("id" => $newcm->section)); if (!$section) { return false; } $newcm->section = course_add_cm_to_section($newcm->course, $newcm->id, $section->section, $cm->id); // Make sure visibility is set correctly (in particular in calendar). // Note: Allow them to set it even without moodle/course:activityvisibility. set_coursemodule_visible($newcm->id, $newcm->visible); return $newcm; }
/** * * @param unknown $user * @param unknown $courseid * @param unknown $sectionid * @param unknown $itemUuid * @param unknown $itemVersion * @param unknown $url * @param unknown $title * @param unknown $description * @param unknown $attachmentUuid * @return array */ public static function add_item_to_course($username, $courseid, $sectionnum, $itemUuid, $itemVersion, $url, $title, $description, $attachmentUuid) { global $DB, $USER; $params = self::validate_parameters(self::add_item_to_course_parameters(), array('user' => $username, 'courseid' => $courseid, 'sectionid' => $sectionnum, 'itemUuid' => $itemUuid, 'itemVersion' => $itemVersion, 'url' => $url, 'title' => $title, 'description' => $description, 'attachmentUuid' => $attachmentUuid)); self::check_modify_permissions($username, $courseid); $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); $modname = 'equella'; $module = $DB->get_record('modules', array('name' => $modname)); $eq = new stdClass(); $eq->course = $courseid; $eq->module = $module->id; $eq->name = $title; $eq->intro = $description; $eq->introformat = FORMAT_HTML; $eq->url = $url; $eq->uuid = $itemUuid; $eq->version = $itemVersion; $eq->mimetype = mimeinfo('type', $title); if (!empty($attachmentUuid)) { $eq->filename = $title; $eq->attachmentuuid = $attachmentUuid; } $eqid = equella_add_instance($eq); $cmid = null; $mod = new stdClass(); $mod->course = $courseid; $mod->module = $module->id; $mod->instance = $eqid; $mod->modulename = $modname; $mod->section = 0; if (!($cmid = add_course_module($mod))) { throw new moodle_exception('cannotaddcoursemodule'); } if (!($addedsectionid = course_add_cm_to_section($courseid, $cmid, $sectionnum))) { throw new moodle_exception('cannotaddcoursemoduletosection'); } set_coursemodule_visible($cmid, true); if (class_exists('core\\event\\course_module_created')) { $cm = get_coursemodule_from_id('equella', $cmid, 0, false, MUST_EXIST); $event = \core\event\course_module_created::create_from_cm($cm); $event->trigger(); } else { $eventdata = new stdClass(); $eventdata->modulename = $modname; $eventdata->name = $eq->name; $eventdata->cmid = $cmid; $eventdata->courseid = $eq->course; $eventdata->userid = $USER->id; events_trigger('mod_created', $eventdata); add_to_log($eq->course, "course", "add mod", "../mod/{$modname}/view.php?id={$cmid}", "{$modname} {$eqid}"); add_to_log($eq->course, $modname, "add equella resource", "view.php?id={$cmid}", "{$eqid}", $cmid); } $result = array('courseid' => $courseid, 'coursename' => $course->fullname, 'sectionid' => $params['sectionid'], 'sectionname' => get_section_name($courseid, $sectionnum)); //flog("DB queries: " . $DB->perf_get_queries()); return $result; }
if (!empty($show) and confirm_sesskey()) { if (!($cm = get_record("course_modules", "id", $show))) { error("This course module doesn't exist"); } require_login($cm->course); // needed to setup proper $COURSE $context = get_context_instance(CONTEXT_COURSE, $cm->course); require_capability('moodle/course:activityvisibility', $context); if (!($section = get_record("course_sections", "id", $cm->section))) { error("This module doesn't exist"); } if (!($module = get_record("modules", "id", $cm->module))) { error("This module doesn't exist"); } if ($module->visible and ($section->visible or SITEID == $cm->course)) { set_coursemodule_visible($cm->id, 1); rebuild_course_cache($cm->course); } if (SITEID == $cm->course) { redirect($CFG->wwwroot); } else { redirect("view.php?id={$cm->course}#section-{$sectionreturn}"); } exit; } else { if ($groupmode > -1 and confirm_sesskey()) { $id = required_param('id', PARAM_INT); if (!($cm = get_record("course_modules", "id", $id))) { error("This course module doesn't exist"); } require_login($cm->course);
/** * Test get_calendar_events */ public function test_get_calendar_events() { global $DB, $USER; $this->resetAfterTest(true); $this->setAdminUser(); // Create a few stuff to test with. $user = $this->getDataGenerator()->create_user(); $course = $this->getDataGenerator()->create_course(); $record = new stdClass(); $record->courseid = $course->id; $group = $this->getDataGenerator()->create_group($record); $beforecount = $DB->count_records('event'); // Let's create a few events. $siteevent = $this->create_calendar_event('site', $USER->id, 'site'); $record = new stdClass(); $record->courseid = $course->id; $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record); $userevent = $this->create_calendar_event('user', $USER->id); $record = new stdClass(); $record->courseid = $course->id; $record->groupid = $group->id; $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record); $paramevents = array('eventids' => array($siteevent->id), 'courseids' => array($course->id), 'groupids' => array($group->id)); $options = array('siteevents' => true, 'userevents' => true); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); // Check to see if we got all events. $this->assertEquals(5, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + 7 * WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(5, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); // Let's play around with caps. $this->setUser($user); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(2, count($events['events'])); // site, user. $this->assertEquals(2, count($events['warnings'])); // course, group. $role = $DB->get_record('role', array('shortname' => 'student')); $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(4, count($events['events'])); // site, user, both course events. $this->assertEquals(1, count($events['warnings'])); // group. $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(3, count($events['events'])); // site, user, one course event. $this->assertEquals(1, count($events['warnings'])); // group. groups_add_member($group, $user); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('courseids' => array($course->id), 'groupids' => array($group->id)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('groupids' => array($group->id, 23)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(3, count($events['events'])); // site, user, group. $this->assertEquals(1, count($events['warnings'])); $paramevents = array('courseids' => array(23)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(2, count($events['events'])); // site, user. $this->assertEquals(1, count($events['warnings'])); $paramevents = array(); $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(0, count($events['events'])); // nothing returned. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('eventids' => array($siteevent->id, $groupevent->id)); $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(2, count($events['events'])); // site, group. $this->assertEquals(0, count($events['warnings'])); $paramevents = array('eventids' => array($siteevent->id)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(1, count($events['events'])); // site. $this->assertEquals(0, count($events['warnings'])); // Try getting a course event by its id. $paramevents = array('eventids' => array($courseevent->id)); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertEquals(1, count($events['events'])); $this->assertEquals(0, count($events['warnings'])); // Now, create an activity event. $this->setAdminUser(); $nexttime = time() + DAYSECS; $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime)); $this->setUser($user); $paramevents = array('courseids' => array($course->id)); $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); $this->assertCount(5, $events['events']); // Hide the assignment. set_coursemodule_visible($assign->cmid, 0); // Empty all the caches that may be affected by this change. accesslib_clear_all_caches_for_unit_testing(); course_modinfo::clear_instance_cache(); $events = core_calendar_external::get_calendar_events($paramevents, $options); $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); // Expect one less. $this->assertCount(4, $events['events']); }
/** * Tests the get_forum_list() function. This funcion is the meat of the web service but we cannot * check it as a web service so we just call the function. */ public function test_forumlistapi() { global $DB; $this->resetAfterTest(true); // Create course. $record = new stdClass(); $record->shortname = 'testcourse'; $course = self::getDataGenerator()->create_course($record); // Create a teacher user and enrol them onto the course. $record = array(); $record['username'] = '******'; $teacher = self::getDataGenerator()->create_user($record); $roleid = $DB->get_field('role', 'id', array('shortname' => 'teacher')); self::getDataGenerator()->enrol_user($teacher->id, $course->id, $roleid); // Create a student user and enrol them onto the course. $record['username'] = '******'; $student = self::getDataGenerator()->create_user($record); $roleid = $DB->get_field('role', 'id', array('shortname' => 'student')); self::getDataGenerator()->enrol_user($student->id, $course->id, $roleid); // Create forum A. $record = new stdClass(); $record->course = $course->id; $record->name = 'Forum A'; $foruma = self::getDataGenerator()->create_module('forumng', $record); // Needed later when moving forums to specific sections. course_create_sections_if_missing($course->id, array(1)); $modinfo = get_fast_modinfo($course); $mod = $modinfo->get_cm($foruma->cmid); $sectionzero = $modinfo->get_section_info(0, MUST_EXIST); $sectionone = $modinfo->get_section_info(1, MUST_EXIST); // Create forum B. $record = new stdClass(); $record->course = $course->id; $record->name = 'Forum B'; $forumb = self::getDataGenerator()->create_module('forumng', $record); // Create forum C. $record = new stdClass(); $record->course = $course->id; $record->name = 'Forum C'; $forumc = self::getDataGenerator()->create_module('forumng', $record); // Make forum C hidden. set_coursemodule_visible($forumc->cmid, 0); $modinfo = get_fast_modinfo($course); // Move forum A to section 1. $mod = $modinfo->get_cm($foruma->cmid); moveto_module($mod, $sectionone); // Move forum B to section 0. $mod = $modinfo->get_cm($forumb->cmid); moveto_module($mod, $sectionzero); // Move forum C to section 1. $mod = $modinfo->get_cm($forumc->cmid); moveto_module($mod, $sectionone); // Student starts discussion in forum A. $record = new stdClass(); $record->course = $course->id; $record->forum = $foruma->id; $record->userid = $student->id; $this->setUser($student); $discussionid = self::getDataGenerator()->get_plugin_generator('mod_forumng')->create_discussion($record); // Teacher starts discussion in forum B. $record = new stdClass(); $record->course = $course->id; $record->forum = $forumb->id; $record->userid = $teacher->id; $this->setUser($teacher); $discussionid = self::getDataGenerator()->get_plugin_generator('mod_forumng')->create_discussion($record); // Call the web service function to get a list of forums for the teacher. $response = mod_forumng_external::get_forum_list($course->shortname, $teacher->username); // There should be 3 forums in the array. $this->assertEquals(3, count($response)); // Check each forum's data. $this->assertEquals('Forum B', $response[0]->name); $this->assertEquals('n', $response[0]->unread); $this->assertEquals('Forum A', $response[1]->name); $this->assertEquals('y', $response[1]->unread); $this->assertEquals('Forum C', $response[2]->name); $this->assertEquals('n', $response[2]->unread); // Call the web service function to get a list of forums for the student. $response = mod_forumng_external::get_forum_list($course->shortname, $student->username); // There should be 2 forums in the array. $this->assertEquals(2, count($response)); // Check each forum's data. $this->assertEquals('Forum B', $response[0]->name); $this->assertEquals('y', $response[0]->unread); $this->assertEquals('Forum A', $response[1]->name); $this->assertEquals('n', $response[1]->unread); // Call the webservice function with invalid username. $wronguser = '******'; try { // If this does not throw an exception then the test fails. $response = mod_forumng_external::get_forum_list($course->shortname, $wronguser); $this->fail(); } catch (moodle_exception $e) { $this->assertEquals(get_string('cannotfinduser', 'error', $wronguser), $e->errorcode); } // Call the webservice function with invalid course. $wrongcourse = 'doesnotexist'; try { // If this does not throw an exception then the test fails. $response = mod_forumng_external::get_forum_list($wrongcourse, $student->username); $this->fail(); } catch (Exception $e) { $this->assertEquals(get_string('cannotfindcourse', 'error'), $e->errorcode); } }
/** * Test fetching unsubscribable twfs. */ public function test_unsubscribable_twfs() { global $DB; $this->resetAfterTest(true); // Create a course, with a twf. $course = $this->getDataGenerator()->create_course(); // Create a user enrolled in the course as a student. list($user) = $this->helper_create_users($course, 1); // Must be logged in as the current user. $this->setUser($user); // Without any subscriptions, there should be nothing returned. $result = \mod_twf\subscriptions::get_unsubscribable_twfs(); $this->assertEquals(0, count($result)); // Create the twfs. $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE); $forcetwf = $this->getDataGenerator()->create_module('twf', $options); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE); $disallowtwf = $this->getDataGenerator()->create_module('twf', $options); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE); $choosetwf = $this->getDataGenerator()->create_module('twf', $options); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE); $initialtwf = $this->getDataGenerator()->create_module('twf', $options); // At present the user is only subscribed to the initial twf. $result = \mod_twf\subscriptions::get_unsubscribable_twfs(); $this->assertEquals(1, count($result)); // Ensure that the user is enrolled in all of the twfs except force subscribed. \mod_twf\subscriptions::subscribe_user($user->id, $disallowtwf); \mod_twf\subscriptions::subscribe_user($user->id, $choosetwf); $result = \mod_twf\subscriptions::get_unsubscribable_twfs(); $this->assertEquals(3, count($result)); // Hide the twfs. set_coursemodule_visible($forcetwf->cmid, 0); set_coursemodule_visible($disallowtwf->cmid, 0); set_coursemodule_visible($choosetwf->cmid, 0); set_coursemodule_visible($initialtwf->cmid, 0); $result = \mod_twf\subscriptions::get_unsubscribable_twfs(); $this->assertEquals(0, count($result)); // Add the moodle/course:viewhiddenactivities capability to the student user. $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); $context = \context_course::instance($course->id); assign_capability('moodle/course:viewhiddenactivities', CAP_ALLOW, $roleids['student'], $context); $context->mark_dirty(); // All of the unsubscribable twfs should now be listed. $result = \mod_twf\subscriptions::get_unsubscribable_twfs(); $this->assertEquals(3, count($result)); }