PluginProbe
FeedWordPress / 2009.0613
FeedWordPress v2009.0613
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
← All changes | feedfinder.class.php +56 -246 trunk2009.0613 View file →
@@ -1,29 +1,15 @@
1 1 <?php
2 -/**
3 - * class FeedFinder: find likely feeds using autodetection and/or guesswork
4 - * @version 2010.0622
5 - * @uses SimplePie_Misc
6 - */
2 +################################################################################
3 +## class FeedFinder: find likely feeds using autodetection and/or guesswork ####
4 +################################################################################
7 5
8 -if ( ! class_exists( 'SimplePie' ) ) :
9 - require_once ABSPATH . WPINC . '/class-simplepie.php';
10 -endif;
11 -require_once dirname( __FILE__ ) . '/feedwordpresshtml.class.php';
12 -
13 -/**
14 - * FeedFinder attempts to get all possible RSS/Atom feeds from a site.
15 - *
16 - * @see SimplePie_Misc
17 - */
18 6 class FeedFinder {
19 7 var $uri = NULL;
20 - var $credentials = NULL;
21 8 var $_cache_uri = NULL;
22 -
9 +
23 10 var $verify = FALSE;
24 - var $fallbacks = 3;
25 -
11 +
26 12 var $_response = NULL;
27 13 var $_data = NULL;
28 14 var $_error = NULL;
29 15 var $_head = NULL;
@@ -33,139 +19,65 @@
33 19 'application/rss+xml',
34 20 'text/xml',
35 21 'application/atom+xml',
36 22 'application/x.atom+xml',
37 - 'application/x-atom+xml',
23 + 'application/x-atom+xml'
38 24 );
39 25 var $_feed_markers = array('\\<feed', '\\<rss', 'xmlns="http://purl.org/rss/1.0');
40 26 var $_html_markers = array('\\<html');
41 - var $_opml_markers = array('\\<opml', '\\<outline');
42 27 var $_obvious_feed_url = array('[./]rss', '[./]rdf', '[./]atom', '[./]feed', '\.xml');
43 28 var $_maybe_feed_url = array ('rss', 'rdf', 'atom', 'feed', 'xml');
44 29
45 - function __construct( $uri = NULL, $params = array(), $fallbacks = 3 ) {
46 - if (is_bool($params)) :
47 - $params = array("verify" => $params);
48 - endif;
49 -
50 - $params = wp_parse_args($params, array(
51 - "verify" => true,
52 - "authentication" => NULL,
53 - "username" => NULL,
54 - "password" => NULL,
55 - ));
56 - $verify = $params['verify'];
57 - $this->credentials = array(
58 - "authentication" => $params['authentication'],
59 - "username" => $params['username'],
60 - "password" => $params['password'],
61 - );
62 -
30 + function FeedFinder ($uri = NULL, $verify = TRUE) {
63 31 $this->uri = $uri; $this->verify = $verify;
64 - $this->fallbacks = $fallbacks;
65 32 } /* FeedFinder::FeedFinder () */
66 33
67 - function FeedFinder( $uri = NULL, $params = array(), $fallbacks = 3 ) {
68 - self::__construct( $uri, $params, $fallbacks );
69 - }
70 -
71 - function find ($uri = NULL, $params = array()) {
72 - $params = wp_parse_args($params, array( // Defaults
73 - "authentication" => -1,
74 - "username" => NULL,
75 - "password" => NULL,
76 - ));
77 -
78 - // Equivalents
79 - if ($params['authentication']=='-') :
80 - $params['authentication'] = NULL;
81 - $params['username'] = NULL;
82 - $params['password'] = NULL;
83 - endif;
84 -
85 - // Set/reset
86 - if ($params['authentication'] != -1) :
87 - $this->credentials = array(
88 - "authentication" => $params['authentication'],
89 - "username" => $params['username'],
90 - "password" => $params['password'],
91 - );
92 - endif;
93 -
34 + function find ($uri = NULL) {
94 35 $ret = array ();
95 - if ( !is_null($this->data($uri))) :
96 - if ($this->is_opml($uri)) :
97 - $href = $this->_opml_rss_uris();
98 - else :
99 - if ($this->is_feed($uri)) :
100 - $href = array($this->uri);
101 - else :
102 - // Assume that we have HTML or XHTML (even if we don't, who's
103 - // it gonna hurt?) Autodiscovery is the preferred method.
104 - $href = $this->_link_rel_feeds();
36 + if (!is_null($this->data($uri))) {
37 + if ($this->is_feed($uri)) {
38 + $ret = array($this->uri);
39 + } else {
40 + // Assume that we have HTML or XHTML (even if we don't, who's it gonna hurt?)
41 + // Autodiscovery is the preferred method
42 + $href = $this->_link_rel_feeds();
43 +
44 + // ... but we'll also take the little orange buttons
45 + $href = array_merge($href, $this->_a_href_feeds(TRUE));
46 +
47 + // If all that failed, look harder
48 + if (count($href) == 0) $href = $this->_a_href_feeds(FALSE);
105 49
106 - // ... but we'll also take the little orange buttons
107 - if ($this->fallbacks > 0) :
108 - $href = array_merge($href, $this->_a_href_feeds(TRUE));
109 - endif;
50 + // Our search may turn up duplicate URIs. We only need to do any given URI once.
51 + // Props to Camilo <http://projects.radgeek.com/2008/12/14/feedwordpress-20081214/#comment-20090122160414>
52 + $href = array_unique($href);
110 53
111 - // If all that failed, look harder
112 - if ($this->fallbacks > 1) :
113 - if (count($href) == 0) :
114 - $href = $this->_a_href_feeds(FALSE);
115 - endif;
116 - endif;
117 -
118 - // Our search may turn up duplicate URIs. We only need to do
119 - // any given URI once. Props to Camilo <http://projects.radgeek.com/2008/12/14/feedwordpress-20081214/#comment-20090122160414>
120 - $href = array_unique($href);
121 - endif;
122 -
123 - // Try some clever URL little tricks before we go
124 - if ($this->fallbacks > 2) :
125 - $href = array_merge($href, $this->_url_manipulation_feeds());
126 - endif;
127 - endif;
128 -
129 - $href = array_unique($href);
130 -
131 - // Verify feeds and resolve relative URIs
132 - foreach ($href as $u) :
133 - $the_uri = SimplePie_Misc::absolutize_url($u, $this->uri);
134 - if ($this->verify and ($u != $this->uri and $the_uri != $this->uri)) :
135 - $feed = new FeedFinder($the_uri, $this->credentials);
136 - if ($feed->is_feed()) : $ret[] = $the_uri; endif;
137 - unset($feed);
138 - else :
139 - $ret[] = $the_uri;
140 - endif;
141 - endforeach;
142 - endif;
143 -
144 - if ($this->is_401($uri)) :
145 - $ret = array_merge(array(
146 - new WP_Error('http_request_failed', '401 Not authorized', array("uri" => $this->uri, "status" => 401)),
147 - ), $ret);
148 - endif;
149 -
150 - return array_values($ret);
54 + // Verify feeds and resolve relative URIs
55 + foreach ($href as $u) {
56 + $the_uri = Relative_URI::resolve($u, $this->uri);
57 + if ($this->verify) {
58 + $feed =& new FeedFinder($the_uri);
59 + if ($feed->is_feed()) $ret[] = $the_uri;
60 + $feed = NULL;
61 + } else {
62 + $ret[] = $the_uri;
63 + }
64 + } /* foreach */
65 + } /* if */
66 + } /* if */
67 + return array_unique($ret);
151 68 } /* FeedFinder::find () */
152 69
153 70 function data ($uri = NULL) {
154 71 $this->_get($uri);
155 72 return $this->_data;
156 - } /* FeedFinder::data () */
73 + }
157 74
158 - function upload_data ($data) {
159 - $this->uri = 'tag:localhost';
160 - $this->_data = $data;
161 - } /* FeedFinder::upload_data () */
162 -
163 75 function status ($uri = NULL) {
164 76 $this->_get($uri);
165 -
166 - if ( !is_wp_error($this->_response) and isset($this->_response['response']['code'])) :
167 - $ret = $this->_response['response']['code'];
77 +
78 + if (isset($this->_response->status)) :
79 + $ret = $this->_response->status;
168 80 else :
169 81 $ret = NULL;
170 82 endif;
171 83 return $ret;
@@ -170,24 +82,12 @@
170 82 endif;
171 83 return $ret;
172 84 }
173 85
174 - function error ($index = NULL) {
175 - $message = NULL;
176 - if (count($this->_error) > 0) :
177 - if (is_scalar($index) and !is_null($index)) :
178 - $message = $this->_error[$index];
179 - else :
180 - $message = implode(" / ", $this->_error)."\n";
181 - endif;
182 - endif;
183 - return $message;
86 + function error () {
87 + return $this->_error;
184 88 }
185 -
186 - function is_401 ($uri = NULL) {
187 - return (intval($this->status($uri))==401);
188 - } /* FeedFinder::is_401 () */
189 -
89 +
190 90 function is_feed ($uri = NULL) {
191 91 $data = $this->data($uri);
192 92
193 93 return (
@@ -200,45 +100,27 @@
200 100 )
201 101 );
202 102 } /* FeedFinder::is_feed () */
203 103
204 - function is_opml ($uri = NULL) {
205 - $data = $this->data($uri);
206 - return (
207 - preg_match (
208 - "\007(".implode('|',$this->_opml_markers).")\007i",
209 - $data
210 - )
211 - );
212 - } /* FeedFinder::is_opml () */
213 -
214 104 # --- Private methods ---
215 105 function _get ($uri = NULL) {
216 106 if ($uri) $this->uri = $uri;
217 107
218 108 // Is the result not yet cached?
219 - if ($this->uri != 'tag:localhost' and $this->_cache_uri !== $this->uri) :
109 + if ($this->_cache_uri !== $this->uri) :
220 110 $headers['Connection'] = 'close';
221 111 $headers['Accept'] = 'application/atom+xml application/rdf+xml application/rss+xml application/xml text/html */*';
222 112 $headers['User-Agent'] = 'feedfinder/1.2 (compatible; PHP FeedFinder) +http://projects.radgeek.com/feedwordpress';
223 113
224 - // Use WordPress API function
225 - $client = wp_remote_request($this->uri, array_merge(
226 - $this->credentials,
227 - array(
228 - 'headers' => $headers,
229 - 'timeout' => FeedWordPress::fetch_timeout(),
230 - )
231 - ));
232 -
233 - $this->_response = $client;
234 - if (is_wp_error($client)) :
235 - $this->_data = NULL;
236 - $this->_error = $client->get_error_messages();
114 + // Use function provided by MagpieRSS package
115 + $client = _fetch_remote_file($this->uri, $headers);
116 + if (isset($client->error)) :
117 + $this->_error = $client->error;
237 118 else :
238 - $this->_data = $client['body'];
239 119 $this->_error = NULL;
240 120 endif;
121 + $this->_response = $client;
122 + $this->_data = $client->results;
241 123
242 124 // Kilroy was here
243 125 $this->_cache_uri = $this->uri;
244 126 endif;
@@ -243,25 +125,8 @@
243 125 $this->_cache_uri = $this->uri;
244 126 endif;
245 127 } /* FeedFinder::_get () */
246 128
247 - function _opml_rss_uris () {
248 - // Really we should parse the XML and use the structure to
249 - // return something intelligent to programs that want to use it
250 - // Oh babe! maybe some day...
251 -
252 - $opml = $this->data();
253 -
254 - $rx = FeedWordPressHTML::attributeRegex('outline', 'xmlUrl');
255 - if (preg_match_all($rx, $opml, $matches, PREG_SET_ORDER)) :
256 - foreach ($matches as $m) :
257 - $match = FeedWordPressHTML::attributeMatch($m);
258 - $r[] = $match['value'];
259 - endforeach;
260 - endif;
261 - return $r;
262 - } /* FeedFinder::_opml_rss_uris () */
263 -
264 129 function _link_rel_feeds () {
265 130 $links = $this->_tags('link');
266 131 $link_count = count($links);
267 132
@@ -274,9 +139,9 @@
274 139 } /* if */
275 140 } /* if */
276 141 } /* for */
277 142 return $href;
278 - } /* FeedFinder::_link_rel_feeds () */
143 + }
279 144
280 145 function _a_href_feeds ($obvious = TRUE) {
281 146 $pattern = ($obvious ? $this->_obvious_feed_url : $this->_maybe_feed_url);
282 147
@@ -290,68 +155,13 @@
290 155 $href[] = $links[$n]['href'];
291 156 } /* if */
292 157 } /* for */
293 158 return $href;
294 - } /* FeedFinder::_link_a_href_feeds () */
159 + }
295 160
296 - function _url_manipulation_feeds () {
297 - $href = array();
298 -
299 - // check for HTTP GET parameters that look feed-like.
300 - $bits = parse_url($this->uri);
301 - foreach (array('rss', 'rss2', 'atom', 'rdf') as $format) :
302 - if (isset($bits['query']) and (strlen($bits['query']) > 0)) :
303 - $newQuery = preg_replace('/([?&=])(rss2?|atom|rdf)/i', '$1'.$format, $bits['query']);
304 - else :
305 - $newQuery = NULL;
306 - endif;
307 -
308 - if (isset($bits['path']) and (strlen($bits['path']) > 0)) :
309 - $newPath = preg_replace('!([/.])(rss2?|atom|rdf)!i', '$1'.$format, $bits['path']);
310 - else :
311 - $newPath = NULL;
312 - endif;
313 -
314 - // Reassemble, check and return
315 - $credentials = '';
316 - if (isset($bits['user'])) :
317 - $credentials = $bits['user'];
318 - if (isset($bits['pass'])) :
319 - $credentials .= ':'.$bits['pass'];
320 - endif;
321 - $credentials .= '@';
322 - endif;
323 -
324 - // Variations on a theme
325 - $newUrl[0] = (''
326 - .(isset($bits['scheme']) ? $bits['scheme'].':' : '')
327 - .(isset($bits['host']) ? '//'.$credentials.$bits['host'] : '')
328 - .( !is_null($newPath) ? $newPath : '')
329 - .( !is_null($newQuery) ? '?'.$newQuery : '')
330 - .(isset($bits['fragment']) ? '#'.$bits['fragment'] : '')
331 - );
332 - $newUrl[1] = (''
333 - .(isset($bits['scheme']) ? $bits['scheme'].':' : '')
334 - .(isset($bits['host']) ? '//'.$credentials.$bits['host'] : '')
335 - .( !is_null($newPath) ? $newPath : '')
336 - .(isset($bits['query']) ? '?'.$bits['query'] : '')
337 - .(isset($bits['fragment']) ? '#'.$bits['fragment'] : '')
338 - );
339 - $newUrl[2] = (''
340 - .(isset($bits['scheme']) ? $bits['scheme'].':' : '')
341 - .(isset($bits['host']) ? '//'.$credentials.$bits['host'] : '')
342 - .(isset($bits['path']) ? $bits['path'] : '')
343 - .( !is_null($newQuery) ? '?'.$newQuery : '')
344 - .(isset($bits['fragment']) ? '#'.$bits['fragment'] : '')
345 - );
346 - $href = array_merge($href, $newUrl);
347 - endforeach;
348 - return array_unique($href);
349 - } /* FeedFinder::_url_manipulation_feeds () */
350 -
351 161 function _tags ($tag) {
352 162 $html = $this->data();
353 -
163 +
354 164 // search through the HTML, save all <link> tags
355 165 // and store each link's attributes in an associative array
356 166 preg_match_all('/<'.$tag.'\s+(.*?)\s*\/?>/si', $html, $matches);
357 167 $links = $matches[1];
@@ -368,7 +178,7 @@
368 178 } /* foreach */
369 179 $ret[$n] = $final_link;
370 180 } /* for */
371 181 return $ret;
372 - } /* FeedFinder::_tags () */
182 + }
373 183 } /* class FeedFinder */
374 184