From 067f63c59397494744d992120cccb4864cc22b88 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Mon, 4 Jan 2010 18:32:53 +0000 Subject: [PATCH] MDL-19937 workshop submissions migration --- mod/workshop/db/upgrade.php | 84 +++++++++++++++- mod/workshop/db/upgradelib.php | 171 +++++++++++++++++++++++++-------- 2 files changed, 214 insertions(+), 41 deletions(-) diff --git a/mod/workshop/db/upgrade.php b/mod/workshop/db/upgrade.php index 86f4cc8b78..62b8888ca3 100644 --- a/mod/workshop/db/upgrade.php +++ b/mod/workshop/db/upgrade.php @@ -79,7 +79,15 @@ function xmldb_workshop_upgrade($oldversion) { if ($dbman->table_exists($tableorig)) { $dbman->rename_table(new XMLDBTable($tableorig), $tablearchive); } - // append a new field 'newid' in every archived table. null value means the record was not migrated yet + // append a new field 'newplugin' into every archived table. In this field, the name of the subplugin + // who adopted the record during the migration is stored. null value means the record is not migrated yet + $table = new xmldb_table($tablearchive); + $field = new xmldb_field('newplugin', XMLDB_TYPE_CHAR, '28', null, null, null, null); + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + // append a new field 'newid' in every archived table. null value means the record was not migrated yet. + // the field will hold the new id of the migrated record $table = new xmldb_table($tablearchive); $field = new xmldb_field('newid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); if (!$dbman->field_exists($table, $field)) { @@ -105,10 +113,82 @@ function xmldb_workshop_upgrade($oldversion) { if ($result && $oldversion < 2009102903) { require_once(dirname(__FILE__) . '/upgradelib.php'); echo $OUTPUT->notification('Copying workshop core data', 'notifysuccess'); - workshop_upgrade_copy_instances(); + workshop_upgrade_module_instances(); upgrade_mod_savepoint($result, 2009102903, 'workshop'); } + /** + * Migration from 1.9 - step 4 - migrate submissions + */ + if ($result && $oldversion < 2009102904) { + require_once(dirname(__FILE__) . '/upgradelib.php'); + echo $OUTPUT->notification('Copying submissions', 'notifysuccess'); + workshop_upgrade_submissions(); + upgrade_mod_savepoint($result, 2009102904, 'workshop'); + } + + /** + * Migration from 1.9 - step 5 - migrate submission attachment to new file storage + */ + if ($result && $oldversion < 2009102905) { + // $filearea = "$workshop->course/$CFG->moddata/workshop/$submission->id"; + $fs = get_file_storage(); + $from = 'FROM {workshop_submissions} s + JOIN {workshop} w ON (w.id = s.workshopid) + JOIN {modules} m ON (m.name = :modulename) + JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = w.id) + WHERE s.attachment <> 1'; + $params = array('modulename' => 'workshop'); + $count = $DB->count_records_sql('SELECT COUNT(s.id) ' . $from, $params); + $rs = $DB->get_recordset_sql('SELECT s.id, s.authorid, s.workshopid, cm.course, cm.id AS cmid ' . + $from . ' ORDER BY cm.course, w.id', $params); + $pbar = new progress_bar('migrateworkshopsubmissions', 500, true); + $i = 0; + foreach ($rs as $submission) { + $i++; + upgrade_set_timeout(60); // set up timeout, may also abort execution + $pbar->update($i, $count, "Migrating workshop submissions - $i/$count"); + + $filedir = "$CFG->dataroot/$submission->course/$CFG->moddata/workshop/$submission->id"; + if ($files = get_directory_list($filedir, '', false)) { + $context = get_context_instance(CONTEXT_MODULE, $submission->cmid); + foreach ($files as $filename) { + $filepath = $filedir . '/' . $filename; + if (!is_readable($filepath)) { + echo $OUTPUT->notification('File not readable: ' . $filepath); + continue; + } + $filename = clean_param($filename, PARAM_FILE); + if ($filename === '') { + echo $OUTPUT->notification('Unsupported submission filename: ' . $filepath); + continue; + } + if (! $fs->file_exists($context->id, 'workshop_submission_attachment', $submission->id, '/', $filename)) { + $filerecord = array('contextid' => $context->id, + 'filearea' => 'workshop_submission_attachment', + 'itemid' => $submission->id, + 'filepath' => '/', + 'filename' => $filename, + 'userid' => $submission->authorid); + if ($fs->create_file_from_pathname($filerecord, $filepath)) { + $submission->attachment = 1; + if ($DB->update_record('workshop_submissions', $submission)) { + unlink($filepath); + } + } + } + } + } + // remove dirs if empty + @rmdir("$CFG->dataroot/$submission->course/$CFG->moddata/workshop/$submission->id"); + @rmdir("$CFG->dataroot/$submission->course/$CFG->moddata/workshop"); + @rmdir("$CFG->dataroot/$submission->course/$CFG->moddata"); + @rmdir("$CFG->dataroot/$submission->course"); + } + $rs->close(); + upgrade_mod_savepoint($result, 2009102905, 'workshop'); + } + /** * End of migration from 1.9 */ diff --git a/mod/workshop/db/upgradelib.php b/mod/workshop/db/upgradelib.php index c248640d0c..4d787ab47f 100644 --- a/mod/workshop/db/upgradelib.php +++ b/mod/workshop/db/upgradelib.php @@ -34,7 +34,6 @@ function workshop_upgrade_prepare_20_tables() { if (!$dbman->table_exists('workshop')) { $table = new xmldb_table('workshop'); $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); - $table->add_field('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null); // id in 1.9 table $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); $table->add_field('intro', XMLDB_TYPE_TEXT, 'big', null, null, null, null); @@ -145,56 +144,150 @@ function workshop_upgrade_prepare_20_tables() { } /** - * Copies the records from workshop_old into workshop table, keeping the original id in oldid column + * Copies the records from workshop_old into workshop table * * @return void */ -function workshop_upgrade_copy_instances() { +function workshop_upgrade_module_instances() { global $CFG, $DB, $OUTPUT; upgrade_set_timeout(); $moduleid = $DB->get_field('modules', 'id', array('name' => 'workshop'), MUST_EXIST); $rs = $DB->get_recordset_select('workshop_old', 'newid IS NULL'); foreach ($rs as $old) { - $new = new stdClass(); - $new->oldid = $old->id; - $new->course = $old->course; - $new->name = $old->name; - $new->intro = $old->description; - $new->introformat = $old->format; - $new->nattachments = $old->nattachments; - $new->maxbytes = $old->maxbytes; - $new->grade = $old->grade; - $new->gradinggrade = $old->gradinggrade; - $new->phase = 50; // defined in locallib.php as const workshop::PHASE_CLOSED - $new->timemodified = time(); - if ($old->ntassessments > 0) { - $new->useexamples = 1; - } else { - $new->useexamples = 0; - } - $new->usepeerassessment = 1; - $new->useselfassessment = $old->includeself; - switch ($old->gradingstrategy) { - case 0: // 'notgraded' - renamed - $new->strategy = 'comments'; - break; - case 1: // 'accumulative' - $new->strategy = 'accumulative'; - break; - case 2: // 'errorbanded' - renamed - $new->strategy = 'numerrors'; - break; - case 3: // 'criterion' - will be migrated into 'rubric' - $new->strategy = 'rubric'; - break; - case 4: // 'rubric' - $new->strategy = 'rubric'; - break; - } + $new = workshop_upgrade_transform_instance($old); $newid = $DB->insert_record('workshop', $new, true, true); $DB->set_field('course_modules', 'instance', $newid, array('module' => $moduleid, 'instance' => $old->id)); + $DB->set_field('workshop_old', 'newplugin', 'workshop', array('id' => $old->id)); $DB->set_field('workshop_old', 'newid', $newid, array('id' => $old->id)); } $rs->close(); } + +/** + * Given a record containing data from 1.9 workshop table, returns object containing data as should be saved in 2.0 workshop table + * + * @param stdClass $old record from 1.9 workshop table + * @return stdClass + */ +function workshop_upgrade_transform_instance(stdClass $old) { + global $CFG; + require_once(dirname(dirname(__FILE__)) . '/locallib.php'); + + $new = new stdClass(); + $new->course = $old->course; + $new->name = $old->name; + $new->intro = $old->description; + $new->introformat = $old->format; + $new->nattachments = $old->nattachments; + $new->maxbytes = $old->maxbytes; + $new->grade = $old->grade; + $new->gradinggrade = $old->gradinggrade; + $new->phase = workshop::PHASE_CLOSED; + $new->timemodified = time(); + if ($old->ntassessments > 0) { + $new->useexamples = 1; + } else { + $new->useexamples = 0; + } + $new->usepeerassessment = 1; + $new->useselfassessment = $old->includeself; + switch ($old->gradingstrategy) { + case 0: // 'notgraded' - renamed + $new->strategy = 'comments'; + break; + case 1: // 'accumulative' + $new->strategy = 'accumulative'; + break; + case 2: // 'errorbanded' - renamed + $new->strategy = 'numerrors'; + break; + case 3: // 'criterion' - will be migrated into 'rubric' + $new->strategy = 'rubric'; + break; + case 4: // 'rubric' + $new->strategy = 'rubric'; + break; + } + + return $new; +} + +/** + * TODO: short description. + * + * @return TODO + */ +function workshop_upgrade_workshop_id_mappings() { + global $DB; + + $oldrecords = $DB->get_records('workshop_old', null, 'id', 'id,newid'); + $newids = array(); + foreach ($oldrecords as $oldid => $oldrecord) { + if ($oldrecord->id and $oldrecord->newid) { + $newids[$oldid] = $oldrecord->newid; + } + } + return $newids; +} + +/** + * Copies records from workshop_submissions_old into workshop_submissions. Can be called after all workshop module instances + * were correctly migrated and new ids are filled in workshop_old + * + * @return void + */ +function workshop_upgrade_submissions() { + global $CFG, $DB, $OUTPUT; + + upgrade_set_timeout(); + // mapping table from legacy workshop instance id to the new one: array of (int)oldid => (int)newid + $workshopnewids = workshop_upgrade_workshop_id_mappings(); + + // list of teachers in every workshop: array of (int)workshopid => array of (int)userid => notused + $workshopteachers = array(); + $rs = $DB->get_recordset_select('workshop_submissions_old', 'newid IS NULL'); + foreach ($rs as $old) { + if (!isset($workshopteachers[$old->workshopid])) { + $cm = get_coursemodule_from_instance('workshop', $old->workshopid, 0, false, MUST_EXIST); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $workshopteachers[$old->workshopid] = get_users_by_capability($context, 'mod/workshop:manage', 'u.id'); + } + $new = workshop_upgrade_transform_submission($old, $workshopnewids, $workshopteachers[$old->workshopid]); + $newid = $DB->insert_record('workshop_submissions', $new, true, true); + $DB->set_field('workshop_submissions_old', 'newplugin', 'submissions', array('id' => $old->id)); + $DB->set_field('workshop_submissions_old', 'newid', $newid, array('id' => $old->id)); + } + $rs->close(); +} + +/** + * Given a record from 1.x workshop_submissions_old, returns data for 2.0 workshop_submissions + * + * @param stdClass $old + * @param array $workshopnewids $oldid => $newid workshop instances mapping table + * @param array $legacyteachers $userid => notused the list of legacy workshop teachers for the submission's workshop + * @return stdClass + */ +function workshop_upgrade_transform_submission(stdClass $old, array $workshopnewids, array $legacyteachers) { + $new = new stdclass(); // new submission record to be returned + $new->workshopid = $workshopnewids[$old->workshopid]; + if (isset($legacyteachers[$old->userid])) { + // the author of the submission was teacher = had mod/workshop:manage. this is the only way how we can + // recognize the submission should be treated as example submission (ach jo...) + $new->example = 1; + } else { + $new->example = 0; + } + $new->authorid = $old->userid; + $new->timecreated = $old->timecreated; + $new->timemodified = $old->timecreated; + $new->title = $old->title; + $new->content = $old->description; + $new->contentformat = FORMAT_HTML; + $new->contenttrust = 0; + $new->published = 0; + + return $new; +} + -- 2.39.5