MDL-55956 mod: New function *_get_group_override_priorities()
authorJun Pataleta <jun@moodle.com>
Thu, 12 Jan 2017 06:28:36 +0000 (14:28 +0800)
committerJun Pataleta <jun@moodle.com>
Mon, 6 Mar 2017 08:10:54 +0000 (16:10 +0800)
New module functions quiz_get_group_override_priorities() and
lesson_get_group_override_priorities() to calculate the priorities
of group overrides for a quiz/lesson activity.

mod/lesson/lib.php
mod/lesson/tests/lib_test.php [new file with mode: 0644]
mod/quiz/lib.php
mod/quiz/tests/lib_test.php

index 33661b4..42b894a 100644 (file)
@@ -227,6 +227,58 @@ function lesson_update_events($lesson, $override = null) {
     }
 }
 
+/**
+ * Calculates the priorities of timeopen and timeclose values for group overrides for a lesson.
+ *
+ * @param int $lessonid The quiz ID.
+ * @return array|null Array of group override priorities for open and close times. Null if there are no group overrides.
+ */
+function lesson_get_group_override_priorities($lessonid) {
+    global $DB;
+
+    // Fetch group overrides.
+    $where = 'lessonid = :lessonid AND groupid IS NOT NULL';
+    $params = ['lessonid' => $lessonid];
+    $overrides = $DB->get_records_select('lesson_overrides', $where, $params, '', 'id, groupid, available, deadline');
+    if (!$overrides) {
+        return null;
+    }
+
+    $grouptimeopen = [];
+    $grouptimeclose = [];
+    foreach ($overrides as $override) {
+        if ($override->available !== null && !in_array($override->available, $grouptimeopen)) {
+            $grouptimeopen[] = $override->available;
+        }
+        if ($override->deadline !== null && !in_array($override->deadline, $grouptimeclose)) {
+            $grouptimeclose[] = $override->deadline;
+        }
+    }
+
+    // Sort open times in descending manner. The earlier open time gets higher priority.
+    rsort($grouptimeopen);
+    // Set priorities.
+    $opengrouppriorities = [];
+    $openpriority = 1;
+    foreach ($grouptimeopen as $timeopen) {
+        $opengrouppriorities[$timeopen] = $openpriority++;
+    }
+
+    // Sort close times in ascending manner. The later close time gets higher priority.
+    sort($grouptimeclose);
+    // Set priorities.
+    $closegrouppriorities = [];
+    $closepriority = 1;
+    foreach ($grouptimeclose as $timeclose) {
+        $closegrouppriorities[$timeclose] = $closepriority++;
+    }
+
+    return [
+        'open' => $opengrouppriorities,
+        'close' => $closegrouppriorities
+    ];
+}
+
 /**
  * This standard function will check all instances of this module
  * and make sure there are up-to-date events created for each of them.
diff --git a/mod/lesson/tests/lib_test.php b/mod/lesson/tests/lib_test.php
new file mode 100644 (file)
index 0000000..a8ae0f6
--- /dev/null
@@ -0,0 +1,85 @@
+<?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/>.
+
+/**
+ * Unit tests for mod/lesson/lib.php.
+ *
+ * @package    mod_lesson
+ * @category   test
+ * @copyright  2017 Jun Pataleta
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/mod/lesson/lib.php');
+
+/**
+ * Unit tests for mod/lesson/lib.php.
+ *
+ * @copyright  2017 Jun Pataleta
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License
+ */
+class mod_lesson_lib_testcase extends advanced_testcase {
+    /**
+     * Test for lesson_get_group_override_priorities().
+     */
+    public function test_lesson_get_group_override_priorities() {
+        global $DB;
+        $this->resetAfterTest();
+        $this->setAdminUser();
+
+        $dg = $this->getDataGenerator();
+        $course = $dg->create_course();
+        $lessonmodule = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
+
+        $this->assertNull(lesson_get_group_override_priorities($lessonmodule->id));
+
+        $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
+        $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
+
+        $now = 100;
+        $override1 = (object)[
+            'lessonid' => $lessonmodule->id,
+            'groupid' => $group1->id,
+            'available' => $now,
+            'deadline' => $now + 20
+        ];
+        $DB->insert_record('lesson_overrides', $override1);
+
+        $override2 = (object)[
+            'lessonid' => $lessonmodule->id,
+            'groupid' => $group2->id,
+            'available' => $now - 10,
+            'deadline' => $now + 10
+        ];
+        $DB->insert_record('lesson_overrides', $override2);
+
+        $priorities = lesson_get_group_override_priorities($lessonmodule->id);
+        $this->assertNotEmpty($priorities);
+
+        $openpriorities = $priorities['open'];
+        // Override 2's time open has higher priority since it is sooner than override 1's.
+        $this->assertEquals(1, $openpriorities[$override1->available]);
+        $this->assertEquals(2, $openpriorities[$override2->available]);
+
+        $closepriorities = $priorities['close'];
+        // Override 1's time close has higher priority since it is later than override 2's.
+        $this->assertEquals(2, $closepriorities[$override1->deadline]);
+        $this->assertEquals(1, $closepriorities[$override2->deadline]);
+    }
+}
index 21b158f..3c1fb68 100644 (file)
@@ -1306,6 +1306,58 @@ function quiz_update_events($quiz, $override = null) {
     }
 }
 
+/**
+ * Calculates the priorities of timeopen and timeclose values for group overrides for a quiz.
+ *
+ * @param int $quizid The quiz ID.
+ * @return array|null Array of group override priorities for open and close times. Null if there are no group overrides.
+ */
+function quiz_get_group_override_priorities($quizid) {
+    global $DB;
+
+    // Fetch group overrides.
+    $where = 'quiz = :quiz AND groupid IS NOT NULL';
+    $params = ['quiz' => $quizid];
+    $overrides = $DB->get_records_select('quiz_overrides', $where, $params, '', 'id, timeopen, timeclose');
+    if (!$overrides) {
+        return null;
+    }
+
+    $grouptimeopen = [];
+    $grouptimeclose = [];
+    foreach ($overrides as $override) {
+        if ($override->timeopen !== null && !in_array($override->timeopen, $grouptimeopen)) {
+            $grouptimeopen[] = $override->timeopen;
+        }
+        if ($override->timeclose !== null && !in_array($override->timeclose, $grouptimeclose)) {
+            $grouptimeclose[] = $override->timeclose;
+        }
+    }
+
+    // Sort open times in descending manner. The earlier open time gets higher priority.
+    rsort($grouptimeopen);
+    // Set priorities.
+    $opengrouppriorities = [];
+    $openpriority = 1;
+    foreach ($grouptimeopen as $timeopen) {
+        $opengrouppriorities[$timeopen] = $openpriority++;
+    }
+
+    // Sort close times in ascending manner. The later close time gets higher priority.
+    sort($grouptimeclose);
+    // Set priorities.
+    $closegrouppriorities = [];
+    $closepriority = 1;
+    foreach ($grouptimeclose as $timeclose) {
+        $closegrouppriorities[$timeclose] = $closepriority++;
+    }
+
+    return [
+        'open' => $opengrouppriorities,
+        'close' => $closegrouppriorities
+    ];
+}
+
 /**
  * List the actions that correspond to a view of this module.
  * This is used by the participation report.
index 22353ff..e1f7029 100644 (file)
@@ -449,4 +449,52 @@ class mod_quiz_lib_testcase extends advanced_testcase {
         $this->assertEquals($quiz2->id, $attempt->quiz);
     }
 
+    /**
+     * Test for quiz_get_group_override_priorities().
+     */
+    public function test_quiz_get_group_override_priorities() {
+        global $DB;
+        $this->resetAfterTest();
+
+        $dg = $this->getDataGenerator();
+        $quizgen = $dg->get_plugin_generator('mod_quiz');
+        $course = $dg->create_course();
+
+        $quiz = $quizgen->create_instance(['course' => $course->id, 'sumgrades' => 2]);
+
+        $this->assertNull(quiz_get_group_override_priorities($quiz->id));
+
+        $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
+        $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
+
+        $now = 100;
+        $override1 = (object)[
+            'quiz' => $quiz->id,
+            'groupid' => $group1->id,
+            'timeopen' => $now,
+            'timeclose' => $now + 20
+        ];
+        $DB->insert_record('quiz_overrides', $override1);
+
+        $override2 = (object)[
+            'quiz' => $quiz->id,
+            'groupid' => $group2->id,
+            'timeopen' => $now - 10,
+            'timeclose' => $now + 10
+        ];
+        $DB->insert_record('quiz_overrides', $override2);
+
+        $priorities = quiz_get_group_override_priorities($quiz->id);
+        $this->assertNotEmpty($priorities);
+
+        $openpriorities = $priorities['open'];
+        // Override 2's time open has higher priority since it is sooner than override 1's.
+        $this->assertEquals(1, $openpriorities[$override1->timeopen]);
+        $this->assertEquals(2, $openpriorities[$override2->timeopen]);
+
+        $closepriorities = $priorities['close'];
+        // Override 1's time close has higher priority since it is later than override 2's.
+        $this->assertEquals(2, $closepriorities[$override1->timeclose]);
+        $this->assertEquals(1, $closepriorities[$override2->timeclose]);
+    }
 }