Permalink
Browse files

MDL-37247 mod_forum: adding webservice function to allow for the retr…

…ieval of forum instances
  • Loading branch information...
1 parent 9da506c commit 2b9fe87dcad443f799e6f19ab59209ea6792a5b4 @markn86 markn86 committed Dec 12, 2012
Showing with 332 additions and 1 deletion.
  1. +38 −0 mod/forum/db/services.php
  2. +150 −0 mod/forum/externallib.php
  3. +143 −0 mod/forum/tests/externallib_test.php
  4. +1 −1 mod/forum/version.php
@@ -0,0 +1,38 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Forum external functions and service definitions.
+ *
+ * @package mod_forum
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$functions = array(
+
+ 'mod_forum_get_forums_by_courses' => array(
+ 'classname' => 'mod_forum_external',
+ 'methodname' => 'get_forums_by_courses',
+ 'classpath' => 'mod/forum/externallib.php',
+ 'description' => 'Returns a list of forum instances in a provided set of courses, if
+ no courses are provided then all the forum instances the user has access to will be
+ returned.',
+ 'type' => 'read',
+ 'capabilities' => 'mod/forum:viewdiscussion'
+ )
+);
@@ -0,0 +1,150 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * External forum API
+ *
+ * @package mod_forum
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+require_once("$CFG->libdir/externallib.php");
+
+class mod_forum_external extends external_api {
+
+ /**
+ * Describes the parameters for get_forum
+ *
+ * @return external_external_function_parameters
+ * @since Moodle 2.5
+ */
+ public static function get_forums_by_courses_parameters() {
+ return new external_function_parameters (
+ array(
+ 'courseids' => new external_multiple_structure(new external_value(PARAM_INT, 'course ID',
+ '', VALUE_REQUIRED, '', NULL_NOT_ALLOWED), 'Array of course IDs', VALUE_DEFAULT, array()),
+ )
+ );
+ }
+
+ /**
+ * Returns a list of forums in a provided list of courses,
+ * if no list is provided all forums that the user can view
+ * will be returned.
+ *
+ * @param array $courseids the course ids
+ * @return array the forum details
+ * @since Moodle 2.5
+ */
+ public static function get_forums_by_courses($courseids = array()) {
+ global $CFG, $DB, $USER;
+
+ require_once($CFG->dirroot . "/mod/forum/lib.php");
+
+ if (empty($courseids)) {
+ // Get all the courses the user can view.
+ $courseids = array_keys(enrol_get_my_courses());
+ } else {
+ $params = self::validate_parameters(self::get_forums_by_courses_parameters(), array('courseids' => $courseids));
+ $courseids = $params['courseids'];
+ }
+
+ // Array to store the forums to return.
+ $arrforums = array();
+
+ // Go through the courseids and return the forums.
+ if (!empty($courseids)) {
+ // Keep track of the course ids we have performed a require_course_login check on to avoid repeating.
+ $arrcourseschecked = array();
+ // Convert array to string to use in query.
+ list($subsql, $params) = $DB->get_in_or_equal($courseids);
+ $sql = "SELECT *
+ FROM {forum}
+ WHERE course $subsql";
+ if ($forums = $DB->get_records_sql($sql, $params)) {
+ foreach ($forums as $forum) {
+ // Check that that user can view this course if check not performed yet.
+ if (!in_array($forum->course, $arrcourseschecked)) {
+ // Get the course context.
+ $context = context_course::instance($forum->course);
+ // Check the user can function in this context.
+ self::validate_context($context);
+ // Add to the array.
+ $arrcourseschecked[] = $forum->course;
+ }
+ // Get the course module.
+ $cm = get_coursemodule_from_instance('forum', $forum->id, 0, false, MUST_EXIST);
+ // Get the module context.
+ $context = context_module::instance($cm->id);
+ // Check they have the view forum capability.
+ require_capability('mod/forum:viewdiscussion', $context);
+ // Format the intro before being returning using the format setting.
+ list($forum->intro, $forum->introformat) = external_format_text($forum->intro, $forum->introformat,
+ $context->id, 'mod_forum', 'intro', 0);
+ // Add the course module id to the object, this information is useful.
+ $forum->cmid = $cm->id;
+ // Add the forum to the array to return.
+ $arrforums[$forum->id] = (array) $forum;
+ }
+ }
+ }
+
+ return $arrforums;
+ }
+
+ /**
+ * Describes the get_forum return value
+ *
+ * @return external_single_structure
+ * @since Moodle 2.5
+ */
+ public static function get_forums_by_courses_returns() {
+ return new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'id' => new external_value(PARAM_INT, 'Forum id'),
+ 'course' => new external_value(PARAM_TEXT, 'Course id'),
+ 'type' => new external_value(PARAM_TEXT, 'The forum type'),
+ 'name' => new external_value(PARAM_TEXT, 'Forum name'),
+ 'intro' => new external_value(PARAM_RAW, 'The forum intro'),
+ 'introformat' => new external_format_value('intro'),
+ 'assessed' => new external_value(PARAM_INT, 'Aggregate type'),
+ 'assesstimestart' => new external_value(PARAM_INT, 'Assess start time'),
+ 'assesstimefinish' => new external_value(PARAM_INT, 'Assess finish time'),
+ 'scale' => new external_value(PARAM_INT, 'Scale'),
+ 'maxbytes' => new external_value(PARAM_INT, 'Maximum attachment size'),
+ 'maxattachments' => new external_value(PARAM_INT, 'Maximum number of attachments'),
+ 'forcesubscribe' => new external_value(PARAM_INT, 'Force users to subscribe'),
+ 'trackingtype' => new external_value(PARAM_INT, 'Subscription mode'),
+ 'rsstype' => new external_value(PARAM_INT, 'RSS feed for this activity'),
+ 'rssarticles' => new external_value(PARAM_INT, 'Number of RSS recent articles'),
+ 'timemodified' => new external_value(PARAM_INT, 'Time modified'),
+ 'warnafter' => new external_value(PARAM_INT, 'Post threshold for warning'),
+ 'blockafter' => new external_value(PARAM_INT, 'Post threshold for blocking'),
+ 'blockperiod' => new external_value(PARAM_INT, 'Time period for blocking'),
+ 'completiondiscussions' => new external_value(PARAM_INT, 'Student must create discussions'),
+ 'completionreplies' => new external_value(PARAM_INT, 'Student must post replies'),
+ 'completionposts' => new external_value(PARAM_INT, 'Student must post discussions or replies'),
+ 'cmid' => new external_value(PARAM_INT, 'Course module id')
+ ), 'forum'
+ )
+ );
+ }
+}
@@ -0,0 +1,143 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * The module forums external functions unit tests
+ *
+ * @package mod_forum
+ * @category external
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+require_once($CFG->dirroot . '/webservice/tests/helpers.php');
+
+class mod_forum_external_testcase extends externallib_advanced_testcase {
+
+ /**
+ * Tests set up
+ */
+ protected function setUp() {
+ global $CFG;
+
+ require_once($CFG->dirroot . '/mod/forum/externallib.php');
+ }
+
+ /**
+ * Test get forums
+ */
+ public function test_mod_forum_get_forums_by_courses() {
+ global $USER, $CFG, $DB;
+
+ $this->resetAfterTest(true);
+
+ // Create a user.
+ $user = self::getDataGenerator()->create_user();
+
+ // Set to the user.
+ self::setUser($user);
+
+ // Create courses to add the modules.
+ $course1 = self::getDataGenerator()->create_course();
+ $course2 = self::getDataGenerator()->create_course();
+
+ // First forum.
+ $record = new stdClass();
+ $record->introformat = FORMAT_HTML;
+ $record->course = $course1->id;
+ $forum1 = self::getDataGenerator()->create_module('forum', $record);
+
+ // Second forum.
+ $record = new stdClass();
+ $record->introformat = FORMAT_HTML;
+ $record->course = $course2->id;
+ $forum2 = self::getDataGenerator()->create_module('forum', $record);
+
+ // Check the forum was correctly created.
+ $this->assertEquals(2, $DB->count_records_select('forum', 'id = :forum1 OR id = :forum2',
+ array('forum1' => $forum1->id, 'forum2' => $forum2->id)));
+
+ // Enrol the user in two courses.
+ // Enrol them in the first course.
+ $enrol = enrol_get_plugin('manual');
+ $enrolinstances = enrol_get_instances($course1->id, true);
+ foreach ($enrolinstances as $courseenrolinstance) {
+ if ($courseenrolinstance->enrol == "manual") {
+ $instance1 = $courseenrolinstance;
+ break;
+ }
+ }
+ $enrol->enrol_user($instance1, $user->id);
+ // Now enrol into the second course.
+ $enrolinstances = enrol_get_instances($course2->id, true);
+ foreach ($enrolinstances as $courseenrolinstance) {
+ if ($courseenrolinstance->enrol == "manual") {
+ $instance2 = $courseenrolinstance;
+ break;
+ }
+ }
+ $enrol->enrol_user($instance2, $user->id);
+
+ // Assign capabilities to view forums for forum 1.
+ $cm1 = get_coursemodule_from_id('forum', $forum1->id, 0, false, MUST_EXIST);
+ $context1 = context_module::instance($cm1->id);
+ $roleid1 = $this->assignUserCapability('mod/forum:viewdiscussion', $context1->id);
+
+ // Assign capabilities to view forums for forum 2.
+ $cm2 = get_coursemodule_from_id('forum', $forum2->id, 0, false, MUST_EXIST);
+ $context2 = context_module::instance($cm2->id);
+ $newrole = create_role('Role 2', 'role2', 'Role 2 description');
+ $roleid2 = $this->assignUserCapability('mod/forum:viewdiscussion', $context2->id, $newrole);
+
+ // Create what we expect to be returned when querying the two courses.
+ $expectedforums = array();
+ $expectedforums[$forum1->id] = (array) $forum1;
+ $expectedforums[$forum2->id] = (array) $forum2;
+
+ // Call the external function passing course ids.
+ $forums = mod_forum_external::get_forums_by_courses(array($course1->id, $course2->id));
+ $this->assertEquals($forums, $expectedforums);
+ external_api::clean_returnvalue(mod_forum_external::get_forums_by_courses_returns(), $forums);
+
+ // Call the external function without passing course id.
+ $forums = mod_forum_external::get_forums_by_courses();
+ $this->assertEquals($forums, $expectedforums);
+ external_api::clean_returnvalue(mod_forum_external::get_forums_by_courses_returns(), $forums);
+
+ // Unenrol user from second course and alter expected forums.
+ $enrol->unenrol_user($instance2, $user->id);
+ unset($expectedforums[$forum2->id]);
+
+ // Call the external function without passing course id.
+ $forums = mod_forum_external::get_forums_by_courses();
+ $this->assertEquals($forums, $expectedforums);
+ external_api::clean_returnvalue(mod_forum_external::get_forums_by_courses_returns(), $forums);
+
+ // Call for the second course we unenrolled the user from, make sure exception thrown.
+ $this->setExpectedException('require_login_exception');
+ mod_forum_external::get_forums_by_courses(array($course2->id));
+
+ // Call without required capability.
+ $this->unassignUserCapability('mod/forum:viewdiscussion', $context->id, $roleid1);
+ $this->setExpectedException('required_capability_exception');
+ mod_forum_external::get_forums_by_courses(array($course1->id));
+ }
+}
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
-$module->version = 2012112900; // The current module version (Date: YYYYMMDDXX)
+$module->version = 2012112901; // The current module version (Date: YYYYMMDDXX)
$module->requires = 2012112900; // Requires this Moodle version
$module->component = 'mod_forum'; // Full name of the plugin (used for diagnostics)
$module->cron = 60;

0 comments on commit 2b9fe87

Please sign in to comment.