library/SimplePie/Locator.php Quellcode

Locator.php
gehe zur Dokumentation dieser Datei
1 <?php
54 {
56  var $timeout;
57  var $file;
58  var $local = array();
59  var $elsewhere = array();
60  var $cached_entities = array();
62  var $base;
63  var $base_location = 0;
64  var $checked_feeds = 0;
66  protected $registry;
67 
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 
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 
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 




Korrekturen, Hinweise und Ergänzungen

Bitte scheuen Sie sich nicht und melden Sie, was auf dieser Seite sachlich falsch oder irreführend ist, was ergänzt werden sollte, was fehlt usw. Dazu bitte oben aus dem Menü Seite den Eintrag Support Forum wählen. Es ist eine kostenlose Anmeldung erforderlich, um Anmerkungen zu posten. Unpassende Postings, Spam usw. werden kommentarlos entfernt.