From 323abd6da449f9c8ec862d26f174224e2cae4ac9 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Tue, 23 Jul 2013 13:21:54 +0800 Subject: [PATCH] Introduced the functionality to backup and restore the customcert --- .../backup_customcert_activity_task.class.php | 68 +++++++++ backup/moodle2/backup_customcert_stepslib.php | 87 ++++++++++++ ...restore_customcert_activity_task.class.php | 118 +++++++++++++++ .../moodle2/restore_customcert_stepslib.php | 134 ++++++++++++++++++ element/date/lib.php | 18 +++ element/element.class.php | 13 ++ element/grade/lib.php | 19 ++- 7 files changed, 456 insertions(+), 1 deletion(-) create mode 100644 backup/moodle2/backup_customcert_activity_task.class.php create mode 100644 backup/moodle2/backup_customcert_stepslib.php create mode 100644 backup/moodle2/restore_customcert_activity_task.class.php create mode 100644 backup/moodle2/restore_customcert_stepslib.php diff --git a/backup/moodle2/backup_customcert_activity_task.class.php b/backup/moodle2/backup_customcert_activity_task.class.php new file mode 100644 index 0000000..68d4dd3 --- /dev/null +++ b/backup/moodle2/backup_customcert_activity_task.class.php @@ -0,0 +1,68 @@ +. + +/** + * This file contains the backup tasks that provides all the settings and steps to perform + * one complete backup of the activity. + * + * @package mod_customcert + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); + +require_once($CFG->dirroot . '/mod/customcert/backup/moodle2/backup_customcert_stepslib.php'); + +/** + * Handles creating tasks to peform in order to create the backup. + */ +class backup_customcert_activity_task extends backup_activity_task { + + /** + * Define particular settings this activity can have. + */ + protected function define_my_settings() { + // No particular settings for this activity. + } + + /** + * Define particular steps this activity can have. + */ + protected function define_my_steps() { + // The customcert only has one structure step. + $this->add_step(new backup_customcert_activity_structure_step('customcert_structure', 'customcert.xml')); + } + + /** + * Code the transformations to perform in the activity in order to get transportable (encoded) links. + */ + static public function encode_content_links($content) { + global $CFG; + + $base = preg_quote($CFG->wwwroot, "/"); + + // Link to the list of customcerts. + $search ="/(".$base."\/mod\/customcert\/index.php\?id\=)([0-9]+)/"; + $content = preg_replace($search, '$@customcertINDEX*$2@$', $content); + + // Link to customcert view by moduleid. + $search ="/(".$base."\/mod\/customcert\/view.php\?id\=)([0-9]+)/"; + $content = preg_replace($search, '$@customcertVIEWBYID*$2@$', $content); + + return $content; + } +} diff --git a/backup/moodle2/backup_customcert_stepslib.php b/backup/moodle2/backup_customcert_stepslib.php new file mode 100644 index 0000000..5812a7e --- /dev/null +++ b/backup/moodle2/backup_customcert_stepslib.php @@ -0,0 +1,87 @@ +. + +/** + * Define all the backup steps that will be used by the backup_customcert_activity_task. + * + * @package mod_customcert + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); + +/** + * Define the complete customcert structure for backup, with file and id annotations. + */ +class backup_customcert_activity_structure_step extends backup_activity_structure_step { + + /** + * Define the structure of the backup file. + * + * @return backup_nested_element + */ + protected function define_structure() { + + // The instance. + $customcert = new backup_nested_element('customcert', array('id'), array( + 'name', 'intro', 'introformat', 'requiredtime', 'protection', + 'timecreated', 'timemodified')); + + // The issues. + $issues = new backup_nested_element('issues'); + $issue = new backup_nested_element('issue', array('id'), array( + 'customcertid', 'userid', 'timecreated', 'code')); + + // The pages. + $pages = new backup_nested_element('pages'); + $page = new backup_nested_element('page', array('id'), array( + 'customcertid', 'orientation', 'width', 'height', 'pagenumber', + 'timecreated', 'timemodified')); + + // The elements. + $element = new backup_nested_element('element', array('id'), array( + 'pageid', 'name', 'element', 'data', 'font', 'size', 'colour', + 'posx', 'posy', 'sequence', 'timecreated', 'timemodified')); + + // Build the tree. + $customcert->add_child($issues); + $issues->add_child($issue); + $customcert->add_child($pages); + $pages->add_child($page); + $page->add_child($element); + + // Define sources. + $customcert->set_source_table('customcert', array('id' => backup::VAR_ACTIVITYID)); + + // Define page source. + $page->set_source_table('customcert_pages', array('customcertid' => backup::VAR_ACTIVITYID)); + + // Define element source, each element belongs to a page. + $element->set_source_table('customcert_elements', array('pageid' => backup::VAR_PARENTID)); + + // If we are including user info then save the issues. + if ($this->get_setting_value('userinfo')) { + $issue->set_source_table('customcert_issues', array('customcertid' => backup::VAR_ACTIVITYID)); + } + + // Annotate the user id's where required. + $issue->annotate_ids('user', 'userid'); + + // Return the root element (customcert), wrapped into standard activity structure. + return $this->prepare_activity_structure($customcert); + } +} diff --git a/backup/moodle2/restore_customcert_activity_task.class.php b/backup/moodle2/restore_customcert_activity_task.class.php new file mode 100644 index 0000000..d849d62 --- /dev/null +++ b/backup/moodle2/restore_customcert_activity_task.class.php @@ -0,0 +1,118 @@ +. + +/** + * Define all the restore steps that will be used by the restore_customcert_activity_task. + * + * @package mod_customcert + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); + +require_once($CFG->dirroot . '/mod/customcert/backup/moodle2/restore_customcert_stepslib.php'); + +/** + * The class definition for assigning restore tasks that provides all the settings and steps + * to perform one complete restore of the activity. + */ +class restore_customcert_activity_task extends restore_activity_task { + + /** + * Define particular settings this activity can have. + */ + protected function define_my_settings() { + // No particular settings for this activity. + } + + /** + * Define particular steps this activity can have. + */ + protected function define_my_steps() { + // The customcert only has one structure step. + $this->add_step(new restore_customcert_activity_structure_step('customcert_structure', 'customcert.xml')); + } + + /** + * Define the contents in the activity that must be processed by the link decoder. + */ + static public function define_decode_contents() { + $contents = array(); + + $contents[] = new restore_decode_content('customcert', array('intro'), 'customcert'); + + return $contents; + } + + /** + * Define the decoding rules for links belonging to the activity to be executed by the link decoder. + */ + static public function define_decode_rules() { + $rules = array(); + + $rules[] = new restore_decode_rule('CUSTOMCERTVIEWBYID', '/mod/customcert/view.php?id=$1', 'course_module'); + $rules[] = new restore_decode_rule('CUSTOMCERTINDEX', '/mod/customcert/index.php?id=$1', 'course'); + + return $rules; + + } + + /** + * Define the restore log rules that will be applied by the {@link restore_logs_processor} when restoring + * customcert logs. It must return one array of {@link restore_log_rule} objects. + * + * @return array the restore log rules + */ + static public function define_restore_log_rules() { + $rules = array(); + + $rules[] = new restore_log_rule('customcert', 'add', 'view.php?id={course_module}', '{customcert}'); + $rules[] = new restore_log_rule('customcert', 'update', 'view.php?id={course_module}', '{customcert}'); + $rules[] = new restore_log_rule('customcert', 'view', 'view.php?id={course_module}', '{customcert}'); + $rules[] = new restore_log_rule('customcert', 'received', 'report.php?a={customcert}', '{customcert}'); + $rules[] = new restore_log_rule('customcert', 'view report', 'report.php?id={customcert}', '{customcert}'); + + return $rules; + } + + /** + * This function is called after all the activities in the backup have been restored. This allows us to get + * the new course module ids, as they may have been restored after the customcert module, meaning no id + * was available at the time. + */ + public function after_restore() { + global $DB; + + // Get the customcert elements. + $sql = "SELECT e.* + FROM {customcert_elements} e + INNER JOIN {customcert_pages} p + ON e.pageid = p.id + INNER JOIN {customcert} c + ON p.customcertid = c.id + WHERE c.id = :customcertid"; + if ($elements = $DB->get_records_sql($sql, array('customcertid' => $this->get_activityid()))) { + // Go through the elements for the certificate. + foreach ($elements as $e) { + // Get an instance of the element class. + if ($e = customcert_get_element_instance($e)) { + $e->after_restore($this); + } + } + } + } +} diff --git a/backup/moodle2/restore_customcert_stepslib.php b/backup/moodle2/restore_customcert_stepslib.php new file mode 100644 index 0000000..4d31c19 --- /dev/null +++ b/backup/moodle2/restore_customcert_stepslib.php @@ -0,0 +1,134 @@ +. + +/** + * Define all the restore steps that will be used by the restore_customcert_activity_task. + * + * @package mod_customcert + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); + +/** + * Define the complete customcert structure for restore, with file and id annotations. + */ +class restore_customcert_activity_structure_step extends restore_activity_structure_step { + + /** + * Define the different items to restore. + * + * @return array the restore paths + */ + protected function define_structure() { + // The array used to store the path to the items we want to restore. + $paths = array(); + + // The customcert instance. + $paths[] = new restore_path_element('customcert', '/activity/customcert'); + + // The pages. + $paths[] = new restore_path_element('customcert_page', '/activity/customcert/pages/page'); + + // The elements. + $paths[] = new restore_path_element('customcert_element', '/activity/customcert/pages/page/element'); + + // Check if we want the issues as well. + if ($this->get_setting_value('userinfo')) { + $paths[] = new restore_path_element('customcert_issue', '/activity/customcert/issues/issue'); + } + + // Return the paths wrapped into standard activity structure. + return $this->prepare_activity_structure($paths); + } + + /** + * Handles restoring the customcert activity. + * + * @param $data the customcert data + */ + protected function process_customcert($data) { + global $DB; + + $data = (object) $data; + $data->course = $this->get_courseid(); + $data->timecreated = $this->apply_date_offset($data->timecreated); + $data->timemodified = $this->apply_date_offset($data->timemodified); + + // Insert the customcert record. + $newitemid = $DB->insert_record('customcert', $data); + + // Immediately after inserting record call this. + $this->apply_activity_instance($newitemid); + } + + /** + * Handles restoring a customcert page. + * + * @param $data the customcert data + */ + protected function process_customcert_page($data) { + global $DB; + + $data = (object) $data; + $oldid = $data->id; + + $data->customcertid = $this->get_new_parentid('customcert'); + $data->timecreated = $this->apply_date_offset($data->timecreated); + $data->timemodified = $this->apply_date_offset($data->timemodified); + + $newitemid = $DB->insert_record('customcert_pages', $data); + $this->set_mapping('customcert_page', $oldid, $newitemid); + } + + /** + * Handles restoring a customcert element. + * + * @param $data the customcert data + */ + protected function process_customcert_element($data) { + global $DB; + + $data = (object) $data; + $oldid = $data->id; + + $data->pageid = $this->get_new_parentid('customcert_page'); + $data->timecreated = $this->apply_date_offset($data->timecreated); + $data->timemodified = $this->apply_date_offset($data->timemodified); + + $newitemid = $DB->insert_record('customcert_elements', $data); + $this->set_mapping('customcert_element', $oldid, $newitemid); + } + + /** + * Handles restoring a customcert issue. + * + * @param $data the customcert data + */ + protected function process_customcert_issue($data) { + global $DB; + + $data = (object) $data; + $oldid = $data->id; + + $data->customcertid = $this->get_new_parentid('customcert'); + $data->timecreated = $this->apply_date_offset($data->timecreated); + + $newitemid = $DB->insert_record('customcert_issues', $data); + $this->set_mapping('customcert_issue', $oldid, $newitemid); + } +} diff --git a/element/date/lib.php b/element/date/lib.php index dad049e..3675b89 100644 --- a/element/date/lib.php +++ b/element/date/lib.php @@ -169,6 +169,24 @@ class customcert_element_date extends customcert_element_base { parent::definition_after_data($mform); } + /** + * This function is responsible for handling the restoration process of the element. + * + * We will want to update the course module the date element is pointing to as it will + * have changed in the course restore. + * + * @param restore_customcert_activity_task $restore + */ + public function after_restore($restore) { + global $DB; + + $dateinfo = json_decode($this->element->data); + if ($newitem = restore_dbops::get_backup_ids_record($restore->get_restoreid(), 'course_module', $dateinfo->dateitem)) { + $dateinfo->dateitem = $newitem->newitemid; + $DB->set_field('customcert_elements', 'data', self::save_unique_data($dateinfo), array('id' => $this->element->id)); + } + } + /** * Helper function to return all the date formats. * diff --git a/element/element.class.php b/element/element.class.php index 6f325e3..0928ce0 100644 --- a/element/element.class.php +++ b/element/element.class.php @@ -344,6 +344,19 @@ abstract class customcert_element_base { $pdf->setFont($font, $attr, $this->element->size); } + /** + * This function is responsible for handling the restoration process of the element. + * + * For example, the function may save data that is related to another course module, this + * data will need to be updated if we are restoring the course as the course module id will + * be different in the new course. + * + * @param restore_customcert_activity_task $restore + */ + public function after_restore($restore) { + + } + /** * Validates the colour selected. * diff --git a/element/grade/lib.php b/element/grade/lib.php index 9303332..a1db7ed 100644 --- a/element/grade/lib.php +++ b/element/grade/lib.php @@ -75,7 +75,6 @@ class customcert_element_grade extends customcert_element_base { // Encode these variables before saving into the DB. return json_encode($arrtostore); - } /** @@ -122,6 +121,24 @@ class customcert_element_grade extends customcert_element_base { parent::definition_after_data($mform); } + /** + * This function is responsible for handling the restoration process of the element. + * + * We will want to update the course module the grade element is pointing to as it will + * have changed in the course restore. + * + * @param restore_customcert_activity_task $restore + */ + public function after_restore($restore) { + global $DB; + + $gradeinfo = json_decode($this->element->data); + if ($newitem = restore_dbops::get_backup_ids_record($restore->get_restoreid(), 'course_module', $gradeinfo->gradeitem)) { + $gradeinfo->gradeitem = $newitem->newitemid; + $DB->set_field('customcert_elements', 'data', self::save_unique_data($gradeinfo), array('id' => $this->element->id)); + } + } + /** * Helper function to return all the grades items for this course. *