Merge branch 'MDL-57648-master' of git://github.com/jleyva/moodle
authorDan Poltawski <dan@moodle.com>
Fri, 17 Mar 2017 08:21:03 +0000 (08:21 +0000)
committerDan Poltawski <dan@moodle.com>
Fri, 17 Mar 2017 08:21:03 +0000 (08:21 +0000)
mod/lesson/classes/external.php
mod/lesson/db/services.php
mod/lesson/tests/external_test.php
mod/lesson/version.php

index 8c7f522..db3e387 100644 (file)
@@ -474,4 +474,100 @@ class mod_lesson_external extends external_api {
         );
     }
 
+    /**
+     * Describes the parameters for get_questions_attempts.
+     *
+     * @return external_external_function_parameters
+     * @since Moodle 3.3
+     */
+    public static function get_questions_attempts_parameters() {
+        return new external_function_parameters (
+            array(
+                'lessonid' => new external_value(PARAM_INT, 'lesson instance id'),
+                'attempt' => new external_value(PARAM_INT, 'lesson attempt number'),
+                'correct' => new external_value(PARAM_BOOL, 'only fetch correct attempts', VALUE_DEFAULT, false),
+                'pageid' => new external_value(PARAM_INT, 'only fetch attempts at the given page', VALUE_DEFAULT, null),
+                'userid' => new external_value(PARAM_INT, 'only fetch attempts of the given user', VALUE_DEFAULT, null),
+            )
+        );
+    }
+
+    /**
+     * Return the list of page question attempts in a given lesson.
+     *
+     * @param int $lessonid lesson instance id
+     * @param int $attempt the lesson attempt number
+     * @param bool $correct only fetch correct attempts
+     * @param int $pageid only fetch attempts at the given page
+     * @param int $userid only fetch attempts of the given user
+     * @return array of warnings and page attempts
+     * @since Moodle 3.3
+     * @throws moodle_exception
+     */
+    public static function get_questions_attempts($lessonid, $attempt, $correct = false, $pageid = null, $userid = null) {
+        global $DB, $USER;
+
+        $params = array(
+            'lessonid' => $lessonid,
+            'attempt' => $attempt,
+            'correct' => $correct,
+            'pageid' => $pageid,
+            'userid' => $userid,
+        );
+        $params = self::validate_parameters(self::get_questions_attempts_parameters(), $params);
+        $warnings = array();
+
+        list($lesson, $course, $cm, $context) = self::validate_lesson($params['lessonid']);
+
+        // Default value for userid.
+        if (empty($params['userid'])) {
+            $params['userid'] = $USER->id;
+        }
+
+        // Extra checks so only users with permissions can view other users attempts.
+        if ($USER->id != $params['userid']) {
+            $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
+            core_user::require_active_user($user);
+            // Check permissions and that if users share group (if groups enabled).
+            require_capability('mod/lesson:viewreports', $context);
+            if (!groups_user_groups_visible($course, $user->id, $cm)) {
+                throw new moodle_exception('notingroup');
+            }
+        }
+
+        $result = array();
+        $result['attempts'] = $lesson->get_attempts($params['attempt'], $params['correct'], $params['pageid'], $params['userid']);
+        $result['warnings'] = $warnings;
+        return $result;
+    }
+
+    /**
+     * Describes the get_questions_attempts return value.
+     *
+     * @return external_single_structure
+     * @since Moodle 3.3
+     */
+    public static function get_questions_attempts_returns() {
+        return new external_single_structure(
+            array(
+                'attempts' => new external_multiple_structure(
+                    new external_single_structure(
+                        array(
+                            'id' => new external_value(PARAM_INT, 'The attempt id'),
+                            'lessonid' => new external_value(PARAM_INT, 'The attempt lessonid'),
+                            'pageid' => new external_value(PARAM_INT, 'The attempt pageid'),
+                            'userid' => new external_value(PARAM_INT, 'The user who did the attempt'),
+                            'answerid' => new external_value(PARAM_INT, 'The attempt answerid'),
+                            'retry' => new external_value(PARAM_INT, 'The lesson attempt number'),
+                            'correct' => new external_value(PARAM_INT, 'If it was the correct answer'),
+                            'useranswer' => new external_value(PARAM_RAW, 'The complete user answer'),
+                            'timeseen' => new external_value(PARAM_INT, 'The time the question was seen'),
+                        ),
+                        'The question page attempts'
+                    )
+                ),
+                'warnings' => new external_warnings(),
+            )
+        );
+    }
 }
index f5c9c76..cea0b30 100644 (file)
@@ -52,4 +52,12 @@ $functions = array(
         'capabilities'  => 'mod/lesson:view',
         'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
     ),
+    'mod_lesson_get_questions_attempts' => array(
+        'classname'     => 'mod_lesson_external',
+        'methodname'    => 'get_questions_attempts',
+        'description'   => 'Return the list of questions attempts in a given lesson.',
+        'type'          => 'read',
+        'capabilities'  => 'mod/lesson:view',
+        'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
+    ),
 );
index 776ce3a..5710497 100644 (file)
@@ -401,4 +401,67 @@ class mod_lesson_external_testcase extends externallib_advanced_testcase {
         mod_lesson_external::view_lesson($this->lesson->id);
     }
 
+    /**
+     * Test for get_questions_attempts
+     */
+    public function test_get_questions_attempts() {
+        global $DB;
+
+        $this->setUser($this->student);
+        $attemptnumber = 1;
+
+        // Test lesson without page attempts.
+        $result = mod_lesson_external::get_questions_attempts($this->lesson->id, $attemptnumber);
+        $result = external_api::clean_returnvalue(mod_lesson_external::get_questions_attempts_returns(), $result);
+        $this->assertCount(0, $result['warnings']);
+        $this->assertCount(0, $result['attempts']);
+
+        // Create a fake attempt for the first possible answer.
+        $p2answers = $DB->get_records('lesson_answers', array('lessonid' => $this->lesson->id, 'pageid' => $this->page2->id), 'id');
+        $answerid = reset($p2answers)->id;
+
+        $newpageattempt = [
+            'lessonid' => $this->lesson->id,
+            'pageid' => $this->page2->id,
+            'userid' => $this->student->id,
+            'answerid' => $answerid,
+            'retry' => $attemptnumber,
+            'correct' => 1,
+            'useranswer' => '1',
+            'timeseen' => time(),
+        ];
+        $DB->insert_record('lesson_attempts', (object) $newpageattempt);
+
+        $result = mod_lesson_external::get_questions_attempts($this->lesson->id, $attemptnumber);
+        $result = external_api::clean_returnvalue(mod_lesson_external::get_questions_attempts_returns(), $result);
+        $this->assertCount(0, $result['warnings']);
+        $this->assertCount(1, $result['attempts']);
+
+        $newpageattempt['id'] = $result['attempts'][0]['id'];
+        $this->assertEquals($newpageattempt, $result['attempts'][0]);
+
+        // Test filtering. Only correct.
+        $result = mod_lesson_external::get_questions_attempts($this->lesson->id, $attemptnumber, true);
+        $result = external_api::clean_returnvalue(mod_lesson_external::get_questions_attempts_returns(), $result);
+        $this->assertCount(0, $result['warnings']);
+        $this->assertCount(1, $result['attempts']);
+
+        // Test filtering. Only correct only for page 2.
+        $result = mod_lesson_external::get_questions_attempts($this->lesson->id, $attemptnumber, true, $this->page2->id);
+        $result = external_api::clean_returnvalue(mod_lesson_external::get_questions_attempts_returns(), $result);
+        $this->assertCount(0, $result['warnings']);
+        $this->assertCount(1, $result['attempts']);
+
+        // Teacher retrieve student page attempts.
+        $this->setUser($this->teacher);
+        $result = mod_lesson_external::get_questions_attempts($this->lesson->id, $attemptnumber, false, null, $this->student->id);
+        $result = external_api::clean_returnvalue(mod_lesson_external::get_questions_attempts_returns(), $result);
+        $this->assertCount(0, $result['warnings']);
+        $this->assertCount(1, $result['attempts']);
+
+        // Test exception.
+        $this->setUser($this->student);
+        $this->expectException('moodle_exception');
+        $result = mod_lesson_external::get_questions_attempts($this->lesson->id, $attemptnumber, false, null, $this->teacher->id);
+    }
 }
index 9ede9fa..3eba329 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2016120503;     // The current module version (Date: YYYYMMDDXX)
+$plugin->version   = 2016120504;     // The current module version (Date: YYYYMMDDXX)
 $plugin->requires  = 2016112900;    // Requires this Moodle version
 $plugin->component = 'mod_lesson'; // Full name of the plugin (used for diagnostics)
 $plugin->cron      = 0;