Merge branch 'MDL-24521' of git://github.com/samhemelryk/moodle
[moodle.git] / mod / wiki / db / upgrade.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * This file keeps track of upgrades to the wiki module
20  *
21  * Sometimes, changes between versions involve
22  * alterations to database structures and other
23  * major things that may break installations.
24  *
25  * The upgrade function in this file will attempt
26  * to perform all the necessary actions to upgrade
27  * your older installation to the current version.
28  *
29  * @package mod-wiki-2.0
30  * @copyrigth 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu
31  * @copyrigth 2009 Universitat Politecnica de Catalunya http://www.upc.edu
32  *
33  * @author Jordi Piguillem
34  *
35  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
36  *
37  */
39 function xmldb_wiki_upgrade($oldversion) {
40     global $CFG, $DB, $OUTPUT;
42     $dbman = $DB->get_manager();
44     // Step 0: Add new fields to main wiki table
45     if ($oldversion < 2010040100) {
46         require_once(dirname(__FILE__) . '/upgradelib.php');
47         echo $OUTPUT->notification('Adding new fields to wiki table', 'notifysuccess');
48         wiki_add_wiki_fields();
50         upgrade_mod_savepoint(true, 2010040100, 'wiki');
51     }
53     // Step 1: Rename old tables
54     if ($oldversion < 2010040101) {
55         $tables = array('wiki_pages', 'wiki_locks', 'wiki_entries');
57         echo $OUTPUT->notification('Renaming old wiki module tables', 'notifysuccess');
58         foreach ($tables as $tablename) {
59             $table = new xmldb_table($tablename);
60             if ($dbman->table_exists($table)) {
61                 if ($dbman->table_exists($table)) {
62                     $dbman->rename_table($table, $tablename . '_old');
63                 }
64             }
65         }
66         upgrade_mod_savepoint(true, 2010040101, 'wiki');
67     }
69     // Step 2: Creating new tables
70     if ($oldversion < 2010040102) {
71         require_once(dirname(__FILE__) . '/upgradelib.php');
72         echo $OUTPUT->notification('Installing new wiki module tables', 'notifysuccess');
73         wiki_upgrade_install_20_tables();
74         upgrade_mod_savepoint(true, 2010040102, 'wiki');
75     }
77     // Step 3: migrating wiki instances
78     if ($oldversion < 2010040103) {
79         upgrade_set_timeout();
81         // Setting up wiki configuration
82         $sql = "UPDATE {wiki}
83                     SET intro = summary,
84                     firstpagetitle = pagename,
85                     defaultformat = ?";
86         $DB->execute($sql, array('html'));
88         $sql = "UPDATE {wiki}
89                     SET wikimode = ?
90                     WHERE wtype = ?";
91         $DB->execute($sql, array('collaborative', 'group'));
93         $sql = "UPDATE {wiki}
94                     SET wikimode = ?
95                     WHERE wtype != ?";
96         $DB->execute($sql, array('individual', 'group'));
98         // Removing edit & create capability to students in old teacher wikis
99         $studentroles = $DB->get_records('role', array('archetype' => 'student'));
100         $wikis = $DB->get_records('wiki');
101         foreach ($wikis as $wiki) {
102             echo $OUTPUT->notification('Migrating '.$wiki->wtype.' type wiki instance: '.$wiki->name, 'notifysuccess');
103             if ($wiki->wtype == 'teacher') {
104                 $cm = get_coursemodule_from_instance('wiki', $wiki->id);
105                 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
106                 foreach ($studentroles as $studentrole) {
107                     role_change_permission($studentrole->id, $context, 'mod/wiki:editpage', CAP_PROHIBIT);
108                     role_change_permission($studentrole->id, $context, 'mod/wiki:createpage', CAP_PROHIBIT);
109                 }
110             }
111         }
113         echo $OUTPUT->notification('Migrating old wikis to new wikis', 'notifysuccess');
114         upgrade_mod_savepoint(true, 2010040103, 'wiki');
115     }
117     // Step 4: migrating wiki entries to new subwikis
118     if ($oldversion < 2010040104) {
119         /**
120          * Migrating wiki entries to new subwikis
121          */
122         $sql = "INSERT INTO {wiki_subwikis} (wikiid, groupid, userid)
123                 SELECT DISTINCT e.wikiid, e.groupid, e.userid
124                   FROM {wiki_entries_old} e";
125         echo $OUTPUT->notification('Migrating old entries to new subwikis', 'notifysuccess');
127         $DB->execute($sql, array());
129         upgrade_mod_savepoint(true, 2010040104, 'wiki');
130     }
132     // Step 5: Migrating pages
133     if ($oldversion < 2010040105) {
135         // select all wiki pages
136         $sql = "SELECT s.id, p.pagename, p.created, p.lastmodified, p.userid, p.hits
137                   FROM {wiki_pages_old} p
138                   LEFT OUTER JOIN {wiki_entries_old} e ON e.id = p.wiki
139                   LEFT OUTER JOIN {wiki_subwikis} s ON s.wikiid = e.wikiid AND s.groupid = e.groupid AND s.userid = e.userid
140                  WHERE p.version = (SELECT max(po.version)
141                                       FROM {wiki_pages_old} po
142                                      WHERE p.pagename = po.pagename AND p.wiki = po.wiki)";
143         echo $OUTPUT->notification('Migrating old pages to new pages', 'notifysuccess');
145         $records = $DB->get_recordset_sql($sql);
146         foreach ($records as $record) {
147             $page = new stdclass();
148             $page->subwikiid     = $record->id;
149             $page->title         = $record->pagename;
150             $page->cachedcontent = '**reparse needed**';
151             $page->timecreated   = $record->created;
152             $page->timemodified  = $record->lastmodified;
153             $page->userid        = $record->userid;
154             $page->pageviews     = $record->hits;
155             try {
156                 // make sure there is no duplicated records exist
157                 if (!$DB->record_exists('wiki_pages', array('subwikiid'=>$record->id, 'userid'=>$record->userid, 'title'=>$record->pagename))) {
158                     $DB->insert_record('wiki_pages', $page);
159                 }
160             } catch (dml_exception $e) {
161                 // catch possible insert exception
162                 debugging($e->getMessage());
163                 continue;
164             }
165         }
166         $records->close();
168         upgrade_mod_savepoint(true, 2010040105, 'wiki');
169     }
171     // Step 6: Migrating versions
172     if ($oldversion < 2010040106) {
173         require_once(dirname(__FILE__) . '/upgradelib.php');
174         echo $OUTPUT->notification('Migrating old history to new history', 'notifysuccess');
175         wiki_upgrade_migrate_versions();
176         upgrade_mod_savepoint(true, 2010040106, 'wiki');
177     }
179     // Step 7: refresh cachedcontent and fill wiki links table
180     if ($oldversion < 2010040107) {
181         require_once($CFG->dirroot. '/mod/wiki/locallib.php');
182         upgrade_set_timeout();
184         $pages = $DB->get_recordset('wiki_pages');
186         foreach ($pages as $page) {
187             wiki_refresh_cachedcontent($page);
188         }
190         $pages->close();
192         echo $OUTPUT->notification('Caching content', 'notifysuccess');
193         upgrade_mod_savepoint(true, 2010040107, 'wiki');
194     }
195     // Step 8, migrating files
196     if ($oldversion < 2010040108) {
197         $fs = get_file_storage();
198         $sql = "SELECT files.*, po.meta AS filemeta FROM {wiki_pages_old} po JOIN (
199                     SELECT DISTINCT po.id, po.pagename, w.id AS wikiid, po.userid,
200                         eo.id AS entryid, eo.groupid, s.id AS subwiki,
201                         w.course AS courseid, cm.id AS cmid
202                         FROM {wiki_pages_old} po
203                         LEFT OUTER JOIN {wiki_entries_old} eo
204                         ON eo.id=po.wiki
205                         LEFT OUTER JOIN {wiki} w
206                         ON w.id = eo.wikiid
207                         LEFT OUTER JOIN {wiki_subwikis} s
208                         ON s.groupid = eo.groupid AND s.wikiid = eo.wikiid AND eo.userid = s.userid
209                         JOIN {modules} m ON m.name = 'wiki'
210                         JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = w.id)
211                 ) files ON files.id = po.id";
213         $rs = $DB->get_recordset_sql($sql);
214         foreach ($rs as $r) {
215             if (strpos($r->pagename, 'internal://') !== false) {
216                 // Found a file resource!
217                 $pattern = 'internal://';
218                 $matches = array();
219                 $filename = str_replace($pattern, '', $r->pagename);
220                 $orgifilename = $filename = clean_param($filename, PARAM_FILE);
221                 $context = get_context_instance(CONTEXT_MODULE, $r->cmid);
222                 $filemeta = unserialize($r->filemeta);
223                 $filesection = $filemeta['section'];
224                 // When attach a file to wiki page, user can customize the file name instead of original file name
225                 // if user did, old wiki will create two pages, internal://original_pagename and internal://renamed_pagename
226                 // internal://original_pagename record has renamed pagename in meta field
227                 // but all file have this field
228                 // old wiki will rename file names to filter space and special character
229                 if (!empty($filemeta['Content-Location'])) {
230                     $orgifilename = urldecode($filemeta['Content-Location']);
231                     $orgifilename = str_replace(' ', '_', $orgifilename);
232                 }
233                 $thefile = $CFG->dataroot . '/' . $r->courseid . '/moddata/wiki/' . $r->wikiid .'/' . $r->entryid . '/'. $filesection .'/'. $filename;
235                 if (is_file($thefile) && is_readable($thefile)) {
236                     $filerecord = array('contextid' => $context->id,
237                                         'component' => 'mod_wiki',
238                                         'filearea'  => 'attachments',
239                                         'itemid'    => $r->subwiki,
240                                         'filepath'  => '/',
241                                         'filename'  => $orgifilename,
242                                         'userid'    => $r->userid);
243                     if (!$fs->file_exists($context->id, 'mod_wiki', 'attachments', $r->subwiki, '/', $orgifilename)) {
244                         //echo $OUTPUT->notification('Migrating file '.$orgifilename, 'notifysuccess');
245                         $storedfile = $fs->create_file_from_pathname($filerecord, $thefile);
246                     }
247                     // we have to create another file here to make sure interlinks work
248                     if (!$fs->file_exists($context->id, 'mod_wiki', 'attachments', $r->subwiki, '/', $filename)) {
249                         $filerecord['filename'] = $filename;
250                         //echo $OUTPUT->notification('Migrating file '.$filename, 'notifysuccess');
251                         $storedfile = $fs->create_file_from_pathname($filerecord, $thefile);
252                     }
253                 } else {
254                     echo $OUTPUT->notification("Bad data found: $r->pagename <br/> Expected file path: $thefile Please fix the bad file path manually.");
255                 }
256             }
257         }
258         $rs->close();
259         upgrade_mod_savepoint(true, 2010040108, 'wiki');
260     }
262     // Step 9: clean wiki table
263     if ($oldversion < 2010040109) {
264         $fields = array('summary', 'pagename', 'wtype', 'ewikiprinttitle', 'htmlmode', 'ewikiacceptbinary', 'disablecamelcase', 'setpageflags', 'strippages', 'removepages', 'revertchanges', 'initialcontent');
265         $table = new xmldb_table('wiki');
266         foreach ($fields as $fieldname) {
267             $field = new xmldb_field($fieldname);
268             if ($dbman->field_exists($table, $field)) {
269                 $dbman->drop_field($table, $field);
270             }
272         }
273         echo $OUTPUT->notification('Cleaning wiki table', 'notifysuccess');
274         upgrade_mod_savepoint(true, 2010040109, 'wiki');
275     }
277     if ($oldversion < 2010080201) {
279         $sql = "UPDATE {comments}
280                 SET commentarea = 'wiki_page'
281                 WHERE commentarea = 'wiki_comment_section'";
282         $DB->execute($sql);
284         $sql = "UPDATE {tag_instance}
285                 SET itemtype = 'wiki_page'
286                 WHERE itemtype = 'wiki'";
287         $DB->execute($sql);
289         echo $OUTPUT->notification('Updating comments and tags', 'notifysuccess');
291         upgrade_mod_savepoint(true, 2010080201, 'wiki');
292     }
294     if ($oldversion < 2010102500) {
296         // Define key subwikifk (foreign) to be added to wiki_pages
297         $table = new xmldb_table('wiki_pages');
298         $key = new xmldb_key('subwikifk', XMLDB_KEY_FOREIGN, array('subwikiid'), 'wiki_subwikis', array('id'));
300         // Launch add key subwikifk
301         $dbman->add_key($table, $key);
303          // Define key subwikifk (foreign) to be added to wiki_links
304         $table = new xmldb_table('wiki_links');
305         $key = new xmldb_key('subwikifk', XMLDB_KEY_FOREIGN, array('subwikiid'), 'wiki_subwikis', array('id'));
307         // Launch add key subwikifk
308         $dbman->add_key($table, $key);
310         // wiki savepoint reached
311         upgrade_mod_savepoint(true, 2010102500, 'wiki');
312     }
314     if ($oldversion < 2010102800) {
316         $sql = "UPDATE {tag_instance}
317                 SET itemtype = 'wiki_pages'
318                 WHERE itemtype = 'wiki_page'";
319         $DB->execute($sql);
321         echo $OUTPUT->notification('Updating tags itemtype', 'notifysuccess');
323         upgrade_mod_savepoint(true, 2010102800, 'wiki');
324     }
326     // TODO: Will hold the old tables so we will have chance to fix problems
327     // Will remove old tables once migrating 100% stable
328     // Step 10: delete old tables
329     //if ($oldversion < 2011000000) {
330         //$tables = array('wiki_pages', 'wiki_locks', 'wiki_entries');
332         //foreach ($tables as $tablename) {
333             //$table = new xmldb_table($tablename . '_old');
334             //if ($dbman->table_exists($table)) {
335                 //$dbman->drop_table($table);
336             //}
337         //}
338         //echo $OUTPUT->notification('Droping old tables', 'notifysuccess');
339         //upgrade_mod_savepoint(true, 2011000000, 'wiki');
340     //}
342     return true;