weekly release 4.0dev+
[moodle.git] / lib / simplepie / moodle_simplepie.php
CommitLineData
ec00bfc5 1<?php
80d72d56 2
3/**
4 * Moodle - Modular Object-Oriented Dynamic Learning Environment
5 * http://moodle.org
6 * Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * @package moodle
22 * @subpackage lib
23 * @author Dan Poltawski <talktodan@gmail.com>
926987ab 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
80d72d56 25 *
26 * Customised version of SimplePie for Moodle
27 */
28
29require_once($CFG->libdir.'/filelib.php');
30
31// PLEASE NOTE: we use the simplepie class _unmodified_
32// through the joys of OO. Distros are free to use their stock
33// version of this file.
d958e6bd 34require_once($CFG->libdir.'/simplepie/autoloader.php');
80d72d56 35
36/**
37 * Moodle Customised version of the SimplePie class
38 *
39 * This class extends the stock SimplePie class
40 * in order to make sensible configuration choices,
41 * such as using the Moodle cache directory and
926987ab 42 * curl functions/proxy config for making http
43 * requests in line with moodle configuration.
44 *
45 * @copyright 2009 Dan Poltawski <talktodan@gmail.com>
46 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
47 * @since Moodle 2.0
80d72d56 48 */
d958e6bd 49class moodle_simplepie extends SimplePie {
6f5e0852 50 /**
926987ab 51 * Constructor - creates an instance of the SimplePie class
52 * with Moodle defaults.
53 *
6f5e0852 54 * @param string $feedurl optional URL of the feed
f1da1322 55 * @param int $timeout how many seconds requests should wait for server response
926987ab 56 */
f1da1322 57 public function __construct($feedurl = null, $timeout = 2) {
926987ab 58 $cachedir = moodle_simplepie::get_cache_directory();
c426ef3a 59 check_dir_exists($cachedir);
80d72d56 60
3455494c 61 parent::__construct();
d958e6bd
PS
62
63 // Use the Moodle class for http requests
64 $this->set_file_class('moodle_simplepie_file');
65
66 // Use html purifier for text cleaning.
67 $this->set_sanitize_class('moodle_simplepie_sanitize');
68 $this->sanitize = new moodle_simplepie_sanitize();
69
d175fe4c 70 // Match moodle encoding
71 $this->set_output_encoding('UTF-8');
72
73 // default to a short timeout as most operations will be interactive
f1da1322 74 $this->set_timeout($timeout);
d175fe4c 75
76 // 1 hour default cache
3455494c 77 $this->set_cache_location($cachedir);
d175fe4c 78 $this->set_cache_duration(3600);
79
80 // init the feed url if passed in constructor
81 if ($feedurl !== null) {
3455494c
MD
82 $this->set_feed_url($feedurl);
83 $this->init();
d175fe4c 84 }
80d72d56 85 }
926987ab 86
87 /**
88 * Get path for feed cache directory
89 *
90 * @return string absolute path to cache directory
91 */
92 private static function get_cache_directory() {
93 global $CFG;
94
365bec4c 95 return $CFG->cachedir.'/simplepie/';
926987ab 96 }
97
98 /**
6f5e0852 99 * Reset RSS cache
926987ab 100 *
101 * @return boolean success if cache clear or didn't exist
102 */
103 public static function reset_cache() {
104
105 $cachedir = moodle_simplepie::get_cache_directory();
106
107 return remove_dir($cachedir);
108 }
80d72d56 109}
110
111/**
112 * Moodle Customised version of the SimplePie_File class
113 *
114 * This class extends the stock SimplePie class
115 * in order to utilise Moodles own curl class for making
116 * http requests. By using the moodle curl class
117 * we ensure that the correct proxy configuration is used.
118 */
d958e6bd 119class moodle_simplepie_file extends SimplePie_File {
80d72d56 120
121 /**
d958e6bd
PS
122 * The constructor is a copy of the stock simplepie File class which has
123 * been modified to add in use the Moodle curl class rather than php curl
80d72d56 124 * functions.
125 */
d958e6bd 126 public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
80d72d56 127 $this->url = $url;
128 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
129
130 $curl = new curl();
6f5e0852 131 $curl->setopt( array(
d175fe4c 132 'CURLOPT_HEADER' => true,
133 'CURLOPT_TIMEOUT' => $timeout,
134 'CURLOPT_CONNECTTIMEOUT' => $timeout ));
135
80d72d56 136
1597e75d 137 if ($headers !== null) {
138 // translate simplepie headers to those class curl expects
139 foreach($headers as $headername => $headervalue){
140 $headerstr = "{$headername}: {$headervalue}";
141 $curl->setHeader($headerstr);
142 }
143 }
144
85cb4b65 145 $this->headers = curl::strip_double_headers($curl->get($url));
926987ab 146
147 if ($curl->error) {
80d72d56 148 $this->error = 'cURL Error: '.$curl->error;
149 $this->success = false;
150 return false;
151 }
152
926987ab 153 $parser = new SimplePie_HTTP_Parser($this->headers);
80d72d56 154
926987ab 155 if ($parser->parse()) {
80d72d56 156 $this->headers = $parser->headers;
faaf3f63 157 $this->body = trim($parser->body);
80d72d56 158 $this->status_code = $parser->status_code;
159
160
d958e6bd
PS
161 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303
162 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400)
163 && isset($this->headers['location']) && $this->redirects < $redirects) {
80d72d56 164 $this->redirects++;
165 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
d958e6bd 166 return $this->__construct($location, $timeout, $redirects, $headers);
80d72d56 167 }
168 }
169 }
170}
d958e6bd
PS
171
172
173/**
174 * Customised feed sanitization using HTMLPurifier.
175 */
176class moodle_simplepie_sanitize extends SimplePie_Sanitize {
177 public function sanitize($data, $type, $base = '') {
178 $data = trim($data);
179
180 if ($data === '') {
181 return '';
182 }
183
184 if ($type & SIMPLEPIE_CONSTRUCT_BASE64){
185 $data = base64_decode($data);
186 }
187
188 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML) {
189 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data)) {
190 $type |= SIMPLEPIE_CONSTRUCT_HTML;
191 } else {
192 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
193 }
194 }
195
196 if ($type & SIMPLEPIE_CONSTRUCT_IRI) {
197 $absolute = $this->registry->call('Misc', 'absolutize_url', array($data, $base));
198 if ($absolute !== false) {
199 $data = $absolute;
200 }
d037dba8 201 $data = clean_param($data, PARAM_URL);
d958e6bd
PS
202 }
203
204 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI)) {
205 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
206 }
207
208 $data = purify_html($data);
209
210 if ($this->remove_div) {
211 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
212 $data = preg_replace('/<\/div>$/', '', $data);
213 } else {
214 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
215 }
216
217 if ($this->output_encoding !== 'UTF-8') {
2f1e464a 218 core_text::convert($data, 'UTF-8', $this->output_encoding);
d958e6bd
PS
219 }
220
221 return $data;
222 }
223}