4 * Simple RSSParser Class
5 * Based on Duncan Gough RSSParser class
6 * Copyleft Arnaud Fontaine
8 * See lib/plugin/RssFeed.php and lib/XmlParser.php
10 * The myth of RSS compatibility:
11 * http://diveintomark.org/archives/2004/02/04/incompatible-rss
15 * This file is part of PhpWiki.
17 * PhpWiki is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * PhpWiki is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License along
28 * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
29 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 * 2004-04-09 16:30:50 rurban:
34 * added fsockopen allow_url_fopen = Off workaround
35 * 2004-04-12 20:04:12 rurban:
36 * fixes for IMAGE element (sf.net)
37 * 2005-04-10 11:17:35 rurban
38 * certain RSS dont contain <item> tags to describe the list of <items>
39 * http://ws.audioscrobbler.com/rdf/ for example
42 require_once 'lib/XmlParser.php';
52 public $description = "";
53 public $inside_item = false;
54 public $list_items = false;
55 public $item = array();
61 function tag_open($parser, $name, $attrs = '')
63 global $current_tag, $current_attrs;
66 $current_attrs = $attrs;
68 $this->inside_item = true;
69 elseif ($name == "ITEMS")
70 $this->list_items = true; elseif ($name == "IMAGE")
71 $this->inside_item = true;
74 function tag_close($parser, $tagName, $attrs = '')
78 if ($tagName == "ITEM") {
79 if (empty($this->items)) {
80 $this->items = array();
81 $GLOBALS['rss_parser_items'] =& $this->items;
82 } elseif (!empty($this->items[0]['link']) and $this->items[0]['title'] == '') {
83 // override the initial <items> list with detailed <item>'s
84 $this->items = array();
85 $GLOBALS['rss_parser_items'] =& $this->items;
87 $this->items[] = array("title" => $this->item['TITLE'],
88 "author" => $this->item['AUTHOR'],
89 "pubDate" => $this->item['PUBDATE'],
90 "description" => @$this->item['DESCRIPTION'],
91 "link" => $this->item['LINK']);
92 $this->item = array("TITLE" => "",
95 $this->inside_item = false;
96 } elseif ($tagName == "IMAGE") {
97 $this->item = array("TITLE" => "",
100 $this->inside_item = false;
101 } elseif ($tagName == "CHANNEL") {
102 $this->channel = array("title" => $this->title,
103 "description" => $this->description,
104 "link" => $this->link,
105 "date" => $this->date,
106 "divers" => $this->divers);
107 $GLOBALS['rss_parser_channel'] =& $this->channel;
109 $this->description = "";
113 } elseif ($tagName == "ITEMS") {
114 $GLOBALS['rss_parser_items'] =& $this->items;
115 $this->item = array("TITLE" => "",
118 $this->list_items = false;
122 function cdata($parser, $data)
124 global $current_tag, $current_attrs;
126 if ($this->inside_item) {
127 if (empty($this->item[$current_tag]))
128 $this->item[$current_tag] = '';
129 if ($current_tag == 'LINK') {
131 $this->item[$current_tag] = trim($data);
133 $this->item[$current_tag] .= trim($data);
135 } elseif ($this->list_items) {
136 if ($current_tag == 'RDF:LI') {
137 // FIXME: avoid duplicates. cdata called back 4x per RDF:LI
138 if ($this->items[count($this->items) - 1]['link'] != @$current_attrs['RDF:RESOURCE'])
139 $this->items[] = array('link' => @$current_attrs['RDF:RESOURCE'],
143 switch ($current_tag) {
146 $this->title .= " " . trim($data);
150 $this->description .= trim($data);
154 $this->link = trim($data);
158 $this->date .= " " . trim($data);
161 $this->divers .= " " . $current_tag . "/" . $data;
167 function parse($content, $is_final = true)
169 xml_parse($this->_parser, $content, $is_final) or
170 trigger_error(sprintf("XML error: %s at line %d",
171 xml_error_string(xml_get_error_code($this->_parser)),
172 xml_get_current_line_number($this->_parser)),
174 //OO workaround: parser object looses its params. we have to store them in globals
176 if (empty($this->items)) {
177 $this->items = @$GLOBALS['rss_parser_items'];
178 $this->channel = @$GLOBALS['rss_parser_channel'];
180 unset($GLOBALS['rss_parser_items']);
181 unset($GLOBALS['rss_parser_channel']);
190 // c-hanging-comment-ender-p: nil
191 // indent-tabs-mode: nil