implementing web service support
authorcaiobdoneda <caio.doneda@grad.ufsc.br>
Sun, 22 May 2016 18:22:48 +0000 (14:22 -0400)
committercaiobdoneda <caio.doneda@grad.ufsc.br>
Sun, 22 May 2016 18:24:12 +0000 (14:24 -0400)
classes/attendance_webservices_handler.php [new file with mode: 0644]
db/services.php [new file with mode: 0644]
externallib.php [new file with mode: 0644]
tests/attendance_webservices_test.php [new file with mode: 0644]
version.php

diff --git a/classes/attendance_webservices_handler.php b/classes/attendance_webservices_handler.php
new file mode 100644 (file)
index 0000000..d7fdd5a
--- /dev/null
@@ -0,0 +1,130 @@
+<?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/>.
+/**
+ *
+ * @package    local_attendance
+ * @copyright  2015 Caio Bressan Doneda
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__).'/../../../config.php');
+require_once(dirname(__FILE__).'/../locallib.php');
+require_once(dirname(__FILE__).'/structure.php');
+require_once(dirname(__FILE__).'/../../../lib/sessionlib.php');
+require_once(dirname(__FILE__).'/../../../lib/datalib.php');
+
+class attendance_handler {
+    /**
+     * For this user, this method searches in all the courses that this user has permission to take attendance,
+     * looking for today sessions and returns the courses with the sessions.
+     */
+    public static function get_courses_with_today_sessions($userid) {
+        $usercourses = enrol_get_users_courses($userid);
+        $attendanceinstance = get_all_instances_in_courses('attendance', $usercourses);
+
+        $coursessessions = array();
+
+        foreach ($attendanceinstance as $attendance) {
+            $context = context_course::instance($attendance->course);
+            if (has_capability('mod/attendance:takeattendances', $context, $userid)) {
+                $course = $usercourses[$attendance->course];
+                $course->attendance_instance = array();
+
+                $att = new stdClass();
+                $att->id = $attendance->id;
+                $att->course = $attendance->course;
+                $att->name = $attendance->name;
+                $att->grade = $attendance->grade;
+
+                $cm = new stdClass();
+                $cm->id = $attendance->coursemodule;
+
+                $att = new mod_attendance_structure($att, $cm, $course, $context);
+                $course->attendance_instance[$att->id] = array();
+                $course->attendance_instance[$att->id]['name'] = $att->name;
+                $todaysessions = $att->get_today_sessions();
+
+                if (!empty($todaysessions)) {
+                    $course->attendance_instance[$att->id]['today_sessions'] = $todaysessions;
+                    $coursessessions[$course->id] = $course;
+                }
+            }
+        }
+
+        return self::prepare_data($coursessessions);
+    }
+
+    private static function prepare_data($coursessessions) {
+        $courses = array();
+
+        foreach ($coursessessions as $c) {
+            $courses[$c->id] = new stdClass();
+            $courses[$c->id]->shortname = $c->shortname;
+            $courses[$c->id]->fullname = $c->fullname;
+            $courses[$c->id]->attendance_instances = $c->attendance_instance;
+        }
+
+        return $courses;
+    }
+
+    /*
+     ** For this session, returns all the necessary data to take an attendance
+     */
+    public static function get_session($sessionid) {
+        global $DB;
+
+        $session = $DB->get_record('attendance_sessions', array('id' => $sessionid));
+        $session->courseid = $DB->get_field('attendance', 'course', array('id' => $session->attendanceid));
+        $session->statuses = attendance_get_statuses($session->attendanceid, true, $session->statusset);
+        $coursecontext = context_course::instance($session->courseid);
+        $session->users = get_enrolled_users($coursecontext, 'mod/attendance:canbelisted', 0, 'u.id, u.firstname, u.lastname');
+        $session->attendance_log = array();
+
+        if ($attendancelog = $DB->get_records('attendance_log', array('sessionid' => $sessionid),
+                                              '', 'studentid, statusid, remarks, id')) {
+            $session->attendance_log = $attendancelog;
+        }
+
+        return $session;
+    }
+
+    public static function update_user_status($sessionid, $studentid, $takenbyid, $statusid, $statusset) {
+        global $DB;
+
+        $record = new stdClass();
+        $record->statusset = $statusset;
+        $record->sessionid = $sessionid;
+        $record->timetaken = time();
+        $record->takenby = $takenbyid;
+        $record->statusid = $statusid;
+        $record->studentid = $studentid;
+
+        if ($attendancelog = $DB->get_record('attendance_log', array('sessionid' => $sessionid, 'studentid' => $studentid))) {
+            $record->id = $attendancelog->id;
+            $DB->update_record('attendance_log', $record);
+        } else {
+            $DB->insert_record('attendance_log', $record);
+        }
+
+        if ($attendancesession = $DB->get_record('attendance_sessions', array('id' => $sessionid))) {
+            $attendancesession->lasttaken = time();
+            $attendancesession->lasttakenby = $takenbyid;
+            $attendancesession->timemodified = time();
+
+            $DB->update_record('attendance_sessions', $attendancesession);
+        }
+    }
+}
diff --git a/db/services.php b/db/services.php
new file mode 100644 (file)
index 0000000..ef9ce5f
--- /dev/null
@@ -0,0 +1,59 @@
+<?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/>.
+
+/**
+ * Web service local plugin attendance external functions and service definitions.
+ *
+ * @package    localwsattendance
+ * @copyright  2015 Caio Bressan Doneda
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+    /**
+     * We defined the web service functions to install.
+     */
+    $functions = array(
+        'mod_wsattendance_get_courses_with_today_sessions' => array(
+            'classname'   => 'mod_wsattendance_external',
+            'methodname'  => 'get_courses_with_today_sessions',
+            'classpath'   => 'mod/attendance/externallib.php',
+            'description' => 'Method that retrieves courses with today sessions of a teacher.',
+            'type'        => 'read',
+        ),
+        'mod_wsattendance_get_session' => array(
+            'classname'   => 'mod_wsattendance_external',
+            'methodname'  => 'get_session',
+            'classpath'   => 'mod/attendance/externallib.php',
+            'description' => 'Method that retrieves the session data',
+            'type'        => 'read',
+        ),
+
+        'mod_wsattendance_update_user_status' => array(
+            'classname'   => 'mod_wsattendance_external',
+            'methodname'  => 'update_user_status',
+            'classpath'   => 'mod/attendance/externallib.php',
+            'description' => 'Method that updates the user status in a session.',
+            'type'        => 'write',
+        )
+    );
+
+
+    // We define the services to install as pre-build services. A pre-build service is not editable by administrator.
+    $services = array('Attendance' => array('functions' => array('mod_wsattendance_get_courses_with_today_sessions',
+                   'mod_wsattendance_get_session',
+                   'mod_wsattendance_update_user_status'),
+                   'restrictedusers' => 0,
+                   'enabled' => 1));
diff --git a/externallib.php b/externallib.php
new file mode 100644 (file)
index 0000000..eabe7ee
--- /dev/null
@@ -0,0 +1,124 @@
+<?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/>.
+/**
+ *
+ * @package    local_attendance
+ * @copyright  2015 Caio Bressan Doneda
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+require_once("$CFG->libdir/externallib.php");
+require_once(dirname(__FILE__).'/classes/attendance_webservices_handler.php');
+
+class mod_wsattendance_external extends external_api {
+
+    public static function get_courses_with_today_sessions_parameters() {
+        return new external_function_parameters (
+                    array('userid' => new external_value(PARAM_INT, 'User id.',  VALUE_DEFAULT, 0)));
+    }
+
+    public static function get_courses_with_today_sessions($userid) {
+        return attendance_handler::get_courses_with_today_sessions($userid);
+    }
+
+    private static function get_session_structure() {
+        $session = array('id' => new external_value(PARAM_INT, 'Session id.'),
+                         'attendanceid' => new external_value(PARAM_INT, 'Attendance id.'),
+                         'groupid' => new external_value(PARAM_INT, 'Group id.'),
+                         'sessdate' => new external_value(PARAM_INT, 'Session date.'),
+                         'duration' => new external_value(PARAM_INT, 'Session duration.'),
+                         'lasttaken' => new external_value(PARAM_INT, 'Session last taken time.'),
+                         'lasttakenby' => new external_value(PARAM_INT, 'ID of the last user that took this session.'),
+                         'timemodified' => new external_value(PARAM_INT, 'Time modified.'),
+                         'description' => new external_value(PARAM_TEXT, 'Session description.'),
+                         'descriptionformat' => new external_value(PARAM_INT, 'Session description format.'),
+                         'studentscanmark' => new external_value(PARAM_INT, 'Students can mark their own presence.'),
+                         'statusset' => new external_value(PARAM_INT, 'Session statusset.'));
+
+        return $session;
+    }
+
+    public static function get_courses_with_today_sessions_returns() {
+        $todaysessions = self::get_session_structure();
+
+        $attendanceinstances = array('name' => new external_value(PARAM_TEXT, 'Attendance name.'),
+                                      'today_sessions' => new external_multiple_structure(
+                                                          new external_single_structure($todaysessions)));
+
+        $courses = array('shortname' => new external_value(PARAM_TEXT, 'short name of a moodle course.'),
+                         'fullname' => new external_value(PARAM_TEXT, 'full name of a moodle course.'),
+                         'attendance_instances' => new external_multiple_structure(
+                                                   new external_single_structure($attendanceinstances)));
+
+        return new external_multiple_structure(new external_single_structure(($courses)));
+    }
+
+    public static function get_session_parameters() {
+        return new external_function_parameters (
+                    array('sessionid' => new external_value(PARAM_INT, 'session id')));
+    }
+
+    public static function get_session($sessionid) {
+        return attendance_handler::get_session($sessionid);
+    }
+
+    public static function get_session_returns() {
+        $statuses = array('id' => new external_value(PARAM_INT, 'Status id.'),
+                          'attendanceid' => new external_value(PARAM_INT, 'Attendance id.'),
+                          'acronym' => new external_value(PARAM_TEXT, 'Status acronym.'),
+                          'description' => new external_value(PARAM_TEXT, 'Status description.'),
+                          'grade' => new external_value(PARAM_FLOAT, 'Status grade.'),
+                          'visible' => new external_value(PARAM_INT, 'Status visibility.'),
+                          'deleted' => new external_value(PARAM_INT, 'informs if this session was deleted.'),
+                          'setnumber' => new external_value(PARAM_INT, 'Set number.'));
+
+        $users = array('id' => new external_value(PARAM_INT, 'User id.'),
+                       'firstname' => new external_value(PARAM_TEXT, 'User first name.'),
+                       'lastname' => new external_value(PARAM_TEXT, 'User last name.'));
+
+        $attendancelog = array('studentid' => new external_value(PARAM_INT, 'Student id.'),
+                                'statusid' => new external_value(PARAM_TEXT, 'Status id (last time).'),
+                                'remarks' => new external_value(PARAM_TEXT, 'Last remark.'),
+                                'id' => new external_value(PARAM_TEXT, 'log id.'));
+
+        $session = self::get_session_structure();
+        $session['courseid'] = new external_value(PARAM_INT, 'Course moodle id.');
+        $session['statuses'] = new external_multiple_structure(new external_single_structure($statuses));
+        $session['attendance_log'] = new external_multiple_structure(new external_single_structure($attendancelog));
+        $session['users'] = new external_multiple_structure(new external_single_structure($users));
+
+        return new external_single_structure($session);
+    }
+
+    public static function update_user_status_parameters() {
+        return new external_function_parameters(
+                    array('sessionid' => new external_value(PARAM_INT, 'Session id'),
+                          'studentid' => new external_value(PARAM_INT, 'Student id'),
+                          'takenbyid' => new external_value(PARAM_INT, 'Id of the user who took this session'),
+                          'statusid' => new external_value(PARAM_INT, 'Status id'),
+                          'statusset' => new external_value(PARAM_TEXT, 'Status set of session')));
+    }
+
+    public static function update_user_status($sessionid, $studentid, $takenbyid, $statusid, $statusset) {
+        return attendance_handler::update_user_status($sessionid, $studentid, $takenbyid, $statusid, $statusset);
+    }
+
+    public static function update_user_status_returns() {
+        return new external_value(PARAM_TEXT, 'Http code');
+    }
+}
diff --git a/tests/attendance_webservices_test.php b/tests/attendance_webservices_test.php
new file mode 100644 (file)
index 0000000..cd3c364
--- /dev/null
@@ -0,0 +1,148 @@
+<?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/>.
+/**
+ *
+ * @package    local_attendance
+ * @copyright  2015 Caio Bressan Doneda
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');
+}
+
+global $CFG;
+
+// Include the code to test.
+require_once($CFG->dirroot . '/mod/attendance/classes/attendance_webservices_handler.php');
+require_once($CFG->dirroot . '/mod/attendance/classes/structure.php');
+
+/** This class contains the test cases for the functions in attendance_webservices_handler.php. */
+class attendance_webservices_tests extends advanced_testcase {
+    protected $category;
+    protected $course;
+    protected $attendance;
+    protected $teacher;
+    protected $sessions;
+
+    public function setUp() {
+        global $DB;
+
+        $this->category = $this->getDataGenerator()->create_category();
+        $this->course = $this->getDataGenerator()->create_course(array('category' => $this->category->id));
+
+        $record = new stdClass();
+        $record->course = $this->course->id;
+        $record->name = "Attendance";
+        $record->grade = 100;
+
+        $DB->insert_record('attendance', $record);
+
+        $this->getDataGenerator()->create_module('attendance', array('course' => $this->course->id));
+
+        $moduleid = $DB->get_field('modules', 'id', array('name' => 'attendance'));
+        $cm = $DB->get_record('course_modules', array('course' => $this->course->id, 'module' => $moduleid));
+        $context = context_course::instance($this->course->id);
+        $att = $DB->get_record('attendance', array('id' => $cm->instance), '*', MUST_EXIST);
+        $this->attendance = new mod_attendance_structure($att, $cm, $this->course, $context);
+
+        $this->create_and_enrol_users();
+
+        $this->setUser($this->teacher);
+
+        $sessions = array();
+        $session = new stdClass();
+        $session->sessdate = time();
+        $session->duration = 6000;
+        $session->description = "";
+        $session->descriptionformat = 1;
+        $session->descriptionitemid = 0;
+        $session->timemodified = time();
+        $session->statusset = 0;
+        $session->groupid = 0;
+
+        // Creating two sessions.
+        $this->sessions[] = $session;
+
+        $this->attendance->add_sessions($this->sessions);
+    }
+
+    /** Creating 10 students and 1 teacher. */
+    protected function create_and_enrol_users() {
+        for ($i = 0; $i < 10; $i++) {
+            $student = $this->getDataGenerator()->create_user();
+            $this->getDataGenerator()->enrol_user($student->id, $this->course->id, 5); // Enrol as student.
+        }
+
+        $this->teacher = $this->getDataGenerator()->create_user();
+        $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, 3); // Enrol as teacher.
+    }
+
+    public function test_get_courses_with_today_sessions() {
+        $this->resetAfterTest(true);
+
+        // Just adding the same session again to check if the method returns the right amount of instances.
+        $this->attendance->add_sessions($this->sessions);
+
+        $courseswithsessions = attendance_handler::get_courses_with_today_sessions($this->teacher->id);
+
+        $this->assertTrue(is_array($courseswithsessions));
+        $this->assertEquals(count($courseswithsessions), 1);
+        $course = array_pop($courseswithsessions);
+        $this->assertEquals($course->fullname, $this->course->fullname);
+        $attendanceinstance = array_pop($course->attendance_instances);
+        $this->assertEquals(count($attendanceinstance['today_sessions']), 2);
+    }
+
+    public function test_get_session() {
+        $this->resetAfterTest(true);
+
+        $courseswithsessions = attendance_handler::get_courses_with_today_sessions($this->teacher->id);
+
+        $course = array_pop($courseswithsessions);
+        $attendanceinstance = array_pop($course->attendance_instances);
+        $session = array_pop($attendanceinstance['today_sessions']);
+
+        $sessioninfo = attendance_handler::get_session($session->id);
+
+        $this->assertEquals($this->attendance->id, $sessioninfo->attendanceid);
+        $this->assertEquals($session->id, $sessioninfo->id);
+        $this->assertEquals(count($sessioninfo->users), 10);
+    }
+
+    public function test_update_user_status() {
+        $this->resetAfterTest(true);
+
+        $courseswithsessions = attendance_handler::get_courses_with_today_sessions($this->teacher->id);
+
+        $course = array_pop($courseswithsessions);
+        $attendanceinstance = array_pop($course->attendance_instances);
+        $session = array_pop($attendanceinstance['today_sessions']);
+
+        $sessioninfo = attendance_handler::get_session($session->id);
+
+        $student = array_pop($sessioninfo->users);
+        $status = array_pop($sessioninfo->statuses);
+        $statusset = $sessioninfo->statusset;
+        attendance_handler::update_user_status($session->id, $student->id, $this->teacher->id, $status->id, $statusset);
+
+        $sessioninfo = attendance_handler::get_session($session->id);
+        $log = $sessioninfo->attendance_log;
+        $studentlog = $log[$student->id];
+
+        $this->assertEquals($status->id, $studentlog->statusid);
+    }
+}
index 0dfd611..8d75817 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$plugin->version  = 2016052000;
+$plugin->version  = 2016052200;
 $plugin->requires = 2015051100;
 $plugin->release = '3.1.0.2';
 $plugin->maturity  = MATURITY_STABLE;
 $plugin->cron     = 0;
 $plugin->component = 'mod_attendance';
-