MDL-23391 rss cache is now inside the dataroot/cache with the others, so it doesn...
[moodle.git] / mod / forum / rsslib.php
CommitLineData
1adbd2c3 1<?php
8adcb49f 2
8f685009
SH
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/**
fcce139a
AD
19* This file adds support to rss feeds generation
20*
21* @package mod-forum
22* @copyright 2001 Eloy Lafuente (stronk7) http://contiento.com
23* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24*/
25
26/**
27 * Returns the path to the cached rss feed contents. Creates/updates the cache if necessary.
28 * @global object $CFG
29 * @global object $DB
30 * @param object $context the context
31 * @param int $forumid the ID of the forum
fcce139a
AD
32 * @param array $args the arguments received in the url
33 * @return string the full path to the cached RSS feed directory. Null if there is a problem.
8f685009 34 */
274f9840 35function forum_rss_get_feed($context, $args) {
fcce139a 36 global $CFG, $DB;
8f685009 37
fcce139a 38 $status = true;
8adcb49f 39
fcce139a
AD
40 //are RSS feeds enabled?
41 if (empty($CFG->forum_enablerssfeeds)) {
42 debugging('DISABLED (module configuration)');
43 return null;
44 }
8adcb49f 45
274f9840 46 if (!is_enrolled($context, null, 'mod/forum:viewdiscussion')) {
fcce139a
AD
47 return null;
48 }
8adcb49f 49
274f9840 50 $forumid = $args[3];
fcce139a
AD
51 $forum = $DB->get_record('forum', array('id' => $forumid), '*', MUST_EXIST);
52
53 if (!rss_enabled('forum', $forum)) {
54 return null;
8adcb49f 55 }
56
274f9840
AD
57 $cm = get_coursemodule_from_instance('forum', $forumid, 0, false, MUST_EXIST);
58
fcce139a
AD
59 //the sql that will retreive the data for the feed and be hashed to get the cache filename
60 $sql = forum_rss_get_sql($forum, $cm);
83da3d28 61
fcce139a
AD
62 //hash the sql to get the cache file name
63 $filename = rss_get_file_name($forum, $sql);
64 $cachedfilepath = rss_get_file_full_name('forum', $filename);
65
66 //Is the cache out of date?
67 $cachedfilelastmodified = 0;
68 if (file_exists($cachedfilepath)) {
69 $cachedfilelastmodified = filemtime($cachedfilepath);
70 }
71 if (forum_rss_newstuff($forum, $cm, $cachedfilelastmodified)) {
72 //need to regenerate the cached version
73 $result = forum_rss_feed_contents($forum, $sql);
74 if (!empty($result)) {
75 $status = rss_save_file('forum',$filename,$result);
83da3d28 76 }
77 }
78
fcce139a
AD
79 //return the path to the cached version
80 return $cachedfilepath;
81}
83da3d28 82
fcce139a
AD
83/**
84 * Given a forum object, deletes all cached RSS files associated with it.
85 *
86 * @param object $forum
87 * @return void
88 */
89function forum_rss_delete_file($forum) {
90 rss_delete_file('forum', $forum);
91}
92
93///////////////////////////////////////////////////////
94//Utility functions
95
96/**
97 * If there is new stuff in the forum since $time this returns true
98 * Otherwise it returns false.
99 *
100 * @param object $forum the forum object
101 * @param object $cm
102 * @param int $time timestamp
103 * @return bool
104 */
105function forum_rss_newstuff($forum, $cm, $time) {
106 global $DB;
107
108 $sql = forum_rss_get_sql($forum, $cm, $time);
109
110 $recs = $DB->get_records_sql($sql, null, 0, 1);//limit of 1. If we get even 1 back we have new stuff
111 return ($recs && !empty($recs));
112}
113
114function forum_rss_get_sql($forum, $cm, $time=0) {
115 $sql = null;
116
117 if (!empty($forum->rsstype)) {
118 if ($forum->rsstype == 1) { //Discussion RSS
119 $sql = forum_rss_feed_discussions_sql($forum, $cm, $time);
120 } else { //Post RSS
121 $sql = forum_rss_feed_posts_sql($forum, $cm, $time);
6069e206 122 }
6069e206 123 }
124
fcce139a
AD
125 return $sql;
126}
8f0cd6ef 127
fcce139a
AD
128function forum_rss_feed_discussions_sql($forum, $cm, $newsince=0) {
129 global $CFG, $DB, $USER;
130
131 $timelimit = '';
132
133 $modcontext = null;
134
135 $now = round(time(), -2);
136 $params = array($cm->instance);
137
138 $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
139
140 if (!empty($CFG->forum_enabletimedposts)) { /// Users must fulfill timed posts
141 if (!has_capability('mod/forum:viewhiddentimedposts', $modcontext)) {
142 $timelimit = " AND ((d.timestart <= :now1 AND (d.timeend = 0 OR d.timeend > :now2))";
143 $params['now1'] = $now;
144 $params['now2'] = $now;
145 if (isloggedin()) {
146 $timelimit .= " OR d.userid = :userid";
147 $params['userid'] = $USER->id;
8adcb49f 148 }
fcce139a 149 $timelimit .= ")";
8adcb49f 150 }
8adcb49f 151 }
152
fcce139a
AD
153 //do we only want new posts?
154 if ($newsince) {
155 $newsince = " AND p.modified > '$newsince'";
156 } else {
157 $newsince = '';
158 }
8adcb49f 159
fcce139a
AD
160 //get group enforcing SQL
161 $groupmode = groups_get_activity_groupmode($cm);
162 $currentgroup = groups_get_activity_group($cm);
163 $groupselect = forum_rss_get_group_sql($cm, $groupmode, $currentgroup, $modcontext);
8adcb49f 164
fcce139a
AD
165 if ($groupmode && $currentgroup) {
166 $params['groupid'] = $currentgroup;
167 }
8adcb49f 168
fcce139a
AD
169 $forumsort = "d.timemodified DESC";
170 $postdata = "p.id, p.subject, p.created as postcreated, p.modified, p.discussion, p.userid, p.message as postmessage, p.messageformat AS postformat, p.messagetrust AS posttrust";
171
172 $sql = "SELECT $postdata, d.id as discussionid, d.name as discussionname, d.timemodified, d.usermodified, d.groupid, d.timestart, d.timeend,
173 u.firstname as userfirstname, u.lastname as userlastname, u.email, u.picture, u.imagealt
174 FROM {forum_discussions} d
175 JOIN {forum_posts} p ON p.discussion = d.id
176 JOIN {user} u ON p.userid = u.id
177 WHERE d.forum = {$forum->id} AND p.parent = 0
178 $timelimit $groupselect $newsince
179 ORDER BY $forumsort";
180 return $sql;
181}
182
183function forum_rss_feed_posts_sql($forum, $cm, $newsince=0) {
184 $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
185
186 //get group enforcement SQL
187 $groupmode = groups_get_activity_groupmode($cm);
188 $currentgroup = groups_get_activity_group($cm);
189
190 $groupselect = forum_rss_get_group_sql($cm, $groupmode, $currentgroup, $modcontext);
191
192 if ($groupmode && $currentgroup) {
193 $params['groupid'] = $currentgroup;
194 }
6069e206 195
fcce139a
AD
196 //do we only want new posts?
197 if ($newsince) {
198 $newsince = " AND p.modified > '$newsince'";
199 } else {
200 $newsince = '';
201 }
ec41cb3c 202
fcce139a
AD
203 $sql = "SELECT p.id AS postid,
204 d.id AS discussionid,
205 d.name AS discussionname,
206 u.id AS userid,
207 u.firstname AS userfirstname,
208 u.lastname AS userlastname,
209 p.subject AS postsubject,
210 p.message AS postmessage,
211 p.created AS postcreated,
212 p.messageformat AS postformat,
213 p.messagetrust AS posttrust
214 FROM {forum_discussions} d,
215 {forum_posts} p,
216 {user} u
217 WHERE d.forum = {$forum->id} AND
218 p.discussion = d.id AND
219 u.id = p.userid $newsince
220 $groupselect
221 ORDER BY p.created desc";
222
223 return $sql;
224}
225
226function forum_rss_get_group_sql($cm, $groupmode, $currentgroup, $modcontext=null) {
227 $groupselect = '';
228
229 if ($groupmode) {
230 if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $modcontext)) {
231 if ($currentgroup) {
232 $groupselect = "AND (d.groupid = :groupid OR d.groupid = -1)";
233 $params['groupid'] = $currentgroup;
234 }
235 } else {
236 //seprate groups without access all
237 if ($currentgroup) {
238 $groupselect = "AND (d.groupid = :groupid OR d.groupid = -1)";
239 $params['groupid'] = $currentgroup;
240 } else {
241 $groupselect = "AND d.groupid = -1";
8adcb49f 242 }
243 }
8adcb49f 244 }
8f0cd6ef 245
fcce139a
AD
246 return $groupselect;
247}
8adcb49f 248
8adcb49f 249
fcce139a 250
8adcb49f 251
fcce139a
AD
252/**
253 * This function return the XML rss contents about the forum
254 * It returns false if something is wrong
255 *
256 * @param object $forum
257 * @param bool
258 */
259function forum_rss_feed_contents($forum, $sql) {
260 global $CFG, $DB;
6069e206 261
fcce139a
AD
262 $status = true;
263
264 $params = array();
265 //$params['forumid'] = $forum->id;
266 $recs = $DB->get_recordset_sql($sql, $params, 0, $forum->rssarticles);
267
268 //set a flag. Are we displaying discussions or posts?
269 $isdiscussion = true;
270 if (!empty($forum->rsstype) && $forum->rsstype!=1) {
271 $isdiscussion = false;
272 }
318f2100 273
fcce139a
AD
274 $formatoptions = new object;
275 $items = array();
276 foreach ($recs as $rec) {
277 unset($item);
278 unset($user);
279 $item->title = format_string($rec->discussionname);
280 $user->firstname = $rec->userfirstname;
281 $user->lastname = $rec->userlastname;
282 $item->author = fullname($user);
283 $item->pubdate = $rec->postcreated;
284 if ($isdiscussion) {
285 $item->link = $CFG->wwwroot."/mod/forum/discuss.php?d=".$rec->discussionid;
286 } else {
8f0cd6ef 287 $item->link = $CFG->wwwroot."/mod/forum/discuss.php?d=".$rec->discussionid."&parent=".$rec->postid;
fcce139a 288 }
410a24c0 289
fcce139a
AD
290 $formatoptions->trusted = $rec->posttrust;
291 $item->description = format_text($rec->postmessage,$rec->postformat,$formatoptions,$forum->course);
410a24c0 292
fcce139a
AD
293 //TODO: implement post attachment handling
294 /*if (!$isdiscussion) {
318f2100 295 $post_file_area_name = str_replace('//', '/', "$forum->course/$CFG->moddata/forum/$forum->id/$rec->postid");
410a24c0 296 $post_files = get_directory_list("$CFG->dataroot/$post_file_area_name");
4e445355 297
298 if (!empty($post_files)) {
410a24c0 299 $item->attachments = array();
410a24c0 300 }
fcce139a
AD
301 }*/
302
303 $items[] = $item;
304 }
305 $recs->close();
410a24c0 306
fcce139a
AD
307
308 if (!empty($items)) {
309 //First the RSS header
310 $header = rss_standard_header(strip_tags(format_string($forum->name,true)),
311 $CFG->wwwroot."/mod/forum/view.php?f=".$forum->id,
312 format_string($forum->intro,true)); // TODO: fix format
313 //Now all the rss items
314 if (!empty($header)) {
315 $articles = rss_add_items($items);
316 }
317 //Now the RSS footer
318 if (!empty($header) && !empty($articles)) {
319 $footer = rss_standard_footer();
8adcb49f 320 }
fcce139a
AD
321 //Now, if everything is ok, concatenate it
322 if (!empty($header) && !empty($articles) && !empty($footer)) {
323 $status = $header.$articles.$footer;
324 } else {
325 $status = false;
326 }
327 } else {
328 $status = false;
329 }
330
331 return $status;
332}