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; }
if (!$options->sheetfeedback and !$options->gradedsheetfeedback) { print_error('noaccess', 'offlinequiz', $CFG->wwwroot . '/course/view.php?id=' . $COURSE->id, $scannedpage->offlinequizid); } $url = new moodle_url('/mod/offlinequiz/image.php', array('pageid' => $scannedpage->id, 'resultid' => $result->id)); $PAGE->set_url($url); $PAGE->set_pagelayout('popup'); echo "<style>\n"; echo "body {margin:0px; font-family:Arial,Verdana,Helvetica,sans-serif;}\n"; echo ".imagebutton {width:250px; height:24px; text-align:left; margin-bottom:10px;}\n"; echo "</style>\n"; echo '<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>'; offlinequiz_load_useridentification(); $offlinequizconfig = get_config('offlinequiz'); $group = $groups[$result->offlinegroupid]; $offlinequiz->groupid = -$group->id; list($maxquestions, $maxanswers, $formtype, $questionsperpage) = offlinequiz_get_question_numbers($offlinequiz, array($group)); $offlinequizconfig->papergray = $offlinequiz->papergray; // Load corners from DB. $dbcorners = $DB->get_records('offlinequiz_page_corners', array('scannedpageid' => $scannedpage->id)); $corners = array(); foreach ($dbcorners as $corner) { $corners[] = new oq_point($corner->x, $corner->y); } // Initialize a page scanner. $scanner = new offlinequiz_page_scanner($offlinequiz, $context->id, $maxquestions, $maxanswers); // Load the stored picture file. $sheetloaded = $scanner->load_stored_image($scannedpage->filename, $corners); $pagenumber = $scannedpage->pagenumber; // Make a first check. $scanner->check_deleted(); $scanner->calibrate_and_get_group();
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. }
$context = context_module::instance($cm->id); $coursecontext = context_course::instance($course->id); require_capability('mod/offlinequiz:viewreports', $context); $url = new moodle_url('/mod/offlinequiz/correct.php', array('pageid' => $scannedpage->id)); $PAGE->set_url($url); $PAGE->set_pagelayout('report'); offlinequiz_load_useridentification(); $offlinequizconfig = get_config('offlinequiz'); // Determine the maxanswers and maxquestions for the scannedpage. $selectedgroups = $groups; if ($overwrite && $scannedpage->resultid) { $result = $DB->get_record('offlinequiz_results', array('id' => $scannedpage->resultid)); $resultgroup = $DB->get_record('offlinequiz_groups', array('id' => $result->offlinegroupid)); $selectedgroups = array($resultgroup); } list($maxquestions, $maxanswers, $formtype, $questionsperpage) = offlinequiz_get_question_numbers($offlinequiz, $selectedgroups); // Get the corners either from the request parameters of from the offlinequiz_page_corners table. $corners = array(); $nodbcorners = false; if ($action == 'rotate') { $corners[0] = new oq_point(853 - required_param('c-3-x', PARAM_INT), 1208 - required_param('c-3-y', PARAM_INT)); $corners[1] = new oq_point(853 - required_param('c-2-x', PARAM_INT), 1208 - required_param('c-2-y', PARAM_INT)); $corners[2] = new oq_point(853 - required_param('c-1-x', PARAM_INT), 1208 - required_param('c-1-y', PARAM_INT)); $corners[3] = new oq_point(853 - required_param('c-0-x', PARAM_INT), 1208 - required_param('c-0-y', PARAM_INT)); offlinequiz_save_page_corners($scannedpage, $corners); } else { if ($action == 'readjust') { $corners[0] = new oq_point(required_param('c-0-x', PARAM_INT) + 7, required_param('c-0-y', PARAM_INT) + 7); $corners[1] = new oq_point(required_param('c-1-x', PARAM_INT) + 7, required_param('c-1-y', PARAM_INT) + 7); $corners[2] = new oq_point(required_param('c-2-x', PARAM_INT) + 7, required_param('c-2-y', PARAM_INT) + 7); $corners[3] = new oq_point(required_param('c-3-x', PARAM_INT) + 7, required_param('c-3-y', PARAM_INT) + 7);
public function update_all_results_and_logs($offlinequiz) { global $DB, $CFG; $this->prevent_timeout(); // Now we have to migrate offlinequiz_attempts to offlinequiz_results because // we need the new result IDs for the scannedpages. // Get all attempts that have already been migrated to the new question engine. $attempts = $DB->get_records('offlinequiz_attempts', array('offlinequiz' => $offlinequiz->id, 'needsupgradetonewqe' => 0, 'sheet' => 0)); $groups = $DB->get_records('offlinequiz_groups', array('offlinequizid' => $offlinequiz->id), 'number', '*', 0, $offlinequiz->numgroups); list($maxquestions, $maxanswers, $formtype, $questionsperpage) = offlinequiz_get_question_numbers($offlinequiz, $groups); $transaction = $DB->start_delegated_transaction(); foreach ($attempts as $attempt) { $group = $DB->get_record('offlinequiz_groups', array('offlinequizid' => $offlinequiz->id, 'number' => $attempt->groupid)); $attemptlog = $DB->get_record('offlinequiz_i_log', array('offlinequiz' => $offlinequiz->id, 'attempt' => $attempt->id, 'page' => 0)); $result = new StdClass(); $result->offlinequizid = $offlinequiz->id; if ($group) { $result->offlinegroupid = $group->id; } $teacherid = $attemptlog->importadmin; if (empty($teacherid)) { $teacherid = 2; } $result->userid = $attempt->userid; $result->sumgrades = $attempt->sumgrades; $result->usageid = $attempt->uniqueid; $result->teacherid = $teacherid; $result->offlinegroupid = $group->id; $result->status = 'complete'; $result->timestart = $attempt->timestart; $result->timefinish = $attempt->timefinish; $result->timemodified = $attempt->timemodified; if (!($oldresult = $DB->get_record('offlinequiz_results', array('offlinequizid' => $result->offlinequizid, 'userid' => $result->userid)))) { $result->id = $DB->insert_record('offlinequiz_results', $result); } else { $result->id = $oldresult->id; $DB->update_record('offlinequiz_results', $result); } // Save the resultid, s.t. we can still reconstruct the data later. $DB->set_field('offlinequiz_attempts', 'resultid', $result->id, array('id' => $attempt->id)); if ($quba = question_engine::load_questions_usage_by_activity($result->usageid)) { $quba->finish_all_questions(); $slots = $quba->get_slots(); // Get all the page logs that have contributed to the attempt. if ($group->numberofpages == 1) { $pagelogs = array($attemptlog); } else { $sql = "SELECT *\n FROM {offlinequiz_i_log}\n WHERE offlinequiz = :offlinequizid\n AND attempt = :attemptid\n AND page > 0"; $params = array('offlinequizid' => $offlinequiz->id, 'attemptid' => $attempt->id); $pagelogs = $DB->get_records_sql($sql, $params); } foreach ($pagelogs as $pagelog) { $rawdata = $pagelog->rawdata; $scannedpage = new StdClass(); $scannedpage->offlinequizid = $offlinequiz->id; $scannedpage->resultid = $result->id; $scannedpage->filename = $this->get_pic_name($rawdata); $scannedpage->groupnumber = $this->get_group($rawdata); $scannedpage->userkey = $this->get_user_name($rawdata); if ($group->numberofpages == 1) { $scannedpage->pagenumber = 1; } else { $scannedpage->pagenumber = $pagelog->page; } $scannedpage->time = $pagelog->time ? $pagelog->time : time(); $scannedpage->status = 'submitted'; $scannedpage->error = ''; $scannedpage->id = $DB->insert_record('offlinequiz_scanned_pages', $scannedpage); $itemdata = $this->get_item_data($rawdata); $items = explode(',', $itemdata); if (!empty($items)) { // Determine the slice of slots we are interested in. // we start at the top of the page (e.g. 0, 96, etc). $startindex = min(($scannedpage->pagenumber - 1) * $questionsperpage, count($slots)); // We end on the bottom of the page or when the questions are gone (e.g., 95, 105). $endindex = min($scannedpage->pagenumber * $questionsperpage, count($slots)); $questioncounter = 0; for ($slotindex = $startindex; $slotindex < $endindex; $slotindex++) { $slot = $slots[$slotindex]; if (array_key_exists($questioncounter, $items)) { $item = $items[$questioncounter]; for ($key = 0; $key < strlen($item); $key++) { $itemchoice = substr($item, $key, 1); $choice = new stdClass(); $choice->scannedpageid = $scannedpage->id; $choice->slotnumber = $slot; $choice->choicenumber = $key; if ($itemchoice == '1') { $choice->value = 1; } else { if ($itemchoice == '0') { $choice->value = 0; } else { $choice->value = -1; } } $choice->id = $DB->insert_record('offlinequiz_choices', $choice); } } $questioncounter++; } } $rawcorners = explode(',', $pagelog->corners); if (!empty($rawcorners) && count($rawcorners) > 8) { for ($i = 0; $i < count($rawcorners); $i++) { if ($rawcorners[$i] < 0) { $rawcorners[$i] = 0; } if ($rawcorners[$i] > 2000) { $rawcorners[$i] = 2000; } } $corners = array(); $corners[0] = new oq_point($rawcorners[1], $rawcorners[2]); $corners[1] = new oq_point($rawcorners[3], $rawcorners[4]); $corners[2] = new oq_point($rawcorners[5], $rawcorners[6]); $corners[3] = new oq_point($rawcorners[7], $rawcorners[8]); offlinequiz_save_page_corners($scannedpage, $corners); } } } } $DB->set_field('offlinequiz', 'needsilogupgrade', 0, array('id' => $offlinequiz->id)); $transaction->allow_commit(); // We start a new transaction for the remaining i_log entries. $otherlogs = $DB->get_records('offlinequiz_i_log', array('offlinequiz' => $offlinequiz->id, 'attempt' => 0)); $transaction = $DB->start_delegated_transaction(); foreach ($otherlogs as $pagelog) { list($status, $error) = $this->get_status_and_error($pagelog->error); $rawdata = $pagelog->rawdata; $groupnumber = $this->get_group($rawdata); $intgroup = intval($groupnumber); if ($intgroup > 0 && $intgroup <= $offlinequiz->numgroups) { $groupnumber = $intgroup; } else { $groupnumber = 0; } $scannedpage = new StdClass(); $scannedpage->offlinequizid = $offlinequiz->id; $scannedpage->filename = $this->get_pic_name($rawdata); $scannedpage->groupnumber = $groupnumber; $scannedpage->userkey = $this->get_user_name($rawdata); $scannedpage->pagenumber = $pagelog->page; if ($pagelog->time) { $scannedpage->time = $pagelog->time; } else { $scannedpage->time = time(); } $scannedpage->status = $status; $scannedpage->error = $error; $scannedpage->id = $DB->insert_record('offlinequiz_scanned_pages', $scannedpage); // We do not migrate itemdata for the scanned pages with error. // We do store the corners though. $rawcorners = explode(',', $pagelog->corners); if (!empty($rawcorners) && count($rawcorners) > 8) { $corners = array(); $corners[0] = new oq_point($rawcorners[1], $rawcorners[2]); $corners[1] = new oq_point($rawcorners[3], $rawcorners[4]); $corners[2] = new oq_point($rawcorners[5], $rawcorners[6]); $corners[3] = new oq_point($rawcorners[7], $rawcorners[8]); offlinequiz_save_page_corners($scannedpage, $corners); } } $transaction->allow_commit(); return true; }