3 Deciphers RSS and Atom feeds into a simple array/hash structure. Does not
4 evaluate MIME parameters, but elsewhise is rather compliant, even if it
5 only uses simplified and data-oriented XML extraction.
6 It often can evaluate RDF/"RSS"-1.0 feeds, if they aren't too RDFish
7 (no real parser for that), adn the text-only RSS3.0 is also supported.
9 @depends: http, http_cached, xml
13 #-- fetches, caches and decodes RSS/Atom feeds
14 function ewiki_feed_get($url) {
15 global $ewiki_cache_ctype;
16 if ($xml = ewiki_cache_url($url)) {
17 return ewiki_feed_parse($xml);
22 #-- decodes RSS/Atom feeds into struct/hash
23 function ewiki_feed_parse($xml, $ctype="text/xml") {
27 if (preg_match("/charset=[\"']?([-\w\d]+)/i", $ctype, $uu)) {
31 $charset = "ISO-8859-1"; // default for most stuff over HTTP
35 $xml = new easy_xml_rss($xml, $charset);
37 if (isset($xml->channel)) {
38 $r = array($xml->channel, $xml->item);
43 $item = ewiki_decode_rfc822($xml);
46 $r = array($channel, $item);
48 #-- unified timestamps
49 if ($r[1]) foreach($r[1] as $i=>$d) {
50 $r[1][$i]["time"] = ewiki_decode_datetime($d["pubDate"]);
56 #-- separates multiple blocks of name:value pairs
57 function ewiki_decode_rfc822($text) {
59 foreach (preg_split("/\r?\n\r?\n/", $xml) as $part) {
61 foreach (preg_split("/\r?\n(?>[^\s])/") as $field)
63 $r[trim(strtolower(strtok($field, ":")))]
64 = trim(preg_replace("/\s+/", " ", strtok("\000")));
72 #-- tries to decipher a date+time string into a unixish timestamp
73 function ewiki_decode_datetime($str, $localize=1, $gmt=0) {
75 $months = array_flip(array("Err", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"));
79 and preg_match("/(\d+)-(\d+)-(\d+)(T(\d+):(\d+)(:(\d+))?)?/", $str, $uu)) {
80 $t = gmmktime($uu[5], $uu[6], $uu[8], $uu[2], $uu[3], $uu[1]);
82 #-- mbox, ANSI C asctime()
83 elseif (($str[3] == " ")
84 and preg_match("/\w+ (\w+) +(\d+) (\d+):(\d+):(\d+) (\d+)/", $str, $uu)) {
85 $t = gmmktime($uu[3], $uu[4], $uu[5], $months[$uu[1]], $uu[2], $uu[6]);
88 #-- rfc822/1123, (rfc850/1036), mostly for HTTP
90 and preg_match("/\w+, (\d+)[- ](\w+)[- ](\d+) (\d+):(\d+):(\d+)/", $str, $uu)) {
91 $t = gmmktime($uu[4], $uu[5], $uu[6], $months[$uu[2]], $uu[1], $uu[3]);
94 #-- already was a timestamp
95 elseif (((int)$str) == $str) {
101 $t = strtotime($str);
105 #-- is local time (iso8601 only)
106 if (!$gmt && $localize && preg_match('/([+-])(\d+):(\d+)$/', $str, $uu)) {
107 $dt = $uu[1] * 60 + $uu[2];