Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 basis for one execution (backup/restore) task 27 * 28 * TODO: Finish phpdocs 29 */ 30 abstract class base_task implements checksumable, executable, loggable { 31 32 /** @var string */ 33 protected $name; // One simple name for identification purposes 34 /** @var backup_plan|restore_plan */ 35 protected $plan; // Plan this is part of 36 /** @var base_setting[] */ 37 protected $settings; // One array of base_setting elements to define this task 38 /** @var base_step[] */ 39 protected $steps; // One array of base_step elements 40 /** @var bool */ 41 protected $built; // Flag to know if one task has been built 42 /** @var bool */ 43 protected $executed; // Flag to know if one task has been executed 44 45 /** 46 * Constructor - instantiates one object of this class 47 */ 48 public function __construct($name, $plan = null) { 49 if (!is_null($plan) && !($plan instanceof base_plan)) { 50 throw new base_task_exception('wrong_base_plan_specified'); 51 } 52 $this->name = $name; 53 $this->plan = $plan; 54 $this->settings = array(); 55 $this->steps = array(); 56 $this->built = false; 57 $this->executed = false; 58 if (!is_null($plan)) { // Add the task to the plan if specified 59 $plan->add_task($this); 60 } 61 } 62 63 public function get_name() { 64 return $this->name; 65 } 66 67 public function get_steps() { 68 return $this->steps; 69 } 70 71 public function get_settings() { 72 return $this->settings; 73 } 74 75 /** 76 * Returns the weight of this task, an approximation of the amount of time 77 * it will take. By default this value is 1. It can be increased for longer 78 * tasks. 79 * 80 * @return int Weight 81 */ 82 public function get_weight() { 83 return 1; 84 } 85 86 public function get_setting($name) { 87 // First look in task settings 88 $result = null; 89 foreach ($this->settings as $key => $setting) { 90 if ($setting->get_name() == $name) { 91 if ($result != null) { 92 throw new base_task_exception('multiple_settings_by_name_found', $name); 93 } else { 94 $result = $setting; 95 } 96 } 97 } 98 if ($result) { 99 return $result; 100 } else { 101 // Fallback to plan settings 102 return $this->plan->get_setting($name); 103 } 104 } 105 106 public function setting_exists($name) { 107 return $this->plan->setting_exists($name); 108 } 109 110 public function get_setting_value($name) { 111 return $this->get_setting($name)->get_value(); 112 } 113 114 public function get_courseid() { 115 return $this->plan->get_courseid(); 116 } 117 118 public function get_basepath() { 119 return $this->plan->get_basepath(); 120 } 121 122 public function get_taskbasepath() { 123 return $this->get_basepath(); 124 } 125 126 public function get_logger() { 127 return $this->plan->get_logger(); 128 } 129 130 /** 131 * Gets the progress reporter, which can be used to report progress within 132 * the backup or restore process. 133 * 134 * @return \core\progress\base Progress reporting object 135 */ 136 public function get_progress() { 137 return $this->plan->get_progress(); 138 } 139 140 public function log($message, $level, $a = null, $depth = null, $display = false) { 141 backup_helper::log($message, $level, $a, $depth, $display, $this->get_logger()); 142 } 143 144 public function add_step($step) { 145 if (! $step instanceof base_step) { 146 throw new base_task_exception('wrong_base_step_specified'); 147 } 148 // link the step with the task 149 $step->set_task($this); 150 $this->steps[] = $step; 151 } 152 153 public function set_plan($plan) { 154 if (! $plan instanceof base_plan) { 155 throw new base_task_exception('wrong_base_plan_specified'); 156 } 157 $this->plan = $plan; 158 $this->define_settings(); // Settings are defined when plan & task are linked 159 } 160 161 /** 162 * Function responsible for building the steps of any task 163 * (must set the $built property to true) 164 */ 165 public abstract function build(); 166 167 /** 168 * Function responsible for executing the steps of any task 169 * (setting the $executed property to true) 170 */ 171 public function execute() { 172 if (!$this->built) { 173 throw new base_task_exception('base_task_not_built', $this->name); 174 } 175 if ($this->executed) { 176 throw new base_task_exception('base_task_already_executed', $this->name); 177 } 178 179 // Starts progress based on the weight of this task and number of steps. 180 $progress = $this->get_progress(); 181 $progress->start_progress($this->get_name(), count($this->steps), $this->get_weight()); 182 $done = 0; 183 184 // Execute all steps. 185 foreach ($this->steps as $step) { 186 $result = $step->execute(); 187 // If step returns array, it will be forwarded to plan 188 // (TODO: shouldn't be array but proper result object) 189 if (is_array($result) and !empty($result)) { 190 $this->add_result($result); 191 } 192 $done++; 193 $progress->progress($done); 194 } 195 // Mark as executed if any step has been executed 196 if (!empty($this->steps)) { 197 $this->executed = true; 198 } 199 200 // Finish progress for this task. 201 $progress->end_progress(); 202 } 203 204 /** 205 * Destroy all circular references. It helps PHP 5.2 a lot! 206 */ 207 public function destroy() { 208 // Before reseting anything, call destroy recursively 209 foreach ($this->steps as $step) { 210 $step->destroy(); 211 } 212 foreach ($this->settings as $setting) { 213 $setting->destroy(); 214 } 215 // Everything has been destroyed recursively, now we can reset safely 216 $this->steps = array(); 217 $this->settings = array(); 218 $this->plan = null; 219 } 220 221 public function is_checksum_correct($checksum) { 222 return $this->calculate_checksum() === $checksum; 223 } 224 225 public function calculate_checksum() { 226 // Let's do it using name and settings and steps 227 return md5($this->name . '-' . 228 backup_general_helper::array_checksum_recursive($this->settings) . 229 backup_general_helper::array_checksum_recursive($this->steps)); 230 } 231 232 /** 233 * Add the given info to the current plan's results. 234 * 235 * @see base_plan::add_result() 236 * @param array $result associative array describing a result of a task/step 237 */ 238 public function add_result($result) { 239 if (!is_null($this->plan)) { 240 $this->plan->add_result($result); 241 } else { 242 debugging('Attempting to add a result of a task not binded with a plan', DEBUG_DEVELOPER); 243 } 244 } 245 246 /** 247 * Return the current plan's results 248 * 249 * @return array|null 250 */ 251 public function get_results() { 252 if (!is_null($this->plan)) { 253 return $this->plan->get_results(); 254 } else { 255 debugging('Attempting to get results of a task not binded with a plan', DEBUG_DEVELOPER); 256 return null; 257 } 258 } 259 260 // Protected API starts here 261 262 /** 263 * This function is invoked on activity creation in order to add all the settings 264 * that are associated with one task. The function will, directly, inject the settings 265 * in the task. 266 */ 267 protected abstract function define_settings(); 268 269 protected function add_setting($setting) { 270 if (! $setting instanceof base_setting) { 271 throw new base_setting_exception('wrong_base_setting_specified'); 272 } 273 $this->settings[] = $setting; 274 } 275 } 276 277 /* 278 * Exception class used by all the @base_task stuff 279 */ 280 class base_task_exception extends moodle_exception { 281 282 public function __construct($errorcode, $a=NULL, $debuginfo=null) { 283 parent::__construct($errorcode, '', '', $a, $debuginfo); 284 } 285 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body