diff --git a/mod/workshop/backup/moodle2/backup_workshop_activity_task.class.php b/mod/workshop/backup/moodle2/backup_workshop_activity_task.class.php new file mode 100644 index 00000000000..c4b78a5e03a --- /dev/null +++ b/mod/workshop/backup/moodle2/backup_workshop_activity_task.class.php @@ -0,0 +1,70 @@ +. + +/** + * Class {@link backup_workshop_activity_task} definition + * + * @package mod_workshop + * @subpackage backup-moodle2 + * @copyright 2010 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->dirroot . '/mod/workshop/backup/moodle2/backup_workshop_settingslib.php'); +require_once($CFG->dirroot . '/mod/workshop/backup/moodle2/backup_workshop_stepslib.php'); + +/** + * Provides all the settings and steps to perform one complete backup of workshop activity + */ +class backup_workshop_activity_task extends backup_activity_task { + + /** + * Define (add) particular settings this activity can have + */ + protected function define_my_settings() { + // No particular settings for this activity + } + + /** + * Define (add) particular steps this activity can have + */ + protected function define_my_steps() { + $this->add_step(new backup_workshop_activity_structure_step('workshop_structure', 'workshop.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 workshops + $search = "/(" . $base . "\/mod\/workshop\/index.php\?id\=)([0-9]+)/"; + $result = preg_replace($search, '$@WORKSHOPINDEX*$2@$', $content); + + //Link to workshop view by moduleid + $search = "/(" . $base . "\/mod\/workshop\/view.php\?id\=)([0-9]+)/"; + $result= preg_replace($search, '$@WORKSHOPVIEWBYID*$2@$', $result); + + return $content; + } +} diff --git a/mod/workshop/backup/moodle2/backup_workshop_settingslib.php b/mod/workshop/backup/moodle2/backup_workshop_settingslib.php new file mode 100644 index 00000000000..28c4321f884 --- /dev/null +++ b/mod/workshop/backup/moodle2/backup_workshop_settingslib.php @@ -0,0 +1,30 @@ +. + +/** + * Workshop backup settings + * + * Workshop has no particular settings but the inherited from the generic + * {@link backup_activity_task}. + * + * @package mod_workshop + * @subpackage backup-moodle2 + * @copyright 2010 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); diff --git a/mod/workshop/backup/moodle2/backup_workshop_stepslib.php b/mod/workshop/backup/moodle2/backup_workshop_stepslib.php new file mode 100644 index 00000000000..0e2458bd97c --- /dev/null +++ b/mod/workshop/backup/moodle2/backup_workshop_stepslib.php @@ -0,0 +1,202 @@ +. + +/** + * Defines all the backup steps that will be used by {@link backup_workshop_activity_task} + * + * @package mod_workshop + * @subpackage backup-moodle2 + * @copyright 2010 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Defines the complete workshop structure for backup, with file and id annotations + * + * @see http://docs.moodle.org/en/Development:Workshop for XML structure diagram + */ +class backup_workshop_activity_structure_step extends backup_activity_structure_step { + + protected function define_structure() { + + // are we including userinfo? + $userinfo = $this->get_setting_value('userinfo'); + + //////////////////////////////////////////////////////////////////////// + // XML nodes declaration - non-user data + //////////////////////////////////////////////////////////////////////// + + // root element describing workshop instance + $workshop = new backup_nested_element('workshop', array('id'), array( + 'name', 'intro', 'introformat', 'instructauthors', + 'instructauthorsformat', 'instructreviewers', + 'instructreviewersformat', 'timemodified', 'phase', 'useexamples', + 'usepeerassessment', 'useselfassessment', 'grade', 'gradinggrade', + 'strategy', 'evaluation', 'gradedecimals', 'nattachments', + 'latesubmissions', 'maxbytes', 'examplesmode', 'submissionstart', + 'submissionend', 'assessmentstart', 'assessmentend')); + + // assessment forms definition + $this->add_subplugin_structure('workshopform', $workshop, true); + + // grading evaluations data + $this->add_subplugin_structure('workshopeval', $workshop, true); + + // example submissions + $examplesubmissions = new backup_nested_element('examplesubmissions'); + $examplesubmission = new backup_nested_element('examplesubmission', array('id'), array( + 'timecreated', 'timemodified', 'title', 'content', 'contentformat', + 'contenttrust', 'attachment')); + + // reference assessment of the example submission + $referenceassessment = new backup_nested_element('referenceassessment', array('id'), array( + 'timecreated', 'timemodified', 'grade')); + + // dimension grades for the reference assessment (that is how the form is filled) + $this->add_subplugin_structure('workshopform', $referenceassessment, true); + + //////////////////////////////////////////////////////////////////////// + // XML nodes declaration - user data + //////////////////////////////////////////////////////////////////////// + + // assessments of example submissions + $exampleassessments = new backup_nested_element('exampleassessments'); + $exampleassessment = new backup_nested_element('exampleassessment', array('id'), array( + 'reviewerid', 'weight', 'timecreated', 'timemodified', 'grade', + 'gradinggrade', 'gradinggradeover', 'gradinggradeoverby', + 'feedbackauthor', 'feedbackauthorformat', 'feedbackreviewer', + 'feedbackreviewerformat')); + + // dimension grades for the assessment of example submission (that is assessment forms are filled) + $this->add_subplugin_structure('workshopform', $exampleassessment, true); + + // submissions + $submissions = new backup_nested_element('submissions'); + $submission = new backup_nested_element('submission', array('id'), array( + 'authorid', 'timecreated', 'timemodified', 'title', 'content', + 'contentformat', 'contenttrust', 'attachment', 'grade', + 'gradeover', 'gradeoverby', 'feedbackauthor', + 'feedbackauthorformat', 'timegraded', 'published')); + + // allocated assessments + $assessments = new backup_nested_element('assessments'); + $assessment = new backup_nested_element('assessment', array('id'), array( + 'reviewerid', 'weight', 'timecreated', 'timemodified', 'grade', + 'gradinggrade', 'gradinggradeover', 'gradinggradeoverby', + 'feedbackauthor', 'feedbackauthorformat', 'feedbackreviewer', + 'feedbackreviewerformat')); + + // dimension grades for the assessment (that is assessment forms are filled) + $this->add_subplugin_structure('workshopform', $assessment, true); + + // aggregations of grading grades in this workshop + $aggregations = new backup_nested_element('aggregations'); + $aggregation = new backup_nested_element('aggregation', array('id'), array( + 'userid', 'gradinggrade', 'timegraded')); + + //////////////////////////////////////////////////////////////////////// + // build the tree in the order needed for restore + //////////////////////////////////////////////////////////////////////// + $workshop->add_child($examplesubmissions); + $examplesubmissions->add_child($examplesubmission); + + $examplesubmission->add_child($referenceassessment); + + $examplesubmission->add_child($exampleassessments); + $exampleassessments->add_child($exampleassessment); + + $workshop->add_child($submissions); + $submissions->add_child($submission); + + $submission->add_child($assessments); + $assessments->add_child($assessment); + + $workshop->add_child($aggregations); + $aggregations->add_child($aggregation); + + //////////////////////////////////////////////////////////////////////// + // data sources - non-user data + //////////////////////////////////////////////////////////////////////// + + $workshop->set_source_table('workshop', array('id' => backup::VAR_ACTIVITYID)); + + $examplesubmission->set_source_sql(" + SELECT * + FROM {workshop_submissions} + WHERE workshopid = ? AND example = 1", + array(backup::VAR_PARENTID)); + + $referenceassessment->set_source_sql(" + SELECT * + FROM {workshop_assessments} + WHERE weight = 1 AND submissionid = ?", + array(backup::VAR_PARENTID)); + + //////////////////////////////////////////////////////////////////////// + // data sources - user related data + //////////////////////////////////////////////////////////////////////// + + if ($userinfo) { + + $exampleassessment->set_source_sql(" + SELECT * + FROM {workshop_assessments} + WHERE weight = 0 AND submissionid = ?", + array(backup::VAR_PARENTID)); + + $submission->set_source_sql(" + SELECT * + FROM {workshop_submissions} + WHERE workshopid = ? AND example = 0", + array(backup::VAR_PARENTID)); // must use SQL here, for the same reason as above + + $assessment->set_source_table('workshop_assessments', array('submissionid' => backup::VAR_PARENTID)); + + $aggregation->set_source_table('workshop_aggregations', array('workshopid' => backup::VAR_PARENTID)); + } + + //////////////////////////////////////////////////////////////////////// + // id annotations + //////////////////////////////////////////////////////////////////////// + + $exampleassessment->annotate_ids('user', 'reviewerid'); + $submission->annotate_ids('user', 'authorid'); + $submission->annotate_ids('user', 'gradeoverby'); + $assessment->annotate_ids('user', 'reviewerid'); + $assessment->annotate_ids('user', 'gradinggradeoverby'); + $aggregation->annotate_ids('user', 'userid'); + + //////////////////////////////////////////////////////////////////////// + // file annotations + //////////////////////////////////////////////////////////////////////// + + $workshop->annotate_files('mod_workshop', 'intro', null); // no itemid used + $workshop->annotate_files('mod_workshop', 'instructauthors', null); // no itemid used + $workshop->annotate_files('mod_workshop', 'instructreviewers', null); // no itemid used + + $examplesubmission->annotate_files('mod_workshop', 'submission_content', 'id'); + $examplesubmission->annotate_files('mod_workshop', 'submission_attachment', 'id'); + + $submission->annotate_files('mod_workshop', 'submission_content', 'id'); + $submission->annotate_files('mod_workshop', 'submission_attachment', 'id'); + + // return the root element (workshop), wrapped into standard activity structure + return $this->prepare_activity_structure($workshop); + } +} diff --git a/mod/workshop/eval/best/backup/moodle2/backup_workshopeval_best_subplugin.class.php b/mod/workshop/eval/best/backup/moodle2/backup_workshopeval_best_subplugin.class.php new file mode 100644 index 00000000000..ea0a0c9d9f9 --- /dev/null +++ b/mod/workshop/eval/best/backup/moodle2/backup_workshopeval_best_subplugin.class.php @@ -0,0 +1,53 @@ +. + +/** + * @package workshopeval_best + * @subpackage backup-moodle2 + * @copyright 2010 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +defined('MOODLE_INTERNAL') || die(); + +/** + * Provides the information to backup grading evaluation method 'Comparison with the best assessment' + * + * This evaluator just stores a single integer value - the recently used comparison + * strictness factor. It adds its XML data to workshop tag. + */ +class backup_workshopeval_best_subplugin extends backup_subplugin { + + /** + * Returns the subplugin information to attach to workshop element + */ + protected function define_workshop_subplugin_structure() { + + // create XML elements + $subplugin = $this->get_subplugin_element(); // virtual optigroup element + $subplugin_wrapper = new backup_nested_element($this->get_recommended_name()); + $subplugin_table_settings = new backup_nested_element('workshopeval_best_settings', null, array('comparison')); + + // connect XML elements into the tree + $subplugin->add_child($subplugin_wrapper); + $subplugin_wrapper->add_child($subplugin_table_settings); + + // set source to populate the data + $subplugin_table_settings->set_source_table('workshopeval_best_settings', array('workshopid' => backup::VAR_ACTIVITYID)); + + return $subplugin; + } +} diff --git a/mod/workshop/form/accumulative/backup/moodle2/backup_workshopform_accumulative_subplugin.class.php b/mod/workshop/form/accumulative/backup/moodle2/backup_workshopform_accumulative_subplugin.class.php new file mode 100644 index 00000000000..f1e5d866ee8 --- /dev/null +++ b/mod/workshop/form/accumulative/backup/moodle2/backup_workshopform_accumulative_subplugin.class.php @@ -0,0 +1,106 @@ +. + +/** + * @package workshopform_accumulative + * @subpackage backup-moodle2 + * @copyright 2010 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +defined('MOODLE_INTERNAL') || die(); + +/** + * Provides the information to backup accumulative grading strategy information + */ +class backup_workshopform_accumulative_subplugin extends backup_subplugin { + + /** + * Returns the assessment form definition to attach to 'workshop' XML element + */ + protected function define_workshop_subplugin_structure() { + + // XML nodes declaration + $subplugin = $this->get_subplugin_element(); // virtual optigroup element + $subpluginwrapper = new backup_nested_element($this->get_recommended_name()); + $subplugindimension = new backup_nested_element('workshopform_accumulative_dimension', array('id'), array( + 'sort', 'description', 'descriptionformat', 'grade', 'weight')); + + // connect XML elements into the tree + $subplugin->add_child($subpluginwrapper); + $subpluginwrapper->add_child($subplugindimension); + + // set source to populate the data + $subplugindimension->set_source_table('workshopform_accumulative', array('workshopid' => backup::VAR_ACTIVITYID)); + + // file annotations + $subplugindimension->annotate_files('workshopform_accumulative', 'description', 'id'); + + return $subplugin; + } + + /** + * Returns the dimension grades to attach to 'referenceassessment' XML element + */ + protected function define_referenceassessment_subplugin_structure() { + return $this->dimension_grades_structure('workshopform_accumulative_referencegrade'); + } + + /** + * Returns the dimension grades to attach to 'exampleassessment' XML element + */ + protected function define_exampleassessment_subplugin_structure() { + return $this->dimension_grades_structure('workshopform_accumulative_examplegrade'); + } + + /** + * Returns the dimension grades to attach to 'assessment' XML element + */ + protected function define_assessment_subplugin_structure() { + return $this->dimension_grades_structure('workshopform_accumulative_grade'); + } + + //////////////////////////////////////////////////////////////////////////// + // internal private methods + //////////////////////////////////////////////////////////////////////////// + + /** + * Returns the structure of dimension grades + * + * @param string forst parameter of {@link backup_nested_element} constructor + */ + private function dimension_grades_structure($elementname) { + + // create XML elements + $subplugin = $this->get_subplugin_element(); // virtual optigroup element + $subpluginwrapper = new backup_nested_element($this->get_recommended_name()); + $subplugingrade = new backup_nested_element($elementname, array('id'), array( + 'dimensionid', 'grade', 'peercomment', 'peercommentformat')); + + // connect XML elements into the tree + $subplugin->add_child($subpluginwrapper); + $subpluginwrapper->add_child($subplugingrade); + + // set source to populate the data + $subplugingrade->set_source_sql( + "SELECT id, dimensionid, grade, peercomment, peercommentformat + FROM {workshop_grades} + WHERE strategy = 'accumulative' AND assessmentid = ?", + array(backup::VAR_PARENTID)); + + return $subplugin; + } +} diff --git a/mod/workshop/lib.php b/mod/workshop/lib.php index 3ac4667c6c4..31e890d55c2 100644 --- a/mod/workshop/lib.php +++ b/mod/workshop/lib.php @@ -46,6 +46,7 @@ function workshop_supports($feature) { case FEATURE_GROUPINGS: return true; case FEATURE_GROUPMEMBERSONLY: return true; case FEATURE_MOD_INTRO: return true; + case FEATURE_BACKUP_MOODLE2: return true; default: return null; } }