<?php
/*
@package: VEF
@version: 0.1
@author: Comandeer
@desc: Klasa pobierająca RSS/Atom/XML (jak chcesz to możesz nawet JSON dorobić...) z podanego URI
*/
class helper_feeds_Feedarator
{
/*parse
@params: string $URI => URI feeda
@return: array $feed => zawartość feeda jako tablica
@author: Comandeer
@desc: Pobiera feeda z danego URI, obrabia go i zwraca jako tablicę
*/
public function parse($URI)
{
if(!filter_var($URI,FILTER_VALIDATE_URL)) //podany URI nie jest poprawnym linkiem
return false;
$feed=simpleXML_load_file($URI); //w końcu RSS i ATOM to poprawne dokumenty XML (w teorii...)
$type=$feed->getName(); //pobieramy nazwę roota
$method='parse'.$type;
if(method_exists($this,$method)) //jeśli parser takiego typu dokumentu istnieje (może zamiast root element brać po przestrzeni nazw? Mniejsza szansa na pomyłkę... Dupa... RSS nie ma przestrzeni nazw!)
return $this->$method($feed);
return false;
}
/*parseRSS
@params: object: SimpleXML $XML => feed RSS
@return array $feed => przeparsowana zawartość feeda
@author: Comandeer
@desc: Parsuje feeda danego jako parametr i zwraca odpowiednią tablicę
*/
private function parseRSS($XML)
{
$channel=$XML->channel;
$feed=array
(
'link'=>(string)$channel->link,
'title'=>(isset($channel->title))?(string)$channel->title:'(brak tytułu)',
'description'=>(isset($channel->description))?(string)$channel->description:'Brak opisu',
'language'=>(isset($channel->language))?(string)$channel->language:'default',
'image'=>isset($channel->image)?array
(
'title'=>(string)$channel->image->title,
'src'=>(string)$channel->image->url
):NULL
);
foreach($channel->item as $item) //jakby nie było tego tablicowego interfejsu dla obiektu SimpleXML, to sobie nie wyobrażam jego użytkowania...
$feed['items'][]=array
(
'title'=>(isset($item->title))?(string)$item->title:'(brak tytułu)',
'link'=>(string)$item->link,
'description'=>(string)$item->description,
'author'=>(isset($item->author))?(string)$item->author:'Anonim',
'pubdate'=>(isset($item->pubdate))?(string)$item->pubdate:time()
);
return $feed;
}
/*parseFeed
@params: object: SimpleXML $XML => feed Atom
@return array $feed => przeparsowana zawartość feeda
@author: Comandeer
@desc: Parsuje feeda danego jako parametr i zwraca odpowiednią tablicę
*/
private function parseFeed($XML)
{
$channel=$XML;
//roota feed może mieć trzy i trochę formatów - dla pewności sprawdzamy jeszcze przestrzeń nazw
$rattr=(array)$channel->attributes('xml');
$ns=(array)$channel->getDocNamespaces();
if(strtolower((string)$ns['']
$author=(isset($channel->author))?(string)$channel->author->name:'Anonim'; //pobieramy autora feeda
foreach($channel->link as $link) //pobieramy linka do feeda
{
$attr=$link->attributes();
if(!isset($attr['rel']
$link=(string)$attr['href'];
}
$feed=array
(
'link'=>(isset($link))?$link:NULL,
'title'=>(isset($channel->title))?(string)$channel->title:'(brak tytułu)', //nie wiem po co ten workaround, bo w ATOM title jest wymagany
'language'=>(isset($rattr['lang']
'description'=>(isset($channel->description))?(string)$channel->description
);
foreach($channel->entry as $item)
{
foreach($item->link as $link) //wyciągnięcie adresu WWW nie jest zadaniem prostym... ATOM jest bardziej skomplikowany niż RSS
{
$attr=$link->attributes();
if(!isset($attr['rel']
$link=(string)$attr['href'];
}
$feed['items'][]=array
(
'title'=>(isset($item->title))?(string)$item->title:'(brak tytułu)',
'link'=>(isset($link))?$link:'',
'description'=>(isset($item->content))?(string)$item->content
'author'=>(isset($author))?(string)$author:'Anonim',
'pubdate'=>(isset($item->updated))?(string)$item->updated:time()
);
}
return $feed;
}
}
Nie bójcie się śmiesznej nazwy klasy, bo mam po prostu taką konwencję nazewnictwa (hint: własny framework z tandetnym hackiem imitującym namespace).
Przykład zastosowania?
2
3
4
5
6
7
8
require_once('Feedarator.class.php');
$f=new helper_feeds_Feedarator;
$rss=$f->parse('http://kanaly.rss.interia.pl/fakty.xml');
$atom=$f->parse('http://pornel.net/pornelski.atom');
echo '<pre>RSS:';var_dump($rss);echo '</pre>';
echo '<pre>Atom:';var_dump($atom);echo '</pre>';
Życzę miłego oceniania ;D





