NOBUG: Added support for after_restore() methods on restore. Will help some blocks.
[moodle.git] / backup / util / plan / base_task.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 basis for one execution (backup/restore) task
27 *
28 * TODO: Finish phpdocs
29 */
30abstract class base_task implements checksumable, executable, loggable {
31
32 protected $name; // One simple name for identification purposes
33 protected $plan; // Plan this is part of
34 protected $settings; // One array of base_setting elements to define this task
35 protected $steps; // One array of base_task elements
36
648a575e
EL
37 protected $built; // Flag to know if one task has been built
38 protected $executed; // Flag to know if one task has been executed
69dd0c8c
EL
39
40 /**
41 * Constructor - instantiates one object of this class
42 */
43 public function __construct($name, $plan = null) {
44 if (!is_null($plan) && !($plan instanceof base_plan)) {
45 throw new base_task_exception('wrong_base_plan_specified');
46 }
47 $this->name = $name;
48 $this->plan = $plan;
49 $this->settings = array();
50 $this->steps = array();
648a575e
EL
51 $this->built = false;
52 $this->executed = false;
69dd0c8c
EL
53 if (!is_null($plan)) { // Add the task to the plan if specified
54 $plan->add_task($this);
55 }
56 }
57
58 public function get_name() {
59 return $this->name;
60 }
61
62 public function get_steps() {
63 return $this->steps;
64 }
65
66 public function get_settings() {
67 return $this->settings;
68 }
69
70 public function get_setting($name) {
71 // First look in task settings
72 $result = null;
73 foreach ($this->settings as $key => $setting) {
74 if ($setting->get_name() == $name) {
75 if ($result != null) {
76 throw new base_task_exception('multiple_settings_by_name_found', $name);
77 } else {
78 $result = $setting;
79 }
80 }
81 }
82 if ($result) {
83 return $result;
84 } else {
85 // Fallback to plan settings
86 return $this->plan->get_setting($name);
87 }
88 }
89
90 public function get_setting_value($name) {
91 return $this->get_setting($name)->get_value();
92 }
93
69dd0c8c
EL
94 public function get_courseid() {
95 return $this->plan->get_courseid();
96 }
97
98 public function get_basepath() {
99 return $this->plan->get_basepath();
100 }
101
102 public function get_taskbasepath() {
103 return $this->get_basepath();
104 }
105
106 public function get_logger() {
107 return $this->plan->get_logger();
108 }
109
110 public function log($message, $level, $a = null, $depth = null, $display = false) {
111 backup_helper::log($message, $level, $a, $depth, $display, $this->get_logger());
112 }
113
114 public function add_step($step) {
115 if (! $step instanceof base_step) {
116 throw new base_task_exception('wrong_base_step_specified');
117 }
118 // link the step with the task
119 $step->set_task($this);
120 $this->steps[] = $step;
121 }
122
123 public function set_plan($plan) {
124 if (! $plan instanceof base_plan) {
125 throw new base_task_exception('wrong_base_plan_specified');
126 }
127 $this->plan = $plan;
128 $this->define_settings(); // Settings are defined when plan & task are linked
129 }
130
131 /**
132 * Function responsible for building the steps of any task
133 * (must set the $built property to true)
134 */
135 public abstract function build();
136
137 /**
138 * Function responsible for executing the steps of any task
648a575e 139 * (setting the $executed property to true)
69dd0c8c
EL
140 */
141 public function execute() {
142 if (!$this->built) {
143 throw new base_task_exception('base_task_not_built', $this->name);
144 }
648a575e
EL
145 if ($this->executed) {
146 throw new base_task_exception('base_task_already_executed', $this->name);
147 }
69dd0c8c 148 foreach ($this->steps as $step) {
ce937f99
EL
149 $result = $step->execute();
150 // If step returns array, it will be forwarded to plan
151 // (TODO: shouldn't be array but proper result object)
152 if (is_array($result) and !empty($result)) {
153 $this->plan->add_result($result);
154 }
69dd0c8c 155 }
648a575e
EL
156 // Mark as executed if any step has been executed
157 if (!empty($this->steps)) {
158 $this->executed = true;
159 }
69dd0c8c
EL
160 }
161
162 public function is_checksum_correct($checksum) {
163 return $this->calculate_checksum() === $checksum;
164 }
165
166 public function calculate_checksum() {
167 // Let's do it using name and settings and steps
168 return md5($this->name . '-' .
169 backup_general_helper::array_checksum_recursive($this->settings) .
170 backup_general_helper::array_checksum_recursive($this->steps));
171 }
172
173// Protected API starts here
174
175 /**
176 * This function is invoked on activity creation in order to add all the settings
177 * that are associated with one task. The function will, directly, inject the settings
178 * in the task.
179 */
180 protected abstract function define_settings();
181
182 protected function add_setting($setting) {
183 if (! $setting instanceof base_setting) {
184 throw new base_setting_exception('wrong_base_setting_specified');
185 }
186 $this->settings[] = $setting;
187 }
188}
189
190/*
191 * Exception class used by all the @base_task stuff
192 */
193class base_task_exception extends moodle_exception {
194
195 public function __construct($errorcode, $a=NULL, $debuginfo=null) {
196 parent::__construct($errorcode, '', '', $a, $debuginfo);
197 }
198}