diff --git a/mod/wiki/classes/external.php b/mod/wiki/classes/external.php index 1aa157efae0..a6634c51ed6 100644 --- a/mod/wiki/classes/external.php +++ b/mod/wiki/classes/external.php @@ -395,4 +395,203 @@ class mod_wiki_external extends external_api { ); } + /** + * Describes the parameters for get_subwiki_pages. + * + * @return external_function_parameters + * @since Moodle 3.1 + */ + public static function get_subwiki_pages_parameters() { + return new external_function_parameters ( + array( + 'wikiid' => new external_value(PARAM_INT, 'Wiki instance ID.'), + 'groupid' => new external_value(PARAM_INT, 'Subwiki\'s group ID, -1 means current group. It will be ignored' + . ' if the wiki doesn\'t use groups.', VALUE_DEFAULT, -1), + 'userid' => new external_value(PARAM_INT, 'Subwiki\'s user ID, 0 means current user. It will be ignored' + .' in collaborative wikis.', VALUE_DEFAULT, 0), + 'options' => new external_single_structure( + array( + 'sortby' => new external_value(PARAM_ALPHA, + 'Field to sort by (id, title, ...).', VALUE_DEFAULT, 'title'), + 'sortdirection' => new external_value(PARAM_ALPHA, + 'Sort direction: ASC or DESC.', VALUE_DEFAULT, 'ASC'), + 'includecontent' => new external_value(PARAM_INT, + 'Include each page contents or not.', VALUE_DEFAULT, 1), + ), 'Options', VALUE_DEFAULT, array()), + ) + ); + } + + /** + * Returns the list of pages from a specific subwiki. + * + * @param int $wikiid The wiki instance ID. + * @param int $groupid The group ID. If not defined, use current group. + * @param int $userid The user ID. If not defined, use current user. + * @param array $options Several options like sort by, sort direction, ... + * @return array Containing a list of warnings and a list of pages. + * @since Moodle 3.1 + */ + public static function get_subwiki_pages($wikiid, $groupid = -1, $userid = 0, $options = array()) { + global $USER, $DB; + + $returnedpages = array(); + $warnings = array(); + + $params = self::validate_parameters(self::get_subwiki_pages_parameters(), + array( + 'wikiid' => $wikiid, + 'groupid' => $groupid, + 'userid' => $userid, + 'options' => $options + ) + ); + + // Get wiki instance. + if (!$wiki = wiki_get_wiki($params['wikiid'])) { + throw new moodle_exception('incorrectwikiid', 'wiki'); + } + list($course, $cm) = get_course_and_cm_from_instance($wiki, 'wiki'); + $context = context_module::instance($cm->id); + self::validate_context($context); + + // Determine group. + $groupmode = groups_get_activity_groupmode($cm); + if ($groupmode == NOGROUPS) { + $groupid = 0; + } else if ($params['groupid'] == -1) { + // Use current group. + $groupid = groups_get_activity_group($cm); + $groupid = !empty($groupid) ? $groupid : 0; + } else { + $groupid = $params['groupid']; + } + + // Determine user. + if ($wiki->wikimode == 'collaborative') { + // Collaborative wikis don't use userid in subwikis. + $userid = 0; + } else if (empty($params['userid'])) { + // Use current user. + $userid = $USER->id; + } else { + $userid = $params['userid']; + } + + // Get subwiki based on group and user. + if (!$subwiki = wiki_get_subwiki_by_group($cm->instance, $groupid, $userid)) { + // The subwiki doesn't exist. + // Validate if user is valid. + if ($userid != 0 && $userid != $USER->id && !$user = $DB->get_record('user', array('id' => $userid))) { + throw new moodle_exception('invaliduserid', 'error'); + } + + // Validate that groupid is valid. + if ($groupid != 0 && !groups_group_exists($groupid)) { + throw new moodle_exception('cannotfindgroup', 'error'); + } + + // Valid data but subwiki not found. We'll simulate a subwiki object to check if the user would be able to see it + // if it existed. If he's able to see it then we'll return an empty array because the subwiki has no pages. + $subwiki = new stdClass(); + $subwiki->wikiid = $wiki->id; + $subwiki->userid = $userid; + $subwiki->groupid = $groupid; + + // Check that the user can view the subwiki. This function checks capabilities. + if (!wiki_user_can_view($subwiki, $wiki)) { + throw new moodle_exception('cannotviewpage', 'wiki'); + } + } else { + // Check that the user can view the subwiki. This function checks capabilities. + if (!wiki_user_can_view($subwiki, $wiki)) { + throw new moodle_exception('cannotviewpage', 'wiki'); + } + + // Set sort param. + $options = $params['options']; + if (!empty($options['sortby'])) { + if ($options['sortdirection'] != 'ASC' && $options['sortdirection'] != 'DESC') { + // Invalid sort direction. Use default. + $options['sortdirection'] = 'ASC'; + } + $sort = $options['sortby'] . ' ' . $options['sortdirection']; + } + + $pages = wiki_get_page_list($subwiki->id, $sort); + $caneditpages = wiki_user_can_edit($subwiki); + $firstpage = wiki_get_first_page($subwiki->id); + + foreach ($pages as $page) { + $retpage = array( + 'id' => $page->id, + 'subwikiid' => $page->subwikiid, + 'title' => external_format_string($page->title, $context->id), + 'timecreated' => $page->timecreated, + 'timemodified' => $page->timemodified, + 'timerendered' => $page->timerendered, + 'userid' => $page->userid, + 'pageviews' => $page->pageviews, + 'readonly' => $page->readonly, + 'caneditpage' => $caneditpages, + 'firstpage' => $page->id == $firstpage->id + ); + + if ($options['includecontent']) { + // Refresh page cached content if needed. + if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) { + if ($content = wiki_refresh_cachedcontent($page)) { + $page = $content['page']; + } + } + + list($retpage['cachedcontent'], $retpage['contentformat']) = external_format_text( + $page->cachedcontent, FORMAT_HTML, $context->id, 'mod_wiki', 'attachments', $subwiki->id); + } + + $returnedpages[] = $retpage; + } + + } + + $result = array(); + $result['pages'] = $returnedpages; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Describes the get_subwiki_pages return value. + * + * @return external_single_structure + * @since Moodle 3.1 + */ + public static function get_subwiki_pages_returns() { + + return new external_single_structure( + array( + 'pages' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Page ID.'), + 'subwikiid' => new external_value(PARAM_INT, 'Page\'s subwiki ID.'), + 'title' => new external_value(PARAM_RAW, 'Page title.'), + 'timecreated' => new external_value(PARAM_INT, 'Time of creation.'), + 'timemodified' => new external_value(PARAM_INT, 'Time of last modification.'), + 'timerendered' => new external_value(PARAM_INT, 'Time of last renderization.'), + 'userid' => new external_value(PARAM_INT, 'ID of the user that last modified the page.'), + 'pageviews' => new external_value(PARAM_INT, 'Number of times the page has been viewed.'), + 'readonly' => new external_value(PARAM_INT, '1 if readonly, 0 otherwise.'), + 'caneditpage' => new external_value(PARAM_BOOL, 'True if user can edit the page.'), + 'firstpage' => new external_value(PARAM_BOOL, 'True if it\'s the first page.'), + 'cachedcontent' => new external_value(PARAM_RAW, 'Page contents.', VALUE_OPTIONAL), + 'contentformat' => new external_format_value('cachedcontent', VALUE_OPTIONAL), + ), 'Pages' + ) + ), + 'warnings' => new external_warnings(), + ) + ); + } + } diff --git a/mod/wiki/db/services.php b/mod/wiki/db/services.php index 76aa5ea711e..68942601349 100644 --- a/mod/wiki/db/services.php +++ b/mod/wiki/db/services.php @@ -61,5 +61,13 @@ $functions = array( 'type' => 'read', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) + ), + 'mod_wiki_get_subwiki_pages' => array( + 'classname' => 'mod_wiki_external', + 'methodname' => 'get_subwiki_pages', + 'description' => 'Returns the list of pages for a specific subwiki.', + 'type' => 'read', + 'capabilities' => 'mod/wiki:viewpage', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ) ); diff --git a/mod/wiki/locallib.php b/mod/wiki/locallib.php index 474246d1cdb..9162b384ecd 100644 --- a/mod/wiki/locallib.php +++ b/mod/wiki/locallib.php @@ -506,10 +506,11 @@ function wiki_get_missing_or_empty_pages($swid) { /** * Get pages list in wiki * @param int $swid sub wiki id + * @param string $sort How to sort the pages. By default, title ASC. */ -function wiki_get_page_list($swid) { +function wiki_get_page_list($swid, $sort = 'title ASC') { global $DB; - $records = $DB->get_records('wiki_pages', array('subwikiid' => $swid), 'title ASC'); + $records = $DB->get_records('wiki_pages', array('subwikiid' => $swid), $sort); return $records; } diff --git a/mod/wiki/tests/externallib_test.php b/mod/wiki/tests/externallib_test.php index 06c3ace66e4..ec1ddf840ea 100644 --- a/mod/wiki/tests/externallib_test.php +++ b/mod/wiki/tests/externallib_test.php @@ -58,18 +58,90 @@ class mod_wiki_external_testcase extends externallib_advanced_testcase { // Create users. $this->student = self::getDataGenerator()->create_user(); + $this->student2 = self::getDataGenerator()->create_user(); $this->teacher = self::getDataGenerator()->create_user(); // Users enrolments. $this->studentrole = $DB->get_record('role', array('shortname' => 'student')); $this->teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); $this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $this->studentrole->id, 'manual'); + $this->getDataGenerator()->enrol_user($this->student2->id, $this->course->id, $this->studentrole->id, 'manual'); $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, $this->teacherrole->id, 'manual'); - // Create first page. + // Create first pages. $this->firstpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($this->wiki); } + /** + * Create two collaborative wikis (separate/visible groups), 2 groups and a first page for each wiki and group. + */ + private function create_collaborative_wikis_with_groups() { + // Create groups and add student to one of them. + if (!isset($this->group1)) { + $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id)); + $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id)); + $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id)); + } + if (!isset($this->group2)) { + $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id)); + } + + // Create two collaborative wikis. + $this->wikisep = $this->getDataGenerator()->create_module('wiki', + array('course' => $this->course->id, 'groupmode' => SEPARATEGROUPS)); + $this->wikivis = $this->getDataGenerator()->create_module('wiki', + array('course' => $this->course->id, 'groupmode' => VISIBLEGROUPS)); + + // Create pages. + $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki'); + $this->fpsepg1 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group1->id)); + $this->fpsepg2 = $wikigenerator->create_first_page($this->wikisep, array('group' => $this->group2->id)); + $this->fpsepall = $wikigenerator->create_first_page($this->wikisep, array('group' => 0)); // All participants. + $this->fpvisg1 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group1->id)); + $this->fpvisg2 = $wikigenerator->create_first_page($this->wikivis, array('group' => $this->group2->id)); + $this->fpvisall = $wikigenerator->create_first_page($this->wikivis, array('group' => 0)); // All participants. + } + + /** + * Create two individual wikis (separate/visible groups), 2 groups and a first page for each wiki and group. + */ + private function create_individual_wikis_with_groups() { + // Create groups and add student to one of them. + if (!isset($this->group1)) { + $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id)); + $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group1->id)); + $this->getDataGenerator()->create_group_member(array('userid' => $this->student2->id, 'groupid' => $this->group1->id)); + } + if (!isset($this->group2)) { + $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id)); + } + + // Create two individual wikis. + $this->wikisepind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id, + 'groupmode' => SEPARATEGROUPS, 'wikimode' => 'individual')); + $this->wikivisind = $this->getDataGenerator()->create_module('wiki', array('course' => $this->course->id, + 'groupmode' => VISIBLEGROUPS, 'wikimode' => 'individual')); + + // Create pages. Student can only create pages in his groups. + $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki'); + $this->setUser($this->teacher); + $this->fpsepg1indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id)); + $this->fpsepg2indt = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group2->id)); + $this->fpsepallindt = $wikigenerator->create_first_page($this->wikisepind, array('group' => 0)); // All participants. + $this->fpvisg1indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id)); + $this->fpvisg2indt = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group2->id)); + $this->fpvisallindt = $wikigenerator->create_first_page($this->wikivisind, array('group' => 0)); // All participants. + + $this->setUser($this->student); + $this->fpsepg1indstu = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id)); + $this->fpvisg1indstu = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id)); + + $this->setUser($this->student2); + $this->fpsepg1indstu2 = $wikigenerator->create_first_page($this->wikisepind, array('group' => $this->group1->id)); + $this->fpvisg1indstu2 = $wikigenerator->create_first_page($this->wikivisind, array('group' => $this->group1->id)); + + } + /* * Test get wikis by courses */ @@ -372,4 +444,433 @@ class mod_wiki_external_testcase extends externallib_advanced_testcase { } + /** + * Test get_subwiki_pages using an invalid wiki instance. + */ + public function test_get_subwiki_pages_invalid_instance() { + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages(0); + } + + /** + * Test get_subwiki_pages using a user not enrolled in the course. + */ + public function test_get_subwiki_pages_unenrolled_user() { + // Create and use the user. + $usernotenrolled = self::getDataGenerator()->create_user(); + $this->setUser($usernotenrolled); + + $this->setExpectedException('require_login_exception'); + mod_wiki_external::get_subwiki_pages($this->wiki->id); + } + + /** + * Test get_subwiki_pages using a hidden wiki as student. + */ + public function test_get_subwiki_pages_hidden_wiki_as_student() { + // Create a hidden wiki and try to get the list of pages. + $hiddenwiki = $this->getDataGenerator()->create_module('wiki', + array('course' => $this->course->id, 'visible' => false)); + + $this->setUser($this->student); + $this->setExpectedException('require_login_exception'); + mod_wiki_external::get_subwiki_pages($hiddenwiki->id); + } + + /** + * Test get_subwiki_pages without the viewpage capability. + */ + public function test_get_subwiki_pages_without_viewpage_capability() { + // Prohibit capability = mod/wiki:viewpage on the course for students. + $contextcourse = context_course::instance($this->course->id); + assign_capability('mod/wiki:viewpage', CAP_PROHIBIT, $this->studentrole->id, $contextcourse->id); + accesslib_clear_all_caches_for_unit_testing(); + + $this->setUser($this->student); + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($this->wiki->id); + } + + /** + * Test get_subwiki_pages using an invalid userid. + */ + public function test_get_subwiki_pages_invalid_userid() { + // Create an individual wiki. + $indwiki = $this->getDataGenerator()->create_module('wiki', + array('course' => $this->course->id, 'wikimode' => 'individual')); + + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($indwiki->id, 0, -10); + } + + /** + * Test get_subwiki_pages using an invalid groupid. + */ + public function test_get_subwiki_pages_invalid_groupid() { + // Create testing data. + $this->create_collaborative_wikis_with_groups(); + + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($this->wikisep->id, -111); + } + + /** + * Test get_subwiki_pages, check that a student can't see another user pages in an individual wiki without groups. + */ + public function test_get_subwiki_pages_individual_student_see_other_user() { + // Create an individual wiki. + $indwiki = $this->getDataGenerator()->create_module('wiki', + array('course' => $this->course->id, 'wikimode' => 'individual')); + + $this->setUser($this->student); + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id); + } + + /** + * Test get_subwiki_pages, check that a student can't get the pages from another group in + * a collaborative wiki using separate groups. + */ + public function test_get_subwiki_pages_collaborative_separate_groups_student_see_other_group() { + // Create testing data. + $this->create_collaborative_wikis_with_groups(); + + $this->setUser($this->student); + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group2->id); + } + + /** + * Test get_subwiki_pages, check that a student can't get the pages from another group in + * an individual wiki using separate groups. + */ + public function test_get_subwiki_pages_individual_separate_groups_student_see_other_group() { + // Create testing data. + $this->create_individual_wikis_with_groups(); + + $this->setUser($this->student); + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group2->id, $this->teacher->id); + } + + /** + * Test get_subwiki_pages, check that a student can't get the pages from all participants in + * a collaborative wiki using separate groups. + */ + public function test_get_subwiki_pages_collaborative_separate_groups_student_see_all_participants() { + // Create testing data. + $this->create_collaborative_wikis_with_groups(); + + $this->setUser($this->student); + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0); + } + + /** + * Test get_subwiki_pages, check that a student can't get the pages from all participants in + * an individual wiki using separate groups. + */ + public function test_get_subwiki_pages_individual_separate_groups_student_see_all_participants() { + // Create testing data. + $this->create_individual_wikis_with_groups(); + + $this->setUser($this->student); + $this->setExpectedException('moodle_exception'); + mod_wiki_external::get_subwiki_pages($this->wikisepind->id, 0, $this->teacher->id); + } + + /** + * Test get_subwiki_pages without groups and collaborative wiki. + */ + public function test_get_subwiki_pages_collaborative() { + + // Test user with full capabilities. + $this->setUser($this->student); + + // Set expected result: first page. + $expectedpages = array(); + $expectedfirstpage = (array) $this->firstpage; + $expectedfirstpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability. + $expectedfirstpage['firstpage'] = true; + $expectedfirstpage['contentformat'] = 1; + $expectedpages[] = $expectedfirstpage; + + $result = mod_wiki_external::get_subwiki_pages($this->wiki->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that groupid param is ignored since the wiki isn't using groups. + $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that userid param is ignored since the wiki is collaborative. + $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 1234, 1234); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Add a new page to the wiki and test again. We'll use a custom title so it's returned first if sorted by title. + $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page( + $this->wiki, array('title' => 'AAA')); + + $expectednewpage = (array) $newpage; + $expectednewpage['caneditpage'] = true; // No groups and students have 'mod/wiki:editpage' capability. + $expectednewpage['firstpage'] = false; + $expectednewpage['contentformat'] = 1; + array_unshift($expectedpages, $expectednewpage); // Add page to the beginning since it orders by title by default. + + $result = mod_wiki_external::get_subwiki_pages($this->wiki->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Now we'll order by ID. Since first page was created first it'll have a lower ID. + $expectedpages = array($expectedfirstpage, $expectednewpage); + $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id')); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that WS doesn't return page content if includecontent is false. + unset($expectedpages[0]['cachedcontent']); + unset($expectedpages[0]['contentformat']); + unset($expectedpages[1]['cachedcontent']); + unset($expectedpages[1]['contentformat']); + $result = mod_wiki_external::get_subwiki_pages($this->wiki->id, 0, 0, array('sortby' => 'id', 'includecontent' => 0)); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + } + + /** + * Test get_subwiki_pages without groups. + */ + public function test_get_subwiki_pages_individual() { + + // Create an individual wiki to test userid param. + $indwiki = $this->getDataGenerator()->create_module('wiki', + array('course' => $this->course->id, 'wikimode' => 'individual')); + + // Perform a request before creating any page to check that an empty array is returned if subwiki doesn't exist. + $result = mod_wiki_external::get_subwiki_pages($indwiki->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals(array(), $result['pages']); + + // Create first pages as student and teacher. + $this->setUser($this->student); + $indfirstpagestudent = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki); + $this->setUser($this->teacher); + $indfirstpageteacher = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_first_page($indwiki); + + // Check that teacher can get his pages. + $expectedteacherpage = (array) $indfirstpageteacher; + $expectedteacherpage['caneditpage'] = true; + $expectedteacherpage['firstpage'] = true; + $expectedteacherpage['contentformat'] = 1; + $expectedpages = array($expectedteacherpage); + + $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->teacher->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that the teacher can see the student's pages. + $expectedstudentpage = (array) $indfirstpagestudent; + $expectedstudentpage['caneditpage'] = true; + $expectedstudentpage['firstpage'] = true; + $expectedstudentpage['contentformat'] = 1; + $expectedpages = array($expectedstudentpage); + + $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Now check that student can get his pages. + $this->setUser($this->student); + + $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0, $this->student->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that not using userid uses current user. + $result = mod_wiki_external::get_subwiki_pages($indwiki->id, 0); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + } + + /** + * Test get_subwiki_pages with groups and collaborative wikis. + */ + public function test_get_subwiki_pages_separate_groups_collaborative() { + + // Create testing data. + $this->create_collaborative_wikis_with_groups(); + + $this->setUser($this->student); + + // Try to get pages from a valid group in separate groups wiki. + + $expectedpage = (array) $this->fpsepg1; + $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability. + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Let's check that not using groupid returns the same result (current group). + $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that teacher can view a group pages without belonging to it. + $this->setUser($this->teacher); + $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, $this->group1->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that teacher can get the pages from all participants. + $expectedpage = (array) $this->fpsepall; + $expectedpage['caneditpage'] = true; + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikisep->id, 0); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + } + + /** + * Test get_subwiki_pages with groups and collaborative wikis. + */ + public function test_get_subwiki_pages_visible_groups_collaborative() { + + // Create testing data. + $this->create_collaborative_wikis_with_groups(); + + $this->setUser($this->student); + + // Try to get pages from a valid group in visible groups wiki. + + $expectedpage = (array) $this->fpvisg1; + $expectedpage['caneditpage'] = true; // User belongs to group and has 'mod/wiki:editpage' capability. + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group1->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that with visible groups a student can get the pages of groups he doesn't belong to. + $expectedpage = (array) $this->fpvisg2; + $expectedpage['caneditpage'] = false; // User doesn't belong to group so he can't edit the page. + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, $this->group2->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that with visible groups a student can get the pages of all participants. + $expectedpage = (array) $this->fpvisall; + $expectedpage['caneditpage'] = false; + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikivis->id, 0); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + } + + /** + * Test get_subwiki_pages with groups and individual wikis. + */ + public function test_get_subwiki_pages_separate_groups_individual() { + + // Create testing data. + $this->create_individual_wikis_with_groups(); + + $this->setUser($this->student); + + // Check that student can retrieve his pages from separate wiki. + $expectedpage = (array) $this->fpsepg1indstu; + $expectedpage['caneditpage'] = true; + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that not using userid uses current user. + $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that the teacher can see the student pages. + $this->setUser($this->teacher); + $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that a student can see pages from another user that belongs to his groups. + $this->setUser($this->student); + $expectedpage = (array) $this->fpsepg1indstu2; + $expectedpage['caneditpage'] = false; + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikisepind->id, $this->group1->id, $this->student2->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + } + + /** + * Test get_subwiki_pages with groups and individual wikis. + */ + public function test_get_subwiki_pages_visible_groups_individual() { + + // Create testing data. + $this->create_individual_wikis_with_groups(); + + $this->setUser($this->student); + + // Check that student can retrieve his pages from visible wiki. + $expectedpage = (array) $this->fpvisg1indstu; + $expectedpage['caneditpage'] = true; + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group1->id, $this->student->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that student can see teacher pages in visible groups, even if the user doesn't belong to the group. + $expectedpage = (array) $this->fpvisg2indt; + $expectedpage['caneditpage'] = false; + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, $this->group2->id, $this->teacher->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + + // Check that with visible groups a student can get the pages of all participants. + $expectedpage = (array) $this->fpvisallindt; + $expectedpage['caneditpage'] = false; + $expectedpage['firstpage'] = true; + $expectedpage['contentformat'] = 1; + $expectedpages = array($expectedpage); + + $result = mod_wiki_external::get_subwiki_pages($this->wikivisind->id, 0, $this->teacher->id); + $result = external_api::clean_returnvalue(mod_wiki_external::get_subwiki_pages_returns(), $result); + $this->assertEquals($expectedpages, $result['pages']); + } + } diff --git a/mod/wiki/upgrade.txt b/mod/wiki/upgrade.txt new file mode 100644 index 00000000000..611e8a64686 --- /dev/null +++ b/mod/wiki/upgrade.txt @@ -0,0 +1,5 @@ +This files describes API changes in /mod/wiki/*, +information provided here is intended especially for developers. + +=== 3.1 === + * Added a new param $sort to wiki_get_page_list function. Default value behaves exactly like before (sort by title ASC).