Define the structure of the restore workflow.

@return restore_path_element $structure
175781
protected function define_structure() {

        $paths = array();
        // To know if we are including userinfo.
        $userinfo = $this->get_setting_value('userinfo');

        // Define each element separated.
        $paths[] = new restore_path_element('assign', '/activity/assign');
        if ($userinfo) {
            $submission = new restore_path_element('assign_submission',
                                                   '/activity/assign/submissions/submission');
            $paths[] = $submission;
            $this->add_subplugin_structure('assignsubmission', $submission);
            $grade = new restore_path_element('assign_grade', '/activity/assign/grades/grade');
            $paths[] = $grade;
            $this->add_subplugin_structure('assignfeedback', $grade);
            $userflag = new restore_path_element('assign_userflag',
                                                   '/activity/assign/userflags/userflag');
            $paths[] = $userflag;
        }

        $paths[] = new restore_path_element('assign_override', '/activity/assign/overrides/override');
        $paths[] = new restore_path_element('assign_plugin_config',
                                            '/activity/assign/plugin_configs/plugin_config');

        return $this->prepare_activity_structure($paths);
    }
831382
protected function define_question_plugin_structure() {

        // Define the virtual plugin element with the condition to fulfill.
        $plugin = $this->get_plugin_element(null, '../../qtype', 'match');

        // Create one standard named plugin element (the visible container).
        $pluginwrapper = new backup_nested_element($this->get_recommended_name());

        // Connect the visible container ASAP.
        $plugin->add_child($pluginwrapper);

        // Now create the qtype own structures.
        $matchoptions = new backup_nested_element('matchoptions', array('id'), array(
            'shuffleanswers', 'correctfeedback', 'correctfeedbackformat',
            'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
            'incorrectfeedback', 'incorrectfeedbackformat', 'shownumcorrect'));

        $matches = new backup_nested_element('matches');

        $match = new backup_nested_element('match', array('id'), array(
            'questiontext', 'questiontextformat', 'answertext'));

        // Now the own qtype tree.
        $pluginwrapper->add_child($matchoptions);
        $pluginwrapper->add_child($matches);
        $matches->add_child($match);

        // Set source to populate the data.
        $matchoptions->set_source_table('qtype_match_options',
                array('questionid' => backup::VAR_PARENTID));
        $match->set_source_table('qtype_match_subquestions', array('questionid' => backup::VAR_PARENTID), 'id ASC');

        // Don't need to annotate ids nor files.

        return $plugin;
    }
929632
private function createProcessesNodeDefinition()
    {
        $processesNode = new ArrayNodeDefinition('processes');

        $processesNode
            ->useAttributeAsKey('name')
            ->prototype('array')
                ->validate()
                    ->ifTrue(function ($value) {
                        return !empty($value['import']) && !empty($value['steps']);
                    })
                    ->thenInvalid('You can\'t use "import" and "steps" keys at the same time.')
                ->end()
                ->children()
                    ->scalarNode('import')
                        ->defaultNull()
                    ->end()

                    ->scalarNode('start')
                        ->defaultNull()
                    ->end()

                    ->arrayNode('end')
                        ->defaultValue(array())
                        ->prototype('scalar')->end()
                    ->end()
                ->end()
                ->append($this->createStepsNodeDefinition())
            ->end()
        ;

        return $processesNode;
    }
458444
public function createPath()
    {
        if ($this->isReference()) {
            throw $this->noChildrenAllowed();
        }
        $p = new Path($this->project);
        $this->elements[] = $p;
        $this->checked = false;

        return $p;
    }
499342
public function define_course_plugin_structure() {
        global $DB;

        // Since this method is executed before the restore we can do some pre-checks here.
        // In case of merging backup into existing course find the current number of sections.
        $target = $this->step->get_task()->get_target();
        if (($target == backup::TARGET_CURRENT_ADDING || $target == backup::TARGET_EXISTING_ADDING) &&
                $this->is_pre_33_backup()) {
            $maxsection = $DB->get_field_sql(
                'SELECT max(section) FROM {course_sections} WHERE course = ?',
                [$this->step->get_task()->get_courseid()]);
            $this->originalnumsections = (int)$maxsection;
        }

        // Dummy path element is needed in order for after_restore_course() to be called.
        return [new restore_path_element('dummy_course', $this->get_pathfor('/dummycourse'))];
    }
77936
public function doRestoreToStage()
    {
        $this->invokeWithExtensions('onBeforeRestoreToStage', $this);

        // Ensure that the parent page is restored, otherwise restore to root
        if ($this->isParentArchived()) {
            $this->ParentID = 0;
        }

        // Restore
        $this->writeToStage(Versioned::DRAFT);

        // Need to update pages linking to this one as no longer broken
        /** @var SiteTree $result */
        $result = Versioned::get_by_stage(self::class, Versioned::DRAFT)
            ->byID($this->ID);
        $result->updateDependentPages();

        $this->invokeWithExtensions('onAfterRestoreToStage', $result);

        return $result;
    }
445539
public function get_progress_bar() {
        global $PAGE;
        $stage = restore_ui::STAGE_COMPLETE;
        $currentstage = $this->get_stage();
        $items = array();
        while ($stage > 0) {
            $classes = array('backup_stage');
            if (floor($stage / 2) == $currentstage) {
                $classes[] = 'backup_stage_next';
            } else if ($stage == $currentstage) {
                $classes[] = 'backup_stage_current';
            } else if ($stage < $currentstage) {
                $classes[] = 'backup_stage_complete';
            }
            $item = array('text' => strlen(decbin($stage)).'. '.get_string('restorestage'.$stage, 'backup'), 'class' => join(' ', $classes));
            if ($stage < $currentstage && $currentstage < restore_ui::STAGE_COMPLETE) {
                // By default you can't go back to independent stages, if that changes in the future uncomment the next line.
                // $item['link'] = new moodle_url($PAGE->url, array('restore' => $this->get_restoreid(), 'stage' => $stage));
            }
            array_unshift($items, $item);
            $stage = floor($stage / 2);
        }
        return $items;
    }
702344
private function removeDefaultStructure ()
    {
        $confirm = $this->confirm ('Are you sure? It will delete some directories with all files in them.)');

        if ($confirm) {
            try {

                $this->makeBackup();

                // deleting files and folders
                if (!file_exists (HCNewProject::CONFIG))
                    $this->abort ('Missing project configuration file for laravel version');

                $json = validateJSONFromPath (HCNewProject::CONFIG);

                foreach ($json['remove_folders'] as $location)
                    $this->deleteDirectory ($location, true);

                foreach ($json['remove_files'] as $location) {
                    $this->info ('Deleting file: ' . $location);
                    File::delete ($location);
                }

                foreach ($json['create_folders'] as $location) {
                    $this->info ('Creating folder: ' . $location);
                    $this->createDirectory ($location);
                }

                $this->createFileFromTemplate ([
                    "destination"         => 'app/' . HCNewService::CONFIG_PATH,
                    "templateDestination" => __DIR__ . '/templates/shared/hc.config.hctpl',
                    "content"             => [
                        "serviceProviderNameSpace" => "app",
                    ],
                ]);

                foreach ($json['create_files'] as $source => $destinations)
                {
                    if (!is_array($destinations))
                        $this->createProjectFile($source, $destinations);
                    else
                        foreach ($destinations as $destination)
                            $this->createProjectFile($source, $destination);
                }

                foreach ($json['copy_folders'] as $source => $destinations)
                {
                    if (!is_array($destinations))
                        File::copyDirectory(__DIR__ . "/templates/$source", base_path($destinations));
                    else
                        foreach ($destinations as $destination)
                            File::copyDirectory(__DIR__ . "/templates/$source", base_path($destination));
                }


                replaceTextInFile('composer.json', ['"App\\\\"' => '"app\\\\"']);
                replaceTextInFile('config/auth.php', ['=> App\User::class' => '=> interactivesolutions\honeycombacl\app\models\HCUsers::class']);
                replaceTextInFile('config/auth.php', ['password_resets' => 'hc_users_password_resets']);
                replaceTextInFile('config/database.php', ['utf8\'' => 'utf8mb4\'', 'utf8_' => 'utf8mb4_']);

            } catch (Exception $e) {
                $this->comment ('Error occurred!');
                $this->error ('Error code: ' . $e->getCode ());
                $this->error ('Error message: ' . $e->getMessage ());
                $this->info ('');
                $this->info ('Rolling back configuration.');
                $this->restore();
                $this->abort ('');
            }
        }
    }
1001526
public function structureProto()
    {
        if ($this->structurePrototype === null) {
            $model = $this->createStructureModel();

            if ($model instanceof DescribableInterface) {
                $model->setMetadata($this->structureMetadata());
            }

            $this->structurePrototype = $model;
        }

        return $this->structurePrototype;
    }
63440
public function restoreMode() {
		if ( $this->originalMode === null ) {
			throw new TreeBuilderError( "original insertion mode is not set" );
		}
		$mode = $this->mode = $this->originalMode;
		$this->originalMode = null;
		$this->handler = $this->dispatchTable[$mode];
		return $this->handler;
	}
1060150
public function after_restore() {
        global $DB;

        // Get the blockid.
        $blockid = $this->get_blockid();

        // Extract block configdata and remove tag collection reference if this is another site. Also map contextid.
        if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) {
            $config = unserialize(base64_decode($configdata));
            $changed = false;
            if (!empty($config->tagcoll) && $config->tagcoll > 1 && !$this->is_samesite()) {
                $config->tagcoll = 0;
                $changed = true;
            }
            if (!empty($config->ctx)) {
                if ($ctxmap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'context', $config->ctx)) {
                    $config->ctx = $ctxmap->newitemid;
                } else {
                    $config->ctx = 0;
                }
                $changed = true;
            }
            if ($changed) {
                $configdata = base64_encode(serialize($config));
                $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid));
            }
        }
    }
1100396
public function process() {
        if ($this->progress >= self::PROGRESS_PROCESSED) {
            throw new restore_ui_exception('restoreuialreadyprocessed');
        }
        $this->progress = self::PROGRESS_PROCESSED;

        if (optional_param('previous', false, PARAM_BOOL) && $this->stage->get_stage() > self::STAGE_CONFIRM) {
            $this->stage = $this->initialise_stage($this->stage->get_prev_stage(), $this->stage->get_params());
            return false;
        }

        // Process the stage.
        $processoutcome = $this->stage->process();
        if ($processoutcome !== false && !($this->get_stage() == self::STAGE_PROCESS && optional_param('substage', false, PARAM_BOOL))) {
            $this->stage = $this->initialise_stage($this->stage->get_next_stage(), $this->stage->get_params());
        }

        // Process UI event after to check changes are valid.
        $this->controller->process_ui_event();
        return $processoutcome;
    }
938
public function initializeStructure()
    {
        $structure = [
            'id' => $this->getId(),
            'name' => $this->getName(),
            'description' => $this->getDescription(),
            'manualProgressionAllowed' => $this->manualProgressionAllowed,
            'steps' => [],
        ];

        $this->setStructure(json_encode($structure));

        return $this;
    }
23221
protected function get_restore_content_dir() {
        $backupfile = null;
        $shortname = null;

        if (!empty($this->restorefile)) {
            $backupfile = $this->restorefile;
        } else if (!empty($this->templatecourse) || is_numeric($this->templatecourse)) {
            $shortname = $this->templatecourse;
        }

        $dir = tool_uploadcourse_helper::get_restore_content_dir($backupfile, $shortname);
        return $dir;
    }
242494
public function build() {

        // If we have decided not to backup blocks, prevent anything to be built
        if (!$this->get_setting_value('blocks')) {
            $this->built = true;
            return;
        }

        // If "child" of activity task and it has been excluded, nothing to do
        $parent = basename(dirname(dirname($this->taskbasepath)));
        if ($parent != 'course') {
            $includedsetting = $parent . '_included';
            if (!$this->get_setting_value($includedsetting)) {
                $this->built = true;
                return;
            }
        }

        // Process the block.xml common file (instance + positions)
        $this->add_step(new restore_block_instance_structure_step('block_commons', 'block.xml'));

        // Here we add all the common steps for any block and, in the point of interest
        // we call to define_my_steps() in order to get the particular ones inserted in place.
        $this->define_my_steps();

        // Restore block role assignments and overrides (internally will observe the role_assignments setting)
        $this->add_step(new restore_ras_and_caps_structure_step('block_ras_and_caps', 'roles.xml'));

        // Restore block comments (conditionally)
        if ($this->get_setting_value('comments')) {
            $this->add_step(new restore_comments_structure_step('block_comments', 'comments.xml'));
        }

        // Search reindexing (if enabled).
        if (\core_search\manager::is_indexing_enabled()) {
            $wholecourse = $this->get_target() == backup::TARGET_NEW_COURSE;
            $wholecourse = $wholecourse || $this->setting_exists('overwrite_conf') && $this->get_setting_value('overwrite_conf');
            if (!$wholecourse) {
                $this->add_step(new restore_block_search_index('block_search_index'));
            }
        }

        // At the end, mark it as built
        $this->built = true;
    }
311202
public function description() {
        list($missingparent, $loops) = $this->find_problems();

        $description = '<p>The course categories should be arranged into tree ' .
                ' structures by the course_categories.parent field. Sometimes ' .
                ' this tree structure gets messed up.</p>';

        $description .= tool_health_category_list_missing_parents($missingparent);
        $description .= tool_health_category_list_loops($loops);

        return $description;
    }
555627
protected function define_instance_plugin_structure() {

        // Append data only if the ancestor 'definition' element has 'method' set to 'guide'.
        $plugin = $this->get_plugin_element(null, '../../../../method', 'guide');

        // Create a visible container for our data.
        $pluginwrapper = new backup_nested_element($this->get_recommended_name());

        // Connect our visible container to the parent.
        $plugin->add_child($pluginwrapper);

        // Define our elements.

        $fillings = new backup_nested_element('fillings');

        $filling = new backup_nested_element('filling', array('id'), array(
            'criterionid', 'remark', 'remarkformat', 'score'));

        // Build elements hierarchy.

        $pluginwrapper->add_child($fillings);
        $fillings->add_child($filling);

        // Set sources to populate the data.

        $filling->set_source_table('gradingform_guide_fillings',
            array('instanceid' => backup::VAR_PARENTID));

        // No need to annotate ids or files yet (one day when remark field supports
        // embedded fileds, they must be annotated here).

        return $plugin;
    }