8c160822c41e8dfdaaec41ec79c7969c1b2e5dc3
[moodle.git] / mod / data / db / upgrade.php
1 <?php
3 // This file keeps track of upgrades to
4 // the data module
5 //
6 // Sometimes, changes between versions involve
7 // alterations to database structures and other
8 // major things that may break installations.
9 //
10 // The upgrade function in this file will attempt
11 // to perform all the necessary actions to upgrade
12 // your older installtion to the current version.
13 //
14 // If there's something it cannot do itself, it
15 // will tell you what you need to do.
16 //
17 // The commands in here will all be database-neutral,
18 // using the methods of database_manager class
19 //
20 // Please do not forget to use upgrade_set_timeout()
21 // before any action that may take longer time to finish.
23 function xmldb_data_upgrade($oldversion) {
24     global $CFG, $DB, $OUTPUT;
26     $dbman = $DB->get_manager();
27     $result = true;
29 //===== 1.9.0 upgrade line ======//
31     if ($result && $oldversion < 2007101512) {
32     /// Launch add field asearchtemplate again if does not exists yet - reported on several sites
34         $table = new xmldb_table('data');
35         $field = new xmldb_field('asearchtemplate', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'jstemplate');
37         if (!$dbman->field_exists($table, $field)) {
38             $dbman->add_field($table, $field);
39         }
40         upgrade_mod_savepoint($result, 2007101512, 'data');
41     }
43     if ($result && $oldversion < 2007101513) {
44         // Upgrade all the data->notification currently being
45         // NULL to 0
46         $sql = "UPDATE {data} SET notification=0 WHERE notification IS NULL";
47         $result = $DB->execute($sql);
49         $table = new xmldb_table('data');
50         $field = new xmldb_field('notification', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'editany');
51         // First step, Set NOT NULL
52         $dbman->change_field_notnull($table, $field);
53         // Second step, Set default to 0
54         $dbman->change_field_default($table, $field);
55         upgrade_mod_savepoint($result, 2007101513, 'data');
56     }
58     if ($result && $oldversion < 2008081400) {
59         if ($rs = $DB->get_recordset('data')) {
60             $pattern = '/\#\#delete\#\#(\s+)\#\#approve\#\#/';
61             $replacement = '##delete##$1##approve##$1##export##';
62             foreach ($rs as $data) {
63                 $data->listtemplate = preg_replace($pattern, $replacement, $data->listtemplate);
64                 $data->singletemplate = preg_replace($pattern, $replacement, $data->singletemplate);
65                 $DB->update_record('data', $data);
66             }
67             $rs->close();
68         }
69         upgrade_mod_savepoint($result, 2008081400, 'data');
70     }
72     if ($result && $oldversion < 2008091400) {
74         /////////////////////////////////////
75         /// new file storage upgrade code ///
76         /////////////////////////////////////
78         $fs = get_file_storage();
80         $empty = $DB->sql_empty(); // silly oracle empty string handling workaround
82         $sqlfrom = "FROM {data_content} c
83                     JOIN {data_fields} f     ON f.id = c.fieldid
84                     JOIN {data_records} r    ON r.id = c.recordid
85                     JOIN {data} d            ON d.id = r.dataid
86                     JOIN {modules} m         ON m.name = 'data'
87                     JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = d.id)
88                    WHERE c.content <> '$empty' AND c.content IS NOT NULL
89                          AND (f.type = 'file' OR f.type = 'picture')";
91         $count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
93         if ($rs = $DB->get_recordset_sql("SELECT c.id, f.type, r.dataid, c.recordid, f.id AS fieldid, r.userid, c.content, c.content1, d.course, r.userid, cm.id AS cmid $sqlfrom ORDER BY d.course, d.id")) {
95             $pbar = new progress_bar('migratedatafiles', 500, true);
97             $i = 0;
98             foreach ($rs as $content) {
99                 $i++;
100                 upgrade_set_timeout(60); // set up timeout, may also abort execution
101                 $pbar->update($i, $count, "Migrating data entries - $i/$count.");
103                 $filepath = "$CFG->dataroot/$content->course/$CFG->moddata/data/$content->dataid/$content->fieldid/$content->recordid/$content->content";
104                 $context = get_context_instance(CONTEXT_MODULE, $content->cmid);
106                 if (!file_exists($filepath)) {
107                     continue;
108                 }
110                 $filearea = 'data_content';
111                 $oldfilename = $content->content;
112                 $filename    = clean_param($oldfilename, PARAM_FILE);
113                 if ($filename === '') {
114                     continue;
115                 }
116                 if (!$fs->file_exists($context->id, $filearea, $content->id, '/', $filename)) {
117                     $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$content->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$content->userid);
118                     if ($fs->create_file_from_pathname($file_record, $filepath)) {
119                         unlink($filepath);
120                         if ($oldfilename !== $filename) {
121                             // update filename if needed
122                             $DB->set_field('data_content', 'content', $filename, array('id'=>$content->id));
123                         }
124                         if ($content->type == 'picture') {
125                             // migrate thumb
126                             $filepath = "$CFG->dataroot/$content->course/$CFG->moddata/data/$content->dataid/$content->fieldid/$content->recordid/thumb/$content->content";
127                             if (!$fs->file_exists($context->id, $filearea, $content->id, '/', 'thumb_'.$filename)) {
128                                 $file_record['filename'] = 'thumb_'.$file_record['filename'];
129                                 $fs->create_file_from_pathname($file_record, $filepath);
130                                 unlink($filepath);
131                             }
132                         }
133                     }
134                 }
136                 // remove dirs if empty
137                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata/data/$content->dataid/$content->fieldid/$content->recordid/thumb");
138                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata/data/$content->dataid/$content->fieldid/$content->recordid");
139                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata/data/$content->dataid/$content->fieldid");
140                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata/data/$content->dataid");
141                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata/data");
142                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata");
143             }
144             $rs->close();
145         }
146         upgrade_mod_savepoint($result, 2008091400, 'data');
147     }
149     if ($result && $oldversion < 2008112700) {
150         if (!get_config('data', 'requiredentriesfixflag')) {
151             $databases = $DB->get_records_sql("SELECT d.*, c.fullname
152                                                  FROM {data} d, {course} c
153                                                 WHERE d.course = c.id
154                                                       AND (d.requiredentries > 0 OR d.requiredentriestoview > 0)
155                                              ORDER BY c.fullname, d.name");
156             if (!empty($databases)) {
157                 $a = new object();
158                 $a->text = '';
159                 foreach($databases as $database) {
160                     $a->text .= $database->fullname." - " .$database->name. " (course id: ".$database->course." - database id: ".$database->id.")<br/>";
161                 }
162                 //TODO: MDL-17427 send this info to "upgrade log" which will be implemented in 2.0
163                 echo $OUTPUT->notification(get_string('requiredentrieschanged', 'admin', $a));
164             }
165         }
166         unset_config('requiredentriesfixflag', 'data'); // remove old flag
167         upgrade_mod_savepoint($result, 2008112700, 'data');
168     }
170     if ($result && $oldversion < 2009042000) {
172     /// Define field introformat to be added to data
173         $table = new xmldb_table('data');
174         $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'intro');
176     /// Launch add field introformat
177         $dbman->add_field($table, $field);
179     /// data savepoint reached
180         upgrade_mod_savepoint($result, 2009042000, 'data');
181     }
183     if ($result && $oldversion < 2009111701) {
184         require_once($CFG->dirroot . '/comment/lib.php');
185         upgrade_set_timeout(60*20);
187     /// Define table data_comments to be dropped
188         $table = new xmldb_table('data_comments');
190     /// Conditionally launch drop table for data_comments
191         if ($dbman->table_exists($table)) {
192             $sql = 'SELECT d.id AS dataid,
193                 d.course AS courseid,
194                 r.id AS itemid,
195                 c.id AS commentid,
196                 c.content AS comment,
197                 c.format AS format,
198                 c.created AS timemodified
199                 FROM {data_comments} c, {data_records} r, {data} d
200                 WHERE c.recordid=r.id AND r.dataid=d.id ORDER BY dataid, courseid';
202             /// move data comments to new comments table
203             $lastdataid = null;
204             $lastcourseid = null;
205             $modcontext = null;
206             if ($rs = $DB->get_recordset_sql($sql)) {
207                 foreach($rs as $res) {
208                     if ($res->dataid != $lastdataid || $res->courseid != $lastcourseid) {
209                         $cm = get_coursemodule_from_instance('data', $res->dataid, $res->courseid);
210                         if ($cm) {
211                             $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
212                         }
213                         $lastdataid = $res->dataid;
214                         $lastcourseid = $res->courseid;
215                     }
216                     $cmt = new stdclass;
217                     $cmt->contextid = $modcontext->id;
218                     $cmt->courseid  = $res->courseid;
219                     $cmt->area      = 'database_entry';
220                     $cmt->itemid    = $res->itemid;
221                     $comment = new comment($cmt);
222                     // comments class will throw an exception if error occurs
223                     $cmt = $comment->add($res->comment, $res->format);
224                     if (!empty($cmt)) {
225                         $DB->delete_records('data_comments', array('id'=>$res->commentid));
226                     }
227                 }
228             }
229             // the default exception handler will stop the script if error occurs before
230             $dbman->drop_table($table);
231         }
233     /// data savepoint reached
234         upgrade_mod_savepoint($result, 2009111701, 'data');
235     }
237     if ($result && $oldversion < 2010031602) {
238         //add assesstimestart and assesstimefinish columns to data
239         $table = new xmldb_table('data');
241         $field = new xmldb_field('assesstimestart');
242         if (!$dbman->field_exists($table, $field)) {
243             $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'assessed');
244             $dbman->add_field($table, $field);
245         }
247         $field = new xmldb_field('assesstimefinish');
248         if (!$dbman->field_exists($table, $field)) {
249             $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'assesstimestart');
250             $dbman->add_field($table, $field);
251         }
253         upgrade_mod_savepoint($result, 2010031602, 'data');
254     }
256     if($result && $oldversion < 2010031800) {
257         //migrate data_ratings to the central rating table
258         require_once('../lib/db/upgradelib.php');
259         
260         //data ratings didnt store time created and modified so Im using the times from the record the rating was attached to
261         $ratingssql = 'SELECT r.id AS rid, r.recordid AS itemid, r.rating, r.userid, re.timecreated, re.timemodified, d.scale, d.id AS mid
262 FROM {data_ratings} r
263 JOIN {data_records} re ON r.recordid=re.id
264 JOIN {data} d ON d.id=re.dataid';
265         $result = $result && upgrade_module_ratings($ratingssql,'data');
267         //todo andrew drop data_ratings
269         upgrade_mod_savepoint($result, 2010031800, 'data');
270     }
272     return $result;