MDL-53791 mod_wiki: New Web Service edit_page
authorPau Ferrer Ocaña <crazyserver@gmail.com>
Thu, 14 Apr 2016 08:15:50 +0000 (10:15 +0200)
committerPau Ferrer Ocaña <crazyserver@gmail.com>
Tue, 26 Apr 2016 06:25:16 +0000 (08:25 +0200)
mod/wiki/classes/external.php
mod/wiki/db/services.php
mod/wiki/tests/externallib_test.php

index 957a668..4d8f00b 100644 (file)
@@ -1075,4 +1075,109 @@ class mod_wiki_external extends external_api {
         );
     }
 
+    /**
+     * Describes the parameters for edit_page.
+     *
+     * @return external_function_parameters
+     * @since Moodle 3.1
+     */
+    public static function edit_page_parameters() {
+        return new external_function_parameters (
+            array(
+                'pageid' => new external_value(PARAM_INT, 'Page ID.'),
+                'content' => new external_value(PARAM_RAW, 'Page contents.'),
+                'section' => new external_value(PARAM_TEXT, 'Section page title.', VALUE_DEFAULT, null)
+            )
+        );
+    }
+
+    /**
+     * Edit a page contents.
+     *
+     * @param int $pageid The page ID.
+     * @param string $content Page contents.
+     * @param int $section Section to be edited.
+     * @return array of warnings and page data.
+     * @since Moodle 3.1
+     */
+    public static function edit_page($pageid, $content, $section = null) {
+        global $USER;
+
+        $params = self::validate_parameters(self::edit_page_parameters(),
+                                            array(
+                                                'pageid' => $pageid,
+                                                'content' => $content,
+                                                'section' => $section
+                                            )
+            );
+        $warnings = array();
+
+        // Get wiki page.
+        if (!$page = wiki_get_page($params['pageid'])) {
+            throw new moodle_exception('incorrectpageid', 'wiki');
+        }
+
+        // Get wiki instance.
+        if (!$wiki = wiki_get_wiki_from_pageid($params['pageid'])) {
+            throw new moodle_exception('incorrectwikiid', 'wiki');
+        }
+
+        // Get subwiki instance.
+        if (!$subwiki = wiki_get_subwiki($page->subwikiid)) {
+            throw new moodle_exception('incorrectsubwikiid', 'wiki');
+        }
+
+        // Permission validation.
+        $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course);
+        $context = context_module::instance($cm->id);
+        self::validate_context($context);
+
+        if (!wiki_user_can_edit($subwiki)) {
+            throw new moodle_exception('cannoteditpage', 'wiki');
+        }
+
+        if (wiki_is_page_section_locked($page->id, $USER->id, $params['section'])) {
+            throw new moodle_exception('pageislocked', 'wiki');
+        }
+
+        // Save content.
+        if (!is_null($params['section'])) {
+            $version = wiki_get_current_version($page->id);
+            $content = wiki_parser_proxy::get_section($version->content, $version->contentformat, $params['section'], false);
+            if (!$content) {
+                throw new moodle_exception('invalidsection', 'wiki');
+            }
+
+            $save = wiki_save_section($page, $params['section'], $params['content'], $USER->id);
+        } else {
+            $save = wiki_save_page($page, $params['content'], $USER->id);
+        }
+
+        wiki_delete_locks($page->id, $USER->id, $params['section']);
+
+        if (!$save) {
+            throw new moodle_exception('savingerror', 'wiki');
+        }
+
+        $result = array();
+        $result['pageid'] = $page->id;
+        $result['warnings'] = $warnings;
+        return $result;
+    }
+
+    /**
+     * Describes the edit_page return value.
+     *
+     * @return external_single_structure
+     * @since Moodle 3.1
+     */
+    public static function edit_page_returns() {
+        return new external_single_structure(
+            array(
+                'pageid' => new external_value(PARAM_INT, 'Edited page id.'),
+                'warnings' => new external_warnings()
+            )
+        );
+    }
+
 }
index 7aa2968..90e3eb8 100644 (file)
@@ -105,5 +105,14 @@ $functions = array(
         'type'          => 'write',
         'capabilities'  => 'mod/wiki:editpage',
         'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
+    ),
+
+    'mod_wiki_edit_page' => array(
+        'classname'     => 'mod_wiki_external',
+        'methodname'    => 'edit_page',
+        'description'   => 'Save the contents of a page.',
+        'type'          => 'write',
+        'capabilities'  => 'mod/wiki:editpage',
+        'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
     )
 );
index 1abc2c7..3cb4e83 100644 (file)
@@ -1239,4 +1239,68 @@ class mod_wiki_external_testcase extends externallib_advanced_testcase {
 
     }
 
+    /**
+     * Test edit_page. We won't test all the possible cases because that's already
+     * done in the tests for wiki_save_section / wiki_save_page.
+     */
+    public function test_edit_page() {
+
+        $this->create_individual_wikis_with_groups();
+
+        // Test user with full capabilities.
+        $this->setUser($this->student);
+
+        $newpage = $this->getDataGenerator()->get_plugin_generator('mod_wiki')->create_page($this->wikisepind,
+            array('group' => $this->group1->id, 'content' => 'Test'));
+
+        // Test edit whole page.
+        $sectioncontent = '<h1>Title1</h1>Text inside section';
+        $newpagecontent = $sectioncontent.'<h1>Title2</h1>Text inside section';
+
+        $result = mod_wiki_external::edit_page($newpage->id, $newpagecontent);
+        $result = external_api::clean_returnvalue(mod_wiki_external::edit_page_returns(), $result);
+        $this->assertInternalType('int', $result['pageid']);
+
+        $version = wiki_get_current_version($result['pageid']);
+        $this->assertEquals($newpagecontent, $version->content);
+
+        // Test edit section.
+        $newsectioncontent = '<h1>Title2</h1>New test2';
+        $section = 'Title2';
+
+        $result = mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
+        $result = external_api::clean_returnvalue(mod_wiki_external::edit_page_returns(), $result);
+        $this->assertInternalType('int', $result['pageid']);
+
+        $expected = $sectioncontent . $newsectioncontent;
+
+        $version = wiki_get_current_version($result['pageid']);
+        $this->assertEquals($expected, $version->content);
+
+        // Test locked section.
+        $newsectioncontent = '<h1>Title2</h1>New test2';
+        $section = 'Title2';
+
+        try {
+            // Using user 1 to avoid other users to edit.
+            wiki_set_lock($newpage->id, 1, $section, true);
+            mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
+            $this->fail('Exception expected due to locked section');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('pageislocked', $e->errorcode);
+        }
+
+        // Test edit non existing section.
+        $newsectioncontent = '<h1>Title3</h1>New test3';
+        $section = 'Title3';
+
+        try {
+            mod_wiki_external::edit_page($newpage->id, $newsectioncontent, $section);
+            $this->fail('Exception expected due to non existing section in the page.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('invalidsection', $e->errorcode);
+        }
+
+    }
+
 }