MDL-23204 grrr, fixed regression
[moodle.git] / mod / scorm / db / upgrade.php
CommitLineData
e5dd8e3b 1<?php
b8a342d7 2
9528568b 3// This file keeps track of upgrades to
b8a342d7 4// the scorm 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
2e0406a5 12// your older installation to the current version.
b8a342d7 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,
b1f93b15 18// using the methods of database_manager class
775f811a 19//
20// Please do not forget to use upgrade_set_timeout()
21// before any action that may take longer time to finish.
b8a342d7 22
775f811a 23function xmldb_scorm_upgrade($oldversion) {
24 global $CFG, $DB;
b8a342d7 25
c57ce9f2 26 $dbman = $DB->get_manager();
b8a342d7 27
219f652b 28//===== 1.9.0 upgrade line ======//
9858605e 29
c57ce9f2 30 // Adding missing 'whatgrade' field to table scorm
a4cdd6d2 31 if ($oldversion < 2008073000) {
c57ce9f2 32 $table = new xmldb_table('scorm');
33 $field = new xmldb_field('whatgrade');
2a88f626 34 $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'grademethod');
9528568b 35
c57ce9f2 36 /// Launch add field whatgrade
775f811a 37 if (!$dbman->field_exists($table,$field)) {
c57ce9f2 38 $dbman->add_field($table, $field);
d682eadf 39 $whatgradefixed = get_config('scorm', 'whatgradefixed');
b326c85a
DM
40 if (empty($whatgradefixed)) {
41 /// fix bad usage of whatgrade/grading method.
42 $scorms = $DB->get_records('scorm');
43 foreach ($scorms as $scorm) {
44 $scorm->whatgrade = $scorm->grademethod/10;
45 $DB->update_record('scorm', $scorm);
46 }
07b21d04 47 }
b326c85a
DM
48 } else {
49 //dump this config var as it isn't needed anymore.
50 unset_config('whatgradefixed', 'scorm');
c57ce9f2 51 }
9528568b 52
a4cdd6d2 53 upgrade_mod_savepoint(true, 2008073000, 'scorm');
c57ce9f2 54 }
9528568b 55
a4cdd6d2 56 if ($oldversion < 2008082500) {
9528568b 57
58 /// Define field scormtype to be added to scorm
59 $table = new xmldb_table('scorm');
2a88f626 60 $field = new xmldb_field('scormtype', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, 'local', 'name');
9528568b 61
62 /// Launch add field scormtype
63 $dbman->add_field($table, $field);
64
65 /// scorm savepoint reached
a4cdd6d2 66 upgrade_mod_savepoint(true, 2008082500, 'scorm');
9528568b 67 }
68
a4cdd6d2 69 if ($oldversion < 2008090300) {
9528568b 70
71 /// Define field sha1hash to be added to scorm
72 $table = new xmldb_table('scorm');
2a88f626 73 $field = new xmldb_field('sha1hash', XMLDB_TYPE_CHAR, '40', null, null, null, null, 'updatefreq');
9528568b 74
75 /// Launch add field sha1hash
76 $dbman->add_field($table, $field);
77
78 /// scorm savepoint reached
a4cdd6d2 79 upgrade_mod_savepoint(true, 2008090300, 'scorm');
9528568b 80 }
81
a4cdd6d2 82 if ($oldversion < 2008090301) {
9528568b 83
84 /// Define field revision to be added to scorm
85 $table = new xmldb_table('scorm');
2a88f626 86 $field = new xmldb_field('revision', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'md5hash');
9528568b 87
88 /// Launch add field revision
89 $dbman->add_field($table, $field);
90
91 /// scorm savepoint reached
a4cdd6d2 92 upgrade_mod_savepoint(true, 2008090301, 'scorm');
9528568b 93 }
94
a4cdd6d2 95 if ($oldversion < 2008090302) {
9528568b 96 $sql = "UPDATE {scorm}
97 SET scormtype = 'external'
98 WHERE reference LIKE ? OR reference LIKE ? OR reference LIKE ?";
99 $DB->execute($sql, array('http://%imsmanifest.xml', 'https://%imsmanifest.xml', 'www.%imsmanifest.xml'));
100
101 $sql = "UPDATE {scorm}
102 SET scormtype = 'localsync'
103 WHERE reference LIKE ? OR reference LIKE ? OR reference LIKE ?
104 OR reference LIKE ? OR reference LIKE ? OR reference LIKE ?";
105 $DB->execute($sql, array('http://%.zip', 'https://%.zip', 'www.%.zip', 'http://%.pif', 'https://%.pif', 'www.%.pif'));
106
107 $sql = "UPDATE {scorm} SET scormtype = 'imsrepository' WHERE reference LIKE ?";
108 $DB->execute($sql, array('#%'));
109
110 /// scorm savepoint reached
a4cdd6d2 111 upgrade_mod_savepoint(true, 2008090302, 'scorm');
9528568b 112 }
113
a4cdd6d2 114 if ($oldversion < 2008090303) {
9528568b 115 //remove obsoleted config settings
116 unset_config('scorm_advancedsettings');
117 unset_config('scorm_windowsettings');
118
119 /// scorm savepoint reached
a4cdd6d2 120 upgrade_mod_savepoint(true, 2008090303, 'scorm');
9528568b 121 }
122
a4cdd6d2 123 if ($oldversion < 2008090304) {
9528568b 124
125 /////////////////////////////////////
126 /// new file storage upgrade code ///
127 /////////////////////////////////////
128
129 function scorm_migrate_content_files($context, $base, $path) {
6aff538a 130 global $CFG, $OUTPUT;
9528568b 131
132 $fullpathname = $base.$path;
133 $fs = get_file_storage();
64f93798 134 $filearea = 'content';
9528568b 135 $items = new DirectoryIterator($fullpathname);
136
137 foreach ($items as $item) {
138 if ($item->isDot()) {
139 unset($item); // release file handle
140 continue;
141 }
142
143 if ($item->isLink()) {
144 // do not follow symlinks - they were never supported in moddata, sorry
145 unset($item); // release file handle
146 continue;
147 }
148
149 if ($item->isFile()) {
150 if (!$item->isReadable()) {
6aff538a 151 echo $OUTPUT->notification(" File not readable, skipping: ".$fullpathname.$item->getFilename());
9528568b 152 unset($item); // release file handle
153 continue;
154 }
155
156 $filepath = clean_param($path, PARAM_PATH);
157 $filename = clean_param($item->getFilename(), PARAM_FILE);
158 $oldpathname = $fullpathname.$item->getFilename();
159
160 if ($filename === '') {
161 continue;
162 unset($item); // release file handle
163 }
164
64f93798
PS
165 if (!$fs->file_exists($context->id, 'mod_scorm', $filearea, '0', $filepath, $filename)) {
166 $file_record = array('contextid'=>$context->id, 'component'=>'mod_scorm', 'filearea'=>$filearea, 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename,
9528568b 167 'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime());
168 unset($item); // release file handle
169 if ($fs->create_file_from_pathname($file_record, $oldpathname)) {
170 @unlink($oldpathname);
171 }
172 } else {
173 unset($item); // release file handle
174 }
175
176 } else {
177 //migrate recursively all subdirectories
178 $oldpathname = $fullpathname.$item->getFilename().'/';
179 $subpath = $path.$item->getFilename().'/';
180 unset($item); // release file handle
181 scorm_migrate_content_files($context, $base, $subpath);
182 @rmdir($oldpathname); // deletes dir if empty
183 }
184 }
185 unset($items); //release file handles
186 }
187
188 $fs = get_file_storage();
189
190 $sqlfrom = "FROM {scorm} s
191 JOIN {modules} m ON m.name = 'scorm'
192 JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = s.id)";
193
194 $count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
195
196 if ($rs = $DB->get_recordset_sql("SELECT s.id, s.scormtype, s.reference, s.course, cm.id AS cmid $sqlfrom ORDER BY s.course, s.id")) {
197
198 $pbar = new progress_bar('migratescormfiles', 500, true);
199
9528568b 200 $i = 0;
201 foreach ($rs as $scorm) {
202 $i++;
203 upgrade_set_timeout(180); // set up timeout, may also abort execution
204 $pbar->update($i, $count, "Migrating scorm files - $i/$count.");
205
206 $context = get_context_instance(CONTEXT_MODULE, $scorm->cmid);
207 $coursecontext = get_context_instance(CONTEXT_COURSE, $scorm->course);
208
209 // first copy local packages if found - do not delete in case they are shared ;-)
210 if ($scorm->scormtype === 'local' and preg_match('/.*(\.zip|\.pif)$/i', $scorm->reference)) {
64f93798
PS
211 $packagefile = clean_param($scorm->reference, PARAM_PATH);
212 $pathnamehash = sha1("/$coursecontext->id/course/legacy/0/$packagefile");
9528568b 213 if ($file = $fs->get_file_by_hash($pathnamehash)) {
64f93798 214 $file_record = array('scontextid'=>$context->id, 'component'=>'mod_scorm', 'filearea'=>'package',
9528568b 215 'itemid'=>0, 'filepath'=>'/');
84683aba
DM
216 try {
217 $fs->create_file_from_storedfile($file_record, $file);
218 } catch (Exception $x) {
219 }
220 $scorm->reference = $file->get_filepath().$file->get_filename();
221
9528568b 222 } else {
223 $scorm->reference = '';
224 }
225 $DB->update_record('scorm', $scorm);
226 }
227
228 // now migrate the extracted package
229 $basepath = "$CFG->dataroot/$scorm->course/$CFG->moddata/scorm/$scorm->id";
230 if (!is_dir($basepath)) {
231 //no files?
232 continue;
233 }
234
235 scorm_migrate_content_files($context, $basepath, '/');
236
237 // remove dirs if empty
238 @rmdir("$CFG->dataroot/$scorm->course/$CFG->moddata/scorm/$scorm->id/");
239 @rmdir("$CFG->dataroot/$scorm->course/$CFG->moddata/scorm/");
240 @rmdir("$CFG->dataroot/$scorm->course/$CFG->moddata/");
241 }
9528568b 242 $rs->close();
243 }
244
245 /// scorm savepoint reached
a4cdd6d2 246 upgrade_mod_savepoint(true, 2008090304, 'scorm');
9528568b 247 }
248
6381fa56 249
a4cdd6d2 250 if ($oldversion < 2008090305) {
6381fa56 251
252 /// Define new fields forcecompleted, forcenewattempt, displayattemptstatus, and displaycoursestructure to be added to scorm
253 $table = new xmldb_table('scorm');
2a88f626 254 $field = new xmldb_field('forcecompleted', XMLDB_TYPE_INTEGER, '1', null, null, null, '0', 'maxattempt');
6381fa56 255 if (!$dbman->field_exists($table,$field)) {
256 $dbman->add_field($table, $field);
257 }
2a88f626 258 $field = new xmldb_field('forcenewattempt', XMLDB_TYPE_INTEGER, '1', null, null, null, '0', 'forcecompleted');
6381fa56 259 if (!$dbman->field_exists($table,$field)) {
260 $dbman->add_field($table, $field);
261 }
2a88f626 262 $field = new xmldb_field('lastattemptlock', XMLDB_TYPE_INTEGER, '1', null, null, null, '0', 'forcenewattempt');
6381fa56 263 if (!$dbman->field_exists($table,$field)) {
264 $dbman->add_field($table, $field);
265 }
2a88f626 266 $field = new xmldb_field('displayattemptstatus', XMLDB_TYPE_INTEGER, '1', null, null, null, '1', 'lastattemptlock');
6381fa56 267 if (!$dbman->field_exists($table,$field)) {
268 $dbman->add_field($table, $field);
269 }
2a88f626 270 $field = new xmldb_field('displaycoursestructure', XMLDB_TYPE_INTEGER, '1', null, null, null, '1', 'displayattemptstatus');
6381fa56 271 if (!$dbman->field_exists($table,$field)) {
272 $dbman->add_field($table, $field);
273 }
65478eea 274
6381fa56 275 /// scorm savepoint reached
a4cdd6d2 276 upgrade_mod_savepoint(true, 2008090305, 'scorm');
6381fa56 277 }
65478eea 278
30fc6e2d 279
280 // remove redundant config values
a4cdd6d2 281 if ($oldversion < 2008090306) {
65478eea 282 /*
283 * comment this out as it is handled by the update mark 2008090310 below
284 * left for historical documentation as some early adopters may have done
285 * this already.
30fc6e2d 286 $redundant_config = array(
287 'scorm_allowapidebug',
288 'scorm_allowtypeexternal',
289 'scorm_allowtypeimsrepository',
65478eea 290 'scorm_allowtypelocalsync',
291 'scorm_apidebugmask',
292 'scorm_frameheight',
30fc6e2d 293 'scorm_framewidth',
294 'scorm_maxattempts',
295 'scorm_updatetime');
296 foreach ($redundant_config as $rcfg) {
297 if (isset($CFG->$rcfg)) {
298 unset_config($rcfg);
299 }
300 }
65478eea 301 */
1adc77e6 302 /// scorm savepoint reached
a4cdd6d2 303 upgrade_mod_savepoint(true, 2008090306, 'scorm');
1adc77e6 304 }
65478eea 305
306
1adc77e6 307
308 // remove redundant config values
a4cdd6d2 309 if ($oldversion < 2008090307) {
65478eea 310 /*
311 * comment this out as it is handled by the update mark 2008090310 below
312 * left for historical documentation as some early adopters may have done
313 * this already.
1adc77e6 314 $redundant_config = array(
315 'scorm_allowapidebug',
316 'scorm_allowtypeexternal',
317 'scorm_allowtypeimsrepository',
65478eea 318 'scorm_allowtypelocalsync',
319 'scorm_apidebugmask',
320 'scorm_frameheight',
1adc77e6 321 'scorm_framewidth',
322 'scorm_maxattempts',
323 'scorm_updatetime',
65478eea 324 'scorm_resizable',
325 'scorm_scrollbars',
326 'scorm_directories',
1adc77e6 327 'scorm_location',
65478eea 328 'scorm_menubar',
329 'scorm_toolbar',
1adc77e6 330 'scorm_status',
331 'scorm_grademethod',
332 'scorm_maxgrade',
333 'scorm_whatgrade',
334 'scorm_popup',
335 'scorm_skipview',
336 'scorm_hidebrowse',
337 'scorm_hidetoc',
338 'scorm_hidenav',
339 'scorm_auto',
340 'scorm_updatefreq'
341 );
342 foreach ($redundant_config as $rcfg) {
343 if (isset($CFG->$rcfg)) {
344 unset_config($rcfg);
30fc6e2d 345 }
346 }
65478eea 347 */
348
30fc6e2d 349 /// scorm savepoint reached
a4cdd6d2 350 upgrade_mod_savepoint(true, 2008090307, 'scorm');
30fc6e2d 351 }
65478eea 352
a4cdd6d2 353 if ($oldversion < 2008090308) {
d54e2145 354 $table = new xmldb_table('scorm');
2a88f626 355 $field = new xmldb_field('timeopen', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'height');
d54e2145 356 if (!$dbman->field_exists($table,$field)) {
357 $dbman->add_field($table, $field);
358 }
2a88f626 359 $field = new xmldb_field('timeclose', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'timeopen');
d54e2145 360 if (!$dbman->field_exists($table,$field)) {
361 $dbman->add_field($table, $field);
362 }
65478eea 363
d54e2145 364 /// scorm savepoint reached
a4cdd6d2 365 upgrade_mod_savepoint(true, 2008090308, 'scorm');
d54e2145 366 }
65478eea 367
368
a4cdd6d2 369 if ($oldversion < 2008090310) {
65478eea 370 // take above blocks that delete config and move the values in to config_plugins
371
372 $redundant_config = array(
373 'scorm_allowapidebug',
374 'scorm_allowtypeexternal',
375 'scorm_allowtypeimsrepository',
376 'scorm_allowtypelocalsync',
377 'scorm_apidebugmask',
378 'scorm_frameheight',
379 'scorm_framewidth',
380 'scorm_maxattempts',
381 'scorm_updatetime',
382 'scorm_resizable',
383 'scorm_scrollbars',
384 'scorm_directories',
385 'scorm_location',
386 'scorm_menubar',
387 'scorm_toolbar',
388 'scorm_status',
389 'scorm_grademethod',
390 'scorm_maxgrade',
391 'scorm_whatgrade',
392 'scorm_popup',
393 'scorm_skipview',
394 'scorm_hidebrowse',
395 'scorm_hidetoc',
396 'scorm_hidenav',
397 'scorm_auto',
398 'scorm_updatefreq',
399 'scorm_displayattemptstatus',
400 'scorm_displaycoursestructure',
401 'scorm_forcecompleted',
402 'scorm_forcenewattempt',
403 'scorm_lastattemptlock'
404 );
405
406 foreach ($redundant_config as $rcfg) {
407 if (isset($CFG->$rcfg)) {
408 $shortname = substr($rcfg, 6);
a4cdd6d2
PS
409 set_config($shortname, $CFG->$rcfg, 'scorm');
410 unset_config($rcfg);
65478eea 411 }
412 }
413
414 /// scorm savepoint reached
a4cdd6d2 415 upgrade_mod_savepoint(true, 2008090310, 'scorm');
65478eea 416 }
417
a4cdd6d2 418 if ($oldversion < 2009042000) {
d0bcf735 419
420 /// Rename field summary on table scorm to intro
421 $table = new xmldb_table('scorm');
2a88f626 422 $field = new xmldb_field('summary', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, 'reference');
d0bcf735 423
424 /// Launch rename field summary
425 $dbman->rename_field($table, $field, 'intro');
426
427 /// scorm savepoint reached
a4cdd6d2 428 upgrade_mod_savepoint(true, 2009042000, 'scorm');
d0bcf735 429 }
430
a4cdd6d2 431 if ($oldversion < 2009042001) {
d0bcf735 432
433 /// Define field introformat to be added to scorm
434 $table = new xmldb_table('scorm');
2a88f626 435 $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'intro');
d0bcf735 436
437 /// Launch add field introformat
d682eadf
PS
438 if (!$dbman->field_exists($table, $field)) {
439 $dbman->add_field($table, $field);
440 }
441
442 // conditionally migrate to html format in intro
443 if ($CFG->texteditors !== 'textarea') {
39ac3f6e 444 $rs = $DB->get_recordset('scorm', array('introformat'=>FORMAT_MOODLE), '', 'id,intro,introformat');
d682eadf
PS
445 foreach ($rs as $s) {
446 $s->intro = text_to_html($s->intro, false, false, true);
447 $s->introformat = FORMAT_HTML;
39ac3f6e 448 $DB->update_record('scorm', $s);
d682eadf
PS
449 upgrade_set_timeout();
450 }
451 $rs->close();
452 }
d0bcf735 453
454 /// scorm savepoint reached
a4cdd6d2 455 upgrade_mod_savepoint(true, 2009042001, 'scorm');
d0bcf735 456 }
457
a4cdd6d2 458 if ($oldversion < 2009042002) {
1bd51a6c
DM
459
460 /// Define field introformat to be added to scorm
461 $table = new xmldb_table('scorm_scoes');
462 $field = new xmldb_field('launch', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null);
463
464 /// Launch add field introformat
465 $dbman->change_field_type($table, $field);
466
467 /// scorm savepoint reached
a4cdd6d2 468 upgrade_mod_savepoint(true, 2009042002, 'scorm');
1bd51a6c 469 }
03751efe 470 if ($oldversion < 2010070800) {
b326c85a
DM
471 //check to see if this has already been tidied up by a 1.9 upgrade.
472 $grademethodfixed = get_config('scorm', 'grademethodfixed');
473 if (empty($grademethodfixed)) {
474 /// fix bad usage of whatgrade/grading method.
07b21d04
DM
475 $scorms = $DB->get_records('scorm');
476 foreach ($scorms as $scorm) {
477 $scorm->grademethod = $scorm->grademethod%10;
478 $DB->update_record('scorm', $scorm);
479 }
b326c85a
DM
480 } else {
481 //dump this config var as it isn't needed anymore.
482 unset_config('grademethodfixed', 'scorm');
483 }
d682eadf 484
03751efe
DM
485 /// scorm savepoint reached
486 upgrade_mod_savepoint(true, 2010070800, 'scorm');
487 }
a4cdd6d2 488 return true;
b8a342d7 489}
490
e5dd8e3b 491