mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 20:42:22 +02:00
MDL-27379 Backup conversion logging facilities
This commit is contained in:
parent
1b85912abb
commit
fe50f530fd
@ -387,13 +387,17 @@ class restore_controller extends backup implements loggable {
|
||||
throw new restore_controller_exception('cannot_convert_not_required_status');
|
||||
}
|
||||
|
||||
$this->log('backup format conversion required', backup::LOG_INFO);
|
||||
|
||||
// Run conversion to the proper format
|
||||
if (!convert_helper::to_moodle2_format($this->get_tempdir(), $this->format)) {
|
||||
if (!convert_helper::to_moodle2_format($this->get_tempdir(), $this->format, $this->get_logger())) {
|
||||
// todo - unable to find the conversion path, what to do now?
|
||||
// throwing the exception as a temporary solution
|
||||
throw new restore_controller_exception('unable_to_find_conversion_path');
|
||||
}
|
||||
|
||||
$this->log('backup format conversion successful', backup::LOG_INFO);
|
||||
|
||||
// If no exceptions were thrown, then we are in the proper format
|
||||
$this->format = backup::FORMAT_MOODLE;
|
||||
|
||||
|
@ -35,28 +35,68 @@ require_once($CFG->dirroot . '/backup/util/includes/convert_includes.php');
|
||||
*
|
||||
* @throws convert_exception
|
||||
*/
|
||||
abstract class base_converter {
|
||||
abstract class base_converter implements loggable {
|
||||
|
||||
/** @var string unique identifier of this converter instance */
|
||||
protected $id;
|
||||
|
||||
/** @var string the name of the directory containing the unpacked backup being converted */
|
||||
protected $tempdir;
|
||||
|
||||
/** @var string the name of the directory where the backup is converted to */
|
||||
protected $workdir;
|
||||
|
||||
/** @var null|base_logger logger to use during the conversion */
|
||||
protected $logger = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $tempdir the relative path to the directory containing the unpacked backup to convert
|
||||
* @param null|base_logger logger to use during the conversion
|
||||
*/
|
||||
public function __construct($tempdir) {
|
||||
public function __construct($tempdir, $logger = null) {
|
||||
|
||||
$this->tempdir = $tempdir;
|
||||
$this->id = convert_helper::generate_id($tempdir);
|
||||
$this->workdir = $tempdir . '_' . $this->get_name() . '_' . $this->id;
|
||||
$this->set_logger($logger);
|
||||
$this->log('instantiating '.$this->get_name().' converter '.$this->get_id(), backup::LOG_DEBUG);
|
||||
$this->log('conversion source directory', backup::LOG_DEBUG, $this->tempdir);
|
||||
$this->log('conversion target directory', backup::LOG_DEBUG, $this->workdir);
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logger to use during the conversion
|
||||
*
|
||||
* @param null|base_logger $logger
|
||||
*/
|
||||
public function set_logger($logger) {
|
||||
if (is_null($logger) or ($logger instanceof base_logger)) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the logger was set for the converter, log the message
|
||||
*
|
||||
* If the $display is enabled, the spaces in the $message text are removed
|
||||
* and the text is used as a string identifier in the core_backup language file.
|
||||
*
|
||||
* @see backup_helper::log()
|
||||
* @param string $message message text
|
||||
* @param int $level message level {@example backup::LOG_WARNING}
|
||||
* @param null|mixed $a additional information
|
||||
* @param null|int $depth the message depth
|
||||
* @param bool $display whether the message should be sent to the output, too
|
||||
*/
|
||||
public function log($message, $level, $a = null, $depth = null, $display = false) {
|
||||
if ($this->logger instanceof base_logger) {
|
||||
backup_helper::log($message, $level, $a, $depth, $display, $this->logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get instance identifier
|
||||
*
|
||||
@ -81,8 +121,13 @@ abstract class base_converter {
|
||||
public function convert() {
|
||||
|
||||
try {
|
||||
$this->log('creating the target directory', backup::LOG_DEBUG);
|
||||
$this->create_workdir();
|
||||
|
||||
$this->log('executing the conversion', backup::LOG_DEBUG);
|
||||
$this->execute();
|
||||
|
||||
$this->log('replacing the source directory with the converted version', backup::LOG_DEBUG);
|
||||
$this->replace_tempdir();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
@ -96,6 +141,24 @@ abstract class base_converter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the full path to the working directory
|
||||
*/
|
||||
public function get_workdir_path() {
|
||||
global $CFG;
|
||||
|
||||
return "$CFG->dataroot/temp/backup/$this->workdir";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the full path to the directory with the source backup
|
||||
*/
|
||||
public function get_tempdir_path() {
|
||||
global $CFG;
|
||||
|
||||
return "$CFG->dataroot/temp/backup/$this->tempdir";
|
||||
}
|
||||
|
||||
/// public static methods //////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@ -142,24 +205,6 @@ abstract class base_converter {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the full path to the working directory
|
||||
*/
|
||||
public function get_workdir_path() {
|
||||
global $CFG;
|
||||
|
||||
return "$CFG->dataroot/temp/backup/$this->workdir";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the full path to the directory with the source backup
|
||||
*/
|
||||
public function get_tempdir_path() {
|
||||
global $CFG;
|
||||
|
||||
return "$CFG->dataroot/temp/backup/$this->tempdir";
|
||||
}
|
||||
|
||||
/// end of public API //////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -103,7 +103,7 @@ abstract class moodle1_handlers_factory {
|
||||
/**
|
||||
* Base backup conversion handler
|
||||
*/
|
||||
abstract class moodle1_handler {
|
||||
abstract class moodle1_handler implements loggable {
|
||||
|
||||
/** @var moodle1_converter */
|
||||
protected $converter;
|
||||
@ -121,6 +121,19 @@ abstract class moodle1_handler {
|
||||
public function get_converter() {
|
||||
return $this->converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message using the converter's logging mechanism
|
||||
*
|
||||
* @param string $message message text
|
||||
* @param int $level message level {@example backup::LOG_WARNING}
|
||||
* @param null|mixed $a additional information
|
||||
* @param null|int $depth the message depth
|
||||
* @param bool $display whether the message should be sent to the output, too
|
||||
*/
|
||||
public function log($message, $level, $a = null, $depth = null, $display = false) {
|
||||
$this->converter->log($message, $level, $a, $depth, $display);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -287,6 +300,7 @@ class moodle1_root_handler extends moodle1_xml_handler {
|
||||
* Converts course_files and site_files
|
||||
*/
|
||||
public function on_root_element_start() {
|
||||
|
||||
// convert course files
|
||||
$fileshandler = new moodle1_files_handler($this->converter);
|
||||
$fileshandler->process();
|
||||
@ -542,6 +556,7 @@ class moodle1_files_handler extends moodle1_xml_handler {
|
||||
$ids = $fileman->migrate_directory('course_files');
|
||||
$this->converter->set_stash('course_files_ids', $ids);
|
||||
}
|
||||
$this->log('course files migrated', backup::LOG_INFO, count($ids));
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,6 +617,8 @@ class moodle1_info_handler extends moodle1_handler {
|
||||
if (file_exists($CFG->dirroot.'/mod/'.$modname.'/backup/moodle1/lib.php')) {
|
||||
$this->converter->set_stash('modinfo_'.$modname, $this->currentmod);
|
||||
$this->modnames[] = $modname;
|
||||
} else {
|
||||
$this->log('unsupported activity module', backup::LOG_WARNING, $modname);
|
||||
}
|
||||
|
||||
$this->currentmod = array();
|
||||
@ -1154,7 +1171,7 @@ class moodle1_question_bank_handler extends moodle1_xml_handler {
|
||||
$data['questiontext'] .= ' <img src="@@PLUGINFILE@@/' . $filename . '" />';
|
||||
|
||||
} else {
|
||||
debugging('Question id '.$data['id']. ' file not found: '.$filepath.$filename);
|
||||
$this->log('question file not found', backup::LOG_WARNING, array($data['id'], $filepath.$filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1178,7 +1195,7 @@ class moodle1_question_bank_handler extends moodle1_xml_handler {
|
||||
if (!in_array($qtype, array('description', 'random'))) {
|
||||
$handler = $this->get_qtype_handler($qtype);
|
||||
if ($handler === false) {
|
||||
debugging('Question type '.$qtype.' converter not found.', DEBUG_DEVELOPER);
|
||||
$this->log('question type converter not found', backup::LOG_ERROR, $qtype);
|
||||
|
||||
} else {
|
||||
$this->xmlwriter->begin_tag('plugin_qtype_'.$qtype.'_question');
|
||||
@ -1235,7 +1252,7 @@ class moodle1_question_bank_handler extends moodle1_xml_handler {
|
||||
protected function get_qtype_handler($qtype) {
|
||||
|
||||
if (is_null($this->qtypehandlers)) {
|
||||
// initialize the static list of qtype handler instances
|
||||
// initialize the list of qtype handler instances
|
||||
$this->qtypehandlers = array();
|
||||
foreach (get_plugin_list('qtype') as $qtypename => $qtypelocation) {
|
||||
$filename = $qtypelocation.'/backup/moodle1/lib.php';
|
||||
@ -1245,6 +1262,7 @@ class moodle1_question_bank_handler extends moodle1_xml_handler {
|
||||
if (!class_exists($classname)) {
|
||||
throw new moodle1_convert_exception('missing_handler_class', $classname);
|
||||
}
|
||||
$this->log('registering handler', backup::LOG_DEBUG, $classname, 2);
|
||||
$this->qtypehandlers[$qtypename] = new $classname($this, $qtypename);
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,20 @@ class moodle1_converter extends base_converter {
|
||||
*/
|
||||
const SKIP_ALL_CHILDREN = -991399;
|
||||
|
||||
/**
|
||||
* Log a message
|
||||
*
|
||||
* @see parent::log()
|
||||
* @param string $message message text
|
||||
* @param int $level message level {@example backup::LOG_WARNING}
|
||||
* @param null|mixed $a additional information
|
||||
* @param null|int $depth the message depth
|
||||
* @param bool $display whether the message should be sent to the output, too
|
||||
*/
|
||||
public function log($message, $level, $a = null, $depth = null, $display = false) {
|
||||
parent::log('(moodle1) '.$message, $level, $a, $depth, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the Moodle 1.9 format of the backup directory
|
||||
*
|
||||
@ -104,9 +118,13 @@ class moodle1_converter extends base_converter {
|
||||
// ask your mother first before going out playing with toys
|
||||
parent::init();
|
||||
|
||||
$this->log('initializing '.$this->get_name().' converter', backup::LOG_INFO);
|
||||
|
||||
// good boy, prepare XML parser and processor
|
||||
$this->log('setting xml parser', backup::LOG_DEBUG, null, 1);
|
||||
$this->xmlparser = new progressive_parser();
|
||||
$this->xmlparser->set_file($this->get_tempdir_path() . '/moodle.xml');
|
||||
$this->log('setting xml processor', backup::LOG_DEBUG, null, 1);
|
||||
$this->xmlprocessor = new moodle1_parser_processor($this);
|
||||
$this->xmlparser->set_processor($this->xmlprocessor);
|
||||
|
||||
@ -116,6 +134,7 @@ class moodle1_converter extends base_converter {
|
||||
|
||||
// register the conversion handlers
|
||||
foreach (moodle1_handlers_factory::get_handlers($this) as $handler) {
|
||||
$this->log('registering handler', backup::LOG_DEBUG, get_class($handler), 1);
|
||||
$this->register_handler($handler, $handler->get_paths());
|
||||
}
|
||||
}
|
||||
@ -124,8 +143,14 @@ class moodle1_converter extends base_converter {
|
||||
* Converts the contents of the tempdir into the target format in the workdir
|
||||
*/
|
||||
protected function execute() {
|
||||
$this->log('creating the stash storage', backup::LOG_DEBUG);
|
||||
$this->create_stash_storage();
|
||||
|
||||
$this->log('parsing moodle.xml starts', backup::LOG_DEBUG);
|
||||
$this->xmlparser->process();
|
||||
$this->log('parsing moodle.xml done', backup::LOG_DEBUG);
|
||||
|
||||
$this->log('dropping the stash storage', backup::LOG_DEBUG);
|
||||
$this->drop_stash_storage();
|
||||
}
|
||||
|
||||
@ -235,8 +260,7 @@ class moodle1_converter extends base_converter {
|
||||
if ($path !== $data['path']) {
|
||||
if (!array_key_exists($path, $this->pathelements)) {
|
||||
// no handler registered for the transformed MOD or BLOCK path
|
||||
// todo add this event to the convert log instead of debugging
|
||||
//debugging('No handler registered for the path ' . $path);
|
||||
$this->log('no handler attached', backup::LOG_WARNING, $path);
|
||||
return;
|
||||
|
||||
} else {
|
||||
@ -554,7 +578,7 @@ class moodle1_converter extends base_converter {
|
||||
$fileman->migrate_file('course_files'.$file, dirname($file));
|
||||
} catch (moodle1_convert_exception $e) {
|
||||
// file probably does not exist
|
||||
// todo add to the conversion log
|
||||
$fileman->log('error migrating file', backup::LOG_WARNING, 'course_files'.$file);
|
||||
}
|
||||
}
|
||||
$text = self::rewrite_filephp_usage($text, $files);
|
||||
@ -1086,7 +1110,7 @@ class convert_path_exception extends moodle_exception {
|
||||
* The files in Moodle 1.9 backup are stored in moddata, user_files, group_files,
|
||||
* course_files and site_files folders.
|
||||
*/
|
||||
class moodle1_file_manager {
|
||||
class moodle1_file_manager implements loggable {
|
||||
|
||||
/** @var moodle1_converter instance we serve to */
|
||||
public $converter;
|
||||
@ -1270,6 +1294,19 @@ class moodle1_file_manager {
|
||||
$this->fileids = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message using the converter's logging mechanism
|
||||
*
|
||||
* @param string $message message text
|
||||
* @param int $level message level {@example backup::LOG_WARNING}
|
||||
* @param null|mixed $a additional information
|
||||
* @param null|int $depth the message depth
|
||||
* @param bool $display whether the message should be sent to the output, too
|
||||
*/
|
||||
public function log($message, $level, $a = null, $depth = null, $display = false) {
|
||||
$this->converter->log($message, $level, $a, $depth, $display);
|
||||
}
|
||||
|
||||
/// internal implementation details ////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -33,11 +33,12 @@ abstract class convert_factory {
|
||||
* Instantinates the given converter operating on a given directory
|
||||
*
|
||||
* @throws coding_exception
|
||||
* @param $name The converter name
|
||||
* @param $tempdir The temp directory to operate on
|
||||
* @param $name The converter name
|
||||
* @param $tempdir The temp directory to operate on
|
||||
* @param base_logger|null if the conversion should be logged, use this logger
|
||||
* @return base_converter
|
||||
*/
|
||||
public static function get_converter($name, $tempdir) {
|
||||
public static function get_converter($name, $tempdir, $logger = null) {
|
||||
global $CFG;
|
||||
|
||||
$name = clean_param($name, PARAM_SAFEDIR);
|
||||
@ -53,6 +54,7 @@ abstract class convert_factory {
|
||||
if (!class_exists($classname)) {
|
||||
throw new coding_exception("Converter factory error: class not found $classname");
|
||||
}
|
||||
return new $classname($tempdir);
|
||||
|
||||
return new $classname($tempdir, $logger);
|
||||
}
|
||||
}
|
||||
|
@ -114,10 +114,11 @@ abstract class convert_helper {
|
||||
*
|
||||
* @param string $tempdir The directory to convert
|
||||
* @param string $format The current format, if already detected
|
||||
* @param base_logger|null if the conversion should be logged, use this logger
|
||||
* @throws convert_helper_exception
|
||||
* @return bool false if unable to find the conversion path, true otherwise
|
||||
*/
|
||||
public static function to_moodle2_format($tempdir, $format = null) {
|
||||
public static function to_moodle2_format($tempdir, $format = null, $logger = null) {
|
||||
|
||||
if (is_null($format)) {
|
||||
$format = backup_general_helper::detect_backup_format($tempdir);
|
||||
@ -131,6 +132,9 @@ abstract class convert_helper {
|
||||
if (!class_exists($classname)) {
|
||||
throw new convert_helper_exception('class_not_loaded', $classname);
|
||||
}
|
||||
if ($logger instanceof base_logger) {
|
||||
backup_helper::log('available converter', backup::LOG_DEBUG, $classname, 1, false, $logger);
|
||||
}
|
||||
$descriptions[$name] = call_user_func($classname .'::description');
|
||||
}
|
||||
|
||||
@ -138,12 +142,22 @@ abstract class convert_helper {
|
||||
$path = self::choose_conversion_path($format, $descriptions);
|
||||
|
||||
if (empty($path)) {
|
||||
// unable to convert
|
||||
if ($logger instanceof base_logger) {
|
||||
backup_helper::log('unable to find the conversion path', backup::LOG_ERROR, null, 0, false, $logger);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($logger instanceof base_logger) {
|
||||
backup_helper::log('conversion path established', backup::LOG_INFO,
|
||||
implode(' => ', array_merge($path, array('moodle2'))), 0, false, $logger);
|
||||
}
|
||||
|
||||
foreach ($path as $name) {
|
||||
$converter = convert_factory::get_converter($name, $tempdir);
|
||||
if ($logger instanceof base_logger) {
|
||||
backup_helper::log('running converter', backup::LOG_INFO, $name, 0, false, $logger);
|
||||
}
|
||||
$converter = convert_factory::get_converter($name, $tempdir, $logger);
|
||||
$converter->convert();
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->dirroot . '/backup/util/interfaces/loggable.class.php'); // converters are loggable
|
||||
require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php'); // req by backup.class.php
|
||||
require_once($CFG->dirroot . '/backup/backup.class.php'); // provides backup::FORMAT_xxx constants
|
||||
require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php');
|
||||
|
@ -73,7 +73,7 @@ class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
|
||||
$this->fileman->itemid = 1;
|
||||
$this->fileman->migrate_file('moddata/resource/'.$data['id'].'/'.$packagename);
|
||||
} else {
|
||||
// todo add to log
|
||||
$this->log('missing imscp package', backup::LOG_WARNING, 'moddata/resource/'.$data['id'].'/'.$packagename);
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,12 +117,12 @@ class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
|
||||
global $CFG;
|
||||
|
||||
if (!file_exists($manifestfilepath)) {
|
||||
// todo add to conversion log
|
||||
$this->log('missing imscp manifest file', backup::LOG_WARNING);
|
||||
return null;
|
||||
}
|
||||
$manifestfilecontents = file_get_contents($manifestfilepath);
|
||||
if (empty($manifestfilecontents)) {
|
||||
// todo add to conversion log
|
||||
$this->log('empty imscp manifest file', backup::LOG_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ class moodle1_mod_lesson_handler extends moodle1_mod_handler {
|
||||
$this->fileman->migrate_file('course_files/'.$data['mediafile']);
|
||||
} catch (moodle1_convert_exception $e) {
|
||||
// the file probably does not exist
|
||||
// todo add to log
|
||||
$this->log('error migrating lesson mediafile', backup::LOG_WARNING, 'course_files/'.$data['mediafile']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ class moodle1_mod_resource_handler extends moodle1_mod_handler {
|
||||
$this->fileman->migrate_file('course_files/'.$data['reference'], '/', null, 1);
|
||||
} catch (moodle1_convert_exception $e) {
|
||||
// the file probably does not exist
|
||||
// todo add to log
|
||||
$this->log('error migrating the resource main file', backup::LOG_WARNING, 'course_files/'.$data['reference']);
|
||||
}
|
||||
|
||||
// write resource.xml
|
||||
@ -258,6 +258,7 @@ class moodle1_mod_resource_handler extends moodle1_mod_handler {
|
||||
}
|
||||
|
||||
if (!isset($this->successors[$name])) {
|
||||
$this->log('preparing resource successor handler', backup::LOG_DEBUG, $name);
|
||||
$class = 'moodle1_mod_'.$name.'_handler';
|
||||
$this->successors[$name] = new $class($this->converter, 'mod', $name);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user