[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * SimplePie 4 * 5 * A PHP-Based RSS and Atom Feed Framework. 6 * Takes the hard work out of managing a complete RSS/Atom solution. 7 * 8 * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without modification, are 12 * permitted provided that the following conditions are met: 13 * 14 * * Redistributions of source code must retain the above copyright notice, this list of 15 * conditions and the following disclaimer. 16 * 17 * * Redistributions in binary form must reproduce the above copyright notice, this list 18 * of conditions and the following disclaimer in the documentation and/or other materials 19 * provided with the distribution. 20 * 21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used 22 * to endorse or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * @package SimplePie 36 * @version 1.3.1 37 * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue 38 * @author Ryan Parman 39 * @author Geoffrey Sneddon 40 * @author Ryan McCue 41 * @link http://simplepie.org/ SimplePie 42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 43 */ 44 45 /** 46 * Used for feed auto-discovery 47 * 48 * 49 * This class can be overloaded with {@see SimplePie::set_locator_class()} 50 * 51 * @package SimplePie 52 */ 53 class SimplePie_Locator 54 { 55 var $useragent; 56 var $timeout; 57 var $file; 58 var $local = array(); 59 var $elsewhere = array(); 60 var $cached_entities = array(); 61 var $http_base; 62 var $base; 63 var $base_location = 0; 64 var $checked_feeds = 0; 65 var $max_checked_feeds = 10; 66 protected $registry; 67 68 public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10) 69 { 70 $this->file = $file; 71 $this->useragent = $useragent; 72 $this->timeout = $timeout; 73 $this->max_checked_feeds = $max_checked_feeds; 74 75 if (class_exists('DOMDocument')) 76 { 77 $this->dom = new DOMDocument(); 78 79 set_error_handler(array('SimplePie_Misc', 'silence_errors')); 80 $this->dom->loadHTML($this->file->body); 81 restore_error_handler(); 82 } 83 else 84 { 85 $this->dom = null; 86 } 87 } 88 89 public function set_registry(SimplePie_Registry $registry) 90 { 91 $this->registry = $registry; 92 } 93 94 public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working) 95 { 96 if ($this->is_feed($this->file)) 97 { 98 return $this->file; 99 } 100 101 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 102 { 103 $sniffer = $this->registry->create('Content_Type_Sniffer', array($this->file)); 104 if ($sniffer->get_type() !== 'text/html') 105 { 106 return null; 107 } 108 } 109 110 if ($type & ~SIMPLEPIE_LOCATOR_NONE) 111 { 112 $this->get_base(); 113 } 114 115 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) 116 { 117 return $working[0]; 118 } 119 120 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links()) 121 { 122 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) 123 { 124 return $working; 125 } 126 127 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) 128 { 129 return $working; 130 } 131 132 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) 133 { 134 return $working; 135 } 136 137 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) 138 { 139 return $working; 140 } 141 } 142 return null; 143 } 144 145 public function is_feed($file) 146 { 147 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 148 { 149 $sniffer = $this->registry->create('Content_Type_Sniffer', array($file)); 150 $sniffed = $sniffer->get_type(); 151 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml'))) 152 { 153 return true; 154 } 155 else 156 { 157 return false; 158 } 159 } 160 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) 161 { 162 return true; 163 } 164 else 165 { 166 return false; 167 } 168 } 169 170 public function get_base() 171 { 172 if ($this->dom === null) 173 { 174 throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); 175 } 176 $this->http_base = $this->file->url; 177 $this->base = $this->http_base; 178 $elements = $this->dom->getElementsByTagName('base'); 179 foreach ($elements as $element) 180 { 181 if ($element->hasAttribute('href')) 182 { 183 $base = $this->registry->call('Misc', 'absolutize_url', array(trim($element->getAttribute('href')), $this->http_base)); 184 if ($base === false) 185 { 186 continue; 187 } 188 $this->base = $base; 189 $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0; 190 break; 191 } 192 } 193 } 194 195 public function autodiscovery() 196 { 197 $done = array(); 198 $feeds = array(); 199 $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds)); 200 $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds)); 201 $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds)); 202 203 if (!empty($feeds)) 204 { 205 return array_values($feeds); 206 } 207 else 208 { 209 return null; 210 } 211 } 212 213 protected function search_elements_by_tag($name, &$done, $feeds) 214 { 215 if ($this->dom === null) 216 { 217 throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); 218 } 219 220 $links = $this->dom->getElementsByTagName($name); 221 foreach ($links as $link) 222 { 223 if ($this->checked_feeds === $this->max_checked_feeds) 224 { 225 break; 226 } 227 if ($link->hasAttribute('href') && $link->hasAttribute('rel')) 228 { 229 $rel = array_unique($this->registry->call('Misc', 'space_seperated_tokens', array(strtolower($link->getAttribute('rel'))))); 230 $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1; 231 232 if ($this->base_location < $line) 233 { 234 $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base)); 235 } 236 else 237 { 238 $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base)); 239 } 240 if ($href === false) 241 { 242 continue; 243 } 244 245 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href])) 246 { 247 $this->checked_feeds++; 248 $headers = array( 249 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', 250 ); 251 $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent)); 252 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) 253 { 254 $feeds[$href] = $feed; 255 } 256 } 257 $done[] = $href; 258 } 259 } 260 261 return $feeds; 262 } 263 264 public function get_links() 265 { 266 if ($this->dom === null) 267 { 268 throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); 269 } 270 271 $links = $this->dom->getElementsByTagName('a'); 272 foreach ($links as $link) 273 { 274 if ($link->hasAttribute('href')) 275 { 276 $href = trim($link->getAttribute('href')); 277 $parsed = $this->registry->call('Misc', 'parse_url', array($href)); 278 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) 279 { 280 if ($this->base_location < $link->getLineNo()) 281 { 282 $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base)); 283 } 284 else 285 { 286 $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base)); 287 } 288 if ($href === false) 289 { 290 continue; 291 } 292 293 $current = $this->registry->call('Misc', 'parse_url', array($this->file->url)); 294 295 if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority']) 296 { 297 $this->local[] = $href; 298 } 299 else 300 { 301 $this->elsewhere[] = $href; 302 } 303 } 304 } 305 } 306 $this->local = array_unique($this->local); 307 $this->elsewhere = array_unique($this->elsewhere); 308 if (!empty($this->local) || !empty($this->elsewhere)) 309 { 310 return true; 311 } 312 return null; 313 } 314 315 public function extension(&$array) 316 { 317 foreach ($array as $key => $value) 318 { 319 if ($this->checked_feeds === $this->max_checked_feeds) 320 { 321 break; 322 } 323 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml'))) 324 { 325 $this->checked_feeds++; 326 327 $headers = array( 328 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', 329 ); 330 $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent)); 331 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) 332 { 333 return $feed; 334 } 335 else 336 { 337 unset($array[$key]); 338 } 339 } 340 } 341 return null; 342 } 343 344 public function body(&$array) 345 { 346 foreach ($array as $key => $value) 347 { 348 if ($this->checked_feeds === $this->max_checked_feeds) 349 { 350 break; 351 } 352 if (preg_match('/(rss|rdf|atom|xml)/i', $value)) 353 { 354 $this->checked_feeds++; 355 $headers = array( 356 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', 357 ); 358 $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent)); 359 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) 360 { 361 return $feed; 362 } 363 else 364 { 365 unset($array[$key]); 366 } 367 } 368 } 369 return null; 370 } 371 } 372
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |