From a6b6f0d2828e9c77008fa26ddbf62e0ad8ad597f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 14 Apr 2016 10:14:39 +0200 Subject: [PATCH] MDL-53791 mod_wiki: New Web Service new_page --- mod/wiki/classes/external.php | 156 ++++++++++++++++++++++++++++ mod/wiki/db/services.php | 9 ++ mod/wiki/lang/en/wiki.php | 2 +- mod/wiki/tests/externallib_test.php | 72 +++++++++++++ 4 files changed, 238 insertions(+), 1 deletion(-) diff --git a/mod/wiki/classes/external.php b/mod/wiki/classes/external.php index 2a86daaabdb..957a6683d9b 100644 --- a/mod/wiki/classes/external.php +++ b/mod/wiki/classes/external.php @@ -919,4 +919,160 @@ class mod_wiki_external extends external_api { ); } + /** + * Describes the parameters for new_page. + * + * @return external_function_parameters + * @since Moodle 3.1 + */ + public static function new_page_parameters() { + return new external_function_parameters ( + array( + 'title' => new external_value(PARAM_TEXT, 'New page title.'), + 'content' => new external_value(PARAM_RAW, 'Page contents.'), + 'contentformat' => new external_value(PARAM_TEXT, 'Page contents format. If an invalid format is provided, default + wiki format is used.', VALUE_DEFAULT, null), + 'subwikiid' => new external_value(PARAM_INT, 'Page\'s subwiki ID.', VALUE_DEFAULT, null), + 'wikiid' => new external_value(PARAM_INT, 'Page\'s wiki ID. Used if subwiki does not exists.', VALUE_DEFAULT, + null), + 'userid' => new external_value(PARAM_INT, 'Subwiki\'s user ID. Used if subwiki does not exists.', VALUE_DEFAULT, + null), + 'groupid' => new external_value(PARAM_INT, 'Subwiki\'s group ID. Used if subwiki does not exists.', VALUE_DEFAULT, + null) + ) + ); + } + + /** + * Creates a new page. + * + * @param string $title New page title. + * @param string $content Page contents. + * @param int $contentformat Page contents format. If an invalid format is provided, default wiki format is used. + * @param int $subwikiid The Subwiki ID where to store the page. + * @param int $wikiid Page\'s wiki ID. Used if subwiki does not exists. + * @param int $userid Subwiki\'s user ID. Used if subwiki does not exists. + * @param int $groupid Subwiki\'s group ID. Used if subwiki does not exists. + * @return array of warnings and page data. + * @since Moodle 3.1 + */ + public static function new_page($title, $content, $contentformat = null, $subwikiid = null, $wikiid = null, $userid = null, + $groupid = null) { + global $USER; + + $params = self::validate_parameters(self::new_page_parameters(), + array( + 'title' => $title, + 'content' => $content, + 'contentformat' => $contentformat, + 'subwikiid' => $subwikiid, + 'wikiid' => $wikiid, + 'userid' => $userid, + 'groupid' => $groupid + ) + ); + + $warnings = array(); + + // Get wiki and subwiki instances. + if (!empty($params['subwikiid'])) { + if (!$subwiki = wiki_get_subwiki($params['subwikiid'])) { + throw new moodle_exception('incorrectsubwikiid', 'wiki'); + } + + if (!$wiki = wiki_get_wiki($subwiki->wikiid)) { + throw new moodle_exception('incorrectwikiid', 'wiki'); + } + + // Permission validation. + $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course); + $context = context_module::instance($cm->id); + self::validate_context($context); + + } else { + if (!$wiki = wiki_get_wiki($params['wikiid'])) { + throw new moodle_exception('incorrectwikiid', 'wiki'); + } + + // Permission validation. + $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course); + $context = context_module::instance($cm->id); + self::validate_context($context); + + // Determine groupid and userid to use. + list($groupid, $userid) = self::determine_group_and_user($cm, $wiki, $params['groupid'], $params['userid']); + + // Get subwiki and validate it. + $subwiki = wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid); + + if ($subwiki === false) { + // User cannot view page. + throw new moodle_exception('cannoteditpage', 'wiki'); + } else if ($subwiki->id < 0) { + // Subwiki needed to check edit permissions. + if (!wiki_user_can_edit($subwiki)) { + throw new moodle_exception('cannoteditpage', 'wiki'); + } + + // Subwiki does not exists and it can be created. + $swid = wiki_add_subwiki($wiki->id, $groupid, $userid); + if (!$subwiki = wiki_get_subwiki($swid)) { + throw new moodle_exception('incorrectsubwikiid', 'wiki'); + } + } + } + + // Subwiki needed to check edit permissions. + if (!wiki_user_can_edit($subwiki)) { + throw new moodle_exception('cannoteditpage', 'wiki'); + } + + if ($page = wiki_get_page_by_title($subwiki->id, $params['title'])) { + throw new moodle_exception('pageexists', 'wiki'); + } + + // Ignore invalid formats and use default instead. + if (!$params['contentformat'] || $wiki->forceformat) { + $params['contentformat'] = $wiki->defaultformat; + } else { + $formats = wiki_get_formats(); + if (!in_array($params['contentformat'], $formats)) { + $params['contentformat'] = $wiki->defaultformat; + } + } + + $newpageid = wiki_create_page($subwiki->id, $params['title'], $params['contentformat'], $USER->id); + + if (!$page = wiki_get_page($newpageid)) { + throw new moodle_exception('incorrectpageid', 'wiki'); + } + + // Save content. + $save = wiki_save_page($page, $params['content'], $USER->id); + + if (!$save) { + throw new moodle_exception('savingerror', 'wiki'); + } + + $result = array(); + $result['pageid'] = $page->id; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Describes the new_page return value. + * + * @return external_single_structure + * @since Moodle 3.1 + */ + public static function new_page_returns() { + return new external_single_structure( + array( + 'pageid' => new external_value(PARAM_INT, 'New page id.'), + 'warnings' => new external_warnings() + ) + ); + } + } diff --git a/mod/wiki/db/services.php b/mod/wiki/db/services.php index f3aba0c8b60..7aa2968b5fc 100644 --- a/mod/wiki/db/services.php +++ b/mod/wiki/db/services.php @@ -96,5 +96,14 @@ $functions = array( 'type' => 'write', 'capabilities' => 'mod/wiki:editpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) + ), + + 'mod_wiki_new_page' => array( + 'classname' => 'mod_wiki_external', + 'methodname' => 'new_page', + 'description' => 'Create a new page in a subwiki.', + 'type' => 'write', + 'capabilities' => 'mod/wiki:editpage', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ) ); diff --git a/mod/wiki/lang/en/wiki.php b/mod/wiki/lang/en/wiki.php index 3b9b707060b..8e95be3221b 100644 --- a/mod/wiki/lang/en/wiki.php +++ b/mod/wiki/lang/en/wiki.php @@ -183,7 +183,7 @@ $string['page-mod-wiki-view'] = 'Wiki module main page'; $string['page-mod-wiki-comments'] = 'Wiki module comments page'; $string['page-mod-wiki-history'] = 'Wiki history page'; $string['page-mod-wiki-map'] = 'Wiki map page'; -$string['pageexists'] = 'This page already exists. Redirecting to it.'; +$string['pageexists'] = 'This page already exists.'; $string['pageindex'] = 'Page Index'; $string['pageindex_help'] = 'This wiki\'s page tree'; $string['pageislocked'] = 'Someone is editing this page right now. Try to edit it in a few minutes.'; diff --git a/mod/wiki/tests/externallib_test.php b/mod/wiki/tests/externallib_test.php index aeab484d988..1abc2c7dc1c 100644 --- a/mod/wiki/tests/externallib_test.php +++ b/mod/wiki/tests/externallib_test.php @@ -1167,4 +1167,76 @@ class mod_wiki_external_testcase extends externallib_advanced_testcase { $this->assertEquals($expected, $result['pagesection']); } + /** + * Test new_page. We won't test all the possible cases because that's already + * done in the tests for wiki_create_page. + */ + public function test_new_page() { + + $this->create_individual_wikis_with_groups(); + + $sectioncontent = '

Title1

Text inside section'; + $pagecontent = $sectioncontent.'

Title2

Text inside section'; + $pagetitle = 'Page Title'; + + // Test user with full capabilities. + $this->setUser($this->student); + + // Test on existing subwiki. + $result = mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', $this->fpsepg1indstu->subwikiid); + $result = external_api::clean_returnvalue(mod_wiki_external::new_page_returns(), $result); + $this->assertInternalType('int', $result['pageid']); + + $version = wiki_get_current_version($result['pageid']); + $this->assertEquals($pagecontent, $version->content); + $this->assertEquals('html', $version->contentformat); + + $page = wiki_get_page($result['pageid']); + $this->assertEquals($pagetitle, $page->title); + + // Test existing page creation. + try { + mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', $this->fpsepg1indstu->subwikiid); + $this->fail('Exception expected due to creation of an existing page.'); + } catch (moodle_exception $e) { + $this->assertEquals('pageexists', $e->errorcode); + } + + // Test on non existing subwiki. Add student to group2 to have a new subwiki to be created. + $this->getDataGenerator()->create_group_member(array('userid' => $this->student->id, 'groupid' => $this->group2->id)); + $result = mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', null, $this->wikisepind->id, $this->student->id, + $this->group2->id); + $result = external_api::clean_returnvalue(mod_wiki_external::new_page_returns(), $result); + $this->assertInternalType('int', $result['pageid']); + + $version = wiki_get_current_version($result['pageid']); + $this->assertEquals($pagecontent, $version->content); + $this->assertEquals('html', $version->contentformat); + + $page = wiki_get_page($result['pageid']); + $this->assertEquals($pagetitle, $page->title); + + $subwiki = wiki_get_subwiki($page->subwikiid); + $expected = new StdClass(); + $expected->id = $subwiki->id; + $expected->wikiid = $this->wikisepind->id; + $expected->groupid = $this->group2->id; + $expected->userid = $this->student->id; + $this->assertEquals($expected, $subwiki); + + // Check page creation for a user not in course. + $this->studentnotincourse = self::getDataGenerator()->create_user(); + $this->anothercourse = $this->getDataGenerator()->create_course(); + $this->groupnotincourse = $this->getDataGenerator()->create_group(array('courseid' => $this->anothercourse->id)); + + try { + mod_wiki_external::new_page($pagetitle, $pagecontent, 'html', null, $this->wikisepind->id, + $this->studentnotincourse->id, $this->groupnotincourse->id); + $this->fail('Exception expected due to creation of an invalid subwiki creation.'); + } catch (moodle_exception $e) { + $this->assertEquals('cannoteditpage', $e->errorcode); + } + + } + }