See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Page to export forum discussions. 19 * 20 * @package mod_forum 21 * @copyright 2019 Simey Lameze <simey@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 define('NO_OUTPUT_BUFFERING', true); 25 26 require_once(__DIR__ . '/../../config.php'); 27 require_once($CFG->libdir . '/adminlib.php'); 28 require_once($CFG->dirroot . '/calendar/externallib.php'); 29 30 $forumid = required_param('id', PARAM_INT); 31 $userids = optional_param_array('userids', [], PARAM_INT); 32 $discussionids = optional_param_array('discids', [], PARAM_INT); 33 $from = optional_param_array('from', [], PARAM_INT); 34 $to = optional_param_array('to', [], PARAM_INT); 35 $fromtimestamp = optional_param('timestampfrom', '', PARAM_INT); 36 $totimestamp = optional_param('timestampto', '', PARAM_INT); 37 38 if (!empty($from['enabled'])) { 39 unset($from['enabled']); 40 $from = core_calendar_external::get_timestamps([$from])['timestamps'][0]['timestamp']; 41 } else { 42 $from = $fromtimestamp; 43 } 44 45 if (!empty($to['enabled'])) { 46 unset($to['enabled']); 47 $to = core_calendar_external::get_timestamps([$to])['timestamps'][0]['timestamp']; 48 } else { 49 $to = $totimestamp; 50 } 51 52 $vaultfactory = mod_forum\local\container::get_vault_factory(); 53 $managerfactory = mod_forum\local\container::get_manager_factory(); 54 $legacydatamapperfactory = mod_forum\local\container::get_legacy_data_mapper_factory(); 55 56 $forumvault = $vaultfactory->get_forum_vault(); 57 58 $forum = $forumvault->get_from_id($forumid); 59 if (empty($forum)) { 60 throw new moodle_exception('Unable to find forum with id ' . $forumid); 61 } 62 63 $capabilitymanager = $managerfactory->get_capability_manager($forum); 64 if (!$capabilitymanager->can_export_forum($USER)) { 65 throw new moodle_exception('cannotexportforum', 'forum'); 66 } 67 68 $course = $forum->get_course_record(); 69 $coursemodule = $forum->get_course_module_record(); 70 $cm = cm_info::create($coursemodule); 71 72 require_course_login($course, true, $cm); 73 74 $url = new moodle_url('/mod/forum/export.php'); 75 $pagetitle = get_string('export', 'mod_forum'); 76 $context = $forum->get_context(); 77 78 $form = new mod_forum\form\export_form($url->out(false), [ 79 'forum' => $forum 80 ]); 81 82 if ($form->is_cancelled()) { 83 redirect(new moodle_url('/mod/forum/view.php', ['id' => $cm->id])); 84 } else if ($data = $form->get_data()) { 85 $dataformat = $data->format; 86 87 // This may take a very long time and extra memory. 88 \core_php_time_limit::raise(); 89 raise_memory_limit(MEMORY_HUGE); 90 91 $discussionvault = $vaultfactory->get_discussion_vault(); 92 if ($data->discussionids) { 93 $discussionids = $data->discussionids; 94 } else if (empty($discussionids)) { 95 $discussions = $discussionvault->get_all_discussions_in_forum($forum); 96 $discussionids = array_map(function ($discussion) { 97 return $discussion->get_id(); 98 }, $discussions); 99 } 100 101 $filters = ['discussionids' => $discussionids]; 102 if ($data->useridsselected) { 103 $filters['userids'] = $data->useridsselected; 104 } 105 if ($data->from) { 106 $filters['from'] = $data->from; 107 } 108 if ($data->to) { 109 $filters['to'] = $data->to; 110 } 111 112 // Retrieve posts based on the selected filters, note if forum has no discussions then there is nothing to export. 113 if (!empty($filters['discussionids'])) { 114 $postvault = $vaultfactory->get_post_vault(); 115 $posts = $postvault->get_from_filters($USER, $filters, $capabilitymanager->can_view_any_private_reply($USER)); 116 } else { 117 $posts = []; 118 } 119 120 $striphtml = !empty($data->striphtml); 121 $humandates = !empty($data->humandates); 122 123 $fields = ['id', 'discussion', 'parent', 'userid', 'userfullname', 'created', 'modified', 'mailed', 'subject', 'message', 124 'messageformat', 'messagetrust', 'attachment', 'totalscore', 'mailnow', 'deleted', 'privatereplyto', 125 'privatereplytofullname', 'wordcount', 'charcount']; 126 127 $canviewfullname = has_capability('moodle/site:viewfullnames', $context); 128 129 $datamapper = $legacydatamapperfactory->get_post_data_mapper(); 130 $exportdata = new ArrayObject($datamapper->to_legacy_objects($posts)); 131 $iterator = $exportdata->getIterator(); 132 133 $filename = clean_filename('discussion'); 134 \core\dataformat::download_data( 135 $filename, 136 $dataformat, 137 $fields, 138 $iterator, 139 function($exportdata) use ($fields, $striphtml, $humandates, $canviewfullname, $context) { 140 $data = new stdClass(); 141 142 foreach ($fields as $field) { 143 // Set data field's value from the export data's equivalent field by default. 144 $data->$field = $exportdata->$field ?? null; 145 146 if ($field == 'userfullname') { 147 $user = \core_user::get_user($data->userid); 148 $data->userfullname = fullname($user, $canviewfullname); 149 } 150 151 if ($field == 'privatereplytofullname' && !empty($data->privatereplyto)) { 152 $user = \core_user::get_user($data->privatereplyto); 153 $data->privatereplytofullname = fullname($user, $canviewfullname); 154 } 155 156 if ($field == 'message') { 157 $data->message = file_rewrite_pluginfile_urls($data->message, 'pluginfile.php', $context->id, 'mod_forum', 158 'post', $data->id); 159 } 160 161 // Convert any boolean fields to their integer equivalent for output. 162 if (is_bool($data->$field)) { 163 $data->$field = (int) $data->$field; 164 } 165 } 166 167 if ($striphtml) { 168 $data->message = html_to_text(format_text($data->message, $data->messageformat), 0, false); 169 $data->messageformat = FORMAT_PLAIN; 170 } 171 if ($humandates) { 172 $data->created = userdate($data->created); 173 $data->modified = userdate($data->modified); 174 } 175 return $data; 176 }); 177 die; 178 } 179 180 $PAGE->set_context($context); 181 $PAGE->set_url($url); 182 $PAGE->set_title($pagetitle); 183 $PAGE->set_pagelayout('admin'); 184 $PAGE->add_body_class('limitedwidth'); 185 $PAGE->set_heading($pagetitle); 186 $PAGE->activityheader->disable(); 187 188 echo $OUTPUT->header(); 189 if (!$PAGE->has_secondary_navigation()) { 190 echo $OUTPUT->heading($pagetitle); 191 } 192 193 // It is possible that the following fields have been provided in the URL. 194 $userids = array_filter($userids, static function(int $userid) use ($course, $cm): bool { 195 $user = core_user::get_user($userid, '*', MUST_EXIST); 196 return $cm->effectivegroupmode != SEPARATEGROUPS || user_can_view_profile($user, $course); 197 }); 198 $form->set_data(['useridsselected' => $userids, 'discussionids' => $discussionids, 'from' => $from, 'to' => $to]); 199 200 $form->display(); 201 202 echo $OUTPUT->footer();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body