Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 421 lines (372 sloc) 14.379 kb
60812eb @sammarshallou Initial public release
sammarshallou authored
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 * Represents a draft forum post (reply or discussion), as stored in the
19 * forumng_drafts database table.
20 * @see forum
21 * @package mod
22 * @subpackage forumng
23 * @copyright 2011 The Open University
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26 class mod_forumng_draft {
27 private $draftfields;
28
29 /**
30 * Queries for draft posts, including necessary joins with other fields.
31 * @param string $where Text of WHERE clause e.g. 'fdr.id=14'. May refer
32 * to aliases fdr (drafts), fd (discussions), fp (posts; post being
33 * replied to), fpfirst (first post in discussion), and u (user being
34 * replied to)
35 * @return array Array of mod_forumng_draft objects (empty if none)
36 */
37 static function query_drafts($where, $whereparams) {
38 global $DB;
39 $result = array();
40 $rs = $DB->get_recordset_sql("
41 SELECT
42 fdr.*, fd.id AS discussionid, fpfirst.subject AS discussionsubject,
43 f.course AS courseid,
44 " . mod_forumng_utils::select_username_fields('u', false) . "
45 FROM
46 {forumng_drafts} fdr
47 LEFT JOIN {forumng_posts} fp ON fdr.parentpostid = fp.id
48 LEFT JOIN {forumng_discussions} fd ON fp.discussionid = fd.id
49 LEFT JOIN {forumng_posts} fpfirst ON fd.postid = fpfirst.id
50 LEFT JOIN {user} u ON fp.userid = u.id
51 INNER JOIN {forumng} f ON fdr.forumngid = f.id
52 WHERE
53 $where
54 ORDER BY
55 fdr.saved DESC", $whereparams);
56 foreach ($rs as $rec) {
57 $result[] = new mod_forumng_draft($rec);
58 }
59 $rs->close();
60 return $result;
61 }
62
63 /**
64 * @param int $draftid ID of draft
65 * @return mod_forumng_draft Draft post
66 */
67 public static function get_from_id($draftid) {
68 $posts = self::query_drafts("fdr.id = ?", array($draftid));
69 if (count($posts) == 0) {
a53a02e @sammarshallou ForumNG: Improved error message when draft post not found #1818
sammarshallou authored
70 throw new moodle_exception('error_draftnotfound', 'forumng', '');
60812eb @sammarshallou Initial public release
sammarshallou authored
71 }
72 return reset($posts);
73 }
74
75 /**
76 * Constructs draft post.
77 * @param object $draftfields Fields from query_drafts query
78 */
79 private function __construct($draftfields) {
80 $draftfields->replytouser =
81 mod_forumng_utils::extract_subobject($draftfields, 'u_');
82 $this->draftfields = $draftfields;
83 }
84
85 /**
86 * Saves a new draft message.
87 * @param int $forumngid ID of forum
88 * @param int $groupid Group ID (null if none)
89 * @param int $parentpostid ID of post this is in reply to, or 0 for
90 * a new discussion
91 * @param string $subject Subject of draft post
92 * @param string $message Message of draft post
93 * @param int $messageformat Format (FORMAT_xx) of message
94 * @param bool $attachments True if draft contains attachments
95 * @param string $options Options (null if none)
96 * @param int $userid User ID or 0 for current
97 * @return int ID of new draft
98 */
99 static function save_new($forum, $groupid, $parentpostid, $subject,
100 $message, $messageformat, $attachments, $options, $userid=0) {
101 global $DB;
102 $userid = mod_forumng_utils::get_real_userid($userid);
103 $serializedoptions = $options ? serialize($options) : null;
104 $record = (object)array('userid' => $userid, 'forumngid' => $forum->get_id(),
105 'parentpostid' => ($parentpostid ? $parentpostid : null),
106 'subject' => $subject, 'message' => $message,
107 'messageformat' => $messageformat,
108 'attachments' => $attachments ? 1 : 0,
109 'saved' => time(), 'groupid' => $groupid, 'options' => $serializedoptions);
110 return $DB->insert_record('forumng_drafts', $record);
111 }
112
113 /**
114 * Updates the message field of a draft entry. This is necessary in some cases where
115 * the user includes images etc. in the message; these are initially included using
116 * a draft URL which has to be changed to a special relative path on convert, and we
117 * can't do that until the draft ID is known. Additionally, we don't have a draft object
118 * at that point, hence use of static function.
119 * @param int $draftid ID of draft to update
120 * @param string $newtext Updated message text
121 */
122 public static function update_message_for_files($draftid, $newtext) {
123 global $DB;
124 $DB->set_field('forumng_drafts', 'message', $newtext, array('id'=>$draftid));
125 }
126
127 /**
128 * Updates an existing draft message.
129 * @param string $subject Subject of draft post
130 * @param string $message Message of draft post
131 * @param int $messageformat Format (FORMAT_xx) of message
132 * @param bool $attachments True if draft now has attachments
133 * @param int $groupid Group ID (null if none)
134 * @param object $options Options (null if none)
135 */
136 function update($subject, $message,
137 $messageformat, $attachments, $groupid, $options) {
138 global $DB;
139
140 $serializedoptions = $options ? serialize($options) : null;
141
142 $record = (object)array(
143 'id' => $this->get_id(),
144 'subject' => $subject, 'message' => $message,
145 'messageformat' => $messageformat, 'attachments' => $attachments ? 1 : 0,
146 'groupid' => $groupid, 'options' => $serializedoptions, 'saved' => time());
147
148 // Do database update
149 $DB->update_record('forumng_drafts', $record);
150 }
151
152 /**
153 * Deletes an existing draft message.
154 * @param object $filecontext Context used for files (=forum context)
155 */
156 function delete($filecontext) {
157 global $DB;
158 $transaction = $DB->start_delegated_transaction();
159
160 // Delete record
161 $DB->delete_records('forumng_drafts', array('id' => $this->draftfields->id));
162
163 // Delete attachments
164 $fs = get_file_storage();
165 if ($this->has_attachments()) {
166 $fs->delete_area_files($filecontext->id, 'mod_forumng', 'draft', $this->get_id());
167 }
168
169 // Delete message files
170 $fs->delete_area_files($filecontext->id, 'mod_forumng', 'draftmessage', $this->get_id());
171
172 $transaction->allow_commit();
173 }
174
175 // Direct fields
176 ////////////////
177
178 /**
179 * @return int ID of this draft
180 */
181 function get_id() {
182 return $this->draftfields->id;
183 }
184
185 /**
186 * @return int ID of user making draft
187 */
188 function get_user_id() {
189 return $this->draftfields->userid;
190 }
191
192 /**
193 * @return int ID of forum containing draft
194 */
195 function get_forumng_id() {
196 return $this->draftfields->forumngid;
197 }
198
199 /**
200 * @return int Time (seconds since epoch) this draft was saved
201 */
202 function get_saved() {
203 return $this->draftfields->saved;
204 }
205
206 /**
207 * @return string Message subject
208 */
209 function get_subject() {
210 return $this->draftfields->subject;
211 }
212
213 /**
214 * @return string Message content
215 */
216 function get_raw_message() {
217 return $this->draftfields->message;
218 }
219
220 /**
221 * @param mod_forumng $forum Forum object
222 * @return string Message after format_text and replacing file URLs
223 */
224 public function get_formatted_message($forum) {
225 $text = file_rewrite_pluginfile_urls($this->draftfields->message, 'pluginfile.php',
226 $forum->get_context(true)->id, 'mod_forumng', 'draftmessage', $this->draftfields->id);
227 $textoptions = new stdClass();
228 // Don't put a <p> tag round post
229 $textoptions->para = false;
230 // Does not indicate that we trust the text, only that the
231 // TRUSTTEXT marker would be supported. At present though it isn't (hm)
232 $textoptions->trusttext = false;
233 return format_text($text, $this->draftfields->messageformat, $textoptions,
234 $forum->get_course_id());
235 }
236
237 /**
238 * @return int Format (FORMAT_xx) of message content
239 */
240 function get_format() {
241 return $this->draftfields->messageformat;
242 }
243
244 /**
245 * @return object Options object (may be null)
246 */
247 function get_options() {
248 return $this->draftfields->options
249 ? unserialize($this->draftfields->options) : null;
250 }
251
252 // Discussion-related information from joins
253 ////////////////////////////////////////////
254
255 /**
256 * @return bool True if this is a new discussion, false if it's a reply
257 */
258 function is_new_discussion() {
259 return is_null($this->draftfields->discussionid);
260 }
261
262 /**
263 * @return bool True if this is a reply, false if it's a new discussion
264 */
265 function is_reply() {
266 return !is_null($this->draftfields->discussionid);
267 }
268
269 /**
270 * @return int ID of group for new discussion (this field is not set for
271 * replies)
272 */
273 function get_group_id() {
274 return $this->draftfields->groupid;
275 }
276
277 /**
278 * Utility function to check this draft is about a reply in an existing
279 * discussion.
280 * @throws mod_forumng_exception If this is a new discussion (so no id yet)
281 */
282 private function check_discussion_exists() {
283 if (!$this->draftfields->discussionid) {
284 throw new invalid_state_exception("Draft message does not have discussion");
285 }
286 }
287
288 /**
289 * @return int Discussion id
290 * @throws mod_forumng_exception If this is a new discussion (so no id yet)
291 */
292 function get_discussion_id() {
293 $this->check_discussion_exists();
294 return $this->draftfields->discussionid;
295 }
296
297 /**
298 * @return string Discussion subject
299 * @throws mod_forumng_exception If this is a new discussion
300 */
301 function get_discussion_subject() {
302 $this->check_discussion_exists();
303 return $this->draftfields->discussionsubject;
304 }
305
306 /**
307 * @return object Moodle user object (selected fields) for post being
308 * replied to
309 * @throws mod_forumng_exception If this is a new discussion
310 */
311 function get_reply_to_user() {
312 $this->check_discussion_exists();
313 return $this->draftfields->replytouser;
314 }
315
316 /**
317 * @return int Parent post that is being replied to
318 * @throws mod_forumng_exception If this is a new discussion
319 */
320 function get_parent_post_id() {
321 $this->check_discussion_exists();
322 return $this->draftfields->parentpostid;
323 }
324
325 // Attachments
326 ///////////////
327
328 /**
329 * @return bool True if this draft has any attachments
330 */
331 public function has_attachments() {
332 return $this->draftfields->attachments ? true : false;
333 }
334
335 /**
336 * Gets the names of all attachments (if any)
337 * @return array Array of attachment names (may be empty). Names only,
338 * not including path to attachment folder
339 */
340 public function get_attachment_names() {
341 $result = array();
342 if (!$this->has_attachments()) {
343 return $result;
344 }
345 $folder = $this->get_attachment_folder();
346 $handle = mod_forumng_utils::opendir($folder);
347 while (false !== ($name = readdir($handle))) {
348 if ($name != '.' && $name != '..') {
349 if (!is_dir("$folder/$name")) {
350 $result[] = $name;
351 }
352 }
353 }
354 closedir($handle);
355 sort($result);
356 return $result;
357 }
358
359 // UI
360 /////
361
362 /**
363 * Prints the content of this draft as a JavaScript variable (including
364 * surrounding script tag).
365 * @param mod_forumng $forum Forum object
366 * @return string HTML (including JS) code to place in page
367 */
368 public function prepare_edit_js($forum) {
369 global $USER;
370
371 // Copy fields
372 $fields = clone($this->draftfields);
373
374 // Prepare file areas
375 $fileoptions = array('subdirs'=>false, 'maxbytes'=>$forum->get_max_bytes());
376 $filecontext = $forum->get_context(true);
377
378 // Prepare draft area for attachments
379 $draftitemid = 0;
380 file_prepare_draft_area($draftitemid, $filecontext->id,
381 'mod_forumng', 'draft', $this->get_id(), $fileoptions);
382
383 // Prepare draft area for message files
384 $messagedraftitemid = 0;
385 $fields->message = file_prepare_draft_area($messagedraftitemid, $filecontext->id,
386 'mod_forumng', 'draftmessage', $this->get_id(), $fileoptions, $fields->message);
387
388 // Get list of files for main attachment area
389 $options = file_get_drafarea_files($draftitemid, '/');
390 $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
391 $fs = get_file_storage();
392 $files = $fs->get_area_files($usercontext->id, 'user', 'draft',
393 $options->itemid, 'id', false);
394 $options->filecount = count($files);
395 $fields->attachmentoptions = $options;
396
397 // Get list of files for message area
398 $messageoptions = file_get_drafarea_files($messagedraftitemid, '/');
399 $files = $fs->get_area_files($usercontext->id, 'user', 'draft',
400 $messageoptions->itemid, 'id', false);
401 $messageoptions->filecount = count($files);
402 $fields->messageoptions = $messageoptions;
403
404 // Unset things we don't need in JS
405 unset($fields->discussionid);
406 unset($fields->discussionsubject);
407 unset($fields->courseid);
408 unset($fields->replytouser);
409 unset($fields->options);
410 unset($fields->attachments);
411
412 // Add options
413 foreach ( (array)($this->get_options()) as $key=>$value) {
414 $fields->{$key} = $value;
415 }
416
417 return "<script type='text/javascript'>\n" .
418 "var forumng_draft = " . json_encode($fields) . ";\n</script>\n";
419 }
420 }
Something went wrong with that request. Please try again.