Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Defines restore_section_task class
20
 *
21
 * @package     core_backup
22
 * @subpackage  moodle2
23
 * @category    backup
24
 * @copyright   2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
25
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26
 */
27
 
28
defined('MOODLE_INTERNAL') || die();
29
 
30
/**
31
 * section task that provides all the properties and common steps to be performed
32
 * when one section is being restored
33
 *
34
 * TODO: Finish phpdocs
35
 */
36
class restore_section_task extends restore_task {
37
 
38
    protected $info; // info related to section gathered from backup file
39
    protected $contextid; // course context id
40
    protected $sectionid; // new (target) id of the course section
41
 
42
    /**
43
     * Constructor - instantiates one object of this class
44
     */
45
    public function __construct($name, $info, $plan = null) {
46
        $this->info = $info;
47
        $this->sectionid = 0;
48
        parent::__construct($name, $plan);
49
    }
50
 
51
    /**
52
     * Section tasks have their own directory to read files
53
     */
54
    public function get_taskbasepath() {
55
 
56
        return $this->get_basepath() . '/sections/section_' . $this->info->sectionid;
57
    }
58
 
1441 ariadna 59
    /**
60
     * Get the course module that is delegating this section.
61
     *
62
     * @return int|null the course module id that is delegating this section
63
     */
64
    public function get_delegated_cm(): ?int {
65
        if (!isset($this->info->parentcmid) || empty($this->info->parentcmid)) {
66
            return null;
67
        }
68
        return intval($this->info->parentcmid);
69
    }
70
 
71
    /**
72
     * Get the delegated activity modname if any.
73
     *
74
     * @return string|null the modname of the delegated activity
75
     */
76
    public function get_modname(): ?string {
77
        if (!isset($this->info->modname) || empty($this->info->modname)) {
78
            return null;
79
        }
80
        return $this->info->modname;
81
    }
82
 
1 efrain 83
    public function set_sectionid($sectionid) {
84
        $this->sectionid = $sectionid;
85
    }
86
 
87
    public function get_contextid() {
88
        return $this->contextid;
89
    }
90
 
91
    public function get_sectionid() {
92
        return $this->sectionid;
93
    }
94
 
95
    /**
96
     * Create all the steps that will be part of this task
97
     */
98
    public function build() {
99
 
100
        // Define the task contextid (the course one)
101
        $this->contextid = context_course::instance($this->get_courseid())->id;
102
 
103
        // We always try to restore as much info from sections as possible, no matter of the type
104
        // of restore (new, existing, deleting, import...). MDL-27764
105
        $this->add_step(new restore_section_structure_step('course_info', 'section.xml'));
106
 
107
        // At the end, mark it as built
108
        $this->built = true;
109
    }
110
 
111
    /**
112
     * Exceptionally override the execute method, so, based in the section_included setting, we are able
113
     * to skip the execution of one task completely
114
     */
115
    public function execute() {
116
 
117
        // Find activity_included_setting
118
        if (!$this->get_setting_value('included')) {
119
            $this->log('activity skipped by _included setting', backup::LOG_DEBUG, $this->name);
120
 
121
        } else { // Setting tells us it's ok to execute
122
            parent::execute();
123
        }
124
    }
125
 
126
    /**
127
     * Specialisation that, first of all, looks for the setting within
128
     * the task with the the prefix added and later, delegates to parent
129
     * without adding anything
130
     */
131
    public function get_setting($name) {
132
        $namewithprefix = 'section_' . $this->info->sectionid . '_' . $name;
133
        $result = null;
134
        foreach ($this->settings as $key => $setting) {
135
            if ($setting->get_name() == $namewithprefix) {
136
                if ($result != null) {
137
                    throw new base_task_exception('multiple_settings_by_name_found', $namewithprefix);
138
                } else {
139
                    $result = $setting;
140
                }
141
            }
142
        }
143
        if ($result) {
144
            return $result;
145
        } else {
146
            // Fallback to parent
147
            return parent::get_setting($name);
148
        }
149
    }
150
 
151
    /**
152
     * Define the contents in the course that must be
153
     * processed by the link decoder
154
     */
155
    public static function define_decode_contents() {
156
        $contents = array();
157
 
158
        $contents[] = new restore_decode_content('course_sections', 'summary', 'course_section');
159
 
160
        return $contents;
161
    }
162
 
163
    /**
164
     * Define the decoding rules for links belonging
165
     * to the sections to be executed by the link decoder
166
     */
167
    public static function define_decode_rules() {
168
        return array();
169
    }
170
 
171
// Protected API starts here
172
 
173
    /**
174
     * Define the common setting that any restore section will have
175
     */
176
    protected function define_settings() {
177
        // All the settings related to this activity will include this prefix
178
        $settingprefix = 'section_' . $this->info->sectionid . '_';
179
 
1441 ariadna 180
        // All these are common settings to be shared by all sections.
181
        $sectionincluded = $this->add_section_included_setting($settingprefix);
182
        $this->add_section_userinfo_setting($settingprefix, $sectionincluded);
183
    }
1 efrain 184
 
1441 ariadna 185
    /**
186
     * Add the section included setting to the task.
187
     *
188
     * @param string $settingprefix the identifier of the setting
189
     * @return section_backup_setting the setting added
190
     */
191
    protected function add_section_included_setting(string $settingprefix): section_backup_setting {
192
        global $DB;
193
        // Define sectionincluded (to decide if the whole task must be really executed).
1 efrain 194
        $settingname = $settingprefix . 'included';
1441 ariadna 195
 
196
        $delegatedcmid = $this->get_delegated_cm();
197
        if ($delegatedcmid) {
198
            $sectionincluded = new restore_subsection_included_setting($settingname, base_setting::IS_BOOLEAN, true);
199
            // Subsections depends on the parent activity included setting.
200
            $settingname = $this->get_modname() . '_' . $delegatedcmid . '_included';
201
            if ($this->plan->setting_exists($settingname)) {
202
                $cmincluded = $this->plan->get_setting($settingname);
203
                $cmincluded->add_dependency(
204
                    $sectionincluded,
205
                );
206
            }
207
            $label = get_string('subsectioncontent', 'backup');
1 efrain 208
        } else {
1441 ariadna 209
            $sectionincluded = new restore_section_included_setting($settingname, base_setting::IS_BOOLEAN, true);
210
 
211
            if (is_number($this->info->title)) {
212
                $label = get_string('includesection', 'backup', $this->info->title);
213
            } else if (empty($this->info->title)) { // Don't throw error if title is empty, gracefully continue restore.
214
                $this->log(
215
                    'Section title missing in backup for section id ' . $this->info->sectionid,
216
                    backup::LOG_WARNING,
217
                    $this->name
218
                );
219
                $label = get_string('unnamedsection', 'backup');
220
            } else {
221
                $label = $this->info->title;
222
            }
1 efrain 223
        }
224
 
1441 ariadna 225
        $sectionincluded->get_ui()->set_label($label);
226
        $this->add_setting($sectionincluded);
227
 
228
        return $sectionincluded;
229
    }
230
 
231
    /**
232
     * Add the section userinfo setting to the task.
233
     *
234
     * @param string $settingprefix the identifier of the setting
235
     * @param section_backup_setting $includefield the section included setting
236
     * @return section_backup_setting the setting added
237
     */
238
    protected function add_section_userinfo_setting(
239
        string $settingprefix,
240
        section_backup_setting $includefield
241
    ): section_backup_setting {
242
        // Define sectionuserinfo. Dependent of:
243
        // - users root setting.
244
        // - sectionincluded setting.
1 efrain 245
        $settingname = $settingprefix . 'userinfo';
246
        $defaultvalue = false;
247
        if (isset($this->info->settings[$settingname]) && $this->info->settings[$settingname]) { // Only enabled when available
248
            $defaultvalue = true;
249
        }
250
 
1441 ariadna 251
        $delegatedcmid = $this->get_delegated_cm();
252
        if ($delegatedcmid) {
253
            $sectionuserinfo = new restore_subsection_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
254
            // Subsections depends on the parent activity included setting.
255
            $settingname = $this->get_modname() . '_' . $delegatedcmid . '_userinfo';
256
            if ($this->plan->setting_exists($settingname)) {
257
                $cmincluded = $this->plan->get_setting($settingname);
258
                $cmincluded->add_dependency(
259
                    $sectionuserinfo,
260
                );
261
            }
262
        } else {
263
            $sectionuserinfo = new restore_section_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
264
        }
265
 
1 efrain 266
        if (!$defaultvalue) {
267
            // This is a bit hacky, but if there is no user data to restore, then
268
            // we replace the standard check-box with a select menu with the
269
            // single choice 'No', and the select menu is clever enough that if
270
            // there is only one choice, it just displays a static string.
271
            //
272
            // It would probably be better design to have a special UI class
273
            // setting_ui_checkbox_or_no, rather than this hack, but I am not
274
            // going to do that today.
1441 ariadna 275
            $sectionuserinfo->set_ui(
276
                new backup_setting_ui_select($sectionuserinfo,
277
                    get_string('includeuserinfo', 'backup'), [0 => get_string('no')])
278
            );
1 efrain 279
        } else {
1441 ariadna 280
            $sectionuserinfo->get_ui()->set_label(get_string('includeuserinfo', 'backup'));
1 efrain 281
        }
282
 
1441 ariadna 283
        $this->add_setting($sectionuserinfo);
1 efrain 284
 
285
        // Look for "users" root setting.
286
        $users = $this->plan->get_setting('users');
1441 ariadna 287
        $users->add_dependency($sectionuserinfo);
1 efrain 288
 
1441 ariadna 289
        // Look for "section included" section setting.
290
        $includefield->add_dependency($sectionuserinfo);
291
 
292
        return $sectionuserinfo;
1 efrain 293
    }
294
}