PluginProbe
FeedWordPress / 2010.0528
FeedWordPress v2010.0528
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 2010.0528, at feedfinder.class.php

198 lines 5.5 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 unset($feed);
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 (!is_wp_error($this->_response) and isset($this->_response['response']['code'])) :
79 $ret = $this->_response['response']['code'];
80 else :
81 $ret = NULL;
82 endif;
83 return $ret;
84 }
85
86 function error ($index = NULL) {
87 $message = NULL;
88 if (count($this->_error) > 0) :
89 if (is_scalar($index) and !is_null($index)) :
90 $message = $this->_error[$index];
91 else :
92 $message = implode(" / ", $this->_error)."\n";
93 endif;
94 endif;
95 return $message;
96 }
97
98 function is_feed ($uri = NULL) {
99 $data = $this->data($uri);
100
101 return (
102 preg_match (
103 "\007(".implode('|',$this->_feed_markers).")\007i",
104 $data
105 ) and !preg_match (
106 "\007(".implode('|',$this->_html_markers).")\007i",
107 $data
108 )
109 );
110 } /* FeedFinder::is_feed () */
111
112 # --- Private methods ---
113 function _get ($uri = NULL) {
114 if ($uri) $this->uri = $uri;
115
116 // Is the result not yet cached?
117 if ($this->_cache_uri !== $this->uri) :
118 $headers['Connection'] = 'close';
119 $headers['Accept'] = 'application/atom+xml application/rdf+xml application/rss+xml application/xml text/html */*';
120 $headers['User-Agent'] = 'feedfinder/1.2 (compatible; PHP FeedFinder) +http://projects.radgeek.com/feedwordpress';
121
122 // Use WordPress API function
123 $client = wp_remote_request($this->uri, array(
124 'headers' => $headers,
125 'timeout' => FEEDWORDPRESS_FETCH_TIME_OUT,
126 ));
127
128 $this->_response = $client;
129 if (is_wp_error($client)) :
130 $this->_data = NULL;
131 $this->_error = $client->get_error_messages();
132 else :
133 $this->_data = $client['body'];
134 $this->_error = NULL;
135 endif;
136
137 // Kilroy was here
138 $this->_cache_uri = $this->uri;
139 endif;
140 } /* FeedFinder::_get () */
141
142 function _link_rel_feeds () {
143 $links = $this->_tags('link');
144 $link_count = count($links);
145
146 // now figure out which one points to the RSS file
147 $href = array ();
148 for ($n=0; $n<$link_count; $n++) {
149 if (strtolower($links[$n]['rel']) == 'alternate') {
150 if (in_array(strtolower($links[$n]['type']), $this->_feed_types)) {
151 $href[] = $links[$n]['href'];
152 } /* if */
153 } /* if */
154 } /* for */
155 return $href;
156 }
157
158 function _a_href_feeds ($obvious = TRUE) {
159 $pattern = ($obvious ? $this->_obvious_feed_url : $this->_maybe_feed_url);
160
161 $links = $this->_tags('a');
162 $link_count = count($links);
163
164 // now figure out which one points to the RSS file
165 $href = array ();
166 for ($n=0; $n<$link_count; $n++) {
167 if (preg_match("\007(".implode('|',$pattern).")\007i", $links[$n]['href'])) {
168 $href[] = $links[$n]['href'];
169 } /* if */
170 } /* for */
171 return $href;
172 }
173
174 function _tags ($tag) {
175 $html = $this->data();
176
177 // search through the HTML, save all <link> tags
178 // and store each link's attributes in an associative array
179 preg_match_all('/<'.$tag.'\s+(.*?)\s*\/?>/si', $html, $matches);
180 $links = $matches[1];
181 $ret = array();
182 $link_count = count($links);
183 for ($n=0; $n<$link_count; $n++) {
184 $attributes = preg_split('/\s+/s', $links[$n]);
185 foreach($attributes as $attribute) {
186 $att = preg_split('/\s*=\s*/s', $attribute, 2);
187 if (isset($att[1])) {
188 $att[1] = preg_replace('/([\'"]?)(.*)\1/', '$2', $att[1]);
189 $final_link[strtolower($att[0])] = $att[1];
190 } /* if */
191 } /* foreach */
192 $ret[$n] = $final_link;
193 } /* for */
194 return $ret;
195 }
196 } /* class FeedFinder */
197
198