MDL-71163 core: support relative dates in activity dates
[moodle.git] / backup / util / plan / base_plan.class.php
blob5113d5f818a2b05e080da406ede75152c7507001
1 <?php
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.
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/>.
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
25 /**
26 * Abstract class defining the basis for one execution (backup/restore) plan
28 * TODO: Finish phpdocs
30 abstract class base_plan implements checksumable, executable {
32 protected $name; // One simple name for identification purposes
33 protected $settings; // One array of (accumulated from tasks) base_setting elements
34 protected $tasks; // One array of base_task elements
35 protected $results; // One array of results received from tasks
37 protected $built; // Flag to know if one plan has been built
39 /**
40 * Constructor - instantiates one object of this class
42 public function __construct($name) {
43 $this->name = $name;
44 $this->settings = array();
45 $this->tasks = array();
46 $this->results = array();
47 $this->built = false;
50 public function get_name() {
51 return $this->name;
54 public function add_task($task) {
55 if (! $task instanceof base_task) {
56 throw new base_plan_exception('wrong_base_task_specified');
58 $this->tasks[] = $task;
59 // link the task with the plan
60 $task->set_plan($this);
61 // Append task settings to plan array, if not present, for comodity
62 foreach ($task->get_settings() as $key => $setting) {
63 // Check if there is already a setting for this name.
64 $name = $setting->get_name();
65 if (!isset($this->settings[$name])) {
66 // There is no setting, so add it.
67 $this->settings[$name] = $setting;
68 } else if ($this->settings[$name] != $setting) {
69 // If the setting already exists AND it is not the same setting,
70 // then throw an error. (I.e. you're allowed to add the same
71 // setting twice, but cannot add two different ones with same
72 // name.)
73 throw new base_plan_exception('multiple_settings_by_name_found', $name);
78 public function get_tasks() {
79 return $this->tasks;
82 /**
83 * Add the passed info to the plan results
85 * At the moment we expect an associative array structure to be merged into
86 * the current results. In the future, some sort of base_result class may
87 * be introduced.
89 * @param array $result associative array describing a result of a task/step
91 public function add_result($result) {
92 if (!is_array($result)) {
93 throw new coding_exception('Associative array is expected as a parameter of add_result()');
95 $this->results = array_merge($this->results, $result);
98 /**
99 * Return the results collected via {@link self::add_result()} method
101 * @return array
103 public function get_results() {
104 return $this->results;
107 public function get_settings() {
108 return $this->settings;
112 * return one setting by name, useful to request root/course settings
113 * that are, by definition, unique by name.
115 * @param string $name name of the setting
116 * @return base_setting
117 * @throws base_plan_exception if setting name is not found.
119 public function get_setting($name) {
120 $result = null;
121 if (isset($this->settings[$name])) {
122 $result = $this->settings[$name];
123 } else {
124 throw new base_plan_exception('setting_by_name_not_found', $name);
126 return $result;
130 * Wrapper over @get_setting() that returns if the requested setting exists or no
132 public function setting_exists($name) {
133 try {
134 $this->get_setting($name);
135 return true;
136 } catch (base_plan_exception $e) {
137 // Nothing to do
139 return false;
144 * Function responsible for building the tasks of any plan
145 * with their corresponding settings
146 * (must set the $built property to true)
148 public abstract function build();
150 public function is_checksum_correct($checksum) {
151 return $this->calculate_checksum() === $checksum;
154 public function calculate_checksum() {
155 // Let's do it using name and tasks (settings are part of tasks)
156 return md5($this->name . '-' . backup_general_helper::array_checksum_recursive($this->tasks));
160 * Function responsible for executing the tasks of any plan
162 public function execute() {
163 if (!$this->built) {
164 throw new base_plan_exception('base_plan_not_built');
167 // Calculate the total weight of all tasks and start progress tracking.
168 $progress = $this->get_progress();
169 $totalweight = 0;
170 foreach ($this->tasks as $task) {
171 $totalweight += $task->get_weight();
173 $progress->start_progress($this->get_name(), $totalweight);
175 // Build and execute all tasks.
176 foreach ($this->tasks as $task) {
177 $task->build();
178 $task->execute();
181 // Finish progress tracking.
182 $progress->end_progress();
186 * Gets the progress reporter, which can be used to report progress within
187 * the backup or restore process.
189 * @return \core\progress\base Progress reporting object
191 public abstract function get_progress();
194 * Destroy all circular references. It helps PHP 5.2 a lot!
196 public function destroy() {
197 // Before reseting anything, call destroy recursively
198 foreach ($this->tasks as $task) {
199 $task->destroy();
201 foreach ($this->settings as $setting) {
202 $setting->destroy();
204 // Everything has been destroyed recursively, now we can reset safely
205 $this->tasks = array();
206 $this->settings = array();
212 * Exception class used by all the @base_plan stuff
214 class base_plan_exception extends moodle_exception {
216 public function __construct($errorcode, $a=NULL, $debuginfo=null) {
217 parent::__construct($errorcode, '', '', $a, $debuginfo);