diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index 11dd4ce9c78..49daa6fb41f 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -125,10 +125,9 @@ abstract class backup_activity_structure_step extends backup_structure_step { } /** - * Abstract structure step, to be used by all the activities using core questions stuff - * (namely quiz module), supporting question plugins, states and sessions + * Helper code for use by any plugin that stores question attempt data that it needs to back up. */ -abstract class backup_questions_activity_structure_step extends backup_activity_structure_step { +trait backup_questions_attempt_data_trait { /** * Attach to $element (usually attempts) the needed backup structures @@ -200,6 +199,17 @@ abstract class backup_questions_activity_structure_step extends backup_activity_ } +/** + * Abstract structure step to help activities that store question attempt data. + * + * @copyright 2011 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class backup_questions_activity_structure_step extends backup_activity_structure_step { + use backup_questions_attempt_data_trait; +} + + /** * backup structure step in charge of calculating the categories to be * included in backup, based in the context being backuped (module/course) diff --git a/backup/moodle2/restore_plugin.class.php b/backup/moodle2/restore_plugin.class.php index 4b5631d9d52..31a94f50e9f 100644 --- a/backup/moodle2/restore_plugin.class.php +++ b/backup/moodle2/restore_plugin.class.php @@ -70,9 +70,11 @@ abstract class restore_plugin { $methodname = 'define_' . basename($this->connectionpoint->get_path()) . '_plugin_structure'; if (method_exists($this, $methodname)) { - if ($bluginpaths = $this->$methodname()) { - foreach ($bluginpaths as $path) { - $path->set_processing_object($this); + if ($pluginpaths = $this->$methodname()) { + foreach ($pluginpaths as $path) { + if ($path->get_processing_object() === null && !$this->step->grouped_parent_exists($path, $paths)) { + $path->set_processing_object($this); + } $paths[] = $path; } } @@ -270,4 +272,13 @@ abstract class restore_plugin { 'plugin_' . $this->plugintype . '_' . $this->pluginname . '_' . basename($this->connectionpoint->get_path()) . $path; } + + /** + * Get the task we are part of. + * + * @return restore_activity_task|restore_course_task the task. + */ + protected function get_task() { + return $this->task; + } } diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index 437c9cb3ca9..51fbbb1a325 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -5323,10 +5323,9 @@ class restore_process_file_aliases_queue extends restore_execution_step { /** - * Abstract structure step, to be used by all the activities using core questions stuff - * (like the quiz module), to support qtype plugins, states and sessions + * Helper code for use by any plugin that stores question attempt data that it needs to back up. */ -abstract class restore_questions_activity_structure_step extends restore_activity_structure_step { +trait restore_questions_attempt_data_trait { /** @var array question_attempt->id to qtype. */ protected $qtypes = array(); /** @var array question_attempt->id to questionid. */ @@ -5378,21 +5377,21 @@ abstract class restore_questions_activity_structure_step extends restore_activit /** * Process question_usages */ - protected function process_question_usage($data) { + public function process_question_usage($data) { $this->restore_question_usage_worker($data, ''); } /** * Process question_attempts */ - protected function process_question_attempt($data) { + public function process_question_attempt($data) { $this->restore_question_attempt_worker($data, ''); } /** * Process question_attempt_steps */ - protected function process_question_attempt_step($data) { + public function process_question_attempt_step($data) { $this->restore_question_attempt_step_worker($data, ''); } @@ -5412,8 +5411,7 @@ abstract class restore_questions_activity_structure_step extends restore_activit $data = (object)$data; $oldid = $data->id; - $oldcontextid = $this->get_task()->get_old_contextid(); - $data->contextid = $this->get_mappingid('context', $this->task->get_old_contextid()); + $data->contextid = $this->task->get_contextid(); // Everything ready, insert (no mapping needed) $newitemid = $DB->insert_record('question_usages', $data); @@ -5569,6 +5567,17 @@ abstract class restore_questions_activity_structure_step extends restore_activit $this->add_related_files('question', $filearea, 'question_attempt_step'); } } +} + + +/** + * Abstract structure step to help activities that store question attempt data. + * + * @copyright 2011 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class restore_questions_activity_structure_step extends restore_activity_structure_step { + use restore_questions_attempt_data_trait; /** * Attach below $element (usually attempts) the needed restore_path_elements @@ -5612,7 +5621,7 @@ abstract class restore_questions_activity_structure_step extends restore_activit /** * Process the attempt data defined by {@link add_legacy_question_attempt_data()}. * @param object $data contains all the grouped attempt data to process. - * @param pbject $quiz data about the activity the attempts belong to. Required + * @param object $quiz data about the activity the attempts belong to. Required * fields are (basically this only works for the quiz module): * oldquestions => list of question ids in this activity - using old ids. * preferredbehaviour => the behaviour to use for questionattempts. @@ -5674,7 +5683,7 @@ abstract class restore_questions_activity_structure_step extends restore_activit $data->uniqueid = $usage->id; $upgrader->save_usage($quiz->preferredbehaviour, $data, $qas, - $this->questions_recode_layout($quiz->oldquestions)); + $this->questions_recode_layout($quiz->oldquestions)); } protected function find_question_session_and_states($data, $questionid) { diff --git a/backup/util/plan/restore_structure_step.class.php b/backup/util/plan/restore_structure_step.class.php index bffc7b75290..3fe1978deff 100644 --- a/backup/util/plan/restore_structure_step.class.php +++ b/backup/util/plan/restore_structure_step.class.php @@ -496,9 +496,9 @@ abstract class restore_structure_step extends restore_step { // Now, for each element not having one processing object, if // not child of grouped element, assign $this (the step itself) as processing element // Note method must exist or we'll get one @restore_path_element_exception - foreach($paths as $key => $pelement) { + foreach ($paths as $pelement) { if ($pelement->get_processing_object() === null && !$this->grouped_parent_exists($pelement, $paths)) { - $paths[$key]->set_processing_object($this); + $pelement->set_processing_object($this); } // Populate $elementsoldid and $elementsoldid based on available pathelements $this->elementsoldid[$pelement->get_name()] = null; @@ -510,18 +510,22 @@ abstract class restore_structure_step extends restore_step { /** * Given one pathelement, return true if grouped parent was found + * + * @param restore_path_element $pelement the element we are interested in. + * @param restore_path_element[] $elements the elements that exist. + * @return bool true if this element is inside a grouped parent. */ - protected function grouped_parent_exists($pelement, $elements) { + public function grouped_parent_exists($pelement, $elements) { foreach ($elements as $element) { if ($pelement->get_path() == $element->get_path()) { - continue; // Don't compare against itself + continue; // Don't compare against itself. } - // If element is grouped and parent of pelement, return true + // If element is grouped and parent of pelement, return true. if ($element->is_grouped() and strpos($pelement->get_path() . '/', $element->get_path()) === 0) { return true; } } - return false; // no grouped parent found + return false; // No grouped parent found. } /**