SimplePie_Locator

Used for feed auto-discovery.

Defined (1)

The class is defined in the following location(s).

/wp-includes/SimplePie/Locator.php  
  1. class SimplePie_Locator 
  2. var $useragent; 
  3. var $timeout; 
  4. var $file; 
  5. var $local = array(); 
  6. var $elsewhere = array(); 
  7. var $cached_entities = array(); 
  8. var $http_base; 
  9. var $base; 
  10. var $base_location = 0; 
  11. var $checked_feeds = 0; 
  12. var $max_checked_feeds = 10; 
  13. protected $registry; 
  14.  
  15. public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10) 
  16. $this->file = $file; 
  17. $this->useragent = $useragent; 
  18. $this->timeout = $timeout; 
  19. $this->max_checked_feeds = $max_checked_feeds; 
  20.  
  21. if (class_exists('DOMDocument')) 
  22. $this->dom = new DOMDocument(); 
  23.  
  24. set_error_handler(array('SimplePie_Misc', 'silence_errors')); 
  25. $this->dom->loadHTML($this->file->body); 
  26. restore_error_handler(); 
  27. else 
  28. $this->dom = null; 
  29.  
  30. public function set_registry(SimplePie_Registry $registry) 
  31. $this->registry = $registry; 
  32.  
  33. public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working) 
  34. if ($this->is_feed($this->file)) 
  35. return $this->file; 
  36.  
  37. if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 
  38. $sniffer = $this->registry->create('Content_Type_Sniffer', array($this->file)); 
  39. if ($sniffer->get_type() !== 'text/html') 
  40. return null; 
  41.  
  42. if ($type & ~SIMPLEPIE_LOCATOR_NONE) 
  43. $this->get_base(); 
  44.  
  45. if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) 
  46. return $working[0]; 
  47.  
  48. if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links()) 
  49. if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) 
  50. return $working; 
  51.  
  52. if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) 
  53. return $working; 
  54.  
  55. if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) 
  56. return $working; 
  57.  
  58. if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) 
  59. return $working; 
  60. return null; 
  61.  
  62. public function is_feed($file) 
  63. if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 
  64. $sniffer = $this->registry->create('Content_Type_Sniffer', array($file)); 
  65. $sniffed = $sniffer->get_type(); 
  66. if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml'))) 
  67. return true; 
  68. else 
  69. return false; 
  70. elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) 
  71. return true; 
  72. else 
  73. return false; 
  74.  
  75. public function get_base() 
  76. if ($this->dom === null) 
  77. throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); 
  78. $this->http_base = $this->file->url; 
  79. $this->base = $this->http_base; 
  80. $elements = $this->dom->getElementsByTagName('base'); 
  81. foreach ($elements as $element) 
  82. if ($element->hasAttribute('href')) 
  83. $base = $this->registry->call('Misc', 'absolutize_url', array(trim($element->getAttribute('href')), $this->http_base)); 
  84. if ($base === false) 
  85. continue; 
  86. $this->base = $base; 
  87. $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0; 
  88. break; 
  89.  
  90. public function autodiscovery() 
  91. $done = array(); 
  92. $feeds = array(); 
  93. $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds)); 
  94. $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds)); 
  95. $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds)); 
  96.  
  97. if (!empty($feeds)) 
  98. return array_values($feeds); 
  99. else 
  100. return null; 
  101.  
  102. protected function search_elements_by_tag($name, &$done, $feeds) 
  103. if ($this->dom === null) 
  104. throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); 
  105.  
  106. $links = $this->dom->getElementsByTagName($name); 
  107. foreach ($links as $link) 
  108. if ($this->checked_feeds === $this->max_checked_feeds) 
  109. break; 
  110. if ($link->hasAttribute('href') && $link->hasAttribute('rel')) 
  111. $rel = array_unique($this->registry->call('Misc', 'space_seperated_tokens', array(strtolower($link->getAttribute('rel'))))); 
  112. $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1; 
  113.  
  114. if ($this->base_location < $line) 
  115. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base)); 
  116. else 
  117. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base)); 
  118. if ($href === false) 
  119. continue; 
  120.  
  121. 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])) 
  122. $this->checked_feeds++; 
  123. $headers = array( 
  124. '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',  
  125. ); 
  126. $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent)); 
  127. 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)) 
  128. $feeds[$href] = $feed; 
  129. $done[] = $href; 
  130.   
  131. return $feeds; 
  132.   
  133. public function get_links() 
  134. if ($this->dom === null) 
  135. throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); 
  136.   
  137. $links = $this->dom->getElementsByTagName('a'); 
  138. foreach ($links as $link) 
  139. if ($link->hasAttribute('href')) 
  140. $href = trim($link->getAttribute('href')); 
  141. $parsed = $this->registry->call('Misc', 'parse_url', array($href)); 
  142. if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) 
  143. if (method_exists($link, 'getLineNo') && $this->base_location < $link->getLineNo()) 
  144. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base)); 
  145. else 
  146. $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base)); 
  147. if ($href === false) 
  148. continue; 
  149.   
  150. $current = $this->registry->call('Misc', 'parse_url', array($this->file->url)); 
  151.   
  152. if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority']) 
  153. $this->local[] = $href; 
  154. else 
  155. $this->elsewhere[] = $href; 
  156. $this->local = array_unique($this->local); 
  157. $this->elsewhere = array_unique($this->elsewhere); 
  158. if (!empty($this->local) || !empty($this->elsewhere)) 
  159. return true; 
  160. return null; 
  161.   
  162. public function extension(&$array) 
  163. foreach ($array as $key => $value) 
  164. if ($this->checked_feeds === $this->max_checked_feeds) 
  165. break; 
  166. if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml'))) 
  167. $this->checked_feeds++; 
  168.   
  169. $headers = array( 
  170. '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',  
  171. ); 
  172. $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent)); 
  173. 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)) 
  174. return $feed; 
  175. else 
  176. unset($array[$key]); 
  177. return null; 
  178.  
  179. public function body(&$array) 
  180. foreach ($array as $key => $value) 
  181. if ($this->checked_feeds === $this->max_checked_feeds) 
  182. break; 
  183. if (preg_match('/(rss|rdf|atom|xml)/i', $value)) 
  184. $this->checked_feeds++; 
  185. $headers = array( 
  186. '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',  
  187. ); 
  188. $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent)); 
  189. 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)) 
  190. return $feed; 
  191. else 
  192. unset($array[$key]); 
  193. return null;