| 1 | efrain | 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 |  * 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 |  */
 | 
        
           |  |  | 25 | defined('MOODLE_INTERNAL') || die();
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 | require_once($CFG->dirroot.'/lib/rsslib.php');
 | 
        
           |  |  | 28 | require_once($CFG->dirroot .'/blog/lib.php');
 | 
        
           |  |  | 29 |   | 
        
           |  |  | 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 |  */
 | 
        
           |  |  | 40 | function blog_rss_get_url($contextid, $userid, $filtertype, $filterselect = 0, $tagid = 0) {
 | 
        
           |  |  | 41 |     $componentname = 'blog';
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 |     $additionalargs = null;
 | 
        
           |  |  | 44 |     switch ($filtertype) {
 | 
        
           |  |  | 45 |         case 'site':
 | 
        
           |  |  | 46 |             $additionalargs = 'site/'.SITEID;
 | 
        
           |  |  | 47 |         break;
 | 
        
           |  |  | 48 |         case 'course':
 | 
        
           |  |  | 49 |             $additionalargs = 'course/'.$filterselect;
 | 
        
           |  |  | 50 |         break;
 | 
        
           |  |  | 51 |         case 'group':
 | 
        
           |  |  | 52 |             $additionalargs = 'group/'.$filterselect;
 | 
        
           |  |  | 53 |         break;
 | 
        
           |  |  | 54 |         case 'user':
 | 
        
           |  |  | 55 |             $additionalargs = 'user/'.$filterselect;
 | 
        
           |  |  | 56 |         break;
 | 
        
           |  |  | 57 |     }
 | 
        
           |  |  | 58 |   | 
        
           |  |  | 59 |     if ($tagid) {
 | 
        
           |  |  | 60 |         $additionalargs .= '/'.$tagid;
 | 
        
           |  |  | 61 |     }
 | 
        
           |  |  | 62 |   | 
        
           |  |  | 63 |     return rss_get_url($contextid, $userid, $componentname, $additionalargs);
 | 
        
           |  |  | 64 | }
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 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 |  */
 | 
        
           |  |  | 75 | function blog_rss_print_link($context, $filtertype, $filterselect = 0, $tagid = 0, $tooltiptext = '') {
 | 
        
           |  |  | 76 |     global $CFG, $USER, $OUTPUT;
 | 
        
           |  |  | 77 |   | 
        
           |  |  | 78 |     if (!isloggedin()) {
 | 
        
           |  |  | 79 |         $userid = $CFG->siteguest;
 | 
        
           |  |  | 80 |     } else {
 | 
        
           |  |  | 81 |         $userid = $USER->id;
 | 
        
           |  |  | 82 |     }
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 |     $url = blog_rss_get_url($context->id, $userid, $filtertype, $filterselect, $tagid);
 | 
        
           |  |  | 85 |     $rsspix = $OUTPUT->pix_icon('i/rss', get_string('rss'), 'core', array('title' => $tooltiptext));
 | 
        
           |  |  | 86 |     print '<div class="float-sm-right"><a href="'. $url .'">' . $rsspix . '</a></div>';
 | 
        
           |  |  | 87 | }
 | 
        
           |  |  | 88 |   | 
        
           |  |  | 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 |  */
 | 
        
           |  |  | 98 | function blog_rss_add_http_header($context, $title, $filtertype, $filterselect = 0, $tagid = 0) {
 | 
        
           |  |  | 99 |     global $PAGE, $USER, $CFG;
 | 
        
           |  |  | 100 |   | 
        
           |  |  | 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
 | 
        
           |  |  | 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
 | 
        
           |  |  | 116 |  */
 | 
        
           |  |  | 117 | function blog_rss_get_params($filters) {
 | 
        
           |  |  | 118 |     $thingid = $rsscontext = $filtertype = null;
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |     $sitecontext = context_system::instance();
 | 
        
           |  |  | 121 |   | 
        
           |  |  | 122 |     if (!$filters) {
 | 
        
           |  |  | 123 |         $thingid = SITEID;
 | 
        
           |  |  | 124 |         $filtertype = 'site';
 | 
        
           |  |  | 125 |     } else if (array_key_exists('course', $filters)) {
 | 
        
           |  |  | 126 |         $thingid = $filters['course'];
 | 
        
           |  |  | 127 |         $filtertype = 'course';
 | 
        
           |  |  | 128 |     } else if (array_key_exists('user', $filters)) {
 | 
        
           |  |  | 129 |         $thingid = $filters['user'];
 | 
        
           |  |  | 130 |         $filtertype = 'user';
 | 
        
           |  |  | 131 |     } else if (array_key_exists('group', $filters)) {
 | 
        
           |  |  | 132 |         $thingid = $filters['group'];
 | 
        
           |  |  | 133 |         $filtertype = 'group';
 | 
        
           |  |  | 134 |     }
 | 
        
           |  |  | 135 |   | 
        
           |  |  | 136 |     return array($thingid, $rsscontext, $filtertype);
 | 
        
           |  |  | 137 | }
 | 
        
           |  |  | 138 |   | 
        
           |  |  | 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 |  */
 | 
        
           |  |  | 145 | function blog_rss_get_feed($context, $args) {
 | 
        
           |  |  | 146 |     global $CFG, $SITE, $DB;
 | 
        
           |  |  | 147 |   | 
        
           |  |  | 148 |     if (empty($CFG->enableblogs)) {
 | 
        
           |  |  | 149 |         debugging('Blogging disabled on this site, RSS feeds are not available');
 | 
        
           |  |  | 150 |         return null;
 | 
        
           |  |  | 151 |     }
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 |     if (empty($CFG->enablerssfeeds)) {
 | 
        
           |  |  | 154 |         debugging('Sorry, RSS feeds are disabled on this site');
 | 
        
           |  |  | 155 |         return '';
 | 
        
           |  |  | 156 |     }
 | 
        
           |  |  | 157 |   | 
        
           |  |  | 158 |     if ($CFG->bloglevel == BLOG_SITE_LEVEL) {
 | 
        
           |  |  | 159 |         if (isguestuser()) {
 | 
        
           |  |  | 160 |             debugging(get_string('nopermissiontoshow', 'error'));
 | 
        
           |  |  | 161 |             return '';
 | 
        
           |  |  | 162 |         }
 | 
        
           |  |  | 163 |     }
 | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 |     $sitecontext = context_system::instance();
 | 
        
           |  |  | 166 |     if (!has_capability('moodle/blog:view', $sitecontext)) {
 | 
        
           |  |  | 167 |         return null;
 | 
        
           |  |  | 168 |     }
 | 
        
           |  |  | 169 |   | 
        
           |  |  | 170 |     $type  = clean_param($args[3], PARAM_ALPHA);
 | 
        
           |  |  | 171 |     $id = clean_param($args[4], PARAM_INT);  // Could be groupid / courseid  / userid  depending on $type.
 | 
        
           |  |  | 172 |   | 
        
           |  |  | 173 |     $tagid = 0;
 | 
        
           |  |  | 174 |     if ($args[5] != 'rss.xml') {
 | 
        
           |  |  | 175 |         $tagid = clean_param($args[5], PARAM_INT);
 | 
        
           |  |  | 176 |     } else {
 | 
        
           |  |  | 177 |         $tagid = 0;
 | 
        
           |  |  | 178 |     }
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |     $filename = blog_rss_file_name($type, $id, $tagid);
 | 
        
           |  |  | 181 |   | 
        
           |  |  | 182 |     if (file_exists($filename)) {
 | 
        
           |  |  | 183 |         if (filemtime($filename) + 3600 > time()) {
 | 
        
           |  |  | 184 |             return $filename;   // It's already done so we return cached version.
 | 
        
           |  |  | 185 |         }
 | 
        
           |  |  | 186 |     }
 | 
        
           |  |  | 187 |   | 
        
           |  |  | 188 |     $courseid = $groupid = $userid = null;
 | 
        
           |  |  | 189 |     switch ($type) {
 | 
        
           |  |  | 190 |         case 'site':
 | 
        
           |  |  | 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 |   | 
        
           |  |  | 203 |     // Get all the entries from the database.
 | 
        
           |  |  | 204 |     require_once($CFG->dirroot .'/blog/locallib.php');
 | 
        
           |  |  | 205 |     $blogheaders = blog_get_headers($courseid, $groupid, $userid, $tagid);
 | 
        
           |  |  | 206 |   | 
        
           |  |  | 207 |     $bloglisting = new blog_listing($blogheaders['filters']);
 | 
        
           |  |  | 208 |     $blogentries = $bloglisting->get_entries();
 | 
        
           |  |  | 209 |   | 
        
           |  |  | 210 |     // Now generate an array of RSS items.
 | 
        
           |  |  | 211 |     if ($blogentries) {
 | 
        
           |  |  | 212 |         $items = array();
 | 
        
           |  |  | 213 |         foreach ($blogentries as $blogentry) {
 | 
        
           |  |  | 214 |             $item = new stdClass();
 | 
        
           |  |  | 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);
 | 
        
           |  |  | 222 |             if ($blogtags = core_tag_tag::get_item_tags_array('core', 'post', $blogentry->id)) {
 | 
        
           |  |  | 223 |                 $item->tags = $blogtags;
 | 
        
           |  |  | 224 |                 $item->tagscheme = $CFG->wwwroot . '/tag';
 | 
        
           |  |  | 225 |             }
 | 
        
           |  |  | 226 |             $items[] = $item;
 | 
        
           |  |  | 227 |         }
 | 
        
           |  |  | 228 |         $articles = rss_add_items($items);   // Change structure to XML.
 | 
        
           |  |  | 229 |     } else {
 | 
        
           |  |  | 230 |         $articles = '';
 | 
        
           |  |  | 231 |     }
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 |     // Get header and footer information.
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 |     switch ($type) {
 | 
        
           |  |  | 236 |         case 'user':
 | 
        
           |  |  | 237 |             $userfieldsapi = \core_user\fields::for_name();
 | 
        
           |  |  | 238 |             $info = fullname($DB->get_record('user', array('id' => $id),
 | 
        
           |  |  | 239 |                     $userfieldsapi->get_sql('', false, '', '', false)->selects));
 | 
        
           |  |  | 240 |             break;
 | 
        
           |  |  | 241 |         case 'course':
 | 
        
           |  |  | 242 |             $info = $DB->get_field('course', 'fullname', array('id' => $id));
 | 
        
           |  |  | 243 |             $info = format_string($info, true, array('context' => context_course::instance($id)));
 | 
        
           |  |  | 244 |             break;
 | 
        
           |  |  | 245 |         case 'site':
 | 
        
           |  |  | 246 |             $info = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
 | 
        
           |  |  | 247 |             break;
 | 
        
           |  |  | 248 |         case 'group':
 | 
        
           |  |  | 249 |             $group = groups_get_group($id);
 | 
        
           |  |  | 250 |             $info = $group->name; // TODO: $DB->get_field('groups', 'name', array('id' => $id)).
 | 
        
           |  |  | 251 |             break;
 | 
        
           |  |  | 252 |         default:
 | 
        
           |  |  | 253 |             $info = '';
 | 
        
           |  |  | 254 |             break;
 | 
        
           |  |  | 255 |     }
 | 
        
           |  |  | 256 |   | 
        
           |  |  | 257 |     if ($tagid) {
 | 
        
           |  |  | 258 |         $info .= ': '.$DB->get_field('tags', 'text', array('id' => $tagid));
 | 
        
           |  |  | 259 |     }
 | 
        
           |  |  | 260 |   | 
        
           |  |  | 261 |     $header = rss_standard_header(get_string($type.'blog', 'blog', $info),
 | 
        
           |  |  | 262 |                                   $CFG->wwwroot.'/blog/index.php',
 | 
        
           |  |  | 263 |                                   get_string('intro', 'blog'));
 | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 |     $footer = rss_standard_footer();
 | 
        
           |  |  | 266 |   | 
        
           |  |  | 267 |     // Save the XML contents to file.
 | 
        
           |  |  | 268 |     $rssdata = $header.$articles.$footer;
 | 
        
           |  |  | 269 |     if (blog_rss_save_file($type, $id, $tagid, $rssdata)) {
 | 
        
           |  |  | 270 |         return $filename;
 | 
        
           |  |  | 271 |     } else {
 | 
        
           |  |  | 272 |         return false;   // Couldn't find it or make it.
 | 
        
           |  |  | 273 |     }
 | 
        
           |  |  | 274 | }
 | 
        
           |  |  | 275 |   | 
        
           |  |  | 276 | /**
 | 
        
           |  |  | 277 |  * Retrieve the location and file name of a cached RSS feed
 | 
        
           |  |  | 278 |  *
 | 
        
           |  |  | 279 |  * @param string $type  The source of the RSS feed (site/course/group/user)
 | 
        
           |  |  | 280 |  * @param int    $id    The id of the item defined by $type
 | 
        
           |  |  | 281 |  * @param int    $tagid The id of the row in the tag table that identifies the RSS Feed
 | 
        
           |  |  | 282 |  * @return string
 | 
        
           |  |  | 283 |  */
 | 
        
           |  |  | 284 | function blog_rss_file_name($type, $id, $tagid = 0) {
 | 
        
           |  |  | 285 |     global $CFG;
 | 
        
           |  |  | 286 |   | 
        
           |  |  | 287 |     if ($tagid) {
 | 
        
           |  |  | 288 |         return "$CFG->cachedir/rss/blog/$type/$id/$tagid.xml";
 | 
        
           |  |  | 289 |     } else {
 | 
        
           |  |  | 290 |         return "$CFG->cachedir/rss/blog/$type/$id.xml";
 | 
        
           |  |  | 291 |     }
 | 
        
           |  |  | 292 | }
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 | /**
 | 
        
           |  |  | 295 |  * This function saves to file the rss feed specified in the parameters
 | 
        
           |  |  | 296 |  *
 | 
        
           |  |  | 297 |  * @param string $type     The source of the RSS feed (site/course/group/user)
 | 
        
           |  |  | 298 |  * @param int    $id       The id of the item defined by $type
 | 
        
           |  |  | 299 |  * @param int    $tagid    The id of the row in the tag table that identifies the RSS Feed
 | 
        
           |  |  | 300 |  * @param string $contents The contents of the RSS Feed file
 | 
        
           |  |  | 301 |  * @return bool whether the save was successful or not
 | 
        
           |  |  | 302 |  */
 | 
        
           |  |  | 303 | function blog_rss_save_file($type, $id, $tagid = 0, $contents = '') {
 | 
        
           |  |  | 304 |     global $CFG;
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 |     $status = true;
 | 
        
           |  |  | 307 |   | 
        
           |  |  | 308 |     // Blog creates some additional dirs within the rss cache so make sure they all exist.
 | 
        
           |  |  | 309 |     make_cache_directory('rss/blog');
 | 
        
           |  |  | 310 |     make_cache_directory('rss/blog/'.$type);
 | 
        
           |  |  | 311 |   | 
        
           |  |  | 312 |     $filename = blog_rss_file_name($type, $id, $tagid);
 | 
        
           |  |  | 313 |     $expandfilename = false; // We are supplying a full file path.
 | 
        
           |  |  | 314 |     $status = rss_save_file('blog', $filename, $contents, $expandfilename);
 | 
        
           |  |  | 315 |   | 
        
           |  |  | 316 |     return $status;
 | 
        
           |  |  | 317 | }
 | 
        
           |  |  | 318 |   | 
        
           |  |  | 319 | /**
 | 
        
           |  |  | 320 |  * Delete the supplied user's cached blog post RSS feed.
 | 
        
           |  |  | 321 |  * Only user blogs are available by RSS.
 | 
        
           |  |  | 322 |  * This doesn't call rss_delete_file() as blog RSS caching uses it's own file structure.
 | 
        
           |  |  | 323 |  *
 | 
        
           |  |  | 324 |  * @param int $userid
 | 
        
           |  |  | 325 |  */
 | 
        
           |  |  | 326 | function blog_rss_delete_file($userid) {
 | 
        
           |  |  | 327 |     $filename = blog_rss_file_name('user', $userid);
 | 
        
           |  |  | 328 |     if (file_exists($filename)) {
 | 
        
           |  |  | 329 |         unlink($filename);
 | 
        
           |  |  | 330 |     }
 | 
        
           |  |  | 331 | }
 | 
        
           |  |  | 332 |   |