MDL-24962 backup - now destroying circular refs manually to help PHP 5.2
[moodle.git] / backup / util / plan / backup_structure_step.class.php
CommitLineData
69dd0c8c
EL
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * @package moodlecore
20 * @subpackage backup-plan
21 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25/**
26 * Abstract class defining the needed stuff to backup one @backup_structure
27 *
28 * TODO: Finish phpdocs
29 */
30abstract class backup_structure_step extends backup_step {
31
32 protected $filename; // Name of the file to be generated
33 protected $contenttransformer; // xml content transformer being used
34 // (need it here, apart from xml_writer,
35 // thanks to serialized data to process -
36 // say thanks to blocks!)
37
38 /**
39 * Constructor - instantiates one object of this class
40 */
41 public function __construct($name, $filename, $task = null) {
42 if (!is_null($task) && !($task instanceof backup_task)) {
43 throw new backup_step_exception('wrong_backup_task_specified');
44 }
45 $this->filename = $filename;
2d7cd798 46 $this->contenttransformer = null;
69dd0c8c
EL
47 parent::__construct($name, $task);
48 }
49
50 public function execute() {
51
3b6a4209
EL
52 if (!$this->execute_condition()) { // Check any condition to execute this
53 return;
54 }
55
69dd0c8c
EL
56 $fullpath = $this->task->get_taskbasepath();
57
58 // We MUST have one fullpath here, else, error
59 if (empty($fullpath)) {
60 throw new backup_step_exception('backup_structure_step_undefined_fullpath');
61 }
62
63 // Append the filename to the fullpath
64 $fullpath = rtrim($fullpath, '/') . '/' . $this->filename;
65
66 // Create output, transformer, writer, processor
67 $xo = new file_xml_output($fullpath);
68 $xt = null;
69 if (class_exists('backup_xml_transformer')) {
70 $xt = new backup_xml_transformer($this->get_courseid());
71 $this->contenttransformer = $xt; // Save the reference to the transformer
72 // as far as we are going to need it out
73 // from xml_writer (blame serialized data!)
74 }
75 $xw = new xml_writer($xo, $xt);
76 $pr = new backup_structure_processor($xw);
77
78 // Set processor variables from settings
79 foreach ($this->get_settings() as $setting) {
80 $pr->set_var($setting->get_name(), $setting->get_value());
81 }
82 // Add backupid as one more var for processor
83 $pr->set_var(backup::VAR_BACKUPID, $this->get_backupid());
84
85 // Get structure definition
86 $structure = $this->define_structure();
87 if (! $structure instanceof backup_nested_element) {
88 throw new backup_step_exception('backup_structure_step_wrong_structure');
89 }
90
91 // Start writer
92 $xw->start();
93
94 // Process structure definition
95 $structure->process($pr);
96
97 // Close everything
98 $xw->stop();
d0ad9860
EL
99
100 // Destroy the structure. It helps PHP 5.2 memory a lot!
101 $structure->destroy();
69dd0c8c
EL
102 }
103
104// Protected API starts here
105
767cb7f0 106 /**
41941110 107 * Add plugin structure to any element in the structure backup tree
767cb7f0
EL
108 *
109 * @param string $plugintype type of plugin as defined by get_plugin_types()
41941110 110 * @param backup_nested_element $element element in the structure backup tree that
767cb7f0
EL
111 * we are going to add plugin information to
112 * @param bool $multiple to define if multiple plugins can produce information
113 * for each instance of $element (true) or no (false)
114 */
115 protected function add_plugin_structure($plugintype, $element, $multiple) {
116
117 global $CFG;
118
119 // Check the requested plugintype is a valid one
120 if (!array_key_exists($plugintype, get_plugin_types($plugintype))) {
121 throw new backup_step_exception('incorrect_plugin_type', $plugintype);
122 }
123
124 // Arrived here, plugin is correct, let's create the optigroup
125 $optigroupname = $plugintype . '_' . $element->get_name() . '_plugin';
126 $optigroup = new backup_optigroup($optigroupname, null, $multiple);
127 $element->add_child($optigroup); // Add optigroup to stay connected since beginning
128
129 // Get all the optigroup_elements, looking across all the plugin dirs
130 $pluginsdirs = get_plugin_list($plugintype);
131 foreach ($pluginsdirs as $name => $plugindir) {
132 $classname = 'backup_' . $plugintype . '_' . $name . '_plugin';
133 $backupfile = $plugindir . '/backup/moodle2/' . $classname . '.class.php';
134 if (file_exists($backupfile)) {
135 require_once($backupfile);
136 $backupplugin = new $classname($plugintype, $name, $optigroup);
137 // Add plugin returned structure to optigroup
138 $backupplugin->define_plugin_structure($element->get_name());
139 }
140 }
141 }
142
3b6a4209
EL
143 /**
144 * To conditionally decide if one step will be executed or no
145 *
146 * For steps needing to be executed conditionally, based in dynamic
147 * conditions (at execution time vs at declaration time) you must
148 * override this function. It will return true if the step must be
149 * executed and false if not
150 */
151 protected function execute_condition() {
152 return true;
153 }
154
69dd0c8c
EL
155 /**
156 * Function that will return the structure to be processed by this backup_step.
157 * Must return one backup_nested_element
158 */
159 abstract protected function define_structure();
160}