Files
moodle/mod/book/db/upgradelib.php
T
Eloy Lafuente (stronk7) 8be3d5ab03 MDL-35297 book: replay some steps lost when book landed to core
This commit replays, conditionally, all the upgrade steps from
MOODLE_19_STABLE to MOODLE_23_STABLE in the mod_book activity. That
guarentees that any site using the mod_book before landing to core,
no matter if it was the latest or an outdated one will upgrade
perfectly to the expected current version.

As a general rule, everytime one contrib plugin lands to core, its
complete upgrade code must be kept, at least until the core version
that introduced it, is out completely from the upgrade requirement
conditions.

In this case, with the missing upgrade code being added to 2.4, it
will be safe to delete the upgrade steps once 2.5 (or upwards) become
a requirement. Never always.

Conflicts:
	mod/book/version.php
2012-10-21 17:58:10 +08:00

168 lines
6.5 KiB
PHP

<?php
// This file is part of Book module for Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Book module upgrade related helper functions
*
* @package mod_book
* @copyright 2010 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Migrate book files stored in moddata folders.
*
* Please note it was a big mistake to store the files there in the first place!
*
* @param stdClass $book
* @param stdClass $context
* @param string $path
* @return void
*/
function mod_book_migrate_moddata_dir_to_legacy($book, $context, $path) {
global $OUTPUT, $CFG;
$base = "$CFG->dataroot/$book->course/$CFG->moddata/book/$book->id";
$fulldir = $base.$path;
if (!is_dir($fulldir)) {
// does not exist
return;
}
$fs = get_file_storage();
$items = new DirectoryIterator($fulldir);
foreach ($items as $item) {
if ($item->isDot()) {
unset($item); // release file handle
continue;
}
if ($item->isLink()) {
// do not follow symlinks - they were never supported in moddata, sorry
unset($item); // release file handle
continue;
}
if ($item->isFile()) {
if (!$item->isReadable()) {
echo $OUTPUT->notification(" File not readable, skipping: ".$fulldir.$item->getFilename());
unset($item); // release file handle
continue;
}
$filepath = clean_param("/$CFG->moddata/book/$book->id".$path, PARAM_PATH);
$filename = clean_param($item->getFilename(), PARAM_FILE);
if ($filename === '') {
// unsupported chars, sorry
unset($item); // release file handle
continue;
}
if (textlib::strlen($filepath) > 255) {
echo $OUTPUT->notification(" File path longer than 255 chars, skipping: ".$fulldir.$item->getFilename());
unset($item); // release file handle
continue;
}
if (!$fs->file_exists($context->id, 'course', 'legacy', '0', $filepath, $filename)) {
$file_record = array('contextid'=>$context->id, 'component'=>'course', 'filearea'=>'legacy', 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename,
'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime());
$fs->create_file_from_pathname($file_record, $fulldir.$item->getFilename());
}
$oldpathname = $fulldir.$item->getFilename();
unset($item); // release file handle
@unlink($oldpathname);
} else {
// migrate recursively all subdirectories
$oldpathname = $base.$item->getFilename().'/';
$subpath = $path.$item->getFilename().'/';
unset($item); // release file handle
mod_book_migrate_moddata_dir_to_legacy($book, $context, $subpath);
@rmdir($oldpathname); // deletes dir if empty
}
}
unset($items); // release file handles
}
/**
* Migrate legacy files in intro and chapters
* @return void
*/
function mod_book_migrate_all_areas() {
global $DB;
$rsbooks = $DB->get_recordset('book');
foreach($rsbooks as $book) {
upgrade_set_timeout(360); // set up timeout, may also abort execution
$cm = get_coursemodule_from_instance('book', $book->id);
$context = context_module::instance($cm->id);
mod_book_migrate_area($book, 'intro', 'book', $book->course, $context, 'mod_book', 'intro', 0);
$rschapters = $DB->get_recordset('book_chapters', array('bookid'=>$book->id));
foreach ($rschapters as $chapter) {
mod_book_migrate_area($chapter, 'content', 'book_chapters', $book->course, $context, 'mod_book', 'chapter', $chapter->id);
}
$rschapters->close();
}
$rsbooks->close();
}
/**
* Migrate one area, this should be probably part of moodle core...
*
* @param stdClass $record object to migrate files (book, chapter)
* @param string $field field in the record we are going to migrate
* @param string $table DB table containing the information to migrate
* @param int $courseid id of the course the book module belongs to
* @param context_module $context context of the book module
* @param string $component component to be used for the migrated files
* @param string $filearea filearea to be used for the migrated files
* @param int $itemid id to be used for the migrated files
* @return void
*/
function mod_book_migrate_area($record, $field, $table, $courseid, $context, $component, $filearea, $itemid) {
global $CFG, $DB;
$fs = get_file_storage();
foreach(array(get_site()->id, $courseid) as $cid) {
$matches = null;
$ooldcontext = context_course::instance($cid);
if (preg_match_all("|$CFG->wwwroot/file.php(\?file=)?/$cid(/[^\s'\"&\?#]+)|", $record->$field, $matches)) {
$file_record = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid);
foreach ($matches[2] as $i=>$filepath) {
if (!$file = $fs->get_file_by_hash(sha1("/$ooldcontext->id/course/legacy/0".$filepath))) {
continue;
}
try {
if (!$newfile = $fs->get_file_by_hash(sha1("/$context->id/$component/$filearea/$itemid".$filepath))) {
$fs->create_file_from_storedfile($file_record, $file);
}
$record->$field = str_replace($matches[0][$i], '@@PLUGINFILE@@'.$filepath, $record->$field);
} catch (Exception $ex) {
// ignore problems
}
$DB->set_field($table, $field, $record->$field, array('id'=>$record->id));
}
}
}
}