Permalink
Browse files

MDL-34118 question backup: a mod can use usages in different ways.

An activity module might want to use question_usages in different ways.
We should suppport this, because it lets people make interesting
activities.

At the moment, the backup and restore code does not support this,
because it uses fixed element names for the question_usage element and
its children. This fix changes things so that a prefix can be appended
to all the element names.
  • Loading branch information...
1 parent c92d6f4 commit 3e3ae0ee11ee6c1f525a219a9a20a284a49a6590 @timhunt timhunt committed Jun 29, 2012
@@ -182,8 +182,16 @@ protected function prepare_activity_structure($activitystructure) {
/**
* Attach to $element (usually attempts) the needed backup structures
* for question_usages and all the associated data.
+ *
+ * @param backup_nested_element $element the element that will contain all the question_usages data.
+ * @param string $usageidname the name of the element that holds the usageid.
+ * This must be child of $element, and must be a final element.
+ * @param string $nameprefix this prefix is added to all the element names we create.
+ * Element names in the XML must be unique, so if you are using usages in
+ * two different ways, you must give a prefix to at least one of them. If
+ * you only use one sort of usage, then you can just use the default empty prefix.
*/
- protected function add_question_usages($element, $usageidname) {
+ protected function add_question_usages($element, $usageidname, $nameprefix = '') {
global $CFG;
require_once($CFG->dirroot . '/question/engine/lib.php');
@@ -195,21 +203,21 @@ protected function add_question_usages($element, $usageidname) {
throw new backup_step_exception('question_states_bad_question_attempt_element', $usageidname);
}
- $quba = new backup_nested_element('question_usage', array('id'),
+ $quba = new backup_nested_element($nameprefix . 'question_usage', array('id'),
array('component', 'preferredbehaviour'));
- $qas = new backup_nested_element('question_attempts');
- $qa = new backup_nested_element('question_attempt', array('id'), array(
+ $qas = new backup_nested_element($nameprefix . 'question_attempts');
+ $qa = new backup_nested_element($nameprefix . 'question_attempt', array('id'), array(
'slot', 'behaviour', 'questionid', 'maxmark', 'minfraction',
'flagged', 'questionsummary', 'rightanswer', 'responsesummary',
'timemodified'));
- $steps = new backup_nested_element('steps');
- $step = new backup_nested_element('step', array('id'), array(
+ $steps = new backup_nested_element($nameprefix . 'steps');
+ $step = new backup_nested_element($nameprefix . 'step', array('id'), array(
'sequencenumber', 'state', 'fraction', 'timecreated', 'userid'));
- $response = new backup_nested_element('response');
- $variable = new backup_nested_element('variable', null, array('name', 'value'));
+ $response = new backup_nested_element($nameprefix . 'response');
+ $variable = new backup_nested_element($nameprefix . 'variable', null, array('name', 'value'));
// Build the tree
$element->add_child($quba);
@@ -3478,8 +3478,23 @@ private function add_result_item($name, $value) {
/**
* Attach below $element (usually attempts) the needed restore_path_elements
* to restore question_usages and all they contain.
+ *
+ * If you use the $nameprefix parameter, then you will need to implement some
+ * extra methods in your class, like
+ *
+ * protected function process_{$nameprefix}_question_attempt($data) {
+ * $this->process_question_attempt($data);
+ * }
+ *
+ * You need three methods like this, for question_usage, question_attempt and
+ * question_attempt_step.
+ *
+ * @param restore_path_element $element the parent element that the usages are stored inside.
+ * @param array $paths the paths array that is being built.
+ * @param string $nameprefix should match the prefix passed to the corresponding
+ * backup_questions_activity_structure_step::add_question_usages call.
*/
- protected function add_question_usages($element, &$paths) {
+ protected function add_question_usages($element, &$paths, $nameprefix = '') {
// Check $element is restore_path_element
if (! $element instanceof restore_path_element) {
throw new restore_step_exception('element_must_be_restore_path_element', $element);
@@ -3488,15 +3503,15 @@ protected function add_question_usages($element, &$paths) {
if (!is_array($paths)) {
throw new restore_step_exception('paths_must_be_array', $paths);
}
- $paths[] = new restore_path_element('question_usage',
- $element->get_path() . '/question_usage');
- $paths[] = new restore_path_element('question_attempt',
- $element->get_path() . '/question_usage/question_attempts/question_attempt');
- $paths[] = new restore_path_element('question_attempt_step',
- $element->get_path() . '/question_usage/question_attempts/question_attempt/steps/step',
+ $paths[] = new restore_path_element($nameprefix . 'question_usage',
+ $element->get_path() . "/{$nameprefix}question_usage");
+ $paths[] = new restore_path_element($nameprefix . 'question_attempt',
+ $element->get_path() . "/{$nameprefix}question_usage/{$nameprefix}question_attempts/{$nameprefix}question_attempt");
+ $paths[] = new restore_path_element($nameprefix . 'question_attempt_step',
+ $element->get_path() . "/{$nameprefix}question_usage/{$nameprefix}question_attempts/{$nameprefix}question_attempt/{$nameprefix}steps/{$nameprefix}step",
true);
- $paths[] = new restore_path_element('question_attempt_step_data',
- $element->get_path() . '/question_usage/question_attempts/question_attempt/steps/step/response/variable');
+ $paths[] = new restore_path_element($nameprefix . 'question_attempt_step_data',
+ $element->get_path() . "/{$nameprefix}question_usage/{$nameprefix}question_attempts/{$nameprefix}question_attempt/{$nameprefix}steps/{$nameprefix}step/{$nameprefix}response/{$nameprefix}variable");
}
/**
@@ -47,9 +47,9 @@ class restore_path_element {
/**
* Constructor - instantiates one restore_path_element, specifying its basic info.
*
- * @param string $name name of the element
- * @param string $path path of the element
- * @param bool $grouped to gather information in grouped mode or no
+ * @param string $name name of the thing being restored. This determines the name of the process_... method called.
+ * @param string $path path of the element.
+ * @param bool $grouped to gather information in grouped mode or no.
*/
public function __construct($name, $path, $grouped = false) {

0 comments on commit 3e3ae0e

Please sign in to comment.