|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00017 00028 defined('MOODLE_INTERNAL') || die; 00029 00030 require_once($CFG->dirroot . '/question/engine/upgrade/upgradelib.php'); 00031 00032 00033 class tool_qeupgradehelper_attempt_upgrader extends question_engine_attempt_upgrader { 00034 public $quizid; 00035 public $attemptsdone = 0; 00036 public $attemptstodo; 00037 00038 public function __construct($quizid, $attemptstodo) { 00039 $this->quizid = $quizid; 00040 $this->attemptstodo = $attemptstodo; 00041 } 00042 00043 protected function get_quiz_ids() { 00044 return array($this->quizid); 00045 } 00046 00047 protected function print_progress($done, $outof, $quizid) { 00048 } 00049 00050 protected function convert_quiz_attempt($quiz, $attempt, $questionsessionsrs, $questionsstatesrs) { 00051 $this->attemptsdone += 1; 00052 return parent::convert_quiz_attempt($quiz, $attempt, $questionsessionsrs, $questionsstatesrs); 00053 } 00054 00055 protected function reset_progress($done, $outof) { 00056 if (is_null($this->progressbar)) { 00057 $this->progressbar = new progress_bar('qe2reset'); 00058 $this->progressbar->create(); 00059 } 00060 00061 gc_collect_cycles(); // This was really helpful in PHP 5.2. Perhaps remove. 00062 $a = new stdClass(); 00063 $a->done = $done; 00064 $a->outof = $outof; 00065 $this->progressbar->update($done, $outof, 00066 get_string('resettingquizattemptsprogress', 'tool_qeupgradehelper', $a)); 00067 } 00068 00069 protected function get_resettable_attempts($quiz) { 00070 global $DB; 00071 return $DB->get_records_sql(" 00072 SELECT 00073 quiza.* 00074 00075 FROM {quiz_attempts} quiza 00076 LEFT JOIN ( 00077 SELECT attempt, MAX(timestamp) AS time 00078 FROM {question_states} 00079 GROUP BY attempt 00080 ) AS oldtimemodified ON oldtimemodified.attempt = quiza.uniqueid 00081 LEFT JOIN ( 00082 SELECT qa.questionusageid, MAX(qas.timecreated) AS time 00083 FROM {question_attempts} qa 00084 JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id 00085 GROUP BY qa.questionusageid 00086 ) AS newtimemodified ON newtimemodified.questionusageid = quiza.uniqueid 00087 00088 WHERE quiza.preview = 0 00089 AND quiza.needsupgradetonewqe = 0 00090 AND (newtimemodified.time IS NULL OR oldtimemodified.time >= newtimemodified.time) 00091 AND quiza.quiz = :quizid", array('quizid' => $quiz->id)); 00092 } 00093 00094 public function reset_all_resettable_attempts() { 00095 global $DB; 00096 00097 $transaction = $DB->start_delegated_transaction(); 00098 00099 $quiz = $DB->get_record('quiz', array('id' => $this->quizid)); 00100 $attempts = $this->get_resettable_attempts($quiz); 00101 foreach ($attempts as $attempt) { 00102 $this->reset_attempt($quiz, $attempt); 00103 } 00104 00105 $transaction->allow_commit(); 00106 } 00107 00108 protected function reset_attempt($quiz, $attempt) { 00109 global $DB; 00110 00111 $this->attemptsdone += 1; 00112 $this->reset_progress($this->attemptsdone, $this->attemptstodo); 00113 00114 $questionids = explode(',', $quiz->questions); 00115 $slottoquestionid = array(0 => 0); 00116 foreach ($questionids as $questionid) { 00117 if ($questionid) { 00118 $slottoquestionid[] = $questionid; 00119 } 00120 } 00121 00122 $slotlayout = explode(',', $attempt->layout); 00123 $oldlayout = array(); 00124 $ok = true; 00125 foreach ($slotlayout as $slot) { 00126 if (array_key_exists($slot, $slottoquestionid)) { 00127 $oldlayout[] = $slottoquestionid[$slot]; 00128 } else if (in_array($slot, $questionids)) { 00129 // OK there was probably a problem during the original upgrade. 00130 $oldlayout[] = $slot; 00131 } else { 00132 $ok = false; 00133 break; 00134 } 00135 } 00136 00137 if ($ok) { 00138 $layout = implode(',', $oldlayout); 00139 } else { 00140 $layout = $attempt->layout; 00141 } 00142 00143 $DB->delete_records_select('question_attempt_step_data', "attemptstepid IN ( 00144 SELECT qas.id 00145 FROM {question_attempts} qa 00146 JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id 00147 WHERE questionusageid = :uniqueid)", 00148 array('uniqueid' => $attempt->uniqueid)); 00149 $DB->delete_records_select('question_attempt_steps', "questionattemptid IN ( 00150 SELECT qa.id 00151 FROM {question_attempts} qa 00152 WHERE questionusageid = :uniqueid)", 00153 array('uniqueid' => $attempt->uniqueid)); 00154 $DB->delete_records('question_attempts', 00155 array('questionusageid' => $attempt->uniqueid)); 00156 00157 $DB->set_field('question_usages', 'preferredbehaviour', 'to_be_set_later', 00158 array('id' => $attempt->uniqueid)); 00159 $DB->set_field('quiz_attempts', 'layout', $layout, 00160 array('uniqueid' => $attempt->uniqueid)); 00161 $DB->set_field('quiz_attempts', 'needsupgradetonewqe', 1, 00162 array('uniqueid' => $attempt->uniqueid)); 00163 } 00164 }