MDL-63626 mod_quiz: Fixed a bug when there was no attempt on the quiz
authorShamim Rezaie <shamim@moodle.com>
Thu, 11 Oct 2018 13:42:49 +0000 (00:42 +1100)
committerShamim Rezaie <shamim@moodle.com>
Thu, 11 Oct 2018 14:03:39 +0000 (01:03 +1100)
mod/quiz/classes/privacy/provider.php
mod/quiz/tests/privacy_provider_test.php

index 2e577d6..9929590 100644 (file)
@@ -133,6 +133,30 @@ class provider implements
      * @return  contextlist     $contextlist The contextlist containing the list of contexts used in this plugin.
      */
     public static function get_contexts_for_userid(int $userid) : contextlist {
      * @return  contextlist     $contextlist The contextlist containing the list of contexts used in this plugin.
      */
     public static function get_contexts_for_userid(int $userid) : contextlist {
+        $resultset = new contextlist();
+
+        // Users who attempted the quiz.
+        $sql = "SELECT c.id
+                  FROM {context} c
+                  JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
+                  JOIN {modules} m ON m.id = cm.module AND m.name = :modname
+                  JOIN {quiz} q ON q.id = cm.instance
+                  JOIN {quiz_attempts} qa ON qa.quiz = q.id
+                 WHERE qa.userid = :userid AND qa.preview = 0";
+        $params = ['contextlevel' => CONTEXT_MODULE, 'modname' => 'quiz', 'userid' => $userid];
+        $resultset->add_from_sql($sql, $params);
+
+        // Users with quiz overrides.
+        $sql = "SELECT c.id
+                  FROM {context} c
+                  JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
+                  JOIN {modules} m ON m.id = cm.module AND m.name = :modname
+                  JOIN {quiz} q ON q.id = cm.instance
+                  JOIN {quiz_overrides} qo ON qo.quiz = q.id
+                 WHERE qo.userid = :userid";
+        $params = ['contextlevel' => CONTEXT_MODULE, 'modname' => 'quiz', 'userid' => $userid];
+        $resultset->add_from_sql($sql, $params);
+
         // Get the SQL used to link indirect question usages for the user.
         // This includes where a user is the manual marker on a question attempt.
         $qubaid = \core_question\privacy\provider::get_related_question_usages_for_user('rel', 'mod_quiz', 'qa.uniqueid', $userid);
         // Get the SQL used to link indirect question usages for the user.
         // This includes where a user is the manual marker on a question attempt.
         $qubaid = \core_question\privacy\provider::get_related_question_usages_for_user('rel', 'mod_quiz', 'qa.uniqueid', $userid);
@@ -144,33 +168,16 @@ class provider implements
                   JOIN {modules} m ON m.id = cm.module AND m.name = :modname
                   JOIN {quiz} q ON q.id = cm.instance
                   JOIN {quiz_attempts} qa ON qa.quiz = q.id
                   JOIN {modules} m ON m.id = cm.module AND m.name = :modname
                   JOIN {quiz} q ON q.id = cm.instance
                   JOIN {quiz_attempts} qa ON qa.quiz = q.id
-             LEFT JOIN {quiz_overrides} qo ON qo.quiz = q.id AND qo.userid = :qouserid
             " . $qubaid->from . "
             " . $qubaid->from . "
-            WHERE (
-                qa.userid = :qauserid OR
-                " . $qubaid->where() . " OR
-                qo.id IS NOT NULL
-            ) AND qa.preview = 0
-        ";
-
-        $params = array_merge(
-                [
-                    'contextlevel'      => CONTEXT_MODULE,
-                    'modname'           => 'quiz',
-                    'qauserid'          => $userid,
-                    'qouserid'          => $userid,
-                ],
-                $qubaid->from_where_params()
-            );
-
-        $resultset = new contextlist();
+            WHERE " . $qubaid->where() . " AND qa.preview = 0";
+        $params = ['contextlevel' => CONTEXT_MODULE, 'modname' => 'quiz'] + $qubaid->from_where_params();
         $resultset->add_from_sql($sql, $params);
 
         return $resultset;
     }
 
     /**
         $resultset->add_from_sql($sql, $params);
 
         return $resultset;
     }
 
     /**
-     * Delete all data for all users in the specified context.
+     * Export all user data for the specified user, in the specified contexts.
      *
      * @param   approved_contextlist    $contextlist    The approved contexts to export information for.
      */
      *
      * @param   approved_contextlist    $contextlist    The approved contexts to export information for.
      */
index 9e5ca4b..9078dd3 100644 (file)
@@ -56,6 +56,36 @@ class mod_quiz_privacy_provider_testcase extends \core_privacy\tests\provider_te
         $this->assertEmpty($contextlist);
     }
 
         $this->assertEmpty($contextlist);
     }
 
+    /**
+     * Test for provider::get_contexts_for_userid() when there is no quiz attempt at all.
+     */
+    public function test_get_contexts_for_userid_no_attempt_with_override() {
+        global $DB;
+        $this->resetAfterTest(true);
+
+        $course = $this->getDataGenerator()->create_course();
+        $user = $this->getDataGenerator()->create_user();
+
+        // Make a quiz with an override.
+        $this->setUser();
+        $quiz = $this->create_test_quiz($course);
+        $DB->insert_record('quiz_overrides', [
+            'quiz' => $quiz->id,
+            'userid' => $user->id,
+            'timeclose' => 1300,
+            'timelimit' => null,
+        ]);
+
+        $cm = get_coursemodule_from_instance('quiz', $quiz->id);
+        $context = \context_module::instance($cm->id);
+
+        // Fetch the contexts - only one context should be returned.
+        $this->setUser();
+        $contextlist = provider::get_contexts_for_userid($user->id);
+        $this->assertCount(1, $contextlist);
+        $this->assertEquals($context, $contextlist->current());
+    }
+
     /**
      * The export function should handle an empty contextlist properly.
      */
     /**
      * The export function should handle an empty contextlist properly.
      */