From c351bb50ced7d7353a5046576800c3deb18afddb Mon Sep 17 00:00:00 2001 From: Sam Hemelryk Date: Thu, 6 May 2010 01:53:55 +0000 Subject: [PATCH] backup MDL-22151 Implemented backup in the lesson module --- .../backup_lesson_activity_task.class.php | 102 ++++++++++ .../backup/moodle2/backup_lesson_stepslib.php | 190 ++++++++++++++++++ mod/lesson/lib.php | 2 +- 3 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 mod/lesson/backup/moodle2/backup_lesson_activity_task.class.php create mode 100644 mod/lesson/backup/moodle2/backup_lesson_stepslib.php diff --git a/mod/lesson/backup/moodle2/backup_lesson_activity_task.class.php b/mod/lesson/backup/moodle2/backup_lesson_activity_task.class.php new file mode 100644 index 00000000000..49bb16c63d4 --- /dev/null +++ b/mod/lesson/backup/moodle2/backup_lesson_activity_task.class.php @@ -0,0 +1,102 @@ +. + +/** + * This file contains the backup task for the lesson module + * + * @package moodlecore + * @copyright 2010 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Require the backup lesson steps lib + */ +require_once($CFG->dirroot . '/mod/lesson/backup/moodle2/backup_lesson_stepslib.php'); + +/** + * The backup task class for the lesson module + * @copyright 2010 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class backup_lesson_activity_task extends backup_activity_task { + + protected function define_my_settings() { + // There are no settings + } + + protected function define_my_steps() { + $this->add_step(new backup_lesson_activity_structure_step('lesson structure', 'lesson.xml')); + } + + /** + * Replaces links within the content with links that can be corrected during + * restore + * + * @param string $content + * @return string + */ + static public function encode_content_links($content) { + global $CFG; + + $base = preg_quote($CFG->wwwroot.'/mod/lesson','#'); + + // Provides the interface for overall authoring of lessons + $pattern = '#'.$base.'/edit\.php\?id=([0-9]+)#'; + $replacement = '$@LESSONEDIT*$1@$'; + $content = preg_replace($pattern, $replacement, $content); + + // Action for adding a question page. Prints an HTML form. + $pattern = '#'.$base.'/editpage\.php\?id=([0-9]+)&(amp;)?pageid=([0-9]+)#'; + $replacement = '$@LESSONEDITPAGE*$1*$3@$'; + $content = preg_replace($pattern, $replacement, $content); + + // Provides the interface for grading essay questions + $pattern = '#'.$base.'/essay\.php\?id=([0-9]+)#'; + $replacement = '$@LESSONESSAY*$1@$'; + $content = preg_replace($pattern, $replacement, $content); + + // Provides the interface for viewing and adding high scores + $pattern = '#'.$base.'/highscores\.php\?id=([0-9]+)#'; + $replacement = '$@LESSONHIGHSCORES*$1@$'; + $content = preg_replace($pattern, $replacement, $content); + + // This page lists all the instances of lesson in a particular course + $pattern = '#'.$base.'/index\.php\?id=([0-9]+)#'; + $replacement = '$@LESSONINDEX*$1@$'; + $content = preg_replace($pattern, $replacement, $content); + + // This file plays the mediafile set in lesson settings. + $pattern = '#'.$base.'/mediafile\.php\?id=([0-9]+)#'; + $replacement = '$@LESSONMEDIAFILE*$1@$'; + $content = preg_replace($pattern, $replacement, $content); + + // Displays the lesson statistics. + $pattern = '#'.$base.'/report\.php\?id=([0-9]+)(&(amp;)?pageid=([0-9]+))?#'; + $replacement = '$@LESSONREPORT*$1*$4@$'; + $content = preg_replace($pattern, $replacement, $content); + + // This page prints a particular instance of lesson + $pattern = '#'.$base.'/view\.php\?id=([0-9]+)(&(amp;)?pageid=([0-9]+))?#'; + $replacement = '$@LESSONVIEW*$1*$4@$'; + $content = preg_replace($pattern, $replacement, $content); + + // Return the now encoded content + return $content; + } + +} \ No newline at end of file diff --git a/mod/lesson/backup/moodle2/backup_lesson_stepslib.php b/mod/lesson/backup/moodle2/backup_lesson_stepslib.php new file mode 100644 index 00000000000..3dd86a1360b --- /dev/null +++ b/mod/lesson/backup/moodle2/backup_lesson_stepslib.php @@ -0,0 +1,190 @@ +. + +/** + * This file contains the backup structure for the lesson module + * + * This is the "graphical" structure of the lesson module: + * + * lesson ------------>---------------|-------------->-----------|------------->------------| + * (CL,pk->id) | | | + * | | | | + * | lesson_grades lesson_high_scores lesson_timer + * | (UL, pk->id,fk->lessonid) (UL, pk->id,fk->lessonid) (UL, pk->id,fk->lessonid) + * | | + * | | + * | | + * | | + * lesson_pages----------->---------lesson_branch + * (CL,pk->id,fk->lessonid) (UL, pk->id,fk->pageid) + * | + * | + * | + * lesson_answers + * (CL,pk->id,fk->pageid) + * | + * | + * | + * lesson_attempts + * (UL,pk->id,fk->answerid) + * + * Meaning: pk->primary key field of the table + * fk->foreign key to link with parent + * nt->nested field (recursive data) + * CL->course level info + * UL->user level info + * files->table may have files) + * + * @package moodlecore + * @copyright 2010 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Structure step class that informs a backup task how to backup the lesson module. + * + * @copyright 2010 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class backup_lesson_activity_structure_step extends backup_activity_structure_step { + + protected function define_structure() { + + // The lesson table + // This table contains all of the goodness for the lesson module, quite + // alot goes into it but nothing relational other than course when will + // need to be corrected upon restore + $lesson = new backup_nested_element('lesson', array('id'), array( + 'course','name','practice','modattempts','usepassword','password', + 'dependency','conditions','grade','custom','ongoing','usemaxgrade', + 'maxanswers','maxattempts','review','nextpagedefault','feedback', + 'minquestions','maxpages','timed','maxtime','retake','activitylink', + 'mediafile','mediaheight','mediawidth','mediaclose','slideshow', + 'width','height','bgcolor','displayleft','displayleftif','progressbar', + 'highscores','maxhighscores','available','deadline','timemodified' + )); + + // The lesson_pages table + // Grouped within a `pages` element, important to note that page is relational + // to the lesson, and also to the previous/next page in the series. + // Upon restore prevpageid and nextpageid will need to be corrected. + $pages = new backup_nested_element('pages'); + $page = new backup_nested_element('page', array('id'), array( + 'prevpageid','nextpageid','qtype','qoption','layout', + 'display','timecreated','timemodified','title','contents' + )); + + // The lesson_answers table + // Grouped within an answers `element`, the lesson_answers table relates + // to the page and lesson with `pageid` and `lessonid` that will both need + // to be corrected during restore. + $answers = new backup_nested_element('answers'); + $answer = new backup_nested_element('answer', array('id'), array( + 'jumpto','grade','score','flags','timecreated','timemodified','answer_text', + 'response' + )); + // Tell the answer element about the answer_text elements mapping to the answer + // database field. + $answer->set_source_alias('answer', 'answer_text'); + + // The lesson_attempts table + // Grouped by an `attempts` element this is relational to the page, lesson, + // and user. + $attempts = new backup_nested_element('attempts'); + $attempt = new backup_nested_element('attempt', array('id'), array( + 'userid','retry','correct','useranswer','timeseen' + )); + + // The lesson_branch table + // Grouped by a `branch` element this is relational to the page, lesson, + // and user. + $branches = new backup_nested_element('branches'); + $branch = new backup_nested_element('branch', array('id'), array( + 'userid','retry','flag','timeseen' + )); + + // The lesson_grades table + // Grouped by a grades element this is relational to the lesson and user. + $grades = new backup_nested_element('grades'); + $grade = new backup_nested_element('grade', array('id'), array( + 'userid','grade','late','completed' + )); + + // The lesson_high_scores table + // Grouped by a highscores element this is relational to the lesson, user, + // and possibly a grade. + $highscores = new backup_nested_element('highscores'); + $highscore = new backup_nested_element('highscore', array('id'), array( + 'gradeid','userid','nickname' + )); + + // The lesson_timer table + // Grouped by a `timers` element this is relational to the lesson and user. + $timers = new backup_nested_element('timers'); + $timer = new backup_nested_element('timer', array('id'), array( + 'userid','starttime','lessontime' + )); + + // Now that we have all of the elements created we've got to put them + // together correctly. + $lesson->add_child($pages); + $pages->add_child($page); + $page->add_child($answers); + $answers->add_child($answer); + $answer->add_child($attempts); + $attempts->add_child($attempt); + $page->add_child($branches); + $branches->add_child($branch); + $lesson->add_child($grades); + $grades->add_child($grade); + $lesson->add_child($highscores); + $highscores->add_child($highscore); + $lesson->add_child($timers); + $timers->add_child($timer); + + // Set the source table for the elements that aren't reliant on the user + // at this point (lesson, lesson_pages, lesson_answers) + $lesson->set_source_table('lesson', array('id' => backup::VAR_ACTIVITYID)); + $page->set_source_table('lesson_pages', array('lessonid' => backup::VAR_PARENTID)); + $answer->set_source_table('lesson_answers', array('pageid' => backup::VAR_PARENTID)); + + // Check if we are also backing up user information + if ($this->get_setting_value('userinfo')) { + // Set the source table for elements that are reliant on the user + // lesson_attempts, lesson_branch, lesson_grades, lesson_high_scores, lesson_timer + $attempt->set_source_table('lesson_attempts', array('answerid' => backup::VAR_PARENTID)); + $branch->set_source_table('lesson_branch', array('pageid' => backup::VAR_PARENTID)); + $grade->set_source_table('lesson_grades', array('lessonid'=>backup::VAR_PARENTID)); + $highscore->set_source_table('lesson_high_scores', array('lessonid' => backup::VAR_PARENTID)); + $timer->set_source_table('lesson_timer', array('lessonid' => backup::VAR_PARENTID)); + } + + // Annotate the user id's where required. + $attempt->annotate_ids('user', 'userid'); + $branch->annotate_ids('user', 'userid'); + $grade->annotate_ids('user', 'userid'); + $highscore->annotate_ids('user', 'userid'); + $timer->annotate_ids('user', 'userid'); + + // Annotate the file areas in user by the lesson module. + $lesson->annotate_files(array('lesson_media_file'), 'id'); + $page->annotate_files(array('lesson_page_contents'), 'id'); + + // Prepare and return the structure we have just created for the lesson module. + return $this->prepare_activity_structure($lesson); + } +} \ No newline at end of file diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index 81cc3f99a14..c51d7a73299 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -764,7 +764,7 @@ function lesson_supports($feature) { case FEATURE_COMPLETION_TRACKS_VIEWS: return true; case FEATURE_GRADE_HAS_GRADE: return true; case FEATURE_GRADE_OUTCOMES: return true; - + case FEATURE_BACKUP_MOODLE2: return true; default: return null; } }