PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/resource/db/upgradelib.php

https://github.com/kpike/moodle
PHP | 304 lines | 262 code | 13 blank | 29 comment | 7 complexity | 7fc894d4d02d1fc15da7a1d9845e2325 MD5 | raw file
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Resource module upgrade related helper functions
  18. *
  19. * @package mod
  20. * @subpackage resource
  21. * @copyright 2009 Petr Skoda {@link http://skodak.org}
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. defined('MOODLE_INTERNAL') || die;
  25. /**
  26. * Migrate resource module data from 1.9 resource_old table to new resource table
  27. * @return void
  28. */
  29. function resource_20_migrate() {
  30. global $CFG, $DB;
  31. require_once("$CFG->libdir/filelib.php");
  32. require_once("$CFG->libdir/resourcelib.php");
  33. require_once("$CFG->dirroot/course/lib.php");
  34. $fs = get_file_storage();
  35. $withrelativelinks = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/x-shockwave-flash');
  36. // note: pdf doc and other types may contain links too, but we do not support relative links there
  37. $candidates = $DB->get_recordset('resource_old', array('type'=>'file', 'migrated'=>0));
  38. if (!$candidates->valid()) {
  39. $candidates->close(); // Not going to iterate (but exit), close rs
  40. return;
  41. }
  42. foreach ($candidates as $candidate) {
  43. upgrade_set_timeout();
  44. $path = $candidate->reference;
  45. $siteid = get_site()->id;
  46. $fs = get_file_storage();
  47. if (empty($candidate->cmid)) {
  48. // skip borked records
  49. continue;
  50. } else if (strpos($path, 'LOCALPATH') === 0) {
  51. // ignore not maintained local files - sorry
  52. continue;
  53. } else if (preg_match("|$CFG->wwwroot/file.php(\?file=)?/$siteid(/[^\s'\"&\?#]+)|", $path, $matches)) {
  54. // public site files
  55. $path = $matches[2];
  56. $resource = new stdClass();
  57. $resource->id = $candidate->oldid;
  58. $resource->tobemigrated = 0;
  59. $resource->mainfile = $path;
  60. $resource->filterfiles = $CFG->filteruploadedfiles;
  61. $resource->legacyfiles = RESOURCELIB_LEGACYFILES_NO; // on-demand-migration not possible for site files, sorry
  62. $context = get_context_instance(CONTEXT_MODULE, $candidate->cmid);
  63. $sitecontext = get_context_instance(CONTEXT_COURSE, $siteid);
  64. $file_record = array('contextid'=>$context->id, 'component'=>'mod_resourse', 'filearea'=>'content', 'itemid'=>0);
  65. if ($file = $fs->get_file_by_hash(sha1("/$sitecontext->id/course/legacy/content/0".$path))) {
  66. try {
  67. $fs->create_file_from_storedfile($file_record, $file);
  68. } catch (Exception $x) {
  69. }
  70. $resource->mainfile = $file->get_filepath().$file->get_filename();
  71. }
  72. } else if (preg_match("|$CFG->wwwroot/file.php(\?file=)?/$candidate->course(/[^\s'\"&\?#]+)|", $path, $matches)) {
  73. // current course files
  74. $path = $matches[2];
  75. $resource = new stdClass();
  76. $resource->id = $candidate->oldid;
  77. $resource->tobemigrated = 0;
  78. $resource->mainfile = $path;
  79. $resource->filterfiles = $CFG->filteruploadedfiles;
  80. $mimetype = mimeinfo('type', $resource->mainfile);
  81. if (in_array($mimetype, $withrelativelinks)) {
  82. $resource->legacyfiles = RESOURCELIB_LEGACYFILES_ACTIVE;
  83. } else {
  84. $resource->legacyfiles = RESOURCELIB_LEGACYFILES_NO;
  85. }
  86. // try migration of main file - ignore if does not exist
  87. if ($file = resourcelib_try_file_migration($resource->mainfile, $candidate->cmid, $candidate->course, 'mod_resource', 'content', 0)) {
  88. $resource->mainfile = $file->get_filepath().$file->get_filename();
  89. }
  90. } else if (strpos($path, '://') or strpos($path, '/') === 0) {
  91. // http:// https:// ftp:// OR starts with slash - to be converted to link resource
  92. continue;
  93. } else {
  94. // current course files
  95. // cleanup old path first
  96. $path = '/'.trim(trim($path), '/');
  97. if (strpos($path, '?forcedownload=1') !== false) {
  98. // eliminate old force download tricks
  99. $candidate->options = 'forcedownload';
  100. $path = str_replace('?forcedownload=1', '', $path);
  101. }
  102. // get rid of any extra url parameters, sorry we can not support these
  103. preg_match("/^[^?#]+/", $path, $matches);
  104. $parts = $matches[0];
  105. $resource = new stdClass();
  106. $resource->id = $candidate->oldid;
  107. $resource->tobemigrated = 0;
  108. $resource->mainfile = $path;
  109. $resource->filterfiles = $CFG->filteruploadedfiles;
  110. $mimetype = mimeinfo('type', $resource->mainfile);
  111. if (in_array($mimetype, $withrelativelinks)) {
  112. $resource->legacyfiles = RESOURCELIB_LEGACYFILES_ACTIVE;
  113. } else {
  114. $resource->legacyfiles = RESOURCELIB_LEGACYFILES_NO;
  115. }
  116. // try migration of main file - ignore if does not exist
  117. if ($file = resourcelib_try_file_migration($resource->mainfile, $candidate->cmid, $candidate->course, 'mod_resource', 'content', 0)) {
  118. $resource->mainfile = $file->get_filepath().$file->get_filename();
  119. }
  120. }
  121. $options = array('printheading'=>0, 'printintro'=>1);
  122. if ($candidate->options == 'frame') {
  123. $resource->display = RESOURCELIB_DISPLAY_FRAME;
  124. } else if ($candidate->options == 'objectframe') {
  125. $resource->display = RESOURCELIB_DISPLAY_EMBED;
  126. } else if ($candidate->options == 'forcedownload') {
  127. $resource->display = RESOURCELIB_DISPLAY_DOWNLOAD;
  128. } else if ($candidate->popup) {
  129. $resource->display = RESOURCELIB_DISPLAY_POPUP;
  130. if ($candidate->popup) {
  131. $rawoptions = explode(',', $candidate->popup);
  132. foreach ($rawoptions as $rawoption) {
  133. list($name, $value) = explode('=', trim($rawoption), 2);
  134. if ($value > 0 and ($name == 'width' or $name == 'height')) {
  135. $options['popup'.$name] = $value;
  136. continue;
  137. }
  138. }
  139. }
  140. } else {
  141. $resource->display = RESOURCELIB_DISPLAY_AUTO;
  142. }
  143. $resource->displayoptions = serialize($options);
  144. // update resource instance and mark as migrated
  145. $DB->update_record('resource', $resource);
  146. $candidate->newmodule = 'resource';
  147. $candidate->newid = $candidate->oldid;
  148. $candidate->migrated = time();
  149. $DB->update_record('resource_old', $candidate);
  150. }
  151. $candidates->close();
  152. // clear all course modinfo caches
  153. rebuild_course_cache(0, true);
  154. }
  155. /**
  156. * This function creates resource_old table and copies all data
  157. * from resource table, this functions has to be called from
  158. * all modules that are successors of old resource module types.
  159. * @return bool true if migration required, false if not
  160. */
  161. function resource_20_prepare_migration() {
  162. global $DB;
  163. $dbman = $DB->get_manager();
  164. // If the resource not created yet, this is probably a new install
  165. $table = new xmldb_table('resource');
  166. if (!$dbman->table_exists($table)) {
  167. return false;
  168. }
  169. // Define table resource_old to be created
  170. $table = new xmldb_table('resource_old');
  171. if ($dbman->table_exists($table)) {
  172. //already executed
  173. return true;
  174. }
  175. // fix invalid NULL popup and options data in old mysql databases
  176. $sql = "UPDATE {resource} SET popup = ? WHERE popup IS NULL";
  177. $DB->execute($sql, array($DB->sql_empty()));
  178. $sql = "UPDATE {resource} SET options = ? WHERE options IS NULL";
  179. $DB->execute($sql, array($DB->sql_empty()));
  180. // Adding fields to table resource_old
  181. $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
  182. $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
  183. $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
  184. $table->add_field('type', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null);
  185. $table->add_field('reference', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
  186. $table->add_field('intro', XMLDB_TYPE_TEXT, 'small', null, null, null, null);
  187. $table->add_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
  188. $table->add_field('alltext', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null);
  189. $table->add_field('popup', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null);
  190. $table->add_field('options', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
  191. $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
  192. $table->add_field('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
  193. $table->add_field('cmid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null);
  194. $table->add_field('newmodule', XMLDB_TYPE_CHAR, '50', null, null, null, null);
  195. $table->add_field('newid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null);
  196. $table->add_field('migrated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
  197. // Adding keys to table resource_old
  198. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
  199. // Adding indexes to table resource_old
  200. $table->add_index('oldid', XMLDB_INDEX_UNIQUE, array('oldid'));
  201. $table->add_index('cmid', XMLDB_INDEX_NOTUNIQUE, array('cmid'));
  202. // Launch create table for resource_old
  203. $dbman->create_table($table);
  204. $module = $DB->get_field('modules', 'id', array('name'=>'resource'));
  205. if (!$DB->count_records('resource')) {
  206. // upgrade of fresh new server from 1.9 - no upgrade needed
  207. return false;
  208. }
  209. // copy old data, the intro text format was FORMAT_MOODLE==0
  210. $sql = "INSERT INTO {resource_old} (oldid, course, name, type, reference, intro, introformat, alltext, popup, options, timemodified, cmid)
  211. SELECT r.id, r.course, r.name, r.type, r.reference, r.summary, 0, r.alltext, r.popup, r.options, r.timemodified, cm.id
  212. FROM {resource} r
  213. LEFT JOIN {course_modules} cm ON (r.id = cm.instance AND cm.module = :module)";
  214. $DB->execute($sql, array('module'=>$module));
  215. return true;
  216. }
  217. /**
  218. * Migrate old resource type to new module, updates all related info, keeps the context id.
  219. * @param string $modname name of new module
  220. * @param object $candidate old instance from resource_old
  221. * @param object $newinstance new module instance to be inserted into db
  222. * @return mixed false if error, object new instance with id if success
  223. */
  224. function resource_migrate_to_module($modname, $candidate, $newinstance) {
  225. global $DB;
  226. if (!$cm = get_coursemodule_from_id('resource', $candidate->cmid)) {
  227. return false;
  228. }
  229. if (!$module = $DB->get_record('modules', array('name'=>$modname))) {
  230. return false;
  231. }
  232. if (!$resource = $DB->get_record('resource', array('id'=>$candidate->oldid))) {
  233. return false;
  234. }
  235. // insert new instance
  236. $newinstance->id = $DB->insert_record($modname, $newinstance);
  237. // update course modules
  238. $cm->module = $module->id;
  239. $cm->instance = $newinstance->id;
  240. $DB->update_record('course_modules', $cm);
  241. //delete old record
  242. $DB->delete_records('resource', array('id'=>$resource->id));
  243. //mark as migrated
  244. $candidate->newmodule = $modname;
  245. $candidate->newid = $newinstance->id;
  246. $candidate->migrated = time();
  247. $DB->update_record('resource_old', $candidate);
  248. //no need to upgrade data in logs because resource module is able to redirect to migrated instances
  249. return $newinstance;
  250. }