Commit 0149e6c7 authored by Eloy Lafuente's avatar Eloy Lafuente
Browse files

MDL-26405 restore - dispatch able to skip branches

after this change any restore_structure_step processor
method is able to instruct the dispatcher about to skip
any path below it. Until now, we were doing the checks on
each child processor method, but that was inneficient and
prone to errors (easy to miss the check in a child so some
orphaned piezes of restore may be causing mess here and there).
Once implemented, it's simlpy a matter of the parent deciding if
all its children must be processed or no. Easier for developers
and also small speed improvement because avoids unnecesary
dispatching/processing to happen.

Surely only will be used in parts of core, like in question_categories,
saving 50-60 sub processors (sub-paths) to be dispatched.
parent d911c72b
......@@ -2219,7 +2219,7 @@ class restore_create_categories_and_questions extends restore_structure_step {
// Check we have one mapping for this category
if (!$mapping = $this->get_mapping('question_category', $oldid)) {
return; // No mapping = this category doesn't need to be created/mapped
return self::SKIP_ALL_CHILDREN; // No mapping = this category doesn't need to be created/mapped
}
// Check we have to create the category (newitemid = 0)
......
......@@ -38,6 +38,11 @@ abstract class restore_structure_step extends restore_step {
protected $elementsoldid; // Array to store last oldid used on each element
protected $elementsnewid; // Array to store last newid used on each element
protected $pathlock; // Path currently locking processing of children
const SKIP_ALL_CHILDREN = -991399; // To instruct the dispatcher about to ignore
// all children below path processor returning it
/**
* Constructor - instantiates one object of this class
*/
......@@ -50,10 +55,11 @@ abstract class restore_structure_step extends restore_step {
$this->pathelements = array();
$this->elementsoldid = array();
$this->elementsnewid = array();
$this->pathlock = null;
parent::__construct($name, $task);
}
public function execute() {
final public function execute() {
if (!$this->execute_condition()) { // Check any condition to execute this
return;
......@@ -106,18 +112,37 @@ abstract class restore_structure_step extends restore_step {
* Receive one chunk of information form the xml parser processor and
* dispatch it, following the naming rules
*/
public function process($data) {
final public function process($data) {
if (!array_key_exists($data['path'], $this->pathelements)) { // Incorrect path, must not happen
throw new restore_step_exception('restore_structure_step_missing_path', $data['path']);
}
$element = $this->pathelements[$data['path']];
$object = $element->get_processing_object();
$method = $element->get_processing_method();
$rdata = null;
if (empty($object)) { // No processing object defined
throw new restore_step_exception('restore_structure_step_missing_pobject', $object);
}
$rdata = $object->$method($data['tags']); // Dispatch to proper object/method
if ($rdata !== null) { // If the method has returned any info, set element data to it
// Release the lock if we aren't anymore within children of it
if (!is_null($this->pathlock) and strpos($data['path'], $this->pathlock) === false) {
$this->pathlock = null;
}
if (is_null($this->pathlock)) { // Only dispatch if there isn't any lock
$rdata = $object->$method($data['tags']); // Dispatch to proper object/method
}
// If the dispatched method returns SKIP_ALL_CHILDREN, we grab current path in order to
// lock dispatching to any children
if ($rdata === self::SKIP_ALL_CHILDREN) {
// Check we haven't any previous lock
if (!is_null($this->pathlock)) {
throw new restore_step_exception('restore_structure_step_already_skipping', $data['path']);
}
// Set the lock
$this->pathlock = $data['path'] . '/'; // Lock everything below current path
// Continue with normal processing of return values
} else if ($rdata !== null) { // If the method has returned any info, set element data to it
$element->set_data($rdata);
} else { // Else, put the original parsed data
$element->set_data($data);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment