Updated for better reporting when loading from remote url fails. Now displays error...
[moodle.git] / rss / templib.php
CommitLineData
0eb35827 1<?php
2
3global $CFG;
4
5//initialize config vars for rss_client block if missing
6if (empty($CFG->block_rss_client_submitters) ) {
7 $CFG->block_rss_client_submitters = 2; //default to admin only
8}
9if (empty($CFG->block_rss_client_num_entries) ) {
10 $CFG->block_rss_client_num_entries = 5; //default to 5 entries per block
11}
92ce1eb2 12if (empty($CFG->block_rss_timeout) ) {
13 $CFG->block_rss_timeout = 30;
14}
0eb35827 15
92ce1eb2 16/**
17 * Determines whether or not to get a news feed remotely or from cache and reads it into a string
18 * @param int rssid - id of feed in blog_rss table
19 * @param string url - url of remote feed
20 * @param string type - either 'A' or 'R' where A is an atom feed and R is either rss or rdf
21 * @return Atom|MagpieRSS|null This function returns an Atom object in the case of an Atom feed, a MagpieRSS object in the case of an RDF/RSS feed or null if there was an error loading the remote feed.
22 * NOTE that this function requires allow_url_fopen be On in your php.ini file
23 * (it may be off for security by your web host)
24 */
0eb35827 25function rss_get_feed($rssid, $url, $type) {
26
92ce1eb2 27 global $CFG;
28 $writetofile = false;
29 $urlfailurestring = 'Failed to open remote feed at: ' . $url .'<br /> allow_url_fopen needs to be On in the php.ini file for this file wrapper call to work. Please refer to <a href="http://us2.php.net/filesystem">http://us2.php.net/filesystem</a>';
30 $filefailurestring = 'Could not open the file located at: ';
0eb35827 31 $secs = $CFG->block_rss_timeout * 60;
32
92ce1eb2 33 // If moodle dataroot cache folder is missing create it
0eb35827 34 if (!file_exists($CFG->dataroot .'/cache/')) {
35 mkdir($CFG->dataroot .'/cache');
36 }
92ce1eb2 37 // If moodle dataroot cache/rsscache folder is missing create it
0eb35827 38 if (!file_exists($CFG->dataroot .'/cache/rsscache/')) {
39 mkdir($CFG->dataroot .'/cache/rsscache');
40 }
92ce1eb2 41
0eb35827 42 $file = $CFG->dataroot .'/cache/rsscache/'. $rssid .'.xml';
43// echo "file = ". $file; //debug
44
45 //if feed in cache
46 if (file_exists($file)) {
47 //check age of cache file
48 // echo "file exists $file"; //debug
49 if ($CFG->debug){
50 $data = stat($file);
51 } else {
52 $data = @stat($file);
53 }
54 $now = time();
92ce1eb2 55 if (($now - $data[10]) > $secs) {
56 // The cached file has expired. Attempt to read fresh from source
57 $xml = load_feed_from_url($url);
58 if ($xml) {
59 //success
60 $writetofile = true;
0eb35827 61 } else {
92ce1eb2 62 // Failed to load remote feed. Since the file exists attempt to read from cache
63 if ($CFG->debug) {
64 print $urlfailurestring;
65 }
66 $xml = load_feed_from_file($file);
67 if (!$xml) {
68 // Failed to load from cache as well!
69 if ($CFG->debug) {
70 print $filefailurestring . $file;
71 return;
72 }
73 }
0eb35827 74 }
0eb35827 75 } else {
92ce1eb2 76 // Cached file has not expired. Attempt to read from cached file.
77 $xml = load_feed_from_file($file);
78 if (!$xml) {
79 // Failed to load from cache, attempt to read from source
80 if ($CFG->debug) {
81 print $filefailurestring . $file;
82 }
83 $xml = load_feed_from_url($url);
84 if ($xml) {
85 // success
86 $writetofile = true;
87 } else {
88 // Failed to read from source as well!
89 if ($CFG->debug) {
90 print $urlfailurestring;
91 }
92 return;
93 }
0eb35827 94 }
95 }
92ce1eb2 96 } else {
97 // No cached fil at all, read from source
98 $xml = load_feed_from_url($url);
99 if ($xml) {
100 //success
101 $writetofile = true;
0eb35827 102 } else {
92ce1eb2 103 // Failed to read from source url!
104 if ($CFG->debug) {
105 print $urlfailurestring;
106 }
107 return;
0eb35827 108 }
0eb35827 109 }
110
111 //print_object($xml); //debug
112 if ($CFG->debug){
113 $xmlstr = implode(' ', $xml);
114 } else {
115 $xmlstr = @implode(' ', $xml);
116 }
117
92ce1eb2 118 if ( $writetofile && !empty($xmlstr) ) { //write file to cache
0eb35827 119 // jlb: adding file:/ to the start of the file name fixed
120 // some caching problems that I was experiencing.
121 //$file="file:/" + $file;
122 file_put_contents($file, $xmlstr);
123 }
124
125 if ($type == 'A') {
126 //note: Atom is being modified by a working group
127 //http://www.mnot.net/drafts/draft-nottingham-atom-format-02.html
128 include_once($CFG->dirroot .'/rss/class.Atom.php');
129 $atom = new Atom($xmlstr);
130 $atom->channel = $atom->feed;
131 $atom->items = $atom->entries;
132 $atom->channel['description'] = $atom->channel['tagline'];
133 for($i=0;$i<count($atom->items);$i++) {
134 $atom->items[$i]['description'] = $atom->items[$i]['content'];
135 }
136 return $atom;
137 } else {
138 include_once($CFG->dirroot .'/rss/class.RSS.php');
139 $rss = new MagpieRSS($xmlstr);
140 return $rss;
141 }
142}
143
92ce1eb2 144/**
145 * @param string $file The path to the cached feed to load
146 */
147function load_feed_from_file($file) {
148 global $CFG;
149// echo "read from cache"; //debug
150 //read in from cache
151 if ($CFG->debug){
152 $xml = file($file);
153 } else {
154 $xml = @file($file);
155 }
156 return $xml;
157}
0eb35827 158
92ce1eb2 159/**
160 * @param string $url The url of the remote news feed to load
161 */
162function load_feed_from_url($url) {
163 global $CFG;
164// echo "read from original"; //debug
165 //read from source
166 if ($CFG->debug){
167 $xml = file($url);
168 } else {
169 $xml = @file($url);
170 }
171 return $xml;
172}
173
174/**
175 * @param int $rssid .
176 */
0eb35827 177function rss_display_feeds($rssid='none') {
178 global $db, $USER, $CFG, $THEME;
179 global $blogid; //hackish, but if there is a blogid it would be good to preserve it
180
181 $closeTable = false;
182 //Daryl Hawes note: convert this sql statement to a moodle function call
183 if ($rssid != 'none'){
184 $sql = 'SELECT * FROM '. $CFG->prefix .'block_rss_client WHERE id='. $rssid;
185 } else {
186 $sql = 'SELECT * FROM '. $CFG->prefix .'block_rss_client';
187 }
188
189 $res = $db->Execute($sql);
190// print_object($res); //debug
191
192 if ($res->fields){
193 $closeTable = true;
194 ?>
195 <table width="100%">
196 <tr bgcolor="<?php echo $THEME->cellheading;?>" class="forumpostheadertopic">
197 <td><?php print_string('block_rss_feed', 'block_rss_client'); ?></td>
198 <td><?php print_string('edit'); ?></td>
199 <td><?php print_string('delete'); ?></td>
200 </tr>
201 <?
202 }
203
204 if (isset($res) && $res->fields){
205 while(!$res->EOF) {
206 $editString = '&nbsp;';
207 $deleteString = '&nbsp;';
208 if ($res->fields['userid'] == $USER->id || isadmin()){
209 $editString = '<a href="'. $CFG->wwwroot .'/blocks/rss_client/block_rss_client_action.php?act=rss_edit&rssid='. $res->fields['id'] .'&blogid='. $blogid .'">';
210 $editString .= '<img src="'. $CFG->pixpath .'/t/edit.gif" alt="'. get_string('edit');
211$editString .= '" title="'. get_string('edit') .'" align="absmiddle" height=\"16\" width=\"16\" border=\"0\" /></a>';
212
213 $deleteString = '<a href="'. $CFG->wwwroot .'/blocks/rss_client/block_rss_client_action.php?act=delfeed&rssid='. $res->fields['id'];
214 $deleteString .= '&blogid='. $blogid .'" onClick="return confirm(\''. get_string('block_rss_delete_feed_confirm', 'block_rss_client') .'\');">';
215 $deleteString .= '<img src="'. $CFG->pixpath .'/t/delete.gif" alt="'. get_string('delete');
216$deleteString .= '" title="'. get_string('delete') .'" align="absmiddle" border=\"0\" /></a>';
217 }
218 print '<tr bgcolor="'. $THEME->cellcontent .'" class="forumpostmessage"><td><strong><a href="'. $CFG->wwwroot .'/blocks/rss_client/block_rss_client_action.php?act=view&rssid=';
219 print $res->fields['id'] .'&blogid='. $blogid .'">'. $res->fields['title'] .'</a></strong><br />' ."\n";
220 print $res->fields['description'] .'&nbsp;<br />' ."\n";
221 print $res->fields['url'] .'&nbsp;&nbsp;<a href="'. $res->fields['url'] .'" target=_new><img src="'. $CFG->pixpath .'/blog/xml.gif" border="0" /></a>' ."\n";
222 print '<a href="http://feeds.archive.org/validator/check?url='. $res->fields['url'] .'">(Validate)</a>';
223 print '</td><td align="center">'. $editString .'</td>' ."\n";
224 print '<td align=\"center\">'. $deleteString .'</td>' ."\n";
225 print '</tr>'."\n";
226 $res->MoveNext();
227 }
228 }
229 if ($closeTable){
230 print '</table>'."\n";
231 }
232}
233
92ce1eb2 234/**
235 * @param string $act .
236 * @param string $url .
237 * @param int $rssid .
238 * @param string $rsstype .
239 * @param bool $printnow .
240 */
0eb35827 241function rss_get_form($act, $url, $rssid, $rsstype, $printnow=true) {
242 global $USER, $CFG, $_SERVER, $blockid, $blockaction;
243 global $blogid; //hackish, but if there is a blogid it would be good to preserve it
244
245 $returnstring = '<table><tr><td valign=\"top\">';
246 if ($act == 'rss_edit') {
247 $returnstring .= get_string('edit');
248 } else {
249 $returnstring .= get_string('block_rss_add_new', 'block_rss_client');
250 }
251 $returnstring .= ' '. get_string('block_rss_feed', 'block_rss_client');
252
253 $returnstring .= '</td></tr><tr><td>';
254
255 $returnstring .= '<form action="'. $_SERVER['PHP_SELF'] .'" method=POST name="block_rss">';
256 $returnstring .= 'URL: <input type="text" size="32" maxlength="128" name="url" value="';
257 if ($act == 'rss_edit') {
258 $returnstring .= $url;
259 }
260
261 $returnstring .= '" /><br /><select name="rsstype"><option value="R">RSS/RDF</option>
262 <option value="A"';
263 if ($act == 'rss_edit' and $rsstype == 'A') {
264 $returnstring .= ' selected';
265 }
266
267 $returnstring .= '>Atom</option></select>';
268
269 $returnstring .= '<input type="hidden" name="act" value="';
270 if ($act == 'rss_edit') {
271 $returnstring .= 'updfeed';
272 } else {
273 $returnstring .= 'addfeed';
274 }
275 $returnstring .= '" />';
276 if ($act == 'rss_edit') {
277 $returnstring .= '<input type="hidden" name="rssid" value="'. $rssid .'" />'. "\n";
278 }
279 $returnstring .= '<input type="hidden" name="blogid" value="'. $blogid .'" />';
280 $returnstring .= '<input type="hidden" name="user" value="'. $USER->id .'" />';
281 $returnstring .= '<input type="submit" value="';
282 if ($act == 'rss_edit') {
283 $returnstring .= get_string('update');
284 } else {
285 $returnstring .= get_string('add');
286 }
287 $returnstring .= '" />&nbsp;</form>';
288
289 $returnstring .= '<ul>' . get_string('block_rss_find_more_feeds', 'block_rss_client');
290// removed as this is possibly out of place here
291// $returnstring .= '<li><a href="http://www.syndic8.com" target="_new">syndic8</a> <li><a href="http://www.newsisfree.com" target="_new">NewsIsFree</A>';
292 $returnstring .= '</ul>';
293 $returnstring .= '</td></tr></table>';
294
295 if ($printnow){
296 print $returnstring;
297 }
298 return $returnstring;
299}
300
301/**
302 * added by Daryl Hawes for rss/atom feeds
303 * found at http://us4.php.net/manual/en/function.fwrite.php
304 * added check for moodle debug option. if off then use '@' to suppress error/warning messages
92ce1eb2 305 * @param string $filename .
306 * @param string $content .
0eb35827 307 */
308if (! function_exists('file_put_contents')){
309 function file_put_contents($filename, $content) {
310 global $CFG;
311 $nr_of_bytes = 0;
312 if ($CFG->debug){
313 if (($file = fopen($filename, 'w+')) === false) return false;
314 } else {
315 if (($file = @fopen($filename, 'w+')) === false) return false;
316 }
317 if ($CFG->debug){
318 if ($nr_of_bytes = fwrite($file, $content, strlen($content)) === false) return false;
319 } else {
320 if ($nr_of_bytes = @fwrite($file, $content, strlen($content)) === false) return false;
321 }
322 fclose($file);
323 return $nr_of_bytes;
324 }
325}
326?>