/** * Called before starting to upgrade all the attempts at a particular quiz. * @param int $done the number of quizzes processed so far. * @param int $outof the total number of quizzes to process. * @param int $quizid the id of the quiz that is about to be processed. */ protected function print_progress($done, $outof, $quizid) { if (is_null($this->progressbar)) { $this->progressbar = new progress_bar('qe2upgrade'); $this->progressbar->create(); } gc_collect_cycles(); // This was really helpful in PHP 5.2. Perhaps remove. $a = new stdClass(); $a->done = $done; $a->outof = $outof; $a->info = $quizid; $this->progressbar->update($done, $outof, get_string('upgradingquizattempts', 'quiz', $a)); }
/** * Installation code for the ddmarker question type. It converts all existing imagetarget questions to ddmarker */ function xmldb_qtype_ddmarker_install() { global $DB, $OUTPUT; $from = 'FROM {question_categories} cat, {question} q'; $where = ' WHERE q.qtype = \'imagetarget\' AND q.category = cat.id '; $sql = 'SELECT q.*, cat.contextid ' . $from . $where . 'ORDER BY cat.id, q.name'; $questions = $DB->get_records_sql($sql); if (!empty($questions)) { require_once dirname(__FILE__) . '/../lib.php'; $dragssql = 'SELECT drag.* ' . $from . ', {qtype_ddmarker_drags} drag' . $where . ' AND drag.questionid = q.id'; $drags = xmldb_qtype_ddmarker_index_array_of_records_by_key('questionid', $DB->get_records_sql($dragssql)); $dropssql = 'SELECT drp.* ' . $from . ', {qtype_ddmarker_drops} drp' . $where . ' AND drp.questionid = q.id'; $drops = xmldb_qtype_ddmarker_index_array_of_records_by_key('questionid', $DB->get_records_sql($dropssql)); $answerssql = 'SELECT answer.* ' . $from . ', {question_answers} answer' . $where . ' AND answer.question = q.id'; $answers = xmldb_qtype_ddmarker_index_array_of_records_by_key('question', $DB->get_records_sql($answerssql)); $imgfiles = $DB->get_records_sql_menu('SELECT question, qimage FROM {question_imagetarget}'); $progressbar = new progress_bar('qtype_ddmarker_convert_from_imagetarget'); $progressbar->create(); $done = 0; foreach ($questions as $question) { qtype_ddmarker_convert_image_target_question($question, $imgfiles[$question->id], $answers[$question->id]); $done++; $progressbar->update($done, count($questions), get_string('convertingimagetargetquestion', 'qtype_ddmarker', $question)); } list($qsql, $qparams) = $DB->get_in_or_equal(array_keys($questions)); $DB->delete_records_select('question_answers', 'question ' . $qsql, $qparams); $dbman = $DB->get_manager(); $dbman->drop_table(new xmldb_table('question_imagetarget')); } }
function xmldb_offlinequiz_upgrade($oldversion = 0) { global $CFG, $THEME, $DB, $OUTPUT; $dbman = $DB->get_manager(); // And upgrade begins here. For each one, you'll need one // Block of code similar to the next one. Please, delete // This comment lines once this file start handling proper // Upgrade code. // ONLY UPGRADE FROM Moodle 1.9.x (module version 2009042100) is supported. if ($oldversion < 2009120700) { // Define field counter to be added to offlinequiz_i_log. $table = new xmldb_table('offlinequiz_i_log'); $field = new xmldb_field('counter'); $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'rawdata'); // Launch add field counter. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Define field corners to be added to offlinequiz_i_log. $field = new xmldb_field('corners'); $field->set_attributes(XMLDB_TYPE_CHAR, '50', null, null, null, null, 'counter'); // Launch add field corners. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Define field pdfintro to be added to offlinequiz. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('pdfintro'); $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'intro'); // Launch add field pdfintro. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2009120700, 'offlinequiz'); } if ($oldversion < 2010082900) { // Define table offlinequiz_p_list to be created. $table = new xmldb_table('offlinequiz_p_list'); // Adding fields to table offlinequiz_p_list. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('offlinequiz', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null); $table->add_field('list', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1'); // Adding keys to table offlinequiz_p_list. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Launch create table for offlinequiz_p_list. $dbman->create_table($table); // Define field position to be dropped from offlinequiz_participants. $table = new xmldb_table('offlinequiz_participants'); $field = new xmldb_field('position'); // Launch drop field position. $dbman->drop_field($table, $field); // Define field page to be dropped from offlinequiz_participants. $table = new xmldb_table('offlinequiz_participants'); $field = new xmldb_field('page'); // Launch drop field page. $dbman->drop_field($table, $field); // Define field list to be added to offlinequiz_participants. $table = new xmldb_table('offlinequiz_participants'); $field = new xmldb_field('list'); $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1', 'userid'); // Launch add field list. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2010082900, 'offlinequiz'); } if ($oldversion < 2010090600) { // Define index offlinequiz (not unique) to be added to offlinequiz_p_list. $table = new xmldb_table('offlinequiz_p_list'); $index = new XMLDBIndex('offlinequiz'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('offlinequiz')); // Launch add index offlinequiz. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } $index = new XMLDBIndex('list'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('list')); // Launch add index list. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } // Define index offlinequiz (not unique) to be added to offlinequiz_participants. $table = new xmldb_table('offlinequiz_participants'); $index = new XMLDBIndex('offlinequiz'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('offlinequiz')); // Launch add index offlinequiz. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } $index = new XMLDBIndex('list'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('list')); // Launch add index list. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } $index = new XMLDBIndex('userid'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('userid')); // Launch add index list. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2010090600, 'offlinequiz'); } if ($oldversion < 2011021400) { // Define field fileformat to be added to offlinequiz. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('fileformat'); $field->set_attributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'timemodified'); // Launch add field fileformat. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2011021400, 'offlinequiz'); } if ($oldversion < 2011032900) { // Define field page to be added to offlinequiz_i_log. $table = new xmldb_table('offlinequiz_i_log'); $field = new xmldb_field('page'); $field->set_attributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'corners'); // Launch add field page. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Define field username to be added to offlinequiz_i_log. $field = new xmldb_field('username'); $field->set_attributes(XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'page'); // Launch add field username. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Define index username (not unique) to be added to offlinequiz_i_log. $index = new XMLDBIndex('username'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('username')); // Launch add index username. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } // Define field showgrades to be added to offlinequiz. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('showgrades'); $field->set_attributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'fileformat'); // Launch add field showgrades. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2011032900, 'offlinequiz'); } if ($oldversion < 2011081700) { // Define field showtutorial to be added to offlinequiz. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('showtutorial'); $field->set_attributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'showgrades'); // Launch add field showtutorial. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2011081700, 'offlinequiz'); } // ------------------------------------------------------ // UPGRADE for Moodle 2.0 module starts here. // ------------------------------------------------------ // First we do the changes to the main table 'offlinequiz'. // ------------------------------------------------------ if ($oldversion < 2012010100) { // Define field docscreated to be added to offlinequiz. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('docscreated', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'questionsperpage'); // Conditionally launch add field docscreated. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010100, 'offlinequiz'); } // Fill the new field docscreated. if ($oldversion < 2012010101) { $offlinequizzes = $DB->get_records('offlinequiz'); foreach ($offlinequizzes as $offlinequiz) { $dirname = $CFG->dataroot . '/' . $offlinequiz->course . '/moddata/offlinequiz/' . $offlinequiz->id . '/pdfs'; // If the answer pdf file for group 1 exists then we have created the documents. if (file_exists($dirname . '/answer-a.pdf')) { $DB->set_field('offlinequiz', 'docscreated', 1, array('id' => $offlinequiz->id)); } } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010101, 'offlinequiz'); } if ($oldversion < 2012010105) { // Define table offlinequiz_reports to be created. $table = new xmldb_table('offlinequiz_reports'); // Adding fields to table offlinequiz_reports. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null); $table->add_field('displayorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('lastcron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('cron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('capability', XMLDB_TYPE_CHAR, '255', null, null, null, null); // Adding keys to table offlinequiz_reports. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Adding indexes to table offlinequiz_reports. // $table->add_index('name', XMLDB_INDEX_UNIQUE, array('name'));. // Conditionally launch create table for offlinequiz_reports. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } if (!$DB->get_records_sql("SELECT * FROM {offlinequiz_reports} WHERE name = 'overview'", array())) { $record = new stdClass(); $record->name = 'overview'; $record->displayorder = '10000'; $DB->insert_record('offlinequiz_reports', $record); } if (!$DB->get_records_sql("SELECT * FROM {offlinequiz_reports} WHERE name = 'rimport'", array())) { $record = new stdClass(); $record->name = 'rimport'; $record->displayorder = '9000'; $DB->insert_record('offlinequiz_reports', $record); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010105, 'offlinequiz'); } // Now we create all the new tables. // Create table offlinequiz_groups. if ($oldversion < 2012010200) { echo $OUTPUT->notification('Creating new tables', 'notifysuccess'); // Define table offlinequiz_groups to be created. $table = new xmldb_table('offlinequiz_groups'); // Adding fields to table offlinequiz_groups. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('offlinequizid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('number', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0'); $table->add_field('numberofpages', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('templateusageid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); // Adding keys to table offlinequiz_groups. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Adding indexes to table offlinequiz_groups. $table->add_index('offlinequizid', XMLDB_INDEX_NOTUNIQUE, array('offlinequizid')); // Conditionally launch create table for offlinequiz_groups. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010200, 'offlinequiz'); } // Create table offlinequiz_group_questions. if ($oldversion < 2012010300) { // Define table offlinequiz_group_questions to be created. $table = new xmldb_table('offlinequiz_group_questions'); // Adding fields to table offlinequiz_group_questions. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('offlinequizid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('offlinegroupid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('questionid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('position', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1'); $table->add_field('pagenumber', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null); $table->add_field('usageslot', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null); // Adding keys to table offlinequiz_group_questions. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Adding indexes to table offlinequiz_group_questions. $table->add_index('offlinequiz', XMLDB_INDEX_NOTUNIQUE, array('offlinequizid')); // Conditionally launch create table for offlinequiz_group_questions. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010300, 'offlinequiz'); } if ($oldversion < 2012010400) { // Define table offlinequiz_scanned_pages to be created. $table = new xmldb_table('offlinequiz_scanned_pages'); // Adding fields to table offlinequiz_scanned_pages. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('offlinequizid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('resultid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); $table->add_field('filename', XMLDB_TYPE_CHAR, '1000', null, null, null, null); $table->add_field('warningfilename', XMLDB_TYPE_CHAR, '1000', null, null, null, null); $table->add_field('groupnumber', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null); $table->add_field('userkey', XMLDB_TYPE_CHAR, '255', null, null, null, null); $table->add_field('pagenumber', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null); $table->add_field('time', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('status', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null); $table->add_field('error', XMLDB_TYPE_CHAR, '255', null, null, null, null); $table->add_field('info', XMLDB_TYPE_TEXT, 'medium', null, null, null, null); // Adding keys to table offlinequiz_scanned_pages. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Adding indexes to table offlinequiz_scanned_pages. $table->add_index('offlinequizid', XMLDB_INDEX_NOTUNIQUE, array('offlinequizid')); // Conditionally launch create table for offlinequiz_scanned_pages. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010400, 'offlinequiz'); } if ($oldversion < 2012010500) { // Define table offlinequiz_choices to be created. $table = new xmldb_table('offlinequiz_choices'); // Adding fields to table offlinequiz_choices. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('scannedpageid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('slotnumber', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('choicenumber', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('value', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null); // Adding keys to table offlinequiz_choices. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Adding indexes to table offlinequiz_choices. $table->add_index('scannedpageid', XMLDB_INDEX_NOTUNIQUE, array('scannedpageid')); // Conditionally launch create table for offlinequiz_choices. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010500, 'offlinequiz'); } if ($oldversion < 2012010600) { // Define table offlinequiz_page_corners to be created. $table = new xmldb_table('offlinequiz_page_corners'); // Adding fields to table offlinequiz_page_corners. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('scannedpageid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('x', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('y', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('position', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); // Adding keys to table offlinequiz_page_corners. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Conditionally launch create table for offlinequiz_page_corners. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010600, 'offlinequiz'); } if ($oldversion < 2012010700) { // Define table offlinequiz_results to be created. $table = new xmldb_table('offlinequiz_results'); // Adding fields to table offlinequiz_results. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('offlinequizid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('offlinegroupid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null); $table->add_field('usageid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('teacherid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('attendant', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); $table->add_field('status', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); $table->add_field('timestart', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('timefinish', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, '0'); $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('preview', XMLDB_TYPE_INTEGER, '3', XMLDB_UNSIGNED, null, null, '0'); // Adding keys to table offlinequiz_results. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Conditionally launch create table for offlinequiz_results. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010700, 'offlinequiz'); } if ($oldversion < 2012010800) { // Define table offlinequiz_scanned_p_pages to be created. $table = new xmldb_table('offlinequiz_scanned_p_pages'); // Adding fields to table offlinequiz_scanned_p_pages. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('offlinequizid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('listnumber', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null); $table->add_field('filename', XMLDB_TYPE_CHAR, '1000', null, null, null, null); $table->add_field('time', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('status', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null); $table->add_field('error', XMLDB_TYPE_TEXT, 'small', null, null, null, null); // Adding keys to table offlinequiz_scanned_p_pages. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Conditionally launch create table for offlinequiz_scanned_p_pages. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010800, 'offlinequiz'); } if ($oldversion < 2012010900) { // Define table offlinequiz_p_choices to be created. $table = new xmldb_table('offlinequiz_p_choices'); // Adding fields to table offlinequiz_p_choices. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('scannedppageid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); $table->add_field('value', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0'); // Adding keys to table offlinequiz_p_choices. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Conditionally launch create table for offlinequiz_p_choices. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012010900, 'offlinequiz'); } if ($oldversion < 2012011000) { // Define table offlinequiz_p_lists to be created. $table = new xmldb_table('offlinequiz_p_lists'); // Adding fields to table offlinequiz_p_lists. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('offlinequizid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null); $table->add_field('number', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1'); $table->add_field('filename', XMLDB_TYPE_CHAR, '1000', null, null, null, null); // Adding keys to table offlinequiz_p_lists. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Adding indexes to table offlinequiz_p_lists. $table->add_index('offlinequizid', XMLDB_INDEX_NOTUNIQUE, array('offlinequizid')); // Conditionally launch create table for offlinequiz_p_lists. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012011000, 'offlinequiz'); } // ------------------------------------------------------ // New we rename fields in old tables. // ------------------------------------------------------ // Rename fields in offlinequiz_queue table. if ($oldversion < 2012020100) { echo $OUTPUT->notification('Renaming fields in old tables.', 'notifysuccess'); // Rename field offlinequiz on table offlinequiz_queue to NEWNAMEGOESHERE. $table = new xmldb_table('offlinequiz_queue'); $field = new xmldb_field('offlinequiz'); $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timefinish'); // Launch rename field offlinequiz. $dbman->rename_field($table, $field, 'offlinequizid'); $field = new xmldb_field('importadmin'); $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'id'); // Launch rename field importadmin. $dbman->rename_field($table, $field, 'importuserid'); // New status field. $field = new xmldb_field('status', XMLDB_TYPE_TEXT, 'small', null, null, null, 'processed', 'timefinish'); // Conditionally launch add field status. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012020100, 'offlinequiz'); } // Add and rename fields in table offlinquiz_queue_data. if ($oldversion < 2012020200) { // Define field status to be added to offlinequiz_queue_data. $table = new xmldb_table('offlinequiz_queue_data'); $field = new xmldb_field('status', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, 'ok', 'filename'); // Conditionally launch add field status. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } else { $dbman->change_field_type($table, $field); $dbman->change_field_precision($table, $field); $dbman->change_field_notnull($table, $field); $dbman->change_field_unsigned($table, $field); } // Add new field 'error'. $field = new xmldb_field('error', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'status'); // Conditionally launch add field error. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Rename field queue to queueid. $field = new xmldb_field('queue', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'id'); // Launch rename field queueid. $dbman->rename_field($table, $field, 'queueid'); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012020200, 'offlinequiz'); } // Rename field list on table offlinequiz_participants to listid. if ($oldversion < 2012020300) { // Rename field list on table offlinequiz_participants to listid. $table = new xmldb_table('offlinequiz_participants'); $field = new xmldb_field('list', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'id'); // Launch rename field listid. $dbman->rename_field($table, $field, 'listid'); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012020300, 'offlinequiz'); } // Migrate the old lists of participants to the new table offlinequiz_p_lists (with 's'). if ($oldversion < 2012020400) { $oldplists = $DB->get_records('offlinequiz_p_list'); foreach ($oldplists as $oldplist) { $newplist = new StdClass(); $newplist->offlinequizid = $oldplist->offlinequiz; $newplist->name = $oldplist->name; $newplist->number = $oldplist->list; // NOTE. // We don't set filename because we can always recreate the PDF files if needed. $newplist->id = $DB->insert_record('offlinequiz_p_lists', $newplist); // Get all the participants linked to the old list and link them to the new list in offlinequiz_p_lists. if ($oldparts = $DB->get_records('offlinequiz_participants', array('listid' => $oldplist->id))) { foreach ($oldparts as $oldpart) { $oldpart->listid = $newplist->id; $DB->update_record('offlinequiz_participants', $oldpart); } } } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012020400, 'offlinequiz'); } // Check if there are inconsistencies in the DB, i.e. uniqueids used by both quizzes and offlinequizzes. if ($oldversion < 2012020410) { $sql = 'SELECT uniqueid FROM {offlinequiz_attempts} qa WHERE EXISTS (SELECT id from {quiz_attempts} where uniqueid = qa.uniqueid)'; $doubleids = $DB->get_fieldset_sql($sql, array()); // For each double uniqueid create a new uniqueid and change the fields in the tables. // Offlinequiz_attempts, question_sessions and question_states. echo $OUTPUT->notification('Fixing ' . count($doubleids) . ' question attempt uniqueids that are not unique', 'notifysuccess'); foreach ($doubleids as $doubleid) { echo $doubleid . ', '; if ($usage = $DB->get_record('question_usages', array('id' => $doubleid))) { $transaction = $DB->start_delegated_transaction(); unset($usage->id); $usage->id = $DB->insert_record('question_usages', $usage); $DB->set_field_select('offlinequiz_attempts', 'uniqueid', $usage->id, 'uniqueid = :oldid', array('oldid' => $doubleid)); $DB->set_field_select('question_states', 'attempt', $usage->id, 'attempt = :oldid', array('oldid' => $doubleid)); $DB->set_field_select('question_sessions', 'attemptid', $usage->id, 'attemptid = :oldid', array('oldid' => $doubleid)); $transaction->allow_commit(); } } upgrade_mod_savepoint(true, 2012020410, 'offlinequiz'); } // ----------------------------------------------------- // Update the contextid field in question_usages (compare lib/db/upgrade.php lines 6108 following). // ----------------------------------------------------- if ($oldversion < 2012020500) { echo $OUTPUT->notification('Fixing question usages context ID', 'notifysuccess'); // Update the component field if necessary. $DB->set_field('question_usages', 'component', 'mod_offlinequiz', array('component' => 'offlinequiz')); // Populate the contextid field. $offlinequizmoduleid = $DB->get_field('modules', 'id', array('name' => 'offlinequiz')); $DB->execute("\n UPDATE {question_usages} SET contextid = (\n SELECT ctx.id\n FROM {context} ctx\n JOIN {course_modules} cm ON cm.id = ctx.instanceid AND cm.module = {$offlinequizmoduleid}\n JOIN {offlinequiz_attempts} quiza ON quiza.offlinequiz = cm.instance\n WHERE ctx.contextlevel = " . CONTEXT_MODULE . "\n AND quiza.uniqueid = {question_usages}.id)\n WHERE (\n SELECT ctx.id\n FROM {context} ctx\n JOIN {course_modules} cm ON cm.id = ctx.instanceid AND cm.module = {$offlinequizmoduleid}\n JOIN {offlinequiz_attempts} quiza ON quiza.offlinequiz = cm.instance\n WHERE ctx.contextlevel = " . CONTEXT_MODULE . "\n AND quiza.uniqueid = {question_usages}.id) IS NOT NULL\n "); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012020500, 'offlinequiz'); } // ----------------------------------------------------- // Now we migrate data from the old to the new tables. // ----------------------------------------------------- // We have to delete redundant question instances from offlinequizzes because they are incompatible with the new code. if ($oldversion < 2012030100) { echo $OUTPUT->notification('Migrating old offline quizzes to new offline quizzes..', 'notifysuccess'); require_once $CFG->dirroot . '/mod/offlinequiz/db/upgradelib.php'; offlinequiz_remove_redundant_q_instances(); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012030100, 'offlinequiz'); } // Migrate all entries in the offlinequiz_group table to the new tables offlinequiz_groups and offlinequiz_group_questions. if ($oldversion < 2012030101) { echo $OUTPUT->notification('Creating new offlinequiz groups', 'notifysuccess'); $offlinequizzes = $DB->get_records('offlinequiz'); $counter = 0; foreach ($offlinequizzes as $offlinequiz) { if (!$DB->get_records('offlinequiz_groups', array('offlinequizid' => $offlinequiz->id))) { echo '.'; $counter++; flush(); ob_flush(); if ($counter % 100 == 0) { echo "<br/>\n"; echo $counter; } $transaction = $DB->start_delegated_transaction(); $oldgroups = $DB->get_records('offlinequiz_group', array('offlinequiz' => $offlinequiz->id), 'groupid ASC'); $newgroups = array(); foreach ($oldgroups as $oldgroup) { $newgroup = new StdClass(); $newgroup->offlinequizid = $offlinequiz->id; $newgroup->number = $oldgroup->groupid; $newgroup->sumgrades = $oldgroup->sumgrades; $newgroup->timecreated = time(); $newgroup->timemodified = time(); // First we need the ID of the new group. if (!($oldid = $DB->get_field('offlinequiz_groups', 'id', array('offlinequizid' => $offlinequiz->id, 'number' => $newgroup->number)))) { $newgroup->id = $DB->insert_record('offlinequiz_groups', $newgroup); } else { $newgroup->id = $oldid; } // Now create an entry in offlinquiz_group_questions for each question in the old group layout. $questions = explode(',', $oldgroup->questions); $position = 1; foreach ($questions as $question) { $groupquestion = new StdClass(); $groupquestion->offlinequizid = $offlinequiz->id; $groupquestion->offlinegroupid = $newgroup->id; $groupquestion->questionid = $question; $groupquestion->position = $position++; if (!$DB->get_record('offlinequiz_group_questions', array('offlinequizid' => $offlinequiz->id, 'offlinegroupid' => $newgroup->id, 'questionid' => $question))) { $DB->insert_record('offlinequiz_group_questions', $groupquestion); } } $newgroups[] = $newgroup; } require_once $CFG->dirroot . '/mod/offlinequiz/evallib.php'; list($maxquestions, $maxanswers, $formtype, $questionsperpage) = offlinequiz_get_question_numbers($offlinequiz, $newgroups); foreach ($newgroups as $newgroup) { // Now we know the number of pages of the group. $newgroup->numberofpages = ceil($maxquestions / ($formtype * 24)); $DB->update_record('offlinequiz_groups', $newgroup); } $transaction->allow_commit(); } } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012030101, 'offlinequiz'); } // Migrate all entries in the offlinequiz_i_log table to the new tables offlinequiz_scanned_pages, offlinequiz_choices and. // Offlinequiz_page_corners. Also migrate the files to the new filesystem. // First we mark all offlinequizzes s.t. we upgrade them only once. Many things can go wrong here.. if ($oldversion < 2012030200) { // Define field needsilogupgrade to be added to offlinequiz_attempts. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('needsilogupgrade', XMLDB_TYPE_INTEGER, '3', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'timeopen'); // Launch add field needsilogupgrade. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } $DB->set_field('offlinequiz', 'needsilogupgrade', 1); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012030200, 'offlinequiz'); } // Then we mark all offlinequiz_attempts to be upgraded. if ($oldversion < 2012030300) { // Define field needsupgradetonewqe to be added to offlinequiz_attempts. $table = new xmldb_table('offlinequiz_attempts'); $field = new xmldb_field('needsupgradetonewqe', XMLDB_TYPE_INTEGER, '3', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'sheet'); // Launch add field needsupgradetonewqe. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } $DB->set_field('offlinequiz_attempts', 'needsupgradetonewqe', 1); // Quiz savepoint reached. upgrade_mod_savepoint(true, 2012030300, 'offlinequiz'); } // In a first step we upgrade the offlinequiz_attempts exactly like quiz_attempts (see mod/quiz/db/upgrade.php). if ($oldversion < 2012030400) { $table = new xmldb_table('question_states'); // Echo "upgrading attempts to new question engine <br/>\n";. if ($dbman->table_exists($table)) { // NOTE: We need all attemps, also the ones with sheet=1 because the are the groups' template attempts. // Now update all the old attempt data. $oldrcachesetting = $CFG->rcache; $CFG->rcache = false; require_once $CFG->dirroot . '/mod/offlinequiz/db/upgradelib.php'; $upgrader = new offlinequiz_attempt_upgrader(); $upgrader->convert_all_quiz_attempts(); $CFG->rcache = $oldrcachesetting; } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012030400, 'offlinequiz'); } // Then we mark all offlinequiz_attempts to be upgraded. if ($oldversion < 2012030500) { // Define field resultid to be added to offlinequiz_attempts for later reference. set_time_limit(3000); $table = new xmldb_table('offlinequiz_attempts'); $field = new xmldb_field('resultid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); // Launch add field resultid. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Quiz savepoint reached. upgrade_mod_savepoint(true, 2012030500, 'offlinequiz'); } // In a second step we convert all offlinequiz_attempts into offlinequiz_results and also upgrade the ilog table. if ($oldversion < 2012060101) { require_once $CFG->dirroot . '/mod/offlinequiz/db/upgradelib.php'; $oldrcachesetting = $CFG->rcache; $CFG->rcache = false; $upgrader = new offlinequiz_ilog_upgrader(); $upgrader->convert_all_offlinequiz_attempts(); $CFG->rcache = $oldrcachesetting; // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012060101, 'offlinequiz'); } if ($oldversion < 2012060105) { // Changing type of field grade on table offlinequiz_q_instances to number. $table = new xmldb_table('offlinequiz_q_instances'); $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'question'); // Launch change of type for field grade. $dbman->change_field_type($table, $field); // Launch change of precision for field grade. $dbman->change_field_precision($table, $field); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012060105, 'offlinequiz'); } if ($oldversion < 2012121200) { // Define field introformat to be added to offlinequiz. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'intro'); // Conditionally launch add field introformat. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2012121200, 'offlinequiz'); } if ($oldversion < 2013012400) { // Define field info to be added to offlinequiz_queue. $table = new xmldb_table('offlinequiz_queue'); $field = new xmldb_field('info', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, 'status'); // Conditionally launch add field info. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013012400, 'offlinequiz'); } if ($oldversion < 2013012410) { // Define field info to be added to offlinequiz_queue_data. $table = new xmldb_table('offlinequiz_queue_data'); $field = new xmldb_field('info', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, 'error'); // Conditionally launch add field info. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013012410, 'offlinequiz'); } if ($oldversion < 2013012500) { // Changing type of field grade on table offlinequiz to int. $table = new xmldb_table('offlinequiz'); $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'time'); // Launch change for field grade. $dbman->change_field_type($table, $field); $dbman->change_field_precision($table, $field); $dbman->change_field_unsigned($table, $field); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013012500, 'offlinequiz'); } if ($oldversion < 2013041600) { // Rename field question on table offlinequiz_q_instances to questionid. $table = new xmldb_table('offlinequiz_q_instances'); $field = new xmldb_field('question', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'offlinequiz'); // Launch rename field question. $dbman->rename_field($table, $field, 'questionid'); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013041600, 'offlinequiz'); } if ($oldversion < 2013041601) { // Rename field offlinequiz on table offlinequiz_q_instances to offlinequizid. $table = new xmldb_table('offlinequiz_q_instances'); $field = new xmldb_field('offlinequiz', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id'); // Launch rename field offlinequiz. $dbman->rename_field($table, $field, 'offlinequizid'); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013041601, 'offlinequiz'); } if ($oldversion < 2013061300) { // Define table offlinequiz_hotspots to be created. $table = new xmldb_table('offlinequiz_hotspots'); // Adding fields to table offlinequiz_hotspots. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('scannedpageid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); $table->add_field('x', XMLDB_TYPE_NUMBER, '10, 2', null, XMLDB_NOTNULL, null, null); $table->add_field('y', XMLDB_TYPE_NUMBER, '10, 2', null, XMLDB_NOTNULL, null, null); $table->add_field('blank', XMLDB_TYPE_INTEGER, '1', null, null, null, null); $table->add_field('time', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); // Adding keys to table offlinequiz_hotspots. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Adding indexes to table offlinequiz_hotspots. $table->add_index('scannedpageididx', XMLDB_INDEX_NOTUNIQUE, array('scannedpageid')); // Conditionally launch create table for offlinequiz_hotspots. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013061300, 'offlinequiz'); } if ($oldversion < 2013110800) { // Define field timecreated to be added to offlinequiz_queue. $table = new xmldb_table('offlinequiz_queue'); $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'importuserid'); // Conditionally launch add field timecreated. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013110800, 'offlinequiz'); } if ($oldversion < 2013112500) { // Define index offlinequiz_userid_idx (not unique) to be added to offlinequiz_results. $table = new xmldb_table('offlinequiz_results'); $index = new xmldb_index('offlinequiz_userid_idx', XMLDB_INDEX_NOTUNIQUE, array('userid')); // Conditionally launch add index offlinequiz_userid_idx. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2013112500, 'offlinequiz'); } // Moodle v2.8.5+ release upgrade line. // Put any upgrade step following this. if ($oldversion < 2015060500) { // Rename field page on table offlinequiz_group_questions to NEWNAMEGOESHERE. $table = new xmldb_table('offlinequiz_group_questions'); $field = new xmldb_field('pagenumber', XMLDB_TYPE_INTEGER, '4', null, null, null, null, 'position'); // Launch rename field page. $dbman->rename_field($table, $field, 'page'); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2015060500, 'offlinequiz'); } if ($oldversion < 2015060501) { // Rename field page on table offlinequiz_group_questions to NEWNAMEGOESHERE. $table = new xmldb_table('offlinequiz_group_questions'); $field = new xmldb_field('usageslot', XMLDB_TYPE_INTEGER, '4', null, null, null, null, 'position'); // Launch rename field page. $dbman->rename_field($table, $field, 'slot'); // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2015060501, 'offlinequiz'); } if ($oldversion < 2015060502) { // Define field maxmark to be added to offlinequiz_group_questions. $table = new xmldb_table('offlinequiz_group_questions'); $field = new xmldb_field('maxmark', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '1', 'slot'); // Conditionally launch add field maxmark. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2015060502, 'offlinequiz'); } if ($oldversion < 2015060902) { // This upgrade migrates old offlinequiz_q_instances grades (maxgrades) to new // maxmark field in offlinequiz_group_questions. // It also deletes group questions with questionid 0 (pagebreaks) and inserts the // correct page number instead. $numofflinequizzes = $DB->count_records('offlinequiz'); if ($numofflinequizzes > 0) { $pbar = new progress_bar('offlinequizquestionstoslots', 500, true); $pbar->create(); $pbar->update(0, $numofflinequizzes, "Upgrading offlinequiz group questions - {0}/{$numofflinequizzes}."); $numberdone = 0; $offlinequizzes = $DB->get_recordset('offlinequiz', null, 'id', 'id, numgroups'); foreach ($offlinequizzes as $offlinequiz) { $transaction = $DB->start_delegated_transaction(); $groups = $DB->get_records('offlinequiz_groups', array('offlinequizid' => $offlinequiz->id), 'number', '*'); $instancesraw = $DB->get_records('offlinequiz_q_instances', array('offlinequizid' => $offlinequiz->id)); $questioninstances = array(); foreach ($instancesraw as $instance) { if (!array_key_exists($instance->questionid, $questioninstances)) { $questioninstances[$instance->questionid] = $instance; } } foreach ($groups as $group) { $groupquestions = $DB->get_records('offlinequiz_group_questions', array('offlinequizid' => $offlinequiz->id, 'offlinegroupid' => $group->id), 'position'); // For every group we start on page 1. $currentpage = 1; $currentslot = 1; foreach ($groupquestions as $groupquestion) { $needsupdate = false; if ($groupquestion->questionid == 0) { // We remove the old pagebreaks with questionid==0. $DB->delete_records('offlinequiz_group_questions', array('id' => $groupquestion->id)); $currentpage++; continue; } // If the maxmarks in the question instances differs from the default maxmark (1) // of the offlinequiz_group_questions then change it. if (array_key_exists($groupquestion->questionid, $questioninstances) && ($maxmark = floatval($questioninstances[$groupquestion->questionid]->grade)) && abs(floatval($groupquestion->maxmark) - $maxmark) > 0.001) { $groupquestion->maxmark = $maxmark; $needsupdate = true; } // If the page number is not correct, then change it. if ($groupquestion->page != $currentpage) { $groupquestion->page = $currentpage; $needsupdate = true; } // If the slot is not set, then fill it. if (!$groupquestion->slot) { $groupquestion->slot = $currentslot; $needsupdate = true; } if ($needsupdate) { $DB->update_record('offlinequiz_group_questions', $groupquestion); } $currentslot++; } } // Done with this offlinequiz. Update progress bar. $numberdone++; $pbar->update($numberdone, $numofflinequizzes, "Upgrading offlinequiz group questions - {$numberdone}/{$numofflinequizzes}."); $transaction->allow_commit(); } } // Offlinequiz savepoint reached. upgrade_mod_savepoint(true, 2015060902, 'offlinequiz'); } // TODO migrate old offlinequiz_q_instances maxmarks to new maxmark field in offlinequiz_group_questions. // TODO migrate offlinequiz_group_questions to fill in page field correctly. For every group use the // position field to find new pages and insert them. // Adapt offlinequiz code to handle missing zeros as pagebreaks. return true; }
redirect($returnurl); break; case 'restore': if ($clist) { list($usql, $params) = $DB->get_in_or_equal($clist); $DB->set_field_select('cohort', 'component', '', 'id ' . $usql, $params); } redirect($returnurl); break; case 'delete': if ($clist) { set_time_limit(0); echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('auth_cohorttoolmcae', 'auth_mcae')); $progress = new progress_bar('delcohort'); $progress->create(); $delcount = count($clist); $delcurrent = 1; foreach ($clist as $cid) { $cohort = $DB->get_record('cohort', array('contextid' => $context->id, 'id' => $cid)); cohort_delete_cohort($cohort); $progress->update($delcurrent, $delcount, "{$delcurrent} / {$delcount}"); $delcurrent++; } } echo $OUTPUT->continue_button($returnurl); echo $OUTPUT->footer(); die; break; } echo $OUTPUT->footer();
/** * Quiz module upgrade function. * @param string $oldversion the version we are upgrading from. */ function xmldb_quiz_upgrade($oldversion) { global $CFG, $DB; $dbman = $DB->get_manager(); //===== 1.9.0 upgrade line ======// if ($oldversion < 2008062000) { // Define table quiz_report to be created $table = new xmldb_table('quiz_report'); // Adding fields to table quiz_report $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null); $table->add_field('displayorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); // Adding keys to table quiz_report $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Conditionally launch create table for quiz_report if (!$dbman->table_exists($table)) { $dbman->create_table($table); } upgrade_mod_savepoint(true, 2008062000, 'quiz'); } if ($oldversion < 2008062001) { $reporttoinsert = new stdClass(); $reporttoinsert->name = 'overview'; $reporttoinsert->displayorder = 10000; $DB->insert_record('quiz_report', $reporttoinsert); $reporttoinsert = new stdClass(); $reporttoinsert->name = 'responses'; $reporttoinsert->displayorder = 9000; $DB->insert_record('quiz_report', $reporttoinsert); $reporttoinsert = new stdClass(); $reporttoinsert->name = 'regrade'; $reporttoinsert->displayorder = 7000; $DB->insert_record('quiz_report', $reporttoinsert); $reporttoinsert = new stdClass(); $reporttoinsert->name = 'grading'; $reporttoinsert->displayorder = 6000; $DB->insert_record('quiz_report', $reporttoinsert); upgrade_mod_savepoint(true, 2008062001, 'quiz'); } if ($oldversion < 2008072402) { // Define field lastcron to be added to quiz_report $table = new xmldb_table('quiz_report'); $field = new xmldb_field('lastcron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'displayorder'); // Conditionally launch add field lastcron if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Define field cron to be added to quiz_report $field = new xmldb_field('cron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'lastcron'); // Conditionally launch add field cron if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2008072402, 'quiz'); } if ($oldversion < 2008072900) { // Delete the regrade report - it is now part of the overview report. $DB->delete_records('quiz_report', array('name' => 'regrade')); // quiz savepoint reached upgrade_mod_savepoint(true, 2008072900, 'quiz'); } if ($oldversion < 2008081500) { // Define table quiz_question_versions to be dropped $table = new xmldb_table('quiz_question_versions'); // Launch drop table for quiz_question_versions $dbman->drop_table($table); // quiz savepoint reached upgrade_mod_savepoint(true, 2008081500, 'quiz'); } // Changing the type of all the columns that store grades to be NUMBER(10, 5) or similar. if ($oldversion < 2008081501) { // First set all quiz.sumgrades to 0 if they are null. This should never // happen however some users have encountered a null value there. $DB->execute('UPDATE {quiz} SET sumgrades=0 WHERE sumgrades IS NULL'); $table = new xmldb_table('quiz'); $field = new xmldb_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'questions'); $dbman->change_field_type($table, $field); upgrade_mod_savepoint(true, 2008081501, 'quiz'); } if ($oldversion < 2008081502) { $table = new xmldb_table('quiz'); $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'sumgrades'); $dbman->change_field_type($table, $field); upgrade_mod_savepoint(true, 2008081502, 'quiz'); } if ($oldversion < 2008081503) { // First set all quiz.sumgrades to 0 if they are null. This should never // happen however some users have encountered a null value there. $DB->execute('UPDATE {quiz_attempts} SET sumgrades=0 WHERE sumgrades IS NULL'); $table = new xmldb_table('quiz_attempts'); $field = new xmldb_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'attempt'); $dbman->change_field_type($table, $field); upgrade_mod_savepoint(true, 2008081503, 'quiz'); } if ($oldversion < 2008081504) { $table = new xmldb_table('quiz_feedback'); $field = new xmldb_field('mingrade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'feedbacktext'); $dbman->change_field_type($table, $field); upgrade_mod_savepoint(true, 2008081504, 'quiz'); } if ($oldversion < 2008081505) { $table = new xmldb_table('quiz_feedback'); $field = new xmldb_field('maxgrade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'mingrade'); $dbman->change_field_type($table, $field); upgrade_mod_savepoint(true, 2008081505, 'quiz'); } if ($oldversion < 2008081506) { $table = new xmldb_table('quiz_grades'); $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'userid'); $dbman->change_field_type($table, $field); upgrade_mod_savepoint(true, 2008081506, 'quiz'); } if ($oldversion < 2008081507) { $table = new xmldb_table('quiz_question_instances'); $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'question'); $dbman->change_field_type($table, $field); upgrade_mod_savepoint(true, 2008081507, 'quiz'); } // Move all of the quiz config settings from $CFG to the config_plugins table. if ($oldversion < 2008082200) { foreach (get_object_vars($CFG) as $name => $value) { if (strpos($name, 'quiz_') === 0) { $shortname = substr($name, 5); if ($shortname == 'fix_adaptive') { // Special case - remove old inconsistency. $shortname == 'fix_optionflags'; } set_config($shortname, $value, 'quiz'); unset_config($name); } } upgrade_mod_savepoint(true, 2008082200, 'quiz'); } // Now that the quiz is no longer responsible for creating all the question // bank tables, and some of the tables are now the responsibility of the // datasetdependent question type, which did not have a version.php file before, // we need to say that these tables are already installed, otherwise XMLDB // will try to create them again and give an error. if ($oldversion < 2008082600) { // Since MDL-16505 was fixed, and we eliminated the datasetdependent // question type, this is now a no-op. upgrade_mod_savepoint(true, 2008082600, 'quiz'); } if ($oldversion < 2008112101) { // Define field lastcron to be added to quiz_report $table = new xmldb_table('quiz_report'); $field = new xmldb_field('capability', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'cron'); // Conditionally launch add field lastcron if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2008112101, 'quiz'); } if ($oldversion < 2009010700) { // Define field showuserpicture to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('showuserpicture', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'delay2'); // Conditionally launch add field showuserpicture if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2009010700, 'quiz'); } if ($oldversion < 2009030900) { // If there are no quiz settings set to advanced yet, the set up the default // advanced fields from Moodle 2.0. $quizconfig = get_config('quiz'); $arealreadyadvanced = false; foreach (array($quizconfig) as $name => $value) { if (strpos($name, 'fix_') === 0 && !empty($value)) { $arealreadyadvanced = true; break; } } if (!$arealreadyadvanced) { set_config('fix_penaltyscheme', 1, 'quiz'); set_config('fix_attemptonlast', 1, 'quiz'); set_config('fix_questiondecimalpoints', 1, 'quiz'); set_config('fix_password', 1, 'quiz'); set_config('fix_subnet', 1, 'quiz'); set_config('fix_delay1', 1, 'quiz'); set_config('fix_delay2', 1, 'quiz'); set_config('fix_popup', 1, 'quiz'); } // quiz savepoint reached upgrade_mod_savepoint(true, 2009030900, 'quiz'); } if ($oldversion < 2009031000) { // Add new questiondecimaldigits setting, separate form the overall decimaldigits one. $table = new xmldb_table('quiz'); $field = new xmldb_field('questiondecimalpoints', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '-2', 'decimalpoints'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2009031000, 'quiz'); } if ($oldversion < 2009031001) { // Convert quiz.timelimit from minutes to seconds. $DB->execute('UPDATE {quiz} SET timelimit = timelimit * 60'); $default = get_config('quiz', 'timelimit'); set_config('timelimit', 60 * $default, 'quiz'); // quiz savepoint reached upgrade_mod_savepoint(true, 2009031001, 'quiz'); } if ($oldversion < 2009042000) { // Define field introformat to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'intro'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // conditionally migrate to html format in intro if ($CFG->texteditors !== 'textarea') { $rs = $DB->get_recordset('quiz', array('introformat' => FORMAT_MOODLE), '', 'id, intro, introformat'); foreach ($rs as $q) { $q->intro = text_to_html($q->intro, false, false, true); $q->introformat = FORMAT_HTML; $DB->update_record('quiz', $q); upgrade_set_timeout(); } $rs->close(); } // quiz savepoint reached upgrade_mod_savepoint(true, 2009042000, 'quiz'); } if ($oldversion < 2010030501) { // Define table quiz_overrides to be created $table = new xmldb_table('quiz_overrides'); // Adding fields to table quiz_overrides $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('quiz', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $table->add_field('groupid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); $table->add_field('timeopen', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); $table->add_field('timeclose', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); $table->add_field('timelimit', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); $table->add_field('attempts', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, null, null, null); $table->add_field('password', XMLDB_TYPE_CHAR, '255', null, null, null, null); // Adding keys to table quiz_overrides $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); $table->add_key('quiz', XMLDB_KEY_FOREIGN, array('quiz'), 'quiz', array('id')); $table->add_key('groupid', XMLDB_KEY_FOREIGN, array('groupid'), 'groups', array('id')); $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id')); // Conditionally launch create table for quiz_overrides if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // quiz savepoint reached upgrade_mod_savepoint(true, 2010030501, 'quiz'); } if ($oldversion < 2010051800) { // Define field showblocks to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('showblocks', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'showuserpicture'); // Conditionally launch add field showblocks if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2010051800, 'quiz'); } if ($oldversion < 2010080600) { // Define field feedbacktextformat to be added to quiz_feedback $table = new xmldb_table('quiz_feedback'); $field = new xmldb_field('feedbacktextformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'feedbacktext'); // Conditionally launch add field feedbacktextformat if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // This column defaults to FORMAT_MOODLE, which is correct. // quiz savepoint reached upgrade_mod_savepoint(true, 2010080600, 'quiz'); } if ($oldversion < 2010102000) { // Define field showblocks to be added to quiz // Repeat this step, because the column was missing from install.xml for a time. $table = new xmldb_table('quiz'); $field = new xmldb_field('showblocks', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'showuserpicture'); // Conditionally launch add field showblocks if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2010102000, 'quiz'); } if ($oldversion < 2010122300) { // Fix quiz in the post table after upgrade from 1.9 $table = new xmldb_table('quiz'); $columns = $DB->get_columns('quiz'); // quiz.questiondecimalpoints should be int (4) not null default -2 if (array_key_exists('questiondecimalpoints', $columns) && $columns['questiondecimalpoints']->default_value != '-2') { $field = new xmldb_field('questiondecimalpoints', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, -2, 'decimalpoints'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } // quiz.sumgrades should be decimal(10, 5) not null default 0 if (array_key_exists('sumgrades', $columns) && empty($columns['sumgrades']->not_null)) { // First set all quiz.sumgrades to 0 if they are null. This should never // happen however some users have encountered a null value there. $DB->execute('UPDATE {quiz} SET sumgrades=0 WHERE sumgrades IS NULL'); $field = new xmldb_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'questions'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } // quiz.grade should be decimal(10, 5) not null default 0 if (array_key_exists('grade', $columns) && empty($columns['grade']->not_null)) { $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'sumgrades'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } upgrade_mod_savepoint(true, 2010122300, 'quiz'); } if ($oldversion < 2010122301) { // Fix quiz_attempts in the post table after upgrade from 1.9 $table = new xmldb_table('quiz_attempts'); $columns = $DB->get_columns('quiz_attempts'); // quiz_attempts.sumgrades should be decimal(10, 5) not null default 0 if (array_key_exists('sumgrades', $columns) && empty($columns['sumgrades']->not_null)) { // First set all quiz.sumgrades to 0 if they are null. This should never // happen however some users have encountered a null value there. $DB->execute('UPDATE {quiz_attempts} SET sumgrades=0 WHERE sumgrades IS NULL'); $field = new xmldb_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'attempt'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } upgrade_mod_savepoint(true, 2010122301, 'quiz'); } if ($oldversion < 2010122302) { // Fix quiz_feedback in the post table after upgrade from 1.9 $table = new xmldb_table('quiz_feedback'); $columns = $DB->get_columns('quiz_feedback'); // quiz_feedback.mingrade should be decimal(10, 5) not null default 0 if (array_key_exists('mingrade', $columns) && empty($columns['mingrade']->not_null)) { $field = new xmldb_field('mingrade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'feedbacktextformat'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } // quiz_feedback.maxgrade should be decimal(10, 5) not null default 0 if (array_key_exists('maxgrade', $columns) && empty($columns['maxgrade']->not_null)) { // Fixed in earlier upgrade code $field = new xmldb_field('maxgrade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'mingrade'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } upgrade_mod_savepoint(true, 2010122302, 'quiz'); } if ($oldversion < 2010122303) { // Fix quiz_grades in the post table after upgrade from 1.9 $table = new xmldb_table('quiz_grades'); $columns = $DB->get_columns('quiz_grades'); // quiz_grades.grade should be decimal(10, 5) not null default 0 if (array_key_exists('grade', $columns) && empty($columns['grade']->not_null)) { $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'userid'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } upgrade_mod_savepoint(true, 2010122303, 'quiz'); } if ($oldversion < 2010122304) { // Fix quiz_question_instances in the post table after upgrade from 1.9 $table = new xmldb_table('quiz_question_instances'); $columns = $DB->get_columns('quiz_question_instances'); // quiz_question_instances.grade should be decimal(12, 7) not null default 0 if (array_key_exists('grade', $columns) && empty($columns['grade']->not_null)) { $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'question'); if ($dbman->field_exists($table, $field)) { $dbman->change_field_default($table, $field); } } upgrade_mod_savepoint(true, 2010122304, 'quiz'); } //===== 2.1.0 upgrade line ======// // Complete any old upgrade from 1.5 that was never finished. if ($oldversion < 2011051199) { $table = new xmldb_table('question_states'); if ($dbman->table_exists($table)) { $transaction = $DB->start_delegated_transaction(); $oldattempts = $DB->get_records_sql(' SELECT * FROM {quiz_attempts} quiza WHERE uniqueid IN ( SELECT DISTINCT qst.attempt FROM {question_states} qst LEFT JOIN {question_sessions} qsess ON qst.question = qsess.questionid AND qst.attempt = qsess.attemptid WHERE qsess.id IS NULL ) '); if ($oldattempts) { require_once($CFG->dirroot . '/mod/quiz/db/upgradelib.php'); $pbar = new progress_bar('q15upgrade'); $pbar->create(); $a = new stdClass(); $a->outof = count($oldattempts); $a->done = 0; $pbar->update($a->done, $a->outof, get_string('upgradingveryoldquizattempts', 'quiz', $a)); foreach ($oldattempts as $oldattempt) { quiz_upgrade_very_old_question_sessions($oldattempt); $a->done += 1; $pbar->update($a->done, $a->outof, get_string('upgradingveryoldquizattempts', 'quiz', $a)); } } $transaction->allow_commit(); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051199, 'quiz'); } // Add new preferredbehaviour column to the quiz table. if ($oldversion < 2011051200) { $table = new xmldb_table('quiz'); $field = new xmldb_field('preferredbehaviour'); $field->set_attributes(XMLDB_TYPE_CHAR, '32', null, null, null, null, 'timeclose'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051200, 'quiz'); } // Populate preferredbehaviour column based on old optionflags column. if ($oldversion < 2011051201) { if ($dbman->field_exists('quiz', 'optionflags')) { $DB->set_field_select('quiz', 'preferredbehaviour', 'deferredfeedback', 'optionflags = 0'); $DB->set_field_select('quiz', 'preferredbehaviour', 'adaptive', 'optionflags <> 0 AND penaltyscheme <> 0'); $DB->set_field_select('quiz', 'preferredbehaviour', 'adaptivenopenalty', 'optionflags <> 0 AND penaltyscheme = 0'); set_config('preferredbehaviour', 'deferredfeedback', 'quiz'); set_config('fix_preferredbehaviour', 0, 'quiz'); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051201, 'quiz'); } // Add a not-NULL constraint to the preferredmodel field now that it is populated. if ($oldversion < 2011051202) { $table = new xmldb_table('quiz'); $field = new xmldb_field('preferredbehaviour'); $field->set_attributes(XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'timeclose'); $dbman->change_field_notnull($table, $field); // quiz savepoint reached upgrade_mod_savepoint(true, 2011051202, 'quiz'); } // Drop the old optionflags field. if ($oldversion < 2011051203) { $table = new xmldb_table('quiz'); $field = new xmldb_field('optionflags'); if ($dbman->field_exists($table, $field)) { $dbman->drop_field($table, $field); } unset_config('optionflags', 'quiz'); unset_config('fix_optionflags', 'quiz'); // quiz savepoint reached upgrade_mod_savepoint(true, 2011051203, 'quiz'); } // Drop the old penaltyscheme field. if ($oldversion < 2011051204) { $table = new xmldb_table('quiz'); $field = new xmldb_field('penaltyscheme'); if ($dbman->field_exists($table, $field)) { $dbman->drop_field($table, $field); } unset_config('penaltyscheme', 'quiz'); unset_config('fix_penaltyscheme', 'quiz'); // quiz savepoint reached upgrade_mod_savepoint(true, 2011051204, 'quiz'); } if ($oldversion < 2011051205) { // Changing nullability of field sumgrades on table quiz_attempts to null $table = new xmldb_table('quiz_attempts'); $field = new xmldb_field('sumgrades'); $field->set_attributes(XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, 'attempt'); // Launch change of nullability for field sumgrades $dbman->change_field_notnull($table, $field); // Launch change of default for field sumgrades $dbman->change_field_default($table, $field); // quiz savepoint reached upgrade_mod_savepoint(true, 2011051205, 'quiz'); } if ($oldversion < 2011051207) { // Define field reviewattempt to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('reviewattempt'); $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'review'); // Launch add field reviewattempt if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051207, 'quiz'); } if ($oldversion < 2011051208) { // Define field reviewattempt to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('reviewcorrectness'); $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reviewattempt'); // Launch add field reviewattempt if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051208, 'quiz'); } if ($oldversion < 2011051209) { // Define field reviewattempt to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('reviewmarks'); $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reviewcorrectness'); // Launch add field reviewattempt if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051209, 'quiz'); } if ($oldversion < 2011051210) { // Define field reviewattempt to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('reviewspecificfeedback'); $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reviewmarks'); // Launch add field reviewattempt if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051210, 'quiz'); } if ($oldversion < 2011051211) { // Define field reviewattempt to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('reviewgeneralfeedback'); $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reviewspecificfeedback'); // Launch add field reviewattempt if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051211, 'quiz'); } if ($oldversion < 2011051212) { // Define field reviewattempt to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('reviewrightanswer'); $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reviewgeneralfeedback'); // Launch add field reviewattempt if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051212, 'quiz'); } if ($oldversion < 2011051213) { // Define field reviewattempt to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('reviewoverallfeedback'); $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reviewrightanswer'); // Launch add field reviewattempt if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051213, 'quiz'); } define('QUIZ_NEW_DURING', 0x10000); define('QUIZ_NEW_IMMEDIATELY_AFTER', 0x01000); define('QUIZ_NEW_LATER_WHILE_OPEN', 0x00100); define('QUIZ_NEW_AFTER_CLOSE', 0x00010); define('QUIZ_OLD_IMMEDIATELY', 0x3c003f); define('QUIZ_OLD_OPEN', 0x3c00fc0); define('QUIZ_OLD_CLOSED', 0x3c03f000); define('QUIZ_OLD_RESPONSES', 1*0x1041); // Show responses define('QUIZ_OLD_SCORES', 2*0x1041); // Show scores define('QUIZ_OLD_FEEDBACK', 4*0x1041); // Show question feedback define('QUIZ_OLD_ANSWERS', 8*0x1041); // Show correct answers define('QUIZ_OLD_SOLUTIONS', 16*0x1041); // Show solutions define('QUIZ_OLD_GENERALFEEDBACK', 32*0x1041); // Show question general feedback define('QUIZ_OLD_OVERALLFEEDBACK', 1*0x4440000); // Show quiz overall feedback // Copy the old review settings if ($oldversion < 2011051214) { if ($dbman->field_exists('quiz', 'review')) { $DB->execute(" UPDATE {quiz} SET reviewattempt = " . $DB->sql_bitor($DB->sql_bitor( QUIZ_NEW_DURING, 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_RESPONSES) . ' <> 0 THEN ' . QUIZ_NEW_IMMEDIATELY_AFTER . ' ELSE 0 END'), $DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_OPEN & QUIZ_OLD_RESPONSES) . ' <> 0 THEN ' . QUIZ_NEW_LATER_WHILE_OPEN . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_CLOSED & QUIZ_OLD_RESPONSES) . ' <> 0 THEN ' . QUIZ_NEW_AFTER_CLOSE . ' ELSE 0 END')) . " "); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051214, 'quiz'); } if ($oldversion < 2011051215) { if ($dbman->field_exists('quiz', 'review')) { $DB->execute(" UPDATE {quiz} SET reviewcorrectness = " . $DB->sql_bitor($DB->sql_bitor( QUIZ_NEW_DURING, 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES) . ' <> 0 THEN ' . QUIZ_NEW_IMMEDIATELY_AFTER . ' ELSE 0 END'), $DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_OPEN & QUIZ_OLD_SCORES) . ' <> 0 THEN ' . QUIZ_NEW_LATER_WHILE_OPEN . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES) . ' <> 0 THEN ' . QUIZ_NEW_AFTER_CLOSE . ' ELSE 0 END')) . " "); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051215, 'quiz'); } if ($oldversion < 2011051216) { if ($dbman->field_exists('quiz', 'review')) { $DB->execute(" UPDATE {quiz} SET reviewmarks = " . $DB->sql_bitor($DB->sql_bitor( QUIZ_NEW_DURING, 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES) . ' <> 0 THEN ' . QUIZ_NEW_IMMEDIATELY_AFTER . ' ELSE 0 END'), $DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_OPEN & QUIZ_OLD_SCORES) . ' <> 0 THEN ' . QUIZ_NEW_LATER_WHILE_OPEN . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES) . ' <> 0 THEN ' . QUIZ_NEW_AFTER_CLOSE . ' ELSE 0 END')) . " "); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051216, 'quiz'); } if ($oldversion < 2011051217) { if ($dbman->field_exists('quiz', 'review')) { $DB->execute(" UPDATE {quiz} SET reviewspecificfeedback = " . $DB->sql_bitor($DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_DURING . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_IMMEDIATELY_AFTER . ' ELSE 0 END'), $DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_OPEN & QUIZ_OLD_FEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_LATER_WHILE_OPEN . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_CLOSED & QUIZ_OLD_FEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_AFTER_CLOSE . ' ELSE 0 END')) . " "); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051217, 'quiz'); } if ($oldversion < 2011051218) { if ($dbman->field_exists('quiz', 'review')) { $DB->execute(" UPDATE {quiz} SET reviewgeneralfeedback = " . $DB->sql_bitor($DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_DURING . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_IMMEDIATELY_AFTER . ' ELSE 0 END'), $DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_OPEN & QUIZ_OLD_GENERALFEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_LATER_WHILE_OPEN . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_CLOSED & QUIZ_OLD_GENERALFEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_AFTER_CLOSE . ' ELSE 0 END')) . " "); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051218, 'quiz'); } if ($oldversion < 2011051219) { if ($dbman->field_exists('quiz', 'review')) { $DB->execute(" UPDATE {quiz} SET reviewrightanswer = " . $DB->sql_bitor($DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS) . ' <> 0 THEN ' . QUIZ_NEW_DURING . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS) . ' <> 0 THEN ' . QUIZ_NEW_IMMEDIATELY_AFTER . ' ELSE 0 END'), $DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_OPEN & QUIZ_OLD_ANSWERS) . ' <> 0 THEN ' . QUIZ_NEW_LATER_WHILE_OPEN . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_CLOSED & QUIZ_OLD_ANSWERS) . ' <> 0 THEN ' . QUIZ_NEW_AFTER_CLOSE . ' ELSE 0 END')) . " "); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051219, 'quiz'); } if ($oldversion < 2011051220) { if ($dbman->field_exists('quiz', 'review')) { $DB->execute(" UPDATE {quiz} SET reviewoverallfeedback = " . $DB->sql_bitor($DB->sql_bitor( 0, 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_OVERALLFEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_IMMEDIATELY_AFTER . ' ELSE 0 END'), $DB->sql_bitor( 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_OPEN & QUIZ_OLD_OVERALLFEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_LATER_WHILE_OPEN . ' ELSE 0 END', 'CASE WHEN ' . $DB->sql_bitand('review', QUIZ_OLD_CLOSED & QUIZ_OLD_OVERALLFEEDBACK) . ' <> 0 THEN ' . QUIZ_NEW_AFTER_CLOSE . ' ELSE 0 END')) . " "); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051220, 'quiz'); } // And, do the same for the defaults if ($oldversion < 2011051221) { $quizrevew = get_config('quiz', 'review'); if (!empty($quizrevew)) { set_config('reviewattempt', QUIZ_NEW_DURING | ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_RESPONSES ? QUIZ_NEW_IMMEDIATELY_AFTER : 0) | ($quizrevew & QUIZ_OLD_OPEN & QUIZ_OLD_RESPONSES ? QUIZ_NEW_LATER_WHILE_OPEN : 0) | ($quizrevew & QUIZ_OLD_CLOSED & QUIZ_OLD_RESPONSES ? QUIZ_NEW_AFTER_CLOSE : 0), 'quiz'); set_config('reviewcorrectness', QUIZ_NEW_DURING | ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES ? QUIZ_NEW_IMMEDIATELY_AFTER : 0) | ($quizrevew & QUIZ_OLD_OPEN & QUIZ_OLD_SCORES ? QUIZ_NEW_LATER_WHILE_OPEN : 0) | ($quizrevew & QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES ? QUIZ_NEW_AFTER_CLOSE : 0), 'quiz'); set_config('reviewmarks', QUIZ_NEW_DURING | ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES ? QUIZ_NEW_IMMEDIATELY_AFTER : 0) | ($quizrevew & QUIZ_OLD_OPEN & QUIZ_OLD_SCORES ? QUIZ_NEW_LATER_WHILE_OPEN : 0) | ($quizrevew & QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES ? QUIZ_NEW_AFTER_CLOSE : 0), 'quiz'); set_config('reviewspecificfeedback', ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK ? QUIZ_NEW_DURING : 0) | ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK ? QUIZ_NEW_IMMEDIATELY_AFTER : 0) | ($quizrevew & QUIZ_OLD_OPEN & QUIZ_OLD_FEEDBACK ? QUIZ_NEW_LATER_WHILE_OPEN : 0) | ($quizrevew & QUIZ_OLD_CLOSED & QUIZ_OLD_FEEDBACK ? QUIZ_NEW_AFTER_CLOSE : 0), 'quiz'); set_config('reviewgeneralfeedback', ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK ? QUIZ_NEW_DURING : 0) | ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK ? QUIZ_NEW_IMMEDIATELY_AFTER : 0) | ($quizrevew & QUIZ_OLD_OPEN & QUIZ_OLD_GENERALFEEDBACK ? QUIZ_NEW_LATER_WHILE_OPEN : 0) | ($quizrevew & QUIZ_OLD_CLOSED & QUIZ_OLD_GENERALFEEDBACK ? QUIZ_NEW_AFTER_CLOSE : 0), 'quiz'); set_config('reviewrightanswer', ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS ? QUIZ_NEW_DURING : 0) | ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS ? QUIZ_NEW_IMMEDIATELY_AFTER : 0) | ($quizrevew & QUIZ_OLD_OPEN & QUIZ_OLD_ANSWERS ? QUIZ_NEW_LATER_WHILE_OPEN : 0) | ($quizrevew & QUIZ_OLD_CLOSED & QUIZ_OLD_ANSWERS ? QUIZ_NEW_AFTER_CLOSE : 0), 'quiz'); set_config('reviewoverallfeedback', 0 | ($quizrevew & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_OVERALLFEEDBACK ? QUIZ_NEW_IMMEDIATELY_AFTER : 0) | ($quizrevew & QUIZ_OLD_OPEN & QUIZ_OLD_OVERALLFEEDBACK ? QUIZ_NEW_LATER_WHILE_OPEN : 0) | ($quizrevew & QUIZ_OLD_CLOSED & QUIZ_OLD_OVERALLFEEDBACK ? QUIZ_NEW_AFTER_CLOSE : 0), 'quiz'); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051221, 'quiz'); } // Finally drop the old column if ($oldversion < 2011051222) { // Define field review to be dropped from quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('review'); // Launch drop field review if ($dbman->field_exists($table, $field)) { $dbman->drop_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051222, 'quiz'); } if ($oldversion < 2011051223) { unset_config('review', 'quiz'); // quiz savepoint reached upgrade_mod_savepoint(true, 2011051223, 'quiz'); } if ($oldversion < 2011051225) { // Define table quiz_report to be renamed to quiz_reports $table = new xmldb_table('quiz_report'); // Launch rename table for quiz_reports if ($dbman->table_exists($table)) { $dbman->rename_table($table, 'quiz_reports'); } upgrade_mod_savepoint(true, 2011051225, 'quiz'); } if ($oldversion < 2011051226) { // Define index name (unique) to be added to quiz_reports $table = new xmldb_table('quiz_reports'); $index = new xmldb_index('name', XMLDB_INDEX_UNIQUE, array('name')); // Conditionally launch add index name if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } upgrade_mod_savepoint(true, 2011051226, 'quiz'); } if ($oldversion < 2011051227) { // Changing nullability of field sumgrades on table quiz_attempts to null $table = new xmldb_table('quiz_attempts'); $field = new xmldb_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, 'attempt'); // Launch change of nullability for field sumgrades $dbman->change_field_notnull($table, $field); // quiz savepoint reached upgrade_mod_savepoint(true, 2011051227, 'quiz'); } if ($oldversion < 2011051228) { // Define field needsupgradetonewqe to be added to quiz_attempts $table = new xmldb_table('quiz_attempts'); $field = new xmldb_field('needsupgradetonewqe', XMLDB_TYPE_INTEGER, '3', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'preview'); // Launch add field needsupgradetonewqe if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } $DB->set_field('quiz_attempts', 'needsupgradetonewqe', 1); // quiz savepoint reached upgrade_mod_savepoint(true, 2011051228, 'quiz'); } if ($oldversion < 2011051229) { $table = new xmldb_table('question_states'); if ($dbman->table_exists($table)) { // First delete all data from preview attempts. $DB->delete_records_select('question_states', "attempt IN (SELECT uniqueid FROM {quiz_attempts} WHERE preview = 1)"); $DB->delete_records_select('question_sessions', "attemptid IN (SELECT uniqueid FROM {quiz_attempts} WHERE preview = 1)"); $DB->delete_records('quiz_attempts', array('preview' => 1)); // Now update all the old attempt data. $oldrcachesetting = $CFG->rcache; $CFG->rcache = false; require_once($CFG->dirroot . '/question/engine/upgrade/upgradelib.php'); $upgrader = new question_engine_attempt_upgrader(); $upgrader->convert_all_quiz_attempts(); $CFG->rcache = $oldrcachesetting; } // quiz savepoint reached upgrade_mod_savepoint(true, 2011051229, 'quiz'); } // Moodle v2.1.0 release upgrade line // Put any upgrade step following this if ($oldversion < 2011100600) { // Define field browsersecurity to be added to quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('browsersecurity', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, '[unknownvalue]', 'subnet'); // Conditionally launch add field browsersecurity if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011100600, 'quiz'); } if ($oldversion < 2011100601) { $DB->set_field('quiz', 'browsersecurity', '-', array('popup' => 0)); $DB->set_field('quiz', 'browsersecurity', 'securewindow', array('popup' => 1)); $DB->set_field('quiz', 'browsersecurity', 'safebrowser', array('popup' => 2)); upgrade_mod_savepoint(true, 2011100601, 'quiz'); } if ($oldversion < 2011100602) { // Changing the default of field browsersecurity on table quiz to drop it $table = new xmldb_table('quiz'); $field = new xmldb_field('browsersecurity', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'subnet'); // Launch change of default for field browsersecurity $dbman->change_field_default($table, $field); // quiz savepoint reached upgrade_mod_savepoint(true, 2011100602, 'quiz'); } if ($oldversion < 2011100603) { // Define field popup to be dropped from quiz $table = new xmldb_table('quiz'); $field = new xmldb_field('popup'); // Conditionally launch drop field popup if ($dbman->field_exists($table, $field)) { $dbman->drop_field($table, $field); } // quiz savepoint reached upgrade_mod_savepoint(true, 2011100603, 'quiz'); } if ($oldversion < 2011100604) { switch (get_config('quiz', 'popup')) { case 1: set_config('browsersecurity', 'securewindow', 'quiz'); break; case 2: set_config('browsersecurity', 'safebrowser', 'quiz'); break; default: set_config('browsersecurity', '-', 'quiz'); } unset_config('quiz', 'popup'); set_config('browsersecurity_adv', get_config('quiz', 'popup_adv'), 'quiz'); unset_config('quiz', 'popup_adv'); upgrade_mod_savepoint(true, 2011100604, 'quiz'); } // Moodle v2.2.0 release upgrade line // Put any upgrade step following this return true; }
admin_externalpage_setup('toolcustomlang'); $langs = get_string_manager()->get_list_of_translations(); // pre-output actions if ($action === 'checkout') { require_sesskey(); require_capability('tool/customlang:edit', context_system::instance()); if (empty($lng)) { print_error('missingparameter'); } $PAGE->set_cacheable(false); // progress bar is used here $output = $PAGE->get_renderer('tool_customlang'); echo $output->header(); echo $output->heading(get_string('pluginname', 'tool_customlang')); $progressbar = new progress_bar(); $progressbar->create(); // prints the HTML code of the progress bar // we may need a bit of extra execution time and memory here core_php_time_limit::raise(HOURSECS); raise_memory_limit(MEMORY_EXTRA); tool_customlang_utils::checkout($lng, $progressbar); echo $output->continue_button(new moodle_url('/admin/tool/customlang/edit.php', array('lng' => $lng)), 'get'); echo $output->footer(); exit; } if ($action === 'checkin') { require_sesskey(); require_capability('tool/customlang:edit', context_system::instance()); if (empty($lng)) { print_error('missingparameter'); }
/** * Crea un archivo PDF a partir de un quiz, agregando una hoja de respuestas de opción múltiple * * @param unknown $cm * @param string $debug * @param string $context * @param string $course * @param string $logofilepath * @param boolean $answersheetsonly * @return void|NULL */ function emarking_create_quiz_pdf($cm, $debug = false, $context = null, $course = null, $answersheetsonly = false, $pbar = false) { global $DB, $CFG, $OUTPUT; // Inclusión de librerías require_once $CFG->dirroot . '/mod/assign/feedback/editpdf/fpdi/fpdi2tcpdf_bridge.php'; require_once $CFG->dirroot . '/mod/assign/feedback/editpdf/fpdi/fpdi.php'; require_once $CFG->libdir . '/pdflib.php'; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; require_once $CFG->dirroot . '/mod/emarking/print/locallib.php'; $filedir = $CFG->dataroot . "/temp/emarking/{$context->id}"; emarking_initialize_directory($filedir, true); $fileimg = $CFG->dataroot . "/temp/emarking/{$context->id}/qr"; emarking_initialize_directory($fileimg, true); $userimgdir = $CFG->dataroot . "/temp/emarking/{$context->id}/u"; emarking_initialize_directory($userimgdir, true); $logofile = emarking_get_logo_file(); $logofilepath = $logofile ? emarking_get_path_from_hash($filedir, $logofile->get_pathnamehash()) : null; $fullhtml = array(); $numanswers = array(); $attemptids = array(); $images = array(); $imageshtml = array(); $users = emarking_get_enroled_students($course->id); if ($pbar) { echo $OUTPUT->heading(get_string('loadingquestions', 'mod_emarking'), 3); $progressbar = new progress_bar(); $progressbar->create(); $progressbar->update(0, count($users), get_string('processing', 'mod_emarking')); } $current = 0; foreach ($users as $user) { $current++; if ($pbar) { $progressbar->update($current, count($users), "{$user->firstname}, {$user->lastname}"); } // Get the quiz object $quizobj = quiz::create($cm->instance, $user->id); // Create the new attempt and initialize the question sessions $attemptnumber = 1; $lastattempt = null; $timenow = time(); // Update time now, in case the server is running really slowly. $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $user->id, 'all'); $numattempts = count($attempts); foreach ($attempts as $attempt) { $attemptobj = quiz_attempt::create($attempt->id); $slots = $attemptobj->get_slots(); foreach ($slots as $slot) { $qattempt = $attemptobj->get_question_attempt($slot); $question = $qattempt->get_question(); if ($question->get_type_name() === 'multianswer') { $q = $question->subquestions[1]; $numanswers[$user->id][] = count($q->answers); } else { if ($question->get_type_name() === 'multichoice') { $numanswers[$user->id][] = count($question->answers); } } $attemptids[$user->id] = $attempt->id; $qhtml = $attemptobj->render_question($slot, false); $qhtml = emarking_clean_question_html($qhtml); $currentimages = emarking_extract_images_url($qhtml); $idx = 0; foreach ($currentimages[1] as $imageurl) { if (!array_search($imageurl, $images)) { $images[] = $imageurl; $imageshtml[] = $currentimages[0][$idx]; } $idx++; } $fullhtml[$user->id][] = $qhtml; } // One attempt per user break; } } $save_to = $CFG->tempdir . '/emarking/printquiz/' . $cm->id . '/'; emarking_initialize_directory($save_to, true); // Bajar las imágenes del HTML a dibujar $search = array(); $replace = array(); $replaceweb = array(); $imagesize = array(); $idx = 0; if ($pbar) { $progressbar->update_full(100, get_string('finished', 'mod_emarking')); echo $OUTPUT->heading(get_string('downloadingimages', 'mod_emarking'), 3); $progressbar = new progress_bar(); $progressbar->create(); $progressbar->update(0, count($images), get_string('processing', 'mod_emarking')); } foreach ($images as $image) { if ($pbar) { $imagefilename = explode("/", $image); $progressbar->update($idx + 1, count($images), $imagefilename[count($imagefilename) - 1]); } // Si solamente incluiremos hojas de respuesta terminamos el ciclo if ($answersheetsonly) { break; } if (!(list($filename, $imageinfo) = emarking_get_file_from_url($image, $save_to))) { echo "Problem downloading file {$image} <hr>"; } else { // Buscamos el src de la imagen $search[] = 'src="' . $image . '"'; $replacehtml = ' src="' . $filename . '"'; $replacehtmlxweb = ' src="' . $image . '"'; // Si el html de la misma contiene ancho o alto, se deja tal cual $imghtml = $imageshtml[$idx]; if (substr_count($imghtml, "width") + substr_count($imghtml, "height") == 0) { $width = $imageinfo[0]; $height = $imageinfo[1]; $ratio = floatval(10) / floatval($height); $height = 10; $width = (int) ($ratio * floatval($width)); $sizehtml = 'width="' . $width . '" height="' . $height . '"'; $replacehtml = $sizehtml . ' ' . $replacehtml; $replacehtmlxweb = $sizehtml . ' ' . $replacehtmlxweb; } $replace[] = $replacehtml; $replaceweb[] = $replacehtmlxweb; $imagesize[] = $imageinfo; } $idx++; } if ($debug) { foreach ($fullhtml as $uid => $questions) { $index = 0; foreach ($questions as $question) { echo str_replace($search, $replaceweb, $fullhtml[$uid][$index]); $index++; } } return; } // Now we create the pdf file with the modified html $doc = new FPDI(); $doc->setPrintHeader(false); $doc->setPrintFooter(false); $doc->SetFont('times', '', 12); // set margins $doc->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); $doc->SetHeaderMargin(250); $doc->SetFooterMargin(PDF_MARGIN_FOOTER); if ($pbar) { $progressbar->update_full(100, get_string('finished', 'mod_emarking')); echo $OUTPUT->heading(get_string('creatingpdffile', 'mod_emarking'), 3); $progressbar = new progress_bar(); $progressbar->create(); } $current = 0; foreach ($fullhtml as $uid => $questions) { $current++; $stinfo = $DB->get_record('user', array('id' => $uid)); $stinfo->name = $stinfo->firstname . ' ' . $stinfo->lastname; $stinfo->picture = emarking_get_student_picture($stinfo, $userimgdir); $stinfo->idnumber = $uid . '-' . $attemptids[$uid]; if ($pbar) { $progressbar->update($current, count($fullhtml), $stinfo->name); } $groups = groups_get_user_groups($course->id, $uid); if ($groups && isset($groups[0][0]) && ($group = $DB->get_record('groups', array('id' => $groups[0][0])))) { $stinfo->group = $group->name; } else { $stinfo->group = ''; } emarking_add_answer_sheet($doc, $filedir, $stinfo, $logofilepath, null, $fileimg, $course, $quizobj->get_quiz_name(), $numanswers[$uid], $attemptids[$uid]); // Una vez agregada la página de respuestas, si es todo lo que hay que hacer saltar al siguiente if ($answersheetsonly) { continue; } $doc->AddPage(); emarking_draw_header($doc, $stinfo, $quizobj->get_quiz_name(), 2, $fileimg, $logofilepath, $course, null, false, 0); $doc->SetFont('times', '', 12); $doc->SetAutoPageBreak(true); $doc->SetXY(PDF_MARGIN_LEFT, 40); $index = 0; foreach ($questions as $question) { $prevy = $doc->getY(); $fullhtml[$uid][$index] = str_replace($search, $replace, $fullhtml[$uid][$index]); $doc->writeHTML($fullhtml[$uid][$index]); $y = $doc->getY(); $fmargin = $doc->getFooterMargin(); $height = $doc->getPageHeight(); $spaceleft = $height - $fmargin - $y; $questionsize = $y - $prevy; if ($spaceleft < 70) { $doc->AddPage(); } $index++; } } if ($pbar) { $progressbar->update_full(100, get_string('finished', 'mod_emarking')); } $qid = $quizobj->get_quizid(); $pdfquizfilename = 'quiz-' . $qid . '-' . random_string() . '.pdf'; $fs = get_file_storage(); $filerecord = array('component' => 'mod_emarking', 'filearea' => 'pdfquiz', 'contextid' => $context->id, 'itemid' => $quizobj->get_quizid(), 'filepath' => '/', 'filename' => $pdfquizfilename); $doc->Output($filedir . '/' . $pdfquizfilename, 'F'); $file = $fs->create_file_from_pathname($filerecord, $filedir . '/' . $pdfquizfilename); $downloadurl = moodle_url::make_file_url("{$CFG->wwwroot}/pluginfile.php", "/{$context->id}/mod_emarking/pdfquiz/{$qid}/{$pdfquizfilename}", null, true); return $downloadurl; }
continue; } emarking_insert_user_answers($choices, $user, $attemptid); } echo $OUTPUT->notification(get_string('csvimportsuccessfull', 'mod_emarking'), 'notifysuccess'); echo $OUTPUT->single_button(new moodle_url('/mod/emarking/orm/processomr.php', array('cmid' => $cm->id, 'finish' => true)), get_string('finish', 'mod_emarking')); } else { $answersform->display(); } echo $OUTPUT->footer(); die; } // Get the users enrolled $users = emarking_get_enroled_students($course->id); $pbar = new progress_bar(); $pbar->create(); if ($create) { quiz_delete_all_attempts($quiz); } $cur = 1; $total = count($users); // Insert answers or finish the attempt for each student foreach ($users as $user) { $pbar->update($cur, $total, get_string('processing', 'mod_emarking') . $user->lastname . $user->firstname); flush(); // Get the quiz instance for the specific student $quizobj = quiz::create($cm->instance, $user->id); // Get all the attempts $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $user->id, 'all'); if ($create) { emarking_add_user_attempt($cm, $user);
function offlinequiz_evaluation_cron($jobid = 0, $verbose = false) { global $CFG, $DB; raise_memory_limit(MEMORY_EXTRA); // Only count the jobs with status processing that have been started in the last 24 hours. $expiretime = time() - 86400; $runningsql = "SELECT COUNT(*)\n FROM {offlinequiz_queue}\n WHERE status = 'processing'\n AND timestart > :expiretime"; $runningjobs = $DB->count_records_sql($runningsql, array('expiretime' => $expiretime)); if ($runningjobs >= OFFLINEQUIZ_MAX_CRON_JOBS) { echo "Too many jobs running! Exiting!"; return; } // TODO do this properly. Just for testing. $sql = "SELECT * FROM {offlinequiz_queue} WHERE status = 'new'"; $params = array(); if ($jobid) { $sql .= ' AND id = :jobid '; $params['jobid'] = $jobid; } $sql .= " ORDER BY id ASC"; // If there are no new jobs, we simply exit. if (!($jobs = $DB->get_records_sql($sql, $params, 0, OFFLINEQUIZ_TOP_QUEUE_JOBS))) { if ($verbose) { echo get_string('nothingtodo', 'offlinequiz'); } return; } $numberofjobs = count($jobs); if ($verbose) { $pbar = new progress_bar('offlinequizcronbar', 500, true); $pbar->create(); $pbar->update(0, $numberofjobs, "Processing job - {0}/{$numberofjobs}."); } $numberdone = 0; foreach ($jobs as $job) { // Check whether the status is still 'new' (might have been changed by other cronjob). $transaction = $DB->start_delegated_transaction(); $status = $DB->get_field('offlinequiz_queue', 'status', array('id' => $job->id)); if ($status == 'new') { $DB->set_field('offlinequiz_queue', 'status', 'processing', array('id' => $job->id)); $job->timestart = time(); $DB->set_field('offlinequiz_queue', 'timestart', $job->timestart, array('id' => $job->id)); $alreadydone = false; } else { $alreadydone = true; } $transaction->allow_commit(); // If the job is still new, process it! if (!$alreadydone) { // Set up the context for this job. if (!($offlinequiz = $DB->get_record('offlinequiz', array('id' => $job->offlinequizid)))) { $DB->set_field('offlinequiz_queue', 'status', 'error', array('id' => $job->id)); $DB->set_field('offlinequiz_queue', 'info', 'offlinequiz not found', array('id' => $job->id)); continue; } if (!($course = $DB->get_record('course', array('id' => $offlinequiz->course)))) { $DB->set_field('offlinequiz_queue', 'status', 'error', array('id' => $job->id)); $DB->set_field('offlinequiz_queue', 'info', 'course not found', array('id' => $job->id)); continue; } if (!($cm = get_coursemodule_from_instance("offlinequiz", $offlinequiz->id, $course->id))) { $DB->set_field('offlinequiz_queue', 'status', 'error', array('id' => $job->id)); $DB->set_field('offlinequiz_queue', 'info', 'course module found', array('id' => $job->id)); continue; } if (!($context = context_module::instance($cm->id))) { $DB->set_field('offlinequiz_queue', 'status', 'error', array('id' => $job->id)); $DB->set_field('offlinequiz_queue', 'info', 'context not found', array('id' => $job->id)); continue; } if (!($groups = $DB->get_records('offlinequiz_groups', array('offlinequizid' => $offlinequiz->id), 'number', '*', 0, $offlinequiz->numgroups))) { $DB->set_field('offlinequiz_queue', 'status', 'error', array('id' => $job->id)); $DB->set_field('offlinequiz_queue', 'info', 'no offlinequiz groups found', array('id' => $job->id)); continue; } $coursecontext = context_course::instance($course->id); offlinequiz_load_useridentification(); // TODO. $jobdata = $DB->get_records_sql("\n SELECT *\n FROM {offlinequiz_queue_data}\n WHERE queueid = :queueid\n AND status = 'new'", array('queueid' => $job->id)); list($maxquestions, $maxanswers, $formtype, $questionsperpage) = offlinequiz_get_question_numbers($offlinequiz, $groups); $dirname = ''; $doubleentry = 0; foreach ($jobdata as $data) { $starttime = time(); $DB->set_field('offlinequiz_queue_data', 'status', 'processing', array('id' => $data->id)); // We remember the directory name to be able to remove it later. if (empty($dirname)) { $pathparts = pathinfo($data->filename); $dirname = $pathparts['dirname']; } set_time_limit(120); try { // Create a new scanner for every page. $scanner = new offlinequiz_page_scanner($offlinequiz, $context->id, $maxquestions, $maxanswers); // Try to load the image file. echo 'job ' . $job->id . ': evaluating ' . $data->filename . "\n"; $scannedpage = $scanner->load_image($data->filename); if ($scannedpage->status == 'ok') { echo 'job ' . $job->id . ': image loaded ' . $scannedpage->filename . "\n"; } else { if ($scannedpage->error == 'filenotfound') { echo 'job ' . $job->id . ': image file not found: ' . $scannedpage->filename . "\n"; } } // Unset the origfilename because we don't need it in the DB. unset($scannedpage->origfilename); $scannedpage->offlinequizid = $offlinequiz->id; // If we could load the image file, the status is 'ok', so we can check the page for errors. if ($scannedpage->status == 'ok') { // We autorotate so check_scanned_page will return a potentially new scanner and the scannedpage. list($scanner, $scannedpage) = offlinequiz_check_scanned_page($offlinequiz, $scanner, $scannedpage, $job->importuserid, $coursecontext, true); } else { if (property_exists($scannedpage, 'id') && !empty($scannedpage->id)) { $DB->update_record('offlinequiz_scanned_pages', $scannedpage); } else { $scannedpage->id = $DB->insert_record('offlinequiz_scanned_pages', $scannedpage); } } echo 'job ' . $job->id . ': scannedpage id ' . $scannedpage->id . "\n"; // If the status is still 'ok', we can process the answers. This potentially submits the page and // checks whether the result for a student is complete. if ($scannedpage->status == 'ok') { // We can process the answers and submit them if possible. $scannedpage = offlinequiz_process_scanned_page($offlinequiz, $scanner, $scannedpage, $job->importuserid, $questionsperpage, $coursecontext, true); echo 'job ' . $job->id . ': processed answers for ' . $scannedpage->id . "\n"; } else { if ($scannedpage->status == 'error' && $scannedpage->error == 'resultexists') { // Already process the answers but don't submit them. $scannedpage = offlinequiz_process_scanned_page($offlinequiz, $scanner, $scannedpage, $job->importuserid, $questionsperpage, $coursecontext, false); // Compare the old and the new result wrt. the choices. $scannedpage = offlinequiz_check_different_result($scannedpage); } } // If there is something to correct then store the hotspots for retrieval in correct.php. if ($scannedpage->status != 'ok' && $scannedpage->error != 'couldnotgrab' && $scannedpage->error != 'notadjusted' && $scannedpage->error != 'grouperror') { $scanner->store_hotspots($scannedpage->id); } if ($scannedpage->status == 'ok' || $scannedpage->status == 'submitted' || $scannedpage->status == 'suspended' || $scannedpage->error == 'missingpages') { // Mark the file as processed. $DB->set_field('offlinequiz_queue_data', 'status', 'processed', array('id' => $data->id)); } else { $DB->set_field('offlinequiz_queue_data', 'status', 'error', array('id' => $data->id)); $DB->set_field('offlinequiz_queue_data', 'error', $scannedpage->error, array('id' => $data->id)); } if ($scannedpage->error == 'doublepage') { $doubleentry++; } } catch (Exception $e) { echo 'job ' . $job->id . ': ' . $e->getMessage() . "\n"; $DB->set_field('offlinequiz_queue_data', 'status', 'error', array('id' => $data->id)); $DB->set_field('offlinequiz_queue_data', 'error', 'couldnotgrab', array('id' => $data->id)); $DB->set_field('offlinequiz_queue_data', 'info', $e->getMessage(), array('id' => $data->id)); $scannedpage->status = 'error'; $scannedpage->error = 'couldnotgrab'; if ($scannedpage->id) { $DB->update_record('offlinequiz_scanned_pages', $scannedpage); } else { $DB->insert_record('offlinequiz_scanned_pages', $scannedpage); } } } // End foreach jobdata. offlinequiz_update_grades($offlinequiz); $job->timefinish = time(); $DB->set_field('offlinequiz_queue', 'timefinish', $job->timefinish, array('id' => $job->id)); $job->status = 'finished'; $DB->set_field('offlinequiz_queue', 'status', 'finished', array('id' => $job->id)); echo date('Y-m-d-H:i') . ": Import queue with id {$job->id} imported.\n\n"; if ($user = $DB->get_record('user', array('id' => $job->importuserid))) { $mailtext = get_string('importisfinished', 'offlinequiz', format_text($offlinequiz->name, FORMAT_PLAIN)); // How many pages have been imported successfully. $countsql = "SELECT COUNT(id)\n FROM {offlinequiz_queue_data}\n WHERE queueid = :queueid\n AND status = 'processed'"; $params = array('queueid' => $job->id); $mailtext .= "\n\n" . get_string('importnumberpages', 'offlinequiz', $DB->count_records_sql($countsql, $params)); // How many pages have an error. $countsql = "SELECT COUNT(id)\n FROM {offlinequiz_queue_data}\n WHERE queueid = :queueid\n AND status = 'error'"; $mailtext .= "\n" . get_string('importnumberverify', 'offlinequiz', $DB->count_records_sql($countsql, $params)); $mailtext .= "\n" . get_string('importnumberexisting', 'offlinequiz', $doubleentry); $linkoverview = "{$CFG->wwwroot}/mod/offlinequiz/report.php?q={$job->offlinequizid}&mode=overview"; $mailtext .= "\n\n" . get_string('importlinkresults', 'offlinequiz', $linkoverview); $linkupload = "{$CFG->wwwroot}/mod/offlinequiz/report.php?q={$job->offlinequizid}&mode=rimport"; $mailtext .= "\n" . get_string('importlinkverify', 'offlinequiz', $linkupload); $mailtext .= "\n\n" . get_string('importtimestart', 'offlinequiz', userdate($job->timestart)); $mailtext .= "\n" . get_string('importtimefinish', 'offlinequiz', userdate($job->timefinish)); email_to_user($user, $CFG->noreplyaddress, get_string('importmailsubject', 'offlinequiz'), $mailtext); } } // End !alreadydone. $numberdone++; if ($verbose) { ob_flush(); $pbar->update($numberdone, $numberofjobs, "Processing job - {$numberdone}/{$numberofjobs}."); } } // End foreach. }