Commit | Line | Data |
---|---|---|
516194d0 | 1 | <?php |
13d1c9ed JF |
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 | * Blog RSS Management | |
19 | * | |
20 | * @package core_blog | |
21 | * @category rss | |
22 | * @copyright 2010 Andrew Davis | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
f12d9aa8 SB |
25 | defined('MOODLE_INTERNAL') || die(); |
26 | ||
1c7b8b93 NC |
27 | require_once($CFG->dirroot.'/lib/rsslib.php'); |
28 | require_once($CFG->dirroot .'/blog/lib.php'); | |
516194d0 | 29 | |
13d1c9ed JF |
30 | /** |
31 | * Build the URL for the RSS feed | |
32 | * | |
33 | * @param int $contextid The context under which the URL should be created | |
34 | * @param int $userid The id of the user requesting the RSS Feed | |
35 | * @param string $filtertype The source of the RSS feed (site/course/group/user) | |
36 | * @param int $filterselect The id of the item defined by $filtertype | |
37 | * @param int $tagid The id of the row in the tag table that identifies the RSS Feed | |
38 | * @return string | |
39 | */ | |
f0899a25 | 40 | function blog_rss_get_url($contextid, $userid, $filtertype, $filterselect = 0, $tagid = 0) { |
e858c368 | 41 | $componentname = 'blog'; |
6619a7f4 | 42 | |
e858c368 | 43 | $additionalargs = null; |
1c7b8b93 NC |
44 | switch ($filtertype) { |
45 | case 'site': | |
e858c368 | 46 | $additionalargs = 'site/'.SITEID; |
1c7b8b93 NC |
47 | break; |
48 | case 'course': | |
e858c368 | 49 | $additionalargs = 'course/'.$filterselect; |
1c7b8b93 NC |
50 | break; |
51 | case 'group': | |
e858c368 | 52 | $additionalargs = 'group/'.$filterselect; |
1c7b8b93 NC |
53 | break; |
54 | case 'user': | |
e858c368 | 55 | $additionalargs = 'user/'.$filterselect; |
1c7b8b93 NC |
56 | break; |
57 | } | |
6619a7f4 | 58 | |
1c7b8b93 | 59 | if ($tagid) { |
e858c368 AD |
60 | $additionalargs .= '/'.$tagid; |
61 | } | |
62 | ||
63 | return rss_get_url($contextid, $userid, $componentname, $additionalargs); | |
64 | } | |
65 | ||
13d1c9ed JF |
66 | /** |
67 | * Print the link for the RSS feed with the correct RSS icon (Theme based) | |
68 | * | |
69 | * @param stdClass $context The context under which the URL should be created | |
70 | * @param string $filtertype The source of the RSS feed (site/course/group/user) | |
71 | * @param int $filterselect The id of the item defined by $filtertype | |
72 | * @param int $tagid The id of the row in the tag table that identifies the RSS Feed | |
73 | * @param string $tooltiptext The tooltip to be displayed with the link | |
74 | */ | |
f0899a25 | 75 | function blog_rss_print_link($context, $filtertype, $filterselect = 0, $tagid = 0, $tooltiptext = '') { |
e858c368 AD |
76 | global $CFG, $USER, $OUTPUT; |
77 | ||
78 | if (!isloggedin()) { | |
79 | $userid = $CFG->siteguest; | |
80 | } else { | |
81 | $userid = $USER->id; | |
1c7b8b93 | 82 | } |
6619a7f4 | 83 | |
e858c368 | 84 | $url = blog_rss_get_url($context->id, $userid, $filtertype, $filterselect, $tagid); |
d3d2f09c DW |
85 | $rsspix = $OUTPUT->pix_icon('i/rss', get_string('rss'), 'core', array('title' => $tooltiptext)); |
86 | print '<div class="pull-xs-right"><a href="'. $url .'">' . $rsspix . '</a></div>'; | |
e858c368 | 87 | } |
516194d0 | 88 | |
13d1c9ed JF |
89 | /** |
90 | * Build the URL for the RSS feed amd add it as a header | |
91 | * | |
92 | * @param stdClass $context The context under which the URL should be created | |
93 | * @param string $title Name for the link to be added to the page header | |
94 | * @param string $filtertype The source of the RSS feed (site/course/group/user) | |
95 | * @param int $filterselect The id of the item defined by $filtertype | |
96 | * @param int $tagid The id of the row in the tag table that identifies the RSS Feed | |
97 | */ | |
f0899a25 | 98 | function blog_rss_add_http_header($context, $title, $filtertype, $filterselect = 0, $tagid = 0) { |
e858c368 | 99 | global $PAGE, $USER, $CFG; |
516194d0 | 100 | |
e858c368 AD |
101 | if (!isloggedin()) { |
102 | $userid = $CFG->siteguest; | |
103 | } else { | |
104 | $userid = $USER->id; | |
105 | } | |
106 | ||
107 | $rsspath = blog_rss_get_url($context->id, $userid, $filtertype, $filterselect, $tagid); | |
108 | $PAGE->add_alternate_version($title, $rsspath, 'application/rss+xml'); | |
109 | } | |
110 | ||
111 | /** | |
112 | * Utility function to extract parameters needed to generate RSS URLs from the blog filters | |
13d1c9ed JF |
113 | * |
114 | * @param array $filters filters for the blog | |
115 | * @return array array containing the id of the user/course/group, the relevant context and the filter type: site/user/course/group | |
e858c368 AD |
116 | */ |
117 | function blog_rss_get_params($filters) { | |
118 | $thingid = $rsscontext = $filtertype = null; | |
119 | ||
41b38360 | 120 | $sitecontext = context_system::instance(); |
fd7a6fe2 | 121 | |
e858c368 AD |
122 | if (!$filters) { |
123 | $thingid = SITEID; | |
e858c368 AD |
124 | $filtertype = 'site'; |
125 | } else if (array_key_exists('course', $filters)) { | |
126 | $thingid = $filters['course']; | |
e858c368 AD |
127 | $filtertype = 'course'; |
128 | } else if (array_key_exists('user', $filters)) { | |
129 | $thingid = $filters['user']; | |
e858c368 AD |
130 | $filtertype = 'user'; |
131 | } else if (array_key_exists('group', $filters)) { | |
132 | $thingid = $filters['group']; | |
e858c368 AD |
133 | $filtertype = 'group'; |
134 | } | |
135 | ||
136 | return array($thingid, $rsscontext, $filtertype); | |
1c7b8b93 | 137 | } |
516194d0 | 138 | |
13d1c9ed JF |
139 | /** |
140 | * Generate any blog RSS feed via one function | |
141 | * | |
142 | * @param stdClass $context The context of the blog for which the feed it being generated | |
143 | * @param array $args An array of arguements needed to build the feed (contextid, token, componentname, type, id, tagid) | |
144 | */ | |
274f9840 | 145 | function blog_rss_get_feed($context, $args) { |
1c7b8b93 | 146 | global $CFG, $SITE, $DB; |
ebb73f49 | 147 | |
fe7e411e DM |
148 | if (empty($CFG->enableblogs)) { |
149 | debugging('Blogging disabled on this site, RSS feeds are not available'); | |
150 | return null; | |
151 | } | |
152 | ||
274f9840 AD |
153 | if (empty($CFG->enablerssfeeds)) { |
154 | debugging('Sorry, RSS feeds are disabled on this site'); | |
155 | return ''; | |
156 | } | |
157 | ||
21c3b51e JF |
158 | if ($CFG->bloglevel == BLOG_SITE_LEVEL) { |
159 | if (isguestuser()) { | |
2b6e53e8 | 160 | debugging(get_string('nopermissiontoshow', 'error')); |
21c3b51e JF |
161 | return ''; |
162 | } | |
163 | } | |
164 | ||
41b38360 | 165 | $sitecontext = context_system::instance(); |
274f9840 AD |
166 | if (!has_capability('moodle/blog:view', $sitecontext)) { |
167 | return null; | |
168 | } | |
690aa229 | 169 | |
5ce534eb | 170 | $type = clean_param($args[3], PARAM_ALPHA); |
2b6e53e8 | 171 | $id = clean_param($args[4], PARAM_INT); // Could be groupid / courseid / userid depending on $type. |
690aa229 | 172 | |
0e32a565 | 173 | $tagid = 0; |
690aa229 | 174 | if ($args[5] != 'rss.xml') { |
5ce534eb | 175 | $tagid = clean_param($args[5], PARAM_INT); |
690aa229 AD |
176 | } else { |
177 | $tagid = 0; | |
178 | } | |
179 | ||
1c7b8b93 | 180 | $filename = blog_rss_file_name($type, $id, $tagid); |
6619a7f4 | 181 | |
1c7b8b93 NC |
182 | if (file_exists($filename)) { |
183 | if (filemtime($filename) + 3600 > time()) { | |
2b6e53e8 | 184 | return $filename; // It's already done so we return cached version. |
6619a7f4 | 185 | } |
1c7b8b93 | 186 | } |
6619a7f4 | 187 | |
451f1e38 AD |
188 | $courseid = $groupid = $userid = null; |
189 | switch ($type) { | |
190 | case 'site': | |
451f1e38 AD |
191 | break; |
192 | case 'course': | |
193 | $courseid = $id; | |
194 | break; | |
195 | case 'group': | |
196 | $groupid = $id; | |
197 | break; | |
198 | case 'user': | |
199 | $userid = $id; | |
200 | break; | |
201 | } | |
202 | ||
2b6e53e8 | 203 | // Get all the entries from the database. |
e858c368 | 204 | require_once($CFG->dirroot .'/blog/locallib.php'); |
451f1e38 AD |
205 | $blogheaders = blog_get_headers($courseid, $groupid, $userid, $tagid); |
206 | ||
e858c368 AD |
207 | $bloglisting = new blog_listing($blogheaders['filters']); |
208 | $blogentries = $bloglisting->get_entries(); | |
1c7b8b93 | 209 | |
2b6e53e8 | 210 | // Now generate an array of RSS items. |
1c7b8b93 NC |
211 | if ($blogentries) { |
212 | $items = array(); | |
2b6e53e8 | 213 | foreach ($blogentries as $blogentry) { |
f8b56ac9 | 214 | $item = new stdClass(); |
2b6e53e8 AD |
215 | $item->author = fullname($DB->get_record('user', array('id' => $blogentry->userid))); // TODO: this is slow. |
216 | $item->title = $blogentry->subject; | |
217 | $item->pubdate = $blogentry->lastmodified; | |
218 | $item->link = $CFG->wwwroot.'/blog/index.php?entryid='.$blogentry->id; | |
219 | $summary = file_rewrite_pluginfile_urls($blogentry->summary, 'pluginfile.php', | |
220 | $sitecontext->id, 'blog', 'post', $blogentry->id); | |
221 | $item->description = format_text($summary, $blogentry->format); | |
abea2c5d MG |
222 | if ($blogtags = core_tag_tag::get_item_tags_array('core', 'post', $blogentry->id)) { |
223 | $item->tags = $blogtags; | |
1c7b8b93 | 224 | $item->tagscheme = $CFG->wwwroot . '/tag'; |
ebb73f49 | 225 | } |
1c7b8b93 | 226 | $items[] = $item; |
516194d0 | 227 | } |
2b6e53e8 | 228 | $articles = rss_add_items($items); // Change structure to XML. |
1c7b8b93 NC |
229 | } else { |
230 | $articles = ''; | |
231 | } | |
516194d0 | 232 | |
2b6e53e8 | 233 | // Get header and footer information. |
dba2764d | 234 | |
1c7b8b93 NC |
235 | switch ($type) { |
236 | case 'user': | |
f8b56ac9 | 237 | $info = fullname($DB->get_record('user', array('id' => $id), get_all_user_name_fields(true))); |
1c7b8b93 NC |
238 | break; |
239 | case 'course': | |
0e32a565 | 240 | $info = $DB->get_field('course', 'fullname', array('id' => $id)); |
41b38360 | 241 | $info = format_string($info, true, array('context' => context_course::instance($id))); |
1c7b8b93 NC |
242 | break; |
243 | case 'site': | |
41b38360 | 244 | $info = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID))); |
1c7b8b93 NC |
245 | break; |
246 | case 'group': | |
9250bf81 | 247 | $group = groups_get_group($id); |
0e32a565 | 248 | $info = $group->name; // TODO: $DB->get_field('groups', 'name', array('id' => $id)). |
1c7b8b93 NC |
249 | break; |
250 | default: | |
251 | $info = ''; | |
252 | break; | |
253 | } | |
516194d0 | 254 | |
1c7b8b93 | 255 | if ($tagid) { |
0e32a565 | 256 | $info .= ': '.$DB->get_field('tags', 'text', array('id' => $tagid)); |
1c7b8b93 | 257 | } |
cae83708 | 258 | |
2b6e53e8 | 259 | $header = rss_standard_header(get_string($type.'blog', 'blog', $info), |
1c7b8b93 | 260 | $CFG->wwwroot.'/blog/index.php', |
2b6e53e8 | 261 | get_string('intro', 'blog')); |
516194d0 | 262 | |
1c7b8b93 | 263 | $footer = rss_standard_footer(); |
516194d0 | 264 | |
e858c368 | 265 | // Save the XML contents to file. |
1c7b8b93 | 266 | $rssdata = $header.$articles.$footer; |
2b6e53e8 | 267 | if (blog_rss_save_file($type, $id, $tagid, $rssdata)) { |
1c7b8b93 NC |
268 | return $filename; |
269 | } else { | |
2b6e53e8 | 270 | return false; // Couldn't find it or make it. |
516194d0 | 271 | } |
1c7b8b93 | 272 | } |
516194d0 | 273 | |
13d1c9ed JF |
274 | /** |
275 | * Retrieve the location and file name of a cached RSS feed | |
276 | * | |
277 | * @param string $type The source of the RSS feed (site/course/group/user) | |
278 | * @param int $id The id of the item defined by $type | |
279 | * @param int $tagid The id of the row in the tag table that identifies the RSS Feed | |
280 | * @return string | |
281 | */ | |
f0899a25 | 282 | function blog_rss_file_name($type, $id, $tagid = 0) { |
1c7b8b93 | 283 | global $CFG; |
516194d0 | 284 | |
1c7b8b93 | 285 | if ($tagid) { |
365bec4c | 286 | return "$CFG->cachedir/rss/blog/$type/$id/$tagid.xml"; |
1c7b8b93 | 287 | } else { |
365bec4c | 288 | return "$CFG->cachedir/rss/blog/$type/$id.xml"; |
516194d0 | 289 | } |
1c7b8b93 | 290 | } |
cae83708 | 291 | |
13d1c9ed JF |
292 | /** |
293 | * This function saves to file the rss feed specified in the parameters | |
294 | * | |
295 | * @param string $type The source of the RSS feed (site/course/group/user) | |
296 | * @param int $id The id of the item defined by $type | |
297 | * @param int $tagid The id of the row in the tag table that identifies the RSS Feed | |
298 | * @param string $contents The contents of the RSS Feed file | |
299 | * @return bool whether the save was successful or not | |
300 | */ | |
f0899a25 | 301 | function blog_rss_save_file($type, $id, $tagid = 0, $contents = '') { |
1c7b8b93 | 302 | global $CFG; |
71904f4d | 303 | |
e858c368 | 304 | $status = true; |
516194d0 | 305 | |
2b6e53e8 | 306 | // Blog creates some additional dirs within the rss cache so make sure they all exist. |
5a87c912 TL |
307 | make_cache_directory('rss/blog'); |
308 | make_cache_directory('rss/blog/'.$type); | |
ebb73f49 | 309 | |
71904f4d | 310 | $filename = blog_rss_file_name($type, $id, $tagid); |
2b6e53e8 | 311 | $expandfilename = false; // We are supplying a full file path. |
71904f4d | 312 | $status = rss_save_file('blog', $filename, $contents, $expandfilename); |
e858c368 | 313 | |
1c7b8b93 NC |
314 | return $status; |
315 | } | |
316 | ||
54eb02a4 AD |
317 | /** |
318 | * Delete the supplied user's cached blog post RSS feed. | |
319 | * Only user blogs are available by RSS. | |
320 | * This doesn't call rss_delete_file() as blog RSS caching uses it's own file structure. | |
321 | * | |
322 | * @param int $userid | |
323 | */ | |
324 | function blog_rss_delete_file($userid) { | |
325 | $filename = blog_rss_file_name('user', $userid); | |
326 | if (file_exists($filename)) { | |
327 | unlink($filename); | |
328 | } | |
329 | } | |
330 |