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 mod_forum 20 * @subpackage backup-moodle2 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 * Define all the restore steps that will be used by the restore_forum_activity_task 27 */ 28 29 /** 30 * Structure step to restore one forum activity 31 */ 32 class restore_forum_activity_structure_step extends restore_activity_structure_step { 33 34 protected function define_structure() { 35 36 $paths = array(); 37 $userinfo = $this->get_setting_value('userinfo'); 38 39 $paths[] = new restore_path_element('forum', '/activity/forum'); 40 if ($userinfo) { 41 $paths[] = new restore_path_element('forum_discussion', '/activity/forum/discussions/discussion'); 42 $paths[] = new restore_path_element('forum_post', '/activity/forum/discussions/discussion/posts/post'); 43 $paths[] = new restore_path_element('forum_tag', '/activity/forum/poststags/tag'); 44 $paths[] = new restore_path_element('forum_discussion_sub', '/activity/forum/discussions/discussion/discussion_subs/discussion_sub'); 45 $paths[] = new restore_path_element('forum_rating', '/activity/forum/discussions/discussion/posts/post/ratings/rating'); 46 $paths[] = new restore_path_element('forum_subscription', '/activity/forum/subscriptions/subscription'); 47 $paths[] = new restore_path_element('forum_digest', '/activity/forum/digests/digest'); 48 $paths[] = new restore_path_element('forum_read', '/activity/forum/readposts/read'); 49 $paths[] = new restore_path_element('forum_track', '/activity/forum/trackedprefs/track'); 50 $paths[] = new restore_path_element('forum_grade', '/activity/forum/grades/grade'); 51 } 52 53 // Return the paths wrapped into standard activity structure 54 return $this->prepare_activity_structure($paths); 55 } 56 57 protected function process_forum($data) { 58 global $DB; 59 60 $data = (object)$data; 61 $oldid = $data->id; 62 $data->course = $this->get_courseid(); 63 64 // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset. 65 // See MDL-9367. 66 if (!isset($data->duedate)) { 67 $data->duedate = 0; 68 } 69 $data->duedate = $this->apply_date_offset($data->duedate); 70 if (!isset($data->cutoffdate)) { 71 $data->cutoffdate = 0; 72 } 73 $data->cutoffdate = $this->apply_date_offset($data->cutoffdate); 74 $data->assesstimestart = $this->apply_date_offset($data->assesstimestart); 75 $data->assesstimefinish = $this->apply_date_offset($data->assesstimefinish); 76 if ($data->scale < 0) { // scale found, get mapping 77 $data->scale = -($this->get_mappingid('scale', abs($data->scale))); 78 } 79 80 $newitemid = $DB->insert_record('forum', $data); 81 $this->apply_activity_instance($newitemid); 82 83 // Add current enrolled user subscriptions if necessary. 84 $data->id = $newitemid; 85 $ctx = context_module::instance($this->task->get_moduleid()); 86 forum_instance_created($ctx, $data); 87 } 88 89 protected function process_forum_discussion($data) { 90 global $DB; 91 92 $data = (object)$data; 93 $oldid = $data->id; 94 $data->course = $this->get_courseid(); 95 96 $data->forum = $this->get_new_parentid('forum'); 97 $data->timestart = $this->apply_date_offset($data->timestart); 98 $data->timeend = $this->apply_date_offset($data->timeend); 99 $data->userid = $this->get_mappingid('user', $data->userid); 100 $data->groupid = $this->get_mappingid('group', $data->groupid); 101 $data->usermodified = $this->get_mappingid('user', $data->usermodified); 102 103 $newitemid = $DB->insert_record('forum_discussions', $data); 104 $this->set_mapping('forum_discussion', $oldid, $newitemid); 105 } 106 107 protected function process_forum_post($data) { 108 global $DB; 109 110 $data = (object)$data; 111 $oldid = $data->id; 112 113 $data->discussion = $this->get_new_parentid('forum_discussion'); 114 $data->userid = $this->get_mappingid('user', $data->userid); 115 // If post has parent, map it (it has been already restored) 116 if (!empty($data->parent)) { 117 $data->parent = $this->get_mappingid('forum_post', $data->parent); 118 } 119 120 \mod_forum\local\entities\post::add_message_counts($data); 121 $newitemid = $DB->insert_record('forum_posts', $data); 122 $this->set_mapping('forum_post', $oldid, $newitemid, true); 123 124 // If !post->parent, it's the 1st post. Set it in discussion 125 if (empty($data->parent)) { 126 $DB->set_field('forum_discussions', 'firstpost', $newitemid, array('id' => $data->discussion)); 127 } 128 } 129 130 protected function process_forum_tag($data) { 131 $data = (object)$data; 132 133 if (!core_tag_tag::is_enabled('mod_forum', 'forum_posts')) { // Tags disabled in server, nothing to process. 134 return; 135 } 136 137 $tag = $data->rawname; 138 if (!$itemid = $this->get_mappingid('forum_post', $data->itemid)) { 139 // Some orphaned tag, we could not find the restored post for it - ignore. 140 return; 141 } 142 143 $context = context_module::instance($this->task->get_moduleid()); 144 core_tag_tag::add_item_tag('mod_forum', 'forum_posts', $itemid, $context, $tag); 145 } 146 147 protected function process_forum_rating($data) { 148 global $DB; 149 150 $data = (object)$data; 151 152 // Cannot use ratings API, cause, it's missing the ability to specify times (modified/created) 153 $data->contextid = $this->task->get_contextid(); 154 $data->itemid = $this->get_new_parentid('forum_post'); 155 if ($data->scaleid < 0) { // scale found, get mapping 156 $data->scaleid = -($this->get_mappingid('scale', abs($data->scaleid))); 157 } 158 $data->rating = $data->value; 159 $data->userid = $this->get_mappingid('user', $data->userid); 160 161 // We need to check that component and ratingarea are both set here. 162 if (empty($data->component)) { 163 $data->component = 'mod_forum'; 164 } 165 if (empty($data->ratingarea)) { 166 $data->ratingarea = 'post'; 167 } 168 169 $newitemid = $DB->insert_record('rating', $data); 170 } 171 172 protected function process_forum_subscription($data) { 173 global $DB; 174 175 $data = (object)$data; 176 $oldid = $data->id; 177 178 $data->forum = $this->get_new_parentid('forum'); 179 $data->userid = $this->get_mappingid('user', $data->userid); 180 181 // Create only a new subscription if it does not already exist (see MDL-59854). 182 if ($subscription = $DB->get_record('forum_subscriptions', 183 array('forum' => $data->forum, 'userid' => $data->userid))) { 184 $this->set_mapping('forum_subscription', $oldid, $subscription->id, true); 185 } else { 186 $newitemid = $DB->insert_record('forum_subscriptions', $data); 187 $this->set_mapping('forum_subscription', $oldid, $newitemid, true); 188 } 189 190 } 191 192 protected function process_forum_discussion_sub($data) { 193 global $DB; 194 195 $data = (object)$data; 196 $oldid = $data->id; 197 198 $data->discussion = $this->get_new_parentid('forum_discussion'); 199 $data->forum = $this->get_new_parentid('forum'); 200 $data->userid = $this->get_mappingid('user', $data->userid); 201 202 $newitemid = $DB->insert_record('forum_discussion_subs', $data); 203 $this->set_mapping('forum_discussion_sub', $oldid, $newitemid, true); 204 } 205 206 protected function process_forum_digest($data) { 207 global $DB; 208 209 $data = (object)$data; 210 $oldid = $data->id; 211 212 $data->forum = $this->get_new_parentid('forum'); 213 $data->userid = $this->get_mappingid('user', $data->userid); 214 215 $newitemid = $DB->insert_record('forum_digests', $data); 216 } 217 218 protected function process_forum_grade($data) { 219 global $DB; 220 221 $data = (object)$data; 222 $oldid = $data->id; 223 224 $data->forum = $this->get_new_parentid('forum'); 225 226 $data->userid = $this->get_mappingid('user', $data->userid); 227 228 // We want to ensure the current user has an ID that we can associate to a grade. 229 if ($data->userid != 0) { 230 $newitemid = $DB->insert_record('forum_grades', $data); 231 232 // Note - the old contextid is required in order to be able to restore files stored in 233 // sub plugin file areas attached to the gradeid. 234 $this->set_mapping('grade', $oldid, $newitemid, false, null, $this->task->get_old_contextid()); 235 $this->set_mapping(restore_gradingform_plugin::itemid_mapping('forum'), $oldid, $newitemid); 236 } 237 } 238 239 protected function process_forum_read($data) { 240 global $DB; 241 242 $data = (object)$data; 243 $oldid = $data->id; 244 245 $data->forumid = $this->get_new_parentid('forum'); 246 $data->discussionid = $this->get_mappingid('forum_discussion', $data->discussionid); 247 $data->postid = $this->get_mappingid('forum_post', $data->postid); 248 $data->userid = $this->get_mappingid('user', $data->userid); 249 250 $newitemid = $DB->insert_record('forum_read', $data); 251 } 252 253 protected function process_forum_track($data) { 254 global $DB; 255 256 $data = (object)$data; 257 $oldid = $data->id; 258 259 $data->forumid = $this->get_new_parentid('forum'); 260 $data->userid = $this->get_mappingid('user', $data->userid); 261 262 $newitemid = $DB->insert_record('forum_track_prefs', $data); 263 } 264 265 protected function after_execute() { 266 // Add forum related files, no need to match by itemname (just internally handled context) 267 $this->add_related_files('mod_forum', 'intro', null); 268 269 // Add post related files, matching by itemname = 'forum_post' 270 $this->add_related_files('mod_forum', 'post', 'forum_post'); 271 $this->add_related_files('mod_forum', 'attachment', 'forum_post'); 272 } 273 274 protected function after_restore() { 275 global $DB; 276 277 // If the forum is of type 'single' and no discussion has been ignited 278 // (non-userinfo backup/restore) create the discussion here, using forum 279 // information as base for the initial post. 280 $forumid = $this->task->get_activityid(); 281 $forumrec = $DB->get_record('forum', array('id' => $forumid)); 282 if ($forumrec->type == 'single' && !$DB->record_exists('forum_discussions', array('forum' => $forumid))) { 283 // Create single discussion/lead post from forum data 284 $sd = new stdClass(); 285 $sd->course = $forumrec->course; 286 $sd->forum = $forumrec->id; 287 $sd->name = $forumrec->name; 288 $sd->assessed = $forumrec->assessed; 289 $sd->message = $forumrec->intro; 290 $sd->messageformat = $forumrec->introformat; 291 $sd->messagetrust = true; 292 $sd->mailnow = false; 293 $sdid = forum_add_discussion($sd, null, null, $this->task->get_userid()); 294 // Mark the post as mailed 295 $DB->set_field ('forum_posts','mailed', '1', array('discussion' => $sdid)); 296 // Copy all the files from mod_foum/intro to mod_forum/post 297 $fs = get_file_storage(); 298 $files = $fs->get_area_files($this->task->get_contextid(), 'mod_forum', 'intro'); 299 foreach ($files as $file) { 300 $newfilerecord = new stdClass(); 301 $newfilerecord->filearea = 'post'; 302 $newfilerecord->itemid = $DB->get_field('forum_discussions', 'firstpost', array('id' => $sdid)); 303 $fs->create_file_from_storedfile($newfilerecord, $file); 304 } 305 } 306 } 307 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body