Differences Between: [Versions 311 and 402] [Versions 311 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Defines the quiz repaginate class. 19 * 20 * @package mod_quiz 21 * @copyright 2014 The Open University 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace mod_quiz; 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** 29 * The repaginate class will rearrange questions in pages. 30 * 31 * The quiz setting allows users to write quizzes with one question per page, 32 * n questions per page, or all questions on one page. 33 * 34 * @copyright 2014 The Open University 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class repaginate { 38 39 /** @var int means join pages. */ 40 const LINK = 1; 41 /** @var int means split pages. */ 42 const UNLINK = 2; 43 44 /** @var int the id of the quiz being manipulated. */ 45 private $quizid; 46 /** @var array the quiz_slots for that quiz. */ 47 private $slots; 48 49 /** 50 * Constructor. 51 * @param int $quizid the id of the quiz being manipulated. 52 * @param stdClass[] $slots the quiz_slots for that quiz. 53 */ 54 public function __construct($quizid = 0, $slots = null) { 55 global $DB; 56 $this->quizid = $quizid; 57 if (!$this->quizid) { 58 $this->slots = array(); 59 } 60 if (!$slots) { 61 $this->slots = $DB->get_records('quiz_slots', array('quizid' => $this->quizid), 'slot'); 62 } else { 63 $this->slots = $slots; 64 } 65 } 66 67 /** 68 * Repaginate a given slot with the given pagenumber. 69 * @param stdClass $slot 70 * @param int $newpagenumber 71 * @return stdClass 72 */ 73 protected function repaginate_this_slot($slot, $newpagenumber) { 74 $newslot = clone($slot); 75 $newslot->page = $newpagenumber; 76 return $newslot; 77 } 78 79 /** 80 * Return current slot object. 81 * @param array $slots 82 * @param int $slotnumber 83 * @return stdClass $slot 84 */ 85 protected function get_this_slot($slots, $slotnumber) { 86 foreach ($slots as $key => $slot) { 87 if ($slot->slot == $slotnumber) { 88 return $slot; 89 } 90 } 91 return null; 92 } 93 94 /** 95 * Return array of slots with slot number as key 96 * @param stdClass[] $slots 97 * @return stdClass[] 98 */ 99 protected function get_slots_by_slot_number($slots) { 100 if (!$slots) { 101 return array(); 102 } 103 $newslots = array(); 104 foreach ($slots as $slot) { 105 $newslots[$slot->slot] = $slot; 106 } 107 return $newslots; 108 } 109 110 /** 111 * Return array of slots with slot id as key 112 * @param stdClass[] $slots 113 * @return stdClass[] 114 */ 115 protected function get_slots_by_slotid($slots) { 116 if (!$slots) { 117 return array(); 118 } 119 $newslots = array(); 120 foreach ($slots as $slot) { 121 $newslots[$slot->id] = $slot; 122 } 123 return $newslots; 124 } 125 126 /** 127 * Repaginate, update DB and slots object 128 * @param int $nextslotnumber 129 * @param int $type repaginate::LINK or repaginate::UNLINK. 130 */ 131 public function repaginate_slots($nextslotnumber, $type) { 132 global $DB; 133 $this->slots = $DB->get_records('quiz_slots', array('quizid' => $this->quizid), 'slot'); 134 $nextslot = null; 135 $newslots = array(); 136 foreach ($this->slots as $slot) { 137 if ($slot->slot < $nextslotnumber) { 138 $newslots[$slot->id] = $slot; 139 } else if ($slot->slot == $nextslotnumber) { 140 $nextslot = $this->repaginate_next_slot($nextslotnumber, $type); 141 142 // Update DB. 143 $DB->update_record('quiz_slots', $nextslot, true); 144 145 // Update returning object. 146 $newslots[$slot->id] = $nextslot; 147 } 148 } 149 if ($nextslot) { 150 $newslots = array_merge($newslots, $this->repaginate_the_rest($this->slots, $nextslotnumber, $type)); 151 $this->slots = $this->get_slots_by_slotid($newslots); 152 } 153 } 154 155 /** 156 * Repaginate next slot and return the modified slot object 157 * @param int $nextslotnumber 158 * @param int $type repaginate::LINK or repaginate::UNLINK. 159 * @return stdClass|null 160 */ 161 public function repaginate_next_slot($nextslotnumber, $type) { 162 $currentslotnumber = $nextslotnumber - 1; 163 if (!($currentslotnumber && $nextslotnumber)) { 164 return null; 165 } 166 $currentslot = $this->get_this_slot($this->slots, $currentslotnumber); 167 $nextslot = $this->get_this_slot($this->slots, $nextslotnumber); 168 169 if ($type === self::LINK) { 170 return $this->repaginate_this_slot($nextslot, $currentslot->page); 171 } else if ($type === self::UNLINK) { 172 return $this->repaginate_this_slot($nextslot, $nextslot->page + 1); 173 } 174 return null; 175 } 176 177 /** 178 * Return the slots with the new pagination, regardless of current pagination. 179 * @param stdClass[] $slots the slots to repaginate. 180 * @param int $number number of question per page 181 * @return stdClass[] the updated slots. 182 */ 183 public function repaginate_n_question_per_page($slots, $number) { 184 $slots = $this->get_slots_by_slot_number($slots); 185 $newslots = array(); 186 $count = 0; 187 $page = 1; 188 foreach ($slots as $key => $slot) { 189 for ($page + $count; $page < ($number + $count + 1); $page++) { 190 if ($slot->slot >= $page) { 191 $slot->page = $page; 192 $count++; 193 } 194 } 195 $newslots[$slot->id] = $slot; 196 } 197 return $newslots; 198 } 199 200 /** 201 * Repaginate the rest. 202 * @param stdClass[] $quizslots 203 * @param int $slotfrom 204 * @param int $type 205 * @param bool $dbupdate 206 * @return stdClass[] 207 */ 208 public function repaginate_the_rest($quizslots, $slotfrom, $type, $dbupdate = true) { 209 global $DB; 210 if (!$quizslots) { 211 return null; 212 } 213 $newslots = array(); 214 foreach ($quizslots as $slot) { 215 if ($type == self::LINK) { 216 if ($slot->slot <= $slotfrom) { 217 continue; 218 } 219 $slot->page = $slot->page - 1; 220 } else if ($type == self::UNLINK) { 221 if ($slot->slot <= $slotfrom - 1) { 222 continue; 223 } 224 $slot->page = $slot->page + 1; 225 } 226 // Update DB. 227 if ($dbupdate) { 228 $DB->update_record('quiz_slots', $slot); 229 } 230 $newslots[$slot->id] = $slot; 231 } 232 return $newslots; 233 } 234 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body