PluginProbe
FeedWordPress / 2009.1111
FeedWordPress v2009.1111
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
feedwordpress / feedfinder.class.php

feedfinder.class.php in FeedWordPress 2009.1111, at feedfinder.class.php

185 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 ################################################################################
3 ## class FeedFinder: find likely feeds using autodetection and/or guesswork ####
4 ################################################################################
5
6 class FeedFinder {
7 var $uri = NULL;
8 var $_cache_uri = NULL;
9
10 var $verify = FALSE;
11
12 var $_response = NULL;
13 var $_data = NULL;
14 var $_error = NULL;
15 var $_head = NULL;
16
17 # -- Recognition patterns
18 var $_feed_types = array(
19 'application/rss+xml',
20 'text/xml',
21 'application/atom+xml',
22 'application/x.atom+xml',
23 'application/x-atom+xml'
24 );
25 var $_feed_markers = array('\\<feed', '\\<rss', 'xmlns="http://purl.org/rss/1.0');
26 var $_html_markers = array('\\<html');
27 var $_obvious_feed_url = array('[./]rss', '[./]rdf', '[./]atom', '[./]feed', '\.xml');
28 var $_maybe_feed_url = array ('rss', 'rdf', 'atom', 'feed', 'xml');
29
30 function FeedFinder ($uri = NULL, $verify = TRUE) {
31 $this->uri = $uri; $this->verify = $verify;
32 } /* FeedFinder::FeedFinder () */
33
34 function find ($uri = NULL) {
35 $ret = array ();
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);
49
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);
53
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);
68 } /* FeedFinder::find () */
69
70 function data ($uri = NULL) {
71 $this->_get($uri);
72 return $this->_data;
73 }
74
75 function status ($uri = NULL) {
76 $this->_get($uri);
77
78 if (isset($this->_response->status)) :
79 $ret = $this->_response->status;
80 else :
81 $ret = NULL;
82 endif;
83 return $ret;
84 }
85
86 function error () {
87 return $this->_error;
88 }
89
90 function is_feed ($uri = NULL) {
91 $data = $this->data($uri);
92
93 return (
94 preg_match (
95 "\007(".implode('|',$this->_feed_markers).")\007i",
96 $data
97 ) and !preg_match (
98 "\007(".implode('|',$this->_html_markers).")\007i",
99 $data
100 )
101 );
102 } /* FeedFinder::is_feed () */
103
104 # --- Private methods ---
105 function _get ($uri = NULL) {
106 if ($uri) $this->uri = $uri;
107
108 // Is the result not yet cached?
109 if ($this->_cache_uri !== $this->uri) :
110 $headers['Connection'] = 'close';
111 $headers['Accept'] = 'application/atom+xml application/rdf+xml application/rss+xml application/xml text/html */*';
112 $headers['User-Agent'] = 'feedfinder/1.2 (compatible; PHP FeedFinder) +http://projects.radgeek.com/feedwordpress';
113
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;
118 else :
119 $this->_error = NULL;
120 endif;
121 $this->_response = $client;
122 $this->_data = $client->results;
123
124 // Kilroy was here
125 $this->_cache_uri = $this->uri;
126 endif;
127 } /* FeedFinder::_get () */
128
129 function _link_rel_feeds () {
130 $links = $this->_tags('link');
131 $link_count = count($links);
132
133 // now figure out which one points to the RSS file
134 $href = array ();
135 for ($n=0; $n<$link_count; $n++) {
136 if (strtolower($links[$n]['rel']) == 'alternate') {
137 if (in_array(strtolower($links[$n]['type']), $this->_feed_types)) {
138 $href[] = $links[$n]['href'];
139 } /* if */
140 } /* if */
141 } /* for */
142 return $href;
143 }
144
145 function _a_href_feeds ($obvious = TRUE) {
146 $pattern = ($obvious ? $this->_obvious_feed_url : $this->_maybe_feed_url);
147
148 $links = $this->_tags('a');
149 $link_count = count($links);
150
151 // now figure out which one points to the RSS file
152 $href = array ();
153 for ($n=0; $n<$link_count; $n++) {
154 if (preg_match("\007(".implode('|',$pattern).")\007i", $links[$n]['href'])) {
155 $href[] = $links[$n]['href'];
156 } /* if */
157 } /* for */
158 return $href;
159 }
160
161 function _tags ($tag) {
162 $html = $this->data();
163
164 // search through the HTML, save all <link> tags
165 // and store each link's attributes in an associative array
166 preg_match_all('/<'.$tag.'\s+(.*?)\s*\/?>/si', $html, $matches);
167 $links = $matches[1];
168 $ret = array();
169 $link_count = count($links);
170 for ($n=0; $n<$link_count; $n++) {
171 $attributes = preg_split('/\s+/s', $links[$n]);
172 foreach($attributes as $attribute) {
173 $att = preg_split('/\s*=\s*/s', $attribute, 2);
174 if (isset($att[1])) {
175 $att[1] = preg_replace('/([\'"]?)(.*)\1/', '$2', $att[1]);
176 $final_link[strtolower($att[0])] = $att[1];
177 } /* if */
178 } /* foreach */
179 $ret[$n] = $final_link;
180 } /* for */
181 return $ret;
182 }
183 } /* class FeedFinder */
184
185