[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 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 /** 19 * This file contains all the common stuff to be used in RSS System 20 * 21 * @package core_rss 22 * @category rss 23 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Build the URL for the RSS feed and add it as a header 31 * 32 * @param stdClass $context The context under which the URL should be created 33 * @param string $componentname The name of the component for which the RSS feed exists 34 * @param stdClass $componentinstance The instance of the component 35 * @param string $title Name for the link to be added to the page header 36 */ 37 function rss_add_http_header($context, $componentname, $componentinstance, $title) { 38 global $PAGE, $USER; 39 40 $componentid = null; 41 if (is_object($componentinstance)) { 42 $componentid = $componentinstance->id; 43 } else { 44 $componentid = $componentinstance; 45 } 46 47 $rsspath = rss_get_url($context->id, $USER->id, $componentname, $componentid); 48 $PAGE->add_alternate_version($title, $rsspath, 'application/rss+xml'); 49 } 50 51 /** 52 * Print the link for the RSS feed with the correct RSS icon 53 * 54 * @param stdClass $contextid The id of the context under which the URL should be created 55 * @param int $userid The source of the RSS feed (site/course/group/user) 56 * @param string $componentname The name of the component for which the feed exists 57 * @param string $id The name by which to call the RSS File 58 * @param string $tooltiptext The tooltip to be displayed with the link 59 * @return string HTML output for the RSS link 60 */ 61 function rss_get_link($contextid, $userid, $componentname, $id, $tooltiptext='') { 62 global $OUTPUT; 63 64 static $rsspath = ''; 65 66 $rsspath = rss_get_url($contextid, $userid, $componentname, $id); 67 $rsspix = $OUTPUT->pix_url('i/rss'); 68 69 return '<a href="'. $rsspath .'"><img src="'. $rsspix .'" title="'. strip_tags($tooltiptext) .'" alt="'.get_string('rss').'" /></a>'; 70 } 71 72 /** 73 * This function returns the URL for the RSS XML file. 74 * 75 * @param int $contextid the course id 76 * @param int $userid the current user id 77 * @param string $componentname the name of the current component. For example "forum" 78 * @param string $additionalargs For modules, module instance id 79 * @return string the url of the RSS feed 80 */ 81 function rss_get_url($contextid, $userid, $componentname, $additionalargs) { 82 global $CFG; 83 if (empty($userid)) { 84 $userid = guest_user()->id; 85 } 86 $usertoken = rss_get_token($userid); 87 $url = '/rss/file.php'; 88 return moodle_url::make_file_url($url, '/'.$contextid.'/'.$usertoken.'/'.$componentname.'/'.$additionalargs.'/rss.xml'); 89 } 90 91 /** 92 * Print the link for the RSS feed with the correct RSS icon (Theme based) 93 * 94 * @param stdClass $contextid The id of the context under which the URL should be created 95 * @param int $userid The source of the RSS feed (site/course/group/user) 96 * @param string $componentname The name of the component for which the feed exists 97 * @param string $id The name by which to call the RSS File 98 * @param string $tooltiptext The tooltip to be displayed with the link 99 */ 100 function rss_print_link($contextid, $userid, $componentname, $id, $tooltiptext='') { 101 print rss_get_link($contextid, $userid, $componentname, $id, $tooltiptext); 102 103 } 104 105 /** 106 * Given an object, deletes all RSS files associated with it. 107 * 108 * @param string $componentname the name of the module ie 'forum'. Used to construct the cache path. 109 * @param stdClass $instance An object with an id member variable ie $forum, $glossary. 110 */ 111 function rss_delete_file($componentname, $instance) { 112 global $CFG; 113 114 $dirpath = "$CFG->cachedir/rss/$componentname"; 115 if (is_dir($dirpath)) { 116 if (!$dh = opendir($dirpath)) { 117 error_log("Directory permission error. RSS directory store for component '{$componentname}' exists but cannot be opened.", DEBUG_DEVELOPER); 118 return; 119 } 120 while (false !== ($filename = readdir($dh))) { 121 if ($filename!='.' && $filename!='..') { 122 if (preg_match("/{$instance->id}_/", $filename)) { 123 unlink("$dirpath/$filename"); 124 } 125 } 126 } 127 } 128 } 129 130 /** 131 * Are RSS feeds enabled for the supplied module instance? 132 * 133 * @param string $modname The name of the module to be checked 134 * @param stdClass $instance An instance of an activity module ie $forum, $glossary. 135 * @param bool $hasrsstype Should there be a rsstype member variable? 136 * @param bool $hasrssarticles Should there be a rssarticles member variable? 137 * @return bool whether or not RSS is enabled for the module 138 */ 139 function rss_enabled_for_mod($modname, $instance=null, $hasrsstype=true, $hasrssarticles=true) { 140 if ($hasrsstype) { 141 if (empty($instance->rsstype) || $instance->rsstype==0) { 142 return false; 143 } 144 } 145 146 //have they set the RSS feed to return 0 results? 147 if ($hasrssarticles) { 148 if (empty($instance->rssarticles) || $instance->rssarticles==0) { 149 return false; 150 } 151 } 152 153 if (!empty($instance) && !instance_is_visible($modname,$instance)) { 154 return false; 155 } 156 157 return true; 158 } 159 160 /** 161 * This function saves to file the rss feed specified in the parameters 162 * 163 * @param string $componentname the module name ie forum. Used to create a cache directory. 164 * @param string $filename the name of the file to be created ie "rss.xml" 165 * @param string $contents the data to be written to the file 166 * @param bool $expandfilename whether or not the fullname of the RSS file should be used 167 * @return bool whether the save was successful or not 168 */ 169 function rss_save_file($componentname, $filename, $contents, $expandfilename=true) { 170 global $CFG; 171 172 $status = true; 173 174 if (! $basedir = make_cache_directory ('rss/'. $componentname)) { 175 //Cannot be created, so error 176 $status = false; 177 } 178 179 if ($status) { 180 $fullfilename = $filename; 181 if ($expandfilename) { 182 $fullfilename = rss_get_file_full_name($componentname, $filename); 183 } 184 185 $rss_file = fopen($fullfilename, "w"); 186 if ($rss_file) { 187 $status = fwrite ($rss_file, $contents); 188 fclose($rss_file); 189 } else { 190 $status = false; 191 } 192 } 193 return $status; 194 } 195 196 /** 197 * Retrieve the location and file name of a cached RSS feed 198 * 199 * @param string $componentname the name of the component the RSS feed is being created for 200 * @param string $filename the name of the RSS FEED 201 * @return string The full name and path of the RSS file 202 */ 203 function rss_get_file_full_name($componentname, $filename) { 204 global $CFG; 205 return "$CFG->cachedir/rss/$componentname/$filename.xml"; 206 } 207 208 /** 209 * Construct the file name of the RSS File 210 * 211 * @param stdClass $instance the instance of the source of the RSS feed 212 * @param string $sql the SQL used to produce the RSS feed 213 * @param array $params the parameters used in the SQL query 214 * @return string the name of the RSS file 215 */ 216 function rss_get_file_name($instance, $sql, $params = array()) { 217 if ($params) { 218 // If a parameters array is passed, then we want to 219 // serialize it and then concatenate it with the sql. 220 // The reason for this is to generate a unique filename 221 // for queries using the same sql but different parameters. 222 asort($params); 223 $serializearray = serialize($params); 224 return $instance->id.'_'.md5($sql . $serializearray); 225 } else { 226 return $instance->id.'_'.md5($sql); 227 } 228 } 229 230 /** 231 * This function return all the common headers for every rss feed in the site 232 * 233 * @param string $title the title for the RSS Feed 234 * @param string $link the link for the origin of the RSS feed 235 * @param string $description the description of the contents of the RSS feed 236 * @return bool|string the standard header for the RSS feed 237 */ 238 function rss_standard_header($title = NULL, $link = NULL, $description = NULL) { 239 global $CFG, $USER, $OUTPUT; 240 241 $status = true; 242 $result = ""; 243 244 $site = get_site(); 245 246 if ($status) { 247 248 //Calculate title, link and description 249 if (empty($title)) { 250 $title = format_string($site->fullname); 251 } 252 if (empty($link)) { 253 $link = $CFG->wwwroot; 254 } 255 if (empty($description)) { 256 $description = $site->summary; 257 } 258 259 //xml headers 260 $result .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 261 $result .= "<rss version=\"2.0\">\n"; 262 263 //open the channel 264 $result .= rss_start_tag('channel', 1, true); 265 266 //write channel info 267 $result .= rss_full_tag('title', 2, false, strip_tags($title)); 268 $result .= rss_full_tag('link', 2, false, $link); 269 $result .= rss_full_tag('description', 2, false, $description); 270 $result .= rss_full_tag('generator', 2, false, 'Moodle'); 271 if (!empty($USER->lang)) { 272 $result .= rss_full_tag('language', 2, false, substr($USER->lang,0,2)); 273 } 274 $today = getdate(); 275 $result .= rss_full_tag('copyright', 2, false, '(c) '. $today['year'] .' '. format_string($site->fullname)); 276 /* 277 if (!empty($USER->email)) { 278 $result .= rss_full_tag('managingEditor', 2, false, fullname($USER)); 279 $result .= rss_full_tag('webMaster', 2, false, fullname($USER)); 280 } 281 */ 282 283 //write image info 284 $rsspix = $OUTPUT->pix_url('i/rsssitelogo'); 285 286 //write the info 287 $result .= rss_start_tag('image', 2, true); 288 $result .= rss_full_tag('url', 3, false, $rsspix); 289 $result .= rss_full_tag('title', 3, false, 'moodle'); 290 $result .= rss_full_tag('link', 3, false, $CFG->wwwroot); 291 $result .= rss_full_tag('width', 3, false, '140'); 292 $result .= rss_full_tag('height', 3, false, '35'); 293 $result .= rss_end_tag('image', 2, true); 294 } 295 296 if (!$status) { 297 return false; 298 } else { 299 return $result; 300 } 301 } 302 303 304 /** 305 * Generates the rss XML code for every item passed in the array 306 * 307 * item->title: The title of the item 308 * item->author: The author of the item. Optional !! 309 * item->pubdate: The pubdate of the item 310 * item->link: The link url of the item 311 * item->description: The content of the item 312 * 313 * @param array $items an array of item objects 314 * @return bool|string the rss XML code for every item passed in the array 315 */ 316 function rss_add_items($items) { 317 global $CFG; 318 319 $result = ''; 320 321 if (!empty($items)) { 322 foreach ($items as $item) { 323 $result .= rss_start_tag('item',2,true); 324 //Include the category if exists (some rss readers will use it to group items) 325 if (isset($item->category)) { 326 $result .= rss_full_tag('category',3,false,$item->category); 327 } 328 if (isset($item->tags)) { 329 $attributes = array(); 330 if (isset($item->tagscheme)) { 331 $attributes['domain'] = s($item->tagscheme); 332 } 333 foreach ($item->tags as $tag) { 334 $result .= rss_full_tag('category', 3, false, $tag, $attributes); 335 } 336 } 337 $result .= rss_full_tag('title',3,false,strip_tags($item->title)); 338 $result .= rss_full_tag('link',3,false,$item->link); 339 $result .= rss_add_enclosures($item); 340 $result .= rss_full_tag('pubDate',3,false,gmdate('D, d M Y H:i:s',$item->pubdate).' GMT'); # MDL-12563 341 //Include the author if exists 342 if (isset($item->author) && !empty($item->author)) { 343 //$result .= rss_full_tag('author',3,false,$item->author); 344 //We put it in the description instead because it's more important 345 //for moodle than most other feeds, and most rss software seems to ignore 346 //the author field ... 347 $item->description = get_string('byname','',$item->author).'. <p>'.$item->description.'</p>'; 348 } 349 $result .= rss_full_tag('description',3,false,$item->description); 350 $result .= rss_full_tag('guid',3,false,$item->link,array('isPermaLink' => 'true')); 351 $result .= rss_end_tag('item',2,true); 352 353 } 354 } else { 355 $result = false; 356 } 357 return $result; 358 } 359 360 /** 361 * This function return all the common footers for every rss feed in the site. 362 * 363 * @return string 364 */ 365 function rss_standard_footer() { 366 $status = true; 367 $result = ''; 368 369 $result .= rss_end_tag('channel', 1, true); 370 $result .= '</rss>'; 371 372 return $result; 373 } 374 375 376 /** 377 * This function return an error xml file (string) to be sent when a rss is required (file.php) and something goes wrong 378 * 379 * @param string $errortype Type of error to send, default is rsserror 380 * @return stdClass returns a XML Feed with an error message in it 381 */ 382 function rss_geterrorxmlfile($errortype = 'rsserror') { 383 global $CFG; 384 385 $return = ''; 386 387 //XML Header 388 $return = rss_standard_header(); 389 390 //XML item 391 if ($return) { 392 $item = new stdClass(); 393 $item->title = "RSS Error"; 394 $item->link = $CFG->wwwroot; 395 $item->pubdate = time(); 396 $item->description = get_string($errortype); 397 $return .= rss_add_items(array($item)); 398 } 399 400 //XML Footer 401 if ($return) { 402 $return .= rss_standard_footer(); 403 } 404 405 return $return; 406 } 407 408 /** 409 * Get the ID of the user from a given RSS Token 410 * 411 * @param string $token the RSS token you would like to use to find the user id 412 * @return int The user id 413 */ 414 function rss_get_userid_from_token($token) { 415 global $DB; 416 417 $sql = 'SELECT u.id FROM {user} u 418 JOIN {user_private_key} k ON u.id = k.userid 419 WHERE u.deleted = 0 AND u.confirmed = 1 420 AND u.suspended = 0 AND k.value = ?'; 421 return $DB->get_field_sql($sql, array($token), IGNORE_MISSING); 422 } 423 424 /** 425 * Get the RSS Token from a given user id 426 * 427 * @param int $userid The user id 428 * @return string the RSS token for the user 429 */ 430 function rss_get_token($userid) { 431 return get_user_key('rss', $userid); 432 } 433 434 /** 435 * Removes the token for the given user from the DB 436 * @param int $userid The user id for the token you wish to delete 437 */ 438 function rss_delete_token($userid) { 439 delete_user_key('rss', $userid); 440 } 441 442 /** 443 * Return the xml start tag 444 * 445 * @param string $tag the xml tag name 446 * @param int $level the indentation level 447 * @param bool $endline whether or not to start new tags on a new line 448 * @param array $attributes the attributes of the xml tag 449 * @return string the xml start tag 450 */ 451 function rss_start_tag($tag,$level=0,$endline=false,$attributes=null) { 452 if ($endline) { 453 $endchar = "\n"; 454 } else { 455 $endchar = ""; 456 } 457 $attrstring = ''; 458 if (!empty($attributes) && is_array($attributes)) { 459 foreach ($attributes as $key => $value) { 460 $attrstring .= " ".$key."=\"".$value."\""; 461 } 462 } 463 return str_repeat(" ",$level*2)."<".$tag.$attrstring.">".$endchar; 464 } 465 466 /** 467 * Return the xml end tag 468 * @param string $tag the xml tag name 469 * @param int $level the indentation level 470 * @param bool $endline whether or not to start new tags on a new line 471 * @return string the xml end tag 472 */ 473 function rss_end_tag($tag,$level=0,$endline=true) { 474 if ($endline) { 475 $endchar = "\n"; 476 } else { 477 $endchar = ""; 478 } 479 return str_repeat(" ",$level*2)."</".$tag.">".$endchar; 480 } 481 482 /** 483 * Return the while xml element, including content 484 * 485 * @param string $tag the xml tag name 486 * @param int $level the indentation level 487 * @param bool $endline whether or not to start new tags on a new line 488 * @param string $content the text to go inside the tag 489 * @param array $attributes the attributes of the xml tag 490 * @return string the whole xml element 491 */ 492 function rss_full_tag($tag,$level=0,$endline=true,$content,$attributes=null) { 493 $st = rss_start_tag($tag,$level,$endline,$attributes); 494 $co=""; 495 $co = preg_replace("/\r\n|\r/", "\n", htmlspecialchars($content)); 496 $et = rss_end_tag($tag,0,true); 497 498 return $st.$co.$et; 499 } 500 501 /** 502 * Adds RSS Media Enclosures for "podcasting" by including attachments that 503 * are specified in the item->attachments field. 504 * 505 * @param stdClass $item representing an RSS item 506 * @return string RSS enclosure tags 507 */ 508 function rss_add_enclosures($item){ 509 global $CFG; 510 511 $returnstring = ''; 512 513 // list of media file extensions and their respective mime types 514 include_once($CFG->libdir.'/filelib.php'); 515 $mediafiletypes = get_mimetypes_array(); 516 517 // take into account attachments (e.g. from forum) - with these, we are able to know the file size 518 if (isset($item->attachments) && is_array($item->attachments)) { 519 foreach ($item->attachments as $attachment){ 520 $extension = strtolower(substr($attachment->url, strrpos($attachment->url, '.')+1)); 521 if (isset($mediafiletypes[$extension]['type'])) { 522 $type = $mediafiletypes[$extension]['type']; 523 } else { 524 $type = 'document/unknown'; 525 } 526 $returnstring .= "\n<enclosure url=\"$attachment->url\" length=\"$attachment->length\" type=\"$type\" />\n"; 527 } 528 } 529 530 return $returnstring; 531 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |