]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-19937 workshop submissions migration
authorDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:32:53 +0000 (18:32 +0000)
committerDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 18:32:53 +0000 (18:32 +0000)
mod/workshop/db/upgrade.php
mod/workshop/db/upgradelib.php

index 86f4cc8b78f76afa67a40c0047d8fcb3e0dc59c1..62b8888ca3c7207cb06491b39471e9095b945797 100644 (file)
@@ -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
      */
index c248640d0ccdb862627f4c600a2f7679710bc127..4d787ab47fcb444ee3bfca817b270bb94d093b50 100644 (file)
@@ -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;
+}
+