|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00022 require_once($CFG->dirroot . '/mod/forum/lib.php'); 00023 require_once($CFG->libdir . '/portfolio/caller.php'); 00024 00030 class forum_portfolio_caller extends portfolio_module_caller_base { 00031 00032 protected $postid; 00033 protected $discussionid; 00034 protected $attachment; 00035 00036 private $post; 00037 private $forum; 00038 private $discussion; 00039 private $posts; 00040 private $keyedfiles; // just using multifiles isn't enough if we're exporting a full thread 00041 00045 public static function expected_callbackargs() { 00046 return array( 00047 'postid' => false, 00048 'discussionid' => false, 00049 'attachment' => false, 00050 ); 00051 } 00055 function __construct($callbackargs) { 00056 parent::__construct($callbackargs); 00057 if (!$this->postid && !$this->discussionid) { 00058 throw new portfolio_caller_exception('mustprovidediscussionorpost', 'forum'); 00059 } 00060 } 00064 public function load_data() { 00065 global $DB; 00066 00067 if ($this->postid) { 00068 if (!$this->post = $DB->get_record('forum_posts', array('id' => $this->postid))) { 00069 throw new portfolio_caller_exception('invalidpostid', 'forum'); 00070 } 00071 } 00072 00073 $dparams = array(); 00074 if ($this->discussionid) { 00075 $dbparams = array('id' => $this->discussionid); 00076 } else if ($this->post) { 00077 $dbparams = array('id' => $this->post->discussion); 00078 } else { 00079 throw new portfolio_caller_exception('mustprovidediscussionorpost', 'forum'); 00080 } 00081 00082 if (!$this->discussion = $DB->get_record('forum_discussions', $dbparams)) { 00083 throw new portfolio_caller_exception('invaliddiscussionid', 'forum'); 00084 } 00085 00086 if (!$this->forum = $DB->get_record('forum', array('id' => $this->discussion->forum))) { 00087 throw new portfolio_caller_exception('invalidforumid', 'forum'); 00088 } 00089 00090 if (!$this->cm = get_coursemodule_from_instance('forum', $this->forum->id)) { 00091 throw new portfolio_caller_exception('invalidcoursemodule'); 00092 } 00093 00094 $this->modcontext = get_context_instance(CONTEXT_MODULE, $this->cm->id); 00095 $fs = get_file_storage(); 00096 if ($this->post) { 00097 if ($this->attachment) { 00098 $this->set_file_and_format_data($this->attachment); 00099 } else { 00100 $attach = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'attachment', $this->post->id, 'timemodified', false); 00101 $embed = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'post', $this->post->id, 'timemodified', false); 00102 $files = array_merge($attach, $embed); 00103 $this->set_file_and_format_data($files); 00104 } 00105 if (!empty($this->multifiles)) { 00106 $this->keyedfiles[$this->post->id] = $this->multifiles; 00107 } else if (!empty($this->singlefile)) { 00108 $this->keyedfiles[$this->post->id] = array($this->singlefile); 00109 } 00110 } else { // whole thread 00111 $fs = get_file_storage(); 00112 $this->posts = forum_get_all_discussion_posts($this->discussion->id, 'p.created ASC'); 00113 $this->multifiles = array(); 00114 foreach ($this->posts as $post) { 00115 $attach = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'attachment', $post->id, 'timemodified', false); 00116 $embed = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'post', $post->id, 'timemodified', false); 00117 $files = array_merge($attach, $embed); 00118 if ($files) { 00119 $this->keyedfiles[$post->id] = $files; 00120 } else { 00121 continue; 00122 } 00123 $this->multifiles = array_merge($this->multifiles, array_values($this->keyedfiles[$post->id])); 00124 } 00125 } 00126 if (empty($this->multifiles) && !empty($this->singlefile)) { 00127 $this->multifiles = array($this->singlefile); // copy_files workaround 00128 } 00129 // depending on whether there are files or not, we might have to change richhtml/plainhtml 00130 if (empty($this->attachment)) { 00131 if (!empty($this->multifiles)) { 00132 $this->add_format(PORTFOLIO_FORMAT_RICHHTML); 00133 } else { 00134 $this->add_format(PORTFOLIO_FORMAT_PLAINHTML); 00135 } 00136 } 00137 } 00138 00143 function get_return_url() { 00144 global $CFG; 00145 return $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $this->discussion->id; 00146 } 00151 function get_navigation() { 00152 global $CFG; 00153 00154 $navlinks = array(); 00155 $navlinks[] = array( 00156 'name' => format_string($this->discussion->name), 00157 'link' => $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $this->discussion->id, 00158 'type' => 'title' 00159 ); 00160 return array($navlinks, $this->cm); 00161 } 00172 function prepare_package() { 00173 global $CFG; 00174 00175 // set up the leap2a writer if we need it 00176 $writingleap = false; 00177 if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) { 00178 $leapwriter = $this->exporter->get('format')->leap2a_writer(); 00179 $writingleap = true; 00180 } 00181 if ($this->attachment) { // simplest case first - single file attachment 00182 $this->copy_files(array($this->singlefile), $this->attachment); 00183 if ($writingleap) { // if we're writing leap, make the manifest to go along with the file 00184 $entry = new portfolio_format_leap2a_file($this->singlefile->get_filename(), $this->singlefile); 00185 $leapwriter->add_entry($entry); 00186 return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true); 00187 } 00188 00189 } else if (empty($this->post)) { // exporting whole discussion 00190 $content = ''; // if we're just writing HTML, start a string to add each post to 00191 $ids = array(); // if we're writing leap2a, keep track of all entryids so we can add a selection element 00192 foreach ($this->posts as $post) { 00193 $posthtml = $this->prepare_post($post); 00194 if ($writingleap) { 00195 $ids[] = $this->prepare_post_leap2a($leapwriter, $post, $posthtml); 00196 } else { 00197 $content .= $posthtml . '<br /><br />'; 00198 } 00199 } 00200 $this->copy_files($this->multifiles); 00201 $name = 'discussion.html'; 00202 $manifest = ($this->exporter->get('format') instanceof PORTFOLIO_FORMAT_RICH); 00203 if ($writingleap) { 00204 // add on an extra 'selection' entry 00205 $selection = new portfolio_format_leap2a_entry('forumdiscussion' . $this->discussionid, 00206 get_string('discussion', 'forum') . ': ' . $this->discussion->name, 'selection'); 00207 $leapwriter->add_entry($selection); 00208 $leapwriter->make_selection($selection, $ids, 'Grouping'); 00209 $content = $leapwriter->to_xml(); 00210 $name = $this->get('exporter')->get('format')->manifest_name(); 00211 } 00212 $this->get('exporter')->write_new_file($content, $name, $manifest); 00213 00214 } else { // exporting a single post 00215 $posthtml = $this->prepare_post($this->post); 00216 00217 $content = $posthtml; 00218 $name = 'post.html'; 00219 $manifest = ($this->exporter->get('format') instanceof PORTFOLIO_FORMAT_RICH); 00220 00221 if ($writingleap) { 00222 $this->prepare_post_leap2a($leapwriter, $this->post, $posthtml); 00223 $content = $leapwriter->to_xml(); 00224 $name = $this->exporter->get('format')->manifest_name(); 00225 } 00226 $this->copy_files($this->multifiles); 00227 $this->get('exporter')->write_new_file($content, $name, $manifest); 00228 } 00229 } 00230 00244 private function prepare_post_leap2a(portfolio_format_leap2a_writer $leapwriter, $post, $posthtml) { 00245 $entry = new portfolio_format_leap2a_entry('forumpost' . $post->id, $post->subject, 'resource', $posthtml); 00246 $entry->published = $post->created; 00247 $entry->updated = $post->modified; 00248 $entry->author = $post->author; 00249 if (is_array($this->keyedfiles) && array_key_exists($post->id, $this->keyedfiles) && is_array($this->keyedfiles[$post->id])) { 00250 $leapwriter->link_files($entry, $this->keyedfiles[$post->id], 'forumpost' . $post->id . 'attachment'); 00251 } 00252 $entry->add_category('web', 'resource_type'); 00253 $leapwriter->add_entry($entry); 00254 return $entry->id; 00255 } 00256 00262 private function copy_files($files, $justone=false) { 00263 if (empty($files)) { 00264 return; 00265 } 00266 foreach ($files as $f) { 00267 if ($justone && $f->get_id() != $justone) { 00268 continue; 00269 } 00270 $this->get('exporter')->copy_existing_file($f); 00271 if ($justone && $f->get_id() == $justone) { 00272 return true; // all we need to do 00273 } 00274 } 00275 } 00283 private function prepare_post($post, $fileoutputextras=null) { 00284 global $DB; 00285 static $users; 00286 if (empty($users)) { 00287 $users = array($this->user->id => $this->user); 00288 } 00289 if (!array_key_exists($post->userid, $users)) { 00290 $users[$post->userid] = $DB->get_record('user', array('id' => $post->userid)); 00291 } 00292 // add the user object on to the post so we can pass it to the leap writer if necessary 00293 $post->author = $users[$post->userid]; 00294 $viewfullnames = true; 00295 // format the post body 00296 $options = portfolio_format_text_options(); 00297 $format = $this->get('exporter')->get('format'); 00298 $formattedtext = format_text($post->message, $post->messageformat, $options, $this->get('course')->id); 00299 $formattedtext = portfolio_rewrite_pluginfile_urls($formattedtext, $this->modcontext->id, 'mod_forum', 'post', $post->id, $format); 00300 00301 $output = '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">'; 00302 00303 $output .= '<tr class="header"><td>';// can't print picture. 00304 $output .= '</td>'; 00305 00306 if ($post->parent) { 00307 $output .= '<td class="topic">'; 00308 } else { 00309 $output .= '<td class="topic starter">'; 00310 } 00311 $output .= '<div class="subject">'.format_string($post->subject).'</div>'; 00312 00313 $fullname = fullname($users[$post->userid], $viewfullnames); 00314 $by = new stdClass(); 00315 $by->name = $fullname; 00316 $by->date = userdate($post->modified, '', $this->user->timezone); 00317 $output .= '<div class="author">'.get_string('bynameondate', 'forum', $by).'</div>'; 00318 00319 $output .= '</td></tr>'; 00320 00321 $output .= '<tr><td class="left side" valign="top">'; 00322 00323 $output .= '</td><td class="content">'; 00324 00325 $output .= $formattedtext; 00326 00327 if (is_array($this->keyedfiles) && array_key_exists($post->id, $this->keyedfiles) && is_array($this->keyedfiles[$post->id]) && count($this->keyedfiles[$post->id]) > 0) { 00328 $output .= '<div class="attachments">'; 00329 $output .= '<br /><b>' . get_string('attachments', 'forum') . '</b>:<br /><br />'; 00330 foreach ($this->keyedfiles[$post->id] as $file) { 00331 $output .= $format->file_output($file) . '<br/ >'; 00332 } 00333 $output .= "</div>"; 00334 } 00335 00336 $output .= '</td></tr></table>'."\n\n"; 00337 00338 return $output; 00339 } 00343 function get_sha1() { 00344 $filesha = ''; 00345 try { 00346 $filesha = $this->get_sha1_file(); 00347 } catch (portfolio_caller_exception $e) { } // no files 00348 00349 if ($this->post) { 00350 return sha1($filesha . ',' . $this->post->subject . ',' . $this->post->message); 00351 } else { 00352 $sha1s = array($filesha); 00353 foreach ($this->posts as $post) { 00354 $sha1s[] = sha1($post->subject . ',' . $post->message); 00355 } 00356 return sha1(implode(',', $sha1s)); 00357 } 00358 } 00359 00360 function expected_time() { 00361 $filetime = $this->expected_time_file(); 00362 if ($this->posts) { 00363 $posttime = portfolio_expected_time_db(count($this->posts)); 00364 if ($filetime < $posttime) { 00365 return $posttime; 00366 } 00367 } 00368 return $filetime; 00369 } 00374 function check_permissions() { 00375 $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); 00376 if ($this->post) { 00377 return (has_capability('mod/forum:exportpost', $context) 00378 || ($this->post->userid == $this->user->id 00379 && has_capability('mod/forum:exportownpost', $context))); 00380 } 00381 return has_capability('mod/forum:exportdiscussion', $context); 00382 } 00386 public static function display_name() { 00387 return get_string('modulename', 'forum'); 00388 } 00389 00390 public static function base_supported_formats() { 00391 return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_RICHHTML, PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_LEAP2A); 00392 } 00393 }