mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
MDL-63542 core_course: Support stealth activities in WS
This commit is contained in:
parent
81bbf426f6
commit
10b88bf2c7
@ -58,6 +58,8 @@ class core_course_external extends external_api {
|
||||
'The expected keys (value format) are:
|
||||
excludemodules (bool) Do not return modules, return only the sections structure
|
||||
excludecontents (bool) Do not return module contents (i.e: files inside a resource)
|
||||
includestealthmodules (bool) Return stealth modules for students in a special
|
||||
section (with id -1)
|
||||
sectionid (int) Return only this section
|
||||
sectionnumber (int) Return only this section with number (order)
|
||||
cmid (int) Return only this module information (among the whole sections structure)
|
||||
@ -98,6 +100,7 @@ class core_course_external extends external_api {
|
||||
switch ($name) {
|
||||
case 'excludemodules':
|
||||
case 'excludecontents':
|
||||
case 'includestealthmodules':
|
||||
$value = clean_param($option['value'], PARAM_BOOL);
|
||||
$filters[$name] = $value;
|
||||
break;
|
||||
@ -163,21 +166,12 @@ class core_course_external extends external_api {
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$sections = $modinfo->get_section_info_all();
|
||||
$coursenumsections = course_get_format($course)->get_last_section_number();
|
||||
$stealthmodules = array(); // Array to keep all the modules available but not visible in a course section/topic.
|
||||
|
||||
//for each sections (first displayed to last displayed)
|
||||
$modinfosections = $modinfo->get_sections();
|
||||
foreach ($sections as $key => $section) {
|
||||
|
||||
// Show the section if the user is permitted to access it, OR if it's not available
|
||||
// but there is some available info text which explains the reason & should display.
|
||||
$showsection = $section->uservisible ||
|
||||
($section->visible && !$section->available &&
|
||||
!empty($section->availableinfo));
|
||||
|
||||
if (!$showsection) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// This becomes true when we are filtering and we found the value to filter with.
|
||||
$sectionfound = false;
|
||||
|
||||
@ -218,8 +212,8 @@ class core_course_external extends external_api {
|
||||
|
||||
$sectioncontents = array();
|
||||
|
||||
// For each module of the section (if it is visible).
|
||||
if ($section->uservisible and empty($filters['excludemodules']) and !empty($modinfosections[$section->section])) {
|
||||
// For each module of the section.
|
||||
if (empty($filters['excludemodules']) and !empty($modinfosections[$section->section])) {
|
||||
foreach ($modinfosections[$section->section] as $cmid) {
|
||||
$cm = $modinfo->cms[$cmid];
|
||||
|
||||
@ -312,8 +306,13 @@ class core_course_external extends external_api {
|
||||
}
|
||||
}
|
||||
|
||||
//assign result to $sectioncontents
|
||||
$sectioncontents[] = $module;
|
||||
// Assign result to $sectioncontents, there is an exception,
|
||||
// stealth activities in non-visible sections for students go to a special section.
|
||||
if (!empty($filters['includestealthmodules']) && !$section->uservisible && $cm->is_stealth()) {
|
||||
$stealthmodules[] = $module;
|
||||
} else {
|
||||
$sectioncontents[] = $module;
|
||||
}
|
||||
|
||||
// If we just did a filtering, break the loop.
|
||||
if ($modfound) {
|
||||
@ -325,13 +324,46 @@ class core_course_external extends external_api {
|
||||
$sectionvalues['modules'] = $sectioncontents;
|
||||
|
||||
// assign result to $coursecontents
|
||||
$coursecontents[] = $sectionvalues;
|
||||
$coursecontents[$key] = $sectionvalues;
|
||||
|
||||
// Break the loop if we are filtering.
|
||||
if ($sectionfound) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have iterated over all the sections and activities, check the visibility.
|
||||
// We didn't this before to be able to retrieve stealth activities.
|
||||
foreach ($coursecontents as $sectionnumber => $sectioncontents) {
|
||||
$section = $sections[$sectionnumber];
|
||||
// Show the section if the user is permitted to access it, OR if it's not available
|
||||
// but there is some available info text which explains the reason & should display.
|
||||
$showsection = $section->uservisible ||
|
||||
($section->visible && !$section->available &&
|
||||
!empty($section->availableinfo));
|
||||
|
||||
if (!$showsection) {
|
||||
unset($coursecontents[$sectionnumber]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove modules information if the section is not visible for the user.
|
||||
if (!$section->uservisible) {
|
||||
$coursecontents[$sectionnumber]['modules'] = array();
|
||||
}
|
||||
}
|
||||
|
||||
// Include stealth modules in special section (without any info).
|
||||
if (!empty($stealthmodules)) {
|
||||
$coursecontents[] = array(
|
||||
'id' => -1,
|
||||
'name' => '',
|
||||
'summary' => '',
|
||||
'summaryformat' => FORMAT_MOODLE,
|
||||
'modules' => $stealthmodules
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
return $coursecontents;
|
||||
}
|
||||
|
@ -806,8 +806,11 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
* @return array A list with the course object and course modules objects
|
||||
*/
|
||||
private function prepare_get_course_contents_test() {
|
||||
global $DB;
|
||||
$course = self::getDataGenerator()->create_course(['numsections' => 3]);
|
||||
global $DB, $CFG;
|
||||
|
||||
$CFG->allowstealth = 1; // Allow stealth activities.
|
||||
|
||||
$course = self::getDataGenerator()->create_course(['numsections' => 4]);
|
||||
$forumdescription = 'This is the forum description';
|
||||
$forum = $this->getDataGenerator()->create_module('forum',
|
||||
array('course' => $course->id, 'intro' => $forumdescription),
|
||||
@ -817,6 +820,8 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$datacm = get_coursemodule_from_instance('page', $data->id);
|
||||
$page = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
|
||||
$pagecm = get_coursemodule_from_instance('page', $page->id);
|
||||
// This is an stealth page (set by visibleoncoursepage).
|
||||
$pagestealth = $this->getDataGenerator()->create_module('page', array('course' => $course->id, 'visibleoncoursepage' => 0));
|
||||
$labeldescription = 'This is a very long label to test if more than 50 characters are returned.
|
||||
So bla bla bla bla <b>bold bold bold</b> bla bla bla bla.';
|
||||
$label = $this->getDataGenerator()->create_module('label', array('course' => $course->id,
|
||||
@ -846,10 +851,18 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$conditions = array('course' => $course->id, 'section' => 2);
|
||||
$DB->set_field('course_sections', 'summary', 'Text with iframe <iframe src="https://moodle.org"></iframe>', $conditions);
|
||||
|
||||
// Add date availability condition not met for last section.
|
||||
// Add date availability condition not met for section 3.
|
||||
$availability = '{"op":"&","c":[{"type":"date","d":">=","t":' . $tomorrow . '}],"showc":[true]}';
|
||||
$DB->set_field('course_sections', 'availability', $availability,
|
||||
array('course' => $course->id, 'section' => 3));
|
||||
|
||||
// Create resource for last section.
|
||||
$pageinhiddensection = $this->getDataGenerator()->create_module('page',
|
||||
array('course' => $course->id, 'name' => 'Page in hidden section', 'section' => 4));
|
||||
// Set not visible last section.
|
||||
$DB->set_field('course_sections', 'visible', 0,
|
||||
array('course' => $course->id, 'section' => 4));
|
||||
|
||||
rebuild_course_cache($course->id, true);
|
||||
|
||||
return array($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm);
|
||||
@ -863,6 +876,8 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
|
||||
list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test();
|
||||
|
||||
// We first run the test as admin.
|
||||
$this->setAdminUser();
|
||||
$sections = core_course_external::get_course_contents($course->id, array());
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections);
|
||||
@ -889,21 +904,18 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals(2, $testexecuted);
|
||||
$this->assertEquals(0, $sections[0]['section']);
|
||||
|
||||
// Check that the only return section has the 5 created modules.
|
||||
$this->assertCount(4, $sections[0]['modules']);
|
||||
$this->assertCount(5, $sections[0]['modules']);
|
||||
$this->assertCount(1, $sections[1]['modules']);
|
||||
$this->assertCount(1, $sections[2]['modules']);
|
||||
$this->assertCount(0, $sections[3]['modules']); // No modules for the section with availability restrictions.
|
||||
$this->assertCount(1, $sections[3]['modules']); // One module for the section with availability restrictions.
|
||||
$this->assertCount(1, $sections[4]['modules']); // One module for the hidden section with a visible activity.
|
||||
$this->assertNotEmpty($sections[3]['availabilityinfo']);
|
||||
$this->assertEquals(1, $sections[1]['section']);
|
||||
$this->assertEquals(2, $sections[2]['section']);
|
||||
$this->assertEquals(3, $sections[3]['section']);
|
||||
$this->assertEquals(4, $sections[4]['section']);
|
||||
$this->assertContains('<iframe', $sections[2]['summary']);
|
||||
$this->assertContains('</iframe>', $sections[2]['summary']);
|
||||
// The module with the availability restriction met is returning contents.
|
||||
$this->assertNotEmpty($sections[1]['modules'][0]['contents']);
|
||||
// The module with the availability restriction not met is not returning contents.
|
||||
$this->assertArrayNotHasKey('contents', $sections[2]['modules'][0]);
|
||||
$this->assertNotEmpty($sections[2]['modules'][0]['availabilityinfo']);
|
||||
try {
|
||||
$sections = core_course_external::get_course_contents($course->id,
|
||||
@ -915,6 +927,54 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test get_course_contents as student
|
||||
*/
|
||||
public function test_get_course_contents_student() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test();
|
||||
|
||||
$studentroleid = $DB->get_field('role', 'id', array('shortname' => 'student'));
|
||||
$user = self::getDataGenerator()->create_user();
|
||||
self::getDataGenerator()->enrol_user($user->id, $course->id, $studentroleid);
|
||||
$this->setUser($user);
|
||||
|
||||
$sections = core_course_external::get_course_contents($course->id, array());
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections);
|
||||
|
||||
$this->assertCount(4, $sections); // Nothing for the not visible section.
|
||||
$this->assertCount(5, $sections[0]['modules']);
|
||||
$this->assertCount(1, $sections[1]['modules']);
|
||||
$this->assertCount(1, $sections[2]['modules']);
|
||||
$this->assertCount(0, $sections[3]['modules']); // No modules for the section with availability restrictions.
|
||||
|
||||
$this->assertNotEmpty($sections[3]['availabilityinfo']);
|
||||
$this->assertEquals(1, $sections[1]['section']);
|
||||
$this->assertEquals(2, $sections[2]['section']);
|
||||
$this->assertEquals(3, $sections[3]['section']);
|
||||
// The module with the availability restriction met is returning contents.
|
||||
$this->assertNotEmpty($sections[1]['modules'][0]['contents']);
|
||||
// The module with the availability restriction not met is not returning contents.
|
||||
$this->assertArrayNotHasKey('contents', $sections[2]['modules'][0]);
|
||||
|
||||
// Now include flag for returning stealth information (fake section).
|
||||
$sections = core_course_external::get_course_contents($course->id,
|
||||
array(array("name" => "includestealthmodules", "value" => 1)));
|
||||
// We need to execute the return values cleaning process to simulate the web service server.
|
||||
$sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections);
|
||||
|
||||
$this->assertCount(5, $sections); // Include fake section with stealth activities.
|
||||
$this->assertCount(5, $sections[0]['modules']);
|
||||
$this->assertCount(1, $sections[1]['modules']);
|
||||
$this->assertCount(1, $sections[2]['modules']);
|
||||
$this->assertCount(0, $sections[3]['modules']); // No modules for the section with availability restrictions.
|
||||
$this->assertCount(1, $sections[4]['modules']); // One stealh module.
|
||||
$this->assertEquals(-1, $sections[4]['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_course_contents excluding modules
|
||||
*/
|
||||
@ -972,7 +1032,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections);
|
||||
|
||||
$this->assertCount(1, $sections);
|
||||
$this->assertCount(4, $sections[0]['modules']);
|
||||
$this->assertCount(5, $sections[0]['modules']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user