/** * Test duplicate_course */ public function test_duplicate_course() { $this->resetAfterTest(true); // Create one course with three modules. $course = self::getDataGenerator()->create_course(); $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); $forumcm = get_coursemodule_from_id('forum', $forum->cmid); $forumcontext = context_module::instance($forum->cmid); $data = $this->getDataGenerator()->create_module('data', array('assessed'=>1, 'scale'=>100, 'course'=>$course->id)); $datacontext = context_module::instance($data->cmid); $datacm = get_coursemodule_from_instance('page', $data->id); $page = $this->getDataGenerator()->create_module('page', array('course'=>$course->id)); $pagecontext = context_module::instance($page->cmid); $pagecm = get_coursemodule_from_instance('page', $page->id); // Set the required capabilities by the external function. $coursecontext = context_course::instance($course->id); $categorycontext = context_coursecat::instance($course->category); $roleid = $this->assignUserCapability('moodle/course:create', $categorycontext->id); $this->assignUserCapability('moodle/course:view', $categorycontext->id, $roleid); $this->assignUserCapability('moodle/restore:restorecourse', $categorycontext->id, $roleid); $this->assignUserCapability('moodle/backup:backupcourse', $coursecontext->id, $roleid); $this->assignUserCapability('moodle/backup:configure', $coursecontext->id, $roleid); // Optional capabilities to copy user data. $this->assignUserCapability('moodle/backup:userinfo', $coursecontext->id, $roleid); $this->assignUserCapability('moodle/restore:userinfo', $categorycontext->id, $roleid); $newcourse['fullname'] = 'Course duplicate'; $newcourse['shortname'] = 'courseduplicate'; $newcourse['categoryid'] = $course->category; $newcourse['visible'] = true; $newcourse['options'][] = array('name' => 'users', 'value' => true); $duplicate = core_course_external::duplicate_course($course->id, $newcourse['fullname'], $newcourse['shortname'], $newcourse['categoryid'], $newcourse['visible'], $newcourse['options']); // We need to execute the return values cleaning process to simulate the web service server. $duplicate = external_api::clean_returnvalue(core_course_external::duplicate_course_returns(), $duplicate); // Check that the course has been duplicated. $this->assertEquals($newcourse['shortname'], $duplicate['shortname']); }
/** * Returns description of method result value * * @return external_description * @since Moodle 2.0 * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more. * @see core_course_external::create_courses_returns() */ public static function create_courses_returns() { return core_course_external::create_courses_returns(); }
/** * Ensure import_course handles incorrect deletecontent option correctly. */ public function test_import_course_invalid_deletecontent_option() { $this->resetAfterTest(true); $course1 = self::getDataGenerator()->create_course(); $course2 = self::getDataGenerator()->create_course(); $this->setExpectedException('moodle_exception', get_string('invalidextparam', 'webservice', -1)); // Import from course1 to course2, with invalid option core_course_external::import_course($course1->id, $course2->id, -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); } }
public function test_get_courses_by_field_invalid_courses() { $result = core_course_external::get_courses_by_field('id', '-1'); $result = external_api::clean_returnvalue(core_course_external::get_courses_by_field_returns(), $result); $this->assertCount(0, $result['courses']); }
/** * Test view_course function */ public function test_view_course() { $this->resetAfterTest(); // Course without sections. $course = $this->getDataGenerator()->create_course(array('numsections' => 5), array('createsections' => true)); $this->setAdminUser(); // Redirect events to the sink, so we can recover them later. $sink = $this->redirectEvents(); $result = core_course_external::view_course($course->id, 1); $result = external_api::clean_returnvalue(core_course_external::view_course_returns(), $result); $events = $sink->get_events(); $event = reset($events); // Check the event details are correct. $this->assertInstanceOf('\\core\\event\\course_viewed', $event); $this->assertEquals(context_course::instance($course->id), $event->get_context()); $this->assertEquals(1, $event->other['coursesectionnumber']); $result = core_course_external::view_course($course->id); $result = external_api::clean_returnvalue(core_course_external::view_course_returns(), $result); $events = $sink->get_events(); $event = array_pop($events); $sink->close(); // Check the event details are correct. $this->assertInstanceOf('\\core\\event\\course_viewed', $event); $this->assertEquals(context_course::instance($course->id), $event->get_context()); $this->assertEmpty($event->other); }
public function test_check_updates() { global $DB; $this->resetAfterTest(true); $this->setAdminUser(); // Create different types of activities. $course = self::getDataGenerator()->create_course(); $tocreate = array('assign', 'book', 'choice', 'folder', 'forum', 'glossary', 'imscp', 'label', 'lti', 'page', 'quiz', 'resource', 'scorm', 'survey', 'url', 'wiki'); $modules = array(); foreach ($tocreate as $modname) { $modules[$modname]['instance'] = $this->getDataGenerator()->create_module($modname, array('course' => $course->id)); $modules[$modname]['cm'] = get_coursemodule_from_id(false, $modules[$modname]['instance']->cmid); $modules[$modname]['context'] = context_module::instance($modules[$modname]['instance']->cmid); } $student = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); self::getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); $this->setUser($student); $since = time(); $this->waitForSecond(); $params = array(); foreach ($modules as $modname => $data) { $params[$data['cm']->id] = array('contextlevel' => 'module', 'id' => $data['cm']->id, 'since' => $since); } // Check there is nothing updated because modules are fresh new. $result = core_course_external::check_updates($course->id, $params); $result = external_api::clean_returnvalue(core_course_external::check_updates_returns(), $result); $this->assertCount(0, $result['instances']); $this->assertCount(0, $result['warnings']); // Update a module after a second. $this->waitForSecond(); set_coursemodule_name($modules['forum']['cm']->id, 'New forum name'); $found = false; $result = core_course_external::check_updates($course->id, $params); $result = external_api::clean_returnvalue(core_course_external::check_updates_returns(), $result); $this->assertCount(1, $result['instances']); $this->assertCount(0, $result['warnings']); foreach ($result['instances'] as $module) { foreach ($module['updates'] as $update) { if ($module['id'] == $modules['forum']['cm']->id and $update['name'] == 'configuration') { $found = true; } } } $this->assertTrue($found); // Do not retrieve the configuration field. $filter = array('files'); $found = false; $result = core_course_external::check_updates($course->id, $params, $filter); $result = external_api::clean_returnvalue(core_course_external::check_updates_returns(), $result); $this->assertCount(0, $result['instances']); $this->assertCount(0, $result['warnings']); $this->assertFalse($found); // Add invalid cmid. $params[] = array('contextlevel' => 'module', 'id' => -2, 'since' => $since); $result = core_course_external::check_updates($course->id, $params); $result = external_api::clean_returnvalue(core_course_external::check_updates_returns(), $result); $this->assertCount(1, $result['warnings']); $this->assertEquals(-2, $result['warnings'][0]['itemid']); }
/** * Test delete course_module. */ public function test_delete_modules() { global $DB; // Ensure we reset the data after this test. $this->resetAfterTest(true); // Create a user. $user = self::getDataGenerator()->create_user(); // Set the tests to run as the user. self::setUser($user); // Create a course to add the modules. $course = self::getDataGenerator()->create_course(); // Create two test modules. $record = new stdClass(); $record->course = $course->id; $module1 = self::getDataGenerator()->create_module('forum', $record); $module2 = self::getDataGenerator()->create_module('assignment', $record); // Check the forum was correctly created. $this->assertEquals(1, $DB->count_records('forum', array('id' => $module1->id))); // Check the assignment was correctly created. $this->assertEquals(1, $DB->count_records('assignment', array('id' => $module2->id))); // Check data exists in the course modules table. $this->assertEquals(2, $DB->count_records_select('course_modules', 'id = :module1 OR id = :module2', array('module1' => $module1->cmid, 'module2' => $module2->cmid))); // Enrol the user in the course. $enrol = enrol_get_plugin('manual'); $enrolinstances = enrol_get_instances($course->id, true); foreach ($enrolinstances as $courseenrolinstance) { if ($courseenrolinstance->enrol == "manual") { $instance = $courseenrolinstance; break; } } $enrol->enrol_user($instance, $user->id); // Assign capabilities to delete module 1. $modcontext = context_module::instance($module1->cmid); $this->assignUserCapability('moodle/course:manageactivities', $modcontext->id); // Assign capabilities to delete module 2. $modcontext = context_module::instance($module2->cmid); $newrole = create_role('Role 2', 'role2', 'Role 2 description'); $this->assignUserCapability('moodle/course:manageactivities', $modcontext->id, $newrole); // Deleting these module instances. core_course_external::delete_modules(array($module1->cmid, $module2->cmid)); // Check the forum was deleted. $this->assertEquals(0, $DB->count_records('forum', array('id' => $module1->id))); // Check the assignment was deleted. $this->assertEquals(0, $DB->count_records('assignment', array('id' => $module2->id))); // Check we retrieve no data in the course modules table. $this->assertEquals(0, $DB->count_records_select('course_modules', 'id = :module1 OR id = :module2', array('module1' => $module1->cmid, 'module2' => $module2->cmid))); // Call with non-existent course module id and ensure exception thrown. try { core_course_external::delete_modules(array('1337')); $this->fail('Exception expected due to missing course module.'); } catch (dml_missing_record_exception $e) { $this->assertEquals('invalidrecord', $e->errorcode); } // Create two modules. $module1 = self::getDataGenerator()->create_module('forum', $record); $module2 = self::getDataGenerator()->create_module('assignment', $record); // Since these modules were recreated the user will not have capabilities // to delete them, ensure exception is thrown if they try. try { core_course_external::delete_modules(array($module1->cmid, $module2->cmid)); $this->fail('Exception expected due to missing capability.'); } catch (moodle_exception $e) { $this->assertEquals('nopermissions', $e->errorcode); } // Unenrol user from the course. $enrol->unenrol_user($instance, $user->id); // Try and delete modules from the course the user was unenrolled in, make sure exception thrown. try { core_course_external::delete_modules(array($module1->cmid, $module2->cmid)); $this->fail('Exception expected due to being unenrolled from the course.'); } catch (moodle_exception $e) { $this->assertEquals('requireloginerror', $e->errorcode); } }
/** * Test get_user_administration_options */ public function test_get_user_administration_options() { global $USER; $this->resetAfterTest(); $course1 = self::getDataGenerator()->create_course(); $course2 = self::getDataGenerator()->create_course(); // Create a viewer user. $viewer = self::getDataGenerator()->create_user(); $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); $this->getDataGenerator()->enrol_user($viewer->id, $course2->id); $this->setUser($viewer->id); $courses = array($course1->id, $course2->id, SITEID); $result = core_course_external::get_user_administration_options($courses); $result = external_api::clean_returnvalue(core_course_external::get_user_administration_options_returns(), $result); $this->assertCount(0, $result['warnings']); $this->assertCount(3, $result['courses']); foreach ($result['courses'] as $course) { $adminoptions = new stdClass(); foreach ($course['options'] as $option) { $adminoptions->{$option['name']} = $option['available']; } if ($course['id'] == SITEID) { $this->assertCount(15, $course['options']); $this->assertFalse($adminoptions->update); $this->assertFalse($adminoptions->filters); $this->assertFalse($adminoptions->reports); $this->assertFalse($adminoptions->backup); $this->assertFalse($adminoptions->restore); $this->assertFalse($adminoptions->files); $this->assertFalse(!isset($adminoptions->tags)); $this->assertFalse($adminoptions->gradebook); $this->assertFalse($adminoptions->outcomes); $this->assertFalse($adminoptions->badges); $this->assertFalse($adminoptions->import); $this->assertFalse($adminoptions->publish); $this->assertFalse($adminoptions->reset); $this->assertFalse($adminoptions->roles); $this->assertFalse($adminoptions->grades); } else { $this->assertCount(15, $course['options']); $this->assertFalse($adminoptions->update); $this->assertFalse($adminoptions->filters); $this->assertFalse($adminoptions->reports); $this->assertFalse($adminoptions->backup); $this->assertFalse($adminoptions->restore); $this->assertFalse($adminoptions->files); $this->assertFalse($adminoptions->tags); $this->assertFalse($adminoptions->gradebook); $this->assertFalse($adminoptions->outcomes); $this->assertTrue($adminoptions->badges); $this->assertFalse($adminoptions->import); $this->assertFalse($adminoptions->publish); $this->assertFalse($adminoptions->reset); $this->assertFalse($adminoptions->roles); $this->assertTrue($adminoptions->grades); } } }
/** * Test update_courses */ public function test_update_courses() { global $DB, $CFG, $USER; $this->resetAfterTest(true); // Set the required capabilities by the external function. $contextid = context_system::instance()->id; $roleid = $this->assignUserCapability('moodle/course:update', $contextid); $this->assignUserCapability('moodle/course:changecategory', $contextid, $roleid); $this->assignUserCapability('moodle/course:changefullname', $contextid, $roleid); $this->assignUserCapability('moodle/course:changeshortname', $contextid, $roleid); $this->assignUserCapability('moodle/course:changeidnumber', $contextid, $roleid); $this->assignUserCapability('moodle/course:changesummary', $contextid, $roleid); $this->assignUserCapability('moodle/course:visibility', $contextid, $roleid); $this->assignUserCapability('moodle/course:viewhiddencourses', $contextid, $roleid); // Create category and course. $category1 = self::getDataGenerator()->create_category(); $category2 = self::getDataGenerator()->create_category(); $originalcourse1 = self::getDataGenerator()->create_course(); self::getDataGenerator()->enrol_user($USER->id, $originalcourse1->id, $roleid); $originalcourse2 = self::getDataGenerator()->create_course(); self::getDataGenerator()->enrol_user($USER->id, $originalcourse2->id, $roleid); // Course values to be updated. $course1['id'] = $originalcourse1->id; $course1['fullname'] = 'Updated test course 1'; $course1['shortname'] = 'Udestedtestcourse1'; $course1['categoryid'] = $category1->id; $course2['id'] = $originalcourse2->id; $course2['fullname'] = 'Updated test course 2'; $course2['shortname'] = 'Updestedtestcourse2'; $course2['categoryid'] = $category2->id; $course2['idnumber'] = 'Updatedidnumber2'; $course2['summary'] = 'Updaated description for course 2'; $course2['summaryformat'] = FORMAT_HTML; $course2['format'] = 'topics'; $course2['showgrades'] = 1; $course2['newsitems'] = 3; $course2['startdate'] = 1420092000; // 01/01/2015. $course2['numsections'] = 4; $course2['maxbytes'] = 100000; $course2['showreports'] = 1; $course2['visible'] = 0; $course2['hiddensections'] = 0; $course2['groupmode'] = 0; $course2['groupmodeforce'] = 0; $course2['defaultgroupingid'] = 0; $course2['enablecompletion'] = 1; $course2['lang'] = 'en'; $course2['forcetheme'] = 'base'; $courses = array($course1, $course2); $updatedcoursewarnings = core_course_external::update_courses($courses); // Check that right number of courses were created. $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); // Check that the courses were correctly created. foreach ($courses as $course) { $courseinfo = course_get_format($course['id'])->get_course(); if ($course['id'] == $course2['id']) { $this->assertEquals($course2['fullname'], $courseinfo->fullname); $this->assertEquals($course2['shortname'], $courseinfo->shortname); $this->assertEquals($course2['categoryid'], $courseinfo->category); $this->assertEquals($course2['idnumber'], $courseinfo->idnumber); $this->assertEquals($course2['summary'], $courseinfo->summary); $this->assertEquals($course2['summaryformat'], $courseinfo->summaryformat); $this->assertEquals($course2['format'], $courseinfo->format); $this->assertEquals($course2['showgrades'], $courseinfo->showgrades); $this->assertEquals($course2['newsitems'], $courseinfo->newsitems); $this->assertEquals($course2['startdate'], $courseinfo->startdate); $this->assertEquals($course2['numsections'], $courseinfo->numsections); $this->assertEquals($course2['maxbytes'], $courseinfo->maxbytes); $this->assertEquals($course2['showreports'], $courseinfo->showreports); $this->assertEquals($course2['visible'], $courseinfo->visible); $this->assertEquals($course2['hiddensections'], $courseinfo->hiddensections); $this->assertEquals($course2['groupmode'], $courseinfo->groupmode); $this->assertEquals($course2['groupmodeforce'], $courseinfo->groupmodeforce); $this->assertEquals($course2['defaultgroupingid'], $courseinfo->defaultgroupingid); $this->assertEquals($course2['lang'], $courseinfo->lang); if (!empty($CFG->allowcoursethemes)) { $this->assertEquals($course2['forcetheme'], $courseinfo->theme); } if (completion_info::is_enabled_for_site()) { $this->assertEquals($course2['enabledcompletion'], $courseinfo->enablecompletion); $this->assertEquals($course2['completionstartonenrol'], $courseinfo->completionstartonenrol); } } else { if ($course['id'] == $course1['id']) { $this->assertEquals($course1['fullname'], $courseinfo->fullname); $this->assertEquals($course1['shortname'], $courseinfo->shortname); $this->assertEquals($course1['categoryid'], $courseinfo->category); $this->assertEquals(FORMAT_MOODLE, $courseinfo->summaryformat); $this->assertEquals('topics', $courseinfo->format); $this->assertEquals(5, $courseinfo->numsections); $this->assertEquals(0, $courseinfo->newsitems); $this->assertEquals(FORMAT_MOODLE, $courseinfo->summaryformat); } else { throw moodle_exception('Unexpected shortname'); } } } $courses = array($course1); // Try update course without update capability. $user = self::getDataGenerator()->create_user(); $this->setUser($user); $this->unassignUserCapability('moodle/course:update', $contextid, $roleid); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); // Try update course category without capability. $this->assignUserCapability('moodle/course:update', $contextid, $roleid); $this->unassignUserCapability('moodle/course:changecategory', $contextid, $roleid); $user = self::getDataGenerator()->create_user(); $this->setUser($user); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $course1['categoryid'] = $category2->id; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); // Try update course fullname without capability. $this->assignUserCapability('moodle/course:changecategory', $contextid, $roleid); $this->unassignUserCapability('moodle/course:changefullname', $contextid, $roleid); $user = self::getDataGenerator()->create_user(); $this->setUser($user); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); $course1['fullname'] = 'Testing fullname without permission'; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); // Try update course shortname without capability. $this->assignUserCapability('moodle/course:changefullname', $contextid, $roleid); $this->unassignUserCapability('moodle/course:changeshortname', $contextid, $roleid); $user = self::getDataGenerator()->create_user(); $this->setUser($user); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); $course1['shortname'] = 'Testing shortname without permission'; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); // Try update course idnumber without capability. $this->assignUserCapability('moodle/course:changeshortname', $contextid, $roleid); $this->unassignUserCapability('moodle/course:changeidnumber', $contextid, $roleid); $user = self::getDataGenerator()->create_user(); $this->setUser($user); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); $course1['idnumber'] = 'NEWIDNUMBER'; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); // Try update course summary without capability. $this->assignUserCapability('moodle/course:changeidnumber', $contextid, $roleid); $this->unassignUserCapability('moodle/course:changesummary', $contextid, $roleid); $user = self::getDataGenerator()->create_user(); $this->setUser($user); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); $course1['summary'] = 'New summary'; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); // Try update course with invalid summary format. $this->assignUserCapability('moodle/course:changesummary', $contextid, $roleid); $user = self::getDataGenerator()->create_user(); $this->setUser($user); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); $course1['summaryformat'] = 10; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); // Try update course visibility without capability. $this->unassignUserCapability('moodle/course:visibility', $contextid, $roleid); $user = self::getDataGenerator()->create_user(); $this->setUser($user); self::getDataGenerator()->enrol_user($user->id, $course1['id'], $roleid); $course1['summaryformat'] = FORMAT_MOODLE; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(0, count($updatedcoursewarnings['warnings'])); $course1['visible'] = 0; $courses = array($course1); $updatedcoursewarnings = core_course_external::update_courses($courses); $this->assertEquals(1, count($updatedcoursewarnings['warnings'])); }
private static function fetchActiveCourseIds($userId, $categoryId, $categoryType, $from) { $courses = core_enrol_external::get_users_courses_subcat_offline($userId, $categoryId, $categoryType); $acids = array(); foreach ($courses as $i => $course) { $moduleIds = array(); //@TODO performance - courses could have skipped when fetching from db itself rather than skipping it when iterating. if (!empty($from) && $course['timemodified'] < $from) { unset($courses[$i]); } try { $topicsWithModules = core_course_external::get_course_contents($course['id'], array(), $from); $topics = array_merge($topics, self::extractTopics($course['id'], $topicsWithModules, $from)); foreach ($topicsWithModules as $topicWithModule) { if (isset($topicWithModule['modules']) && is_array($topicWithModule['modules'])) { $moduleIds = array_merge($moduleIds, self::extractModuleIds($course['id'], $topicWithModule['id'], $topicWithModule['modules'], $userid, $fromtimestamp)); } } $cID = $course['id']; $activecourse_mod = $moduleIds; $acids[] = array("id" => $cID, "modules" => $activecourse_mod); } catch (Exception $ex) { } } return $acids; }