diff --git a/backup/converter/moodle1.class.php b/backup/converter/moodle1.class.php new file mode 100644 index 00000000000..29b5e48a9a2 --- /dev/null +++ b/backup/converter/moodle1.class.php @@ -0,0 +1,7 @@ +get_convertid()); // Create ids temp table + } +} + +/** + * Do convert plan related tear down + */ +class convert_drop_and_clean_temp_stuff extends convert_execution_step { + + protected function define_execution() { + backup_controller_dbops::drop_backup_ids_temp_table($this->get_convertid()); // Drop ids temp table + } +} \ No newline at end of file diff --git a/backup/util/converter/base_converter.class.php b/backup/util/converter/base_converter.class.php new file mode 100644 index 00000000000..1c207cef6af --- /dev/null +++ b/backup/util/converter/base_converter.class.php @@ -0,0 +1,92 @@ +tempdir = $tempdir; + $this->convertdir = $this->tempdir.'_'.$this->get_name(); + $this->id = convert_helper::generate_id($this->convertdir); + $this->init(); + } + + public function init() { + } + + public function get_id() { + return $this->id; + } + + public function get_name() { + return array_shift(explode('_', get_class($this))); + } + + public function get_convertdir() { + global $CFG; + + return "$CFG->dirroot/backup/temp/$this->convertdir"; + } + + public function get_tempdir() { + global $CFG; + + return "$CFG->dirroot/backup/temp/$this->tempdir"; + } + + public function delete_convertdir() { + fulldelete($this->get_convertdir()); + } + + public function create_convertdir() { + $this->delete_convertdir(); + make_upload_directory($this->get_convertdir()); + } + + public function replace_tempdir() { + fulldelete($this->get_tempdir()); + + if (!rename($this->get_convertdir(), $this->get_tempdir())) { + throw new backup_exception('failedmoveconvertedintoplace'); // @todo Define this string + } + } + + /** + * @abstract + * @return boolean + */ + abstract public function can_convert(); + + // Kicks things off + public function convert() { + + $e = NULL; + + try { + $this->create_convertdir(); + $this->execute(); + $this->replace_tempdir(); + } catch (Exception $e) { + } + // Do cleanup... + $this->destroy(); + + if ($e instanceof Exception) { + throw $e; + } + } + + abstract public function execute(); + + public function destroy() { + $this->delete_convertdir(); + } +} \ No newline at end of file diff --git a/backup/util/converter/plan_converter.class.php b/backup/util/converter/plan_converter.class.php new file mode 100644 index 00000000000..c651e942247 --- /dev/null +++ b/backup/util/converter/plan_converter.class.php @@ -0,0 +1,30 @@ +plan instanceof convert_plan) { + $this->plan = new convert_plan($this); + } + return $this->plan; + } + + abstract public function build_plan(); + + public function execute() { + $this->get_plan()->build(); // Ends up calling $this->build_plan() + $this->get_plan()->execute(); + } + + public function destroy() { + parent::destroy(); + $this->get_plan()->destroy(); + } +} \ No newline at end of file diff --git a/backup/util/helper/convert_helper.class.php b/backup/util/helper/convert_helper.class.php new file mode 100644 index 00000000000..7553d9fe29a --- /dev/null +++ b/backup/util/helper/convert_helper.class.php @@ -0,0 +1,9 @@ +dirroot.'/backup/util/converter/base_converter.class.php'); +require_once($CFG->dirroot.'/backup/util/converter/plan_converter.class.php'); +require_once($CFG->dirroot.'/backup/util/helper/convert_helper.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/base_plan.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/base_step.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/base_task.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_plan.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_step.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_task.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_structure_step.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_execution_step.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_.class.php'); +require_once($CFG->dirroot.'/backup/util/plan/convert_.class.php'); +require_once($CFG->dirroot.'/backup/moodle2/convert_stepslib.php'); + +// And some moodle stuff too +require_once($CFG->libdir.'/fileslib.php'); \ No newline at end of file diff --git a/backup/util/plan/convert_execution_step.class.php b/backup/util/plan/convert_execution_step.class.php new file mode 100644 index 00000000000..e60184fbc87 --- /dev/null +++ b/backup/util/plan/convert_execution_step.class.php @@ -0,0 +1,15 @@ +define_execution(); + } + + /** + * Function that will contain all the code to be executed + */ + abstract protected function define_execution(); +} \ No newline at end of file diff --git a/backup/util/plan/convert_plan.class.php b/backup/util/plan/convert_plan.class.php new file mode 100644 index 00000000000..68a67d8f12f --- /dev/null +++ b/backup/util/plan/convert_plan.class.php @@ -0,0 +1,40 @@ +converter = $converter; + $this->basepath = $CFG->dataroot . '/temp/backup/' . $converter->get_backupid(); + parent::__construct('convert_plan'); + } + + /** + * This function will be responsible for handling the params, and to call + * to the corresponding logger->process() once all modifications in params + * have been performed + */ + public function log($message, $level, $a = null, $depth = null, $display = false) { + // TODO: Implement log() method. + } + + public function get_converterid() { + return $this->converter->get_id(); + } + + /** + * Function responsible for building the tasks of any plan + * with their corresponding settings + * (must set the $built property to true) + */ + public function build() { + // This seems circular for no real reason.... + $this->converter->build_plan(); + $this->built = true; + } +} \ No newline at end of file diff --git a/backup/util/plan/convert_step.class.php b/backup/util/plan/convert_step.class.php new file mode 100644 index 00000000000..71207666f38 --- /dev/null +++ b/backup/util/plan/convert_step.class.php @@ -0,0 +1,19 @@ +task instanceof convert_task) { + throw new backup_exception('not_specified_convert_task'); // @todo Define string + } + return $this->task->get_convertid(); + } +} \ No newline at end of file diff --git a/backup/util/plan/convert_structure_step.class.php b/backup/util/plan/convert_structure_step.class.php new file mode 100644 index 00000000000..9af22e61226 --- /dev/null +++ b/backup/util/plan/convert_structure_step.class.php @@ -0,0 +1,137 @@ +filename = $filename; + $this->contenttransformer = null; + parent::__construct($name, $task); + } + + public function execute() { + + if (!$this->execute_condition()) { // Check any condition to execute this + return; + } + + $fullpath = $this->task->get_taskbasepath(); + + // We MUST have one fullpath here, else, error + if (empty($fullpath)) { + throw new backup_step_exception('backup_structure_step_undefined_fullpath'); + } + + // Append the filename to the fullpath + $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; + + // Create output, transformer, writer, processor + $xo = new file_xml_output($fullpath); + $xt = null; + if (class_exists('backup_xml_transformer')) { + $xt = new backup_xml_transformer($this->get_courseid()); + $this->contenttransformer = $xt; // Save the reference to the transformer + // as far as we are going to need it out + // from xml_writer (blame serialized data!) + } + $xw = new xml_writer($xo, $xt); + $pr = new backup_structure_processor($xw); + + // Set processor variables from settings + foreach ($this->get_settings() as $setting) { + $pr->set_var($setting->get_name(), $setting->get_value()); + } + // Add backupid as one more var for processor + $pr->set_var(backup::VAR_BACKUPID, $this->get_backupid()); + + // Get structure definition + $structure = $this->define_structure(); + if (! $structure instanceof backup_nested_element) { + throw new backup_step_exception('backup_structure_step_wrong_structure'); + } + + // Start writer + $xw->start(); + + // Process structure definition + $structure->process($pr); + + // Close everything + $xw->stop(); + + // Destroy the structure. It helps PHP 5.2 memory a lot! + $structure->destroy(); + } + + /** + * As far as backup structure steps are implementing backup_plugin stuff, they need to + * have the parent task available for wrapping purposes (get course/context....) + */ + public function get_task() { + return $this->task; + } + + /** + * Add plugin structure to any element in the structure backup tree + * + * @param string $plugintype type of plugin as defined by get_plugin_types() + * @param backup_nested_element $element element in the structure backup tree that + * we are going to add plugin information to + * @param bool $multiple to define if multiple plugins can produce information + * for each instance of $element (true) or no (false) + */ + protected function add_plugin_structure($plugintype, $element, $multiple) { + + global $CFG; + + // Check the requested plugintype is a valid one + if (!array_key_exists($plugintype, get_plugin_types($plugintype))) { + throw new backup_step_exception('incorrect_plugin_type', $plugintype); + } + + // Arrived here, plugin is correct, let's create the optigroup + $optigroupname = $plugintype . '_' . $element->get_name() . '_plugin'; + $optigroup = new backup_optigroup($optigroupname, null, $multiple); + $element->add_child($optigroup); // Add optigroup to stay connected since beginning + + // Get all the optigroup_elements, looking across all the plugin dirs + $pluginsdirs = get_plugin_list($plugintype); + foreach ($pluginsdirs as $name => $plugindir) { + $classname = 'backup_' . $plugintype . '_' . $name . '_plugin'; + $backupfile = $plugindir . '/backup/moodle2/' . $classname . '.class.php'; + if (file_exists($backupfile)) { + require_once($backupfile); + $backupplugin = new $classname($plugintype, $name, $optigroup, $this); + // Add plugin returned structure to optigroup + $backupplugin->define_plugin_structure($element->get_name()); + } + } + } + + /** + * To conditionally decide if one step will be executed or no + * + * For steps needing to be executed conditionally, based in dynamic + * conditions (at execution time vs at declaration time) you must + * override this function. It will return true if the step must be + * executed and false if not + */ + protected function execute_condition() { + return true; + } + + /** + * Function that will return the structure to be processed by this backup_step. + * Must return one backup_nested_element + */ + abstract protected function define_structure(); +} \ No newline at end of file diff --git a/backup/util/plan/convert_task.class.php b/backup/util/plan/convert_task.class.php new file mode 100644 index 00000000000..756be73c7fc --- /dev/null +++ b/backup/util/plan/convert_task.class.php @@ -0,0 +1,13 @@ +plan->get_backupid(); + } +} \ No newline at end of file