2 // PukiWiki - Yet another WikiWikiWeb clone
3 // $Id: showrss.inc.php,v 1.16 2005/01/23 02:06:44 henoheno Exp $
4 // Id:showrss.inc.php,v 1.40 2003/03/18 11:52:58 hiro Exp
6 // Show RSS of remote site plugin
9 * Created by hiro_do3ob@yahoo.co.jp
10 * Modified by PANDA <panda@arino.jp>, and PukiWiki Developer Team
11 * Licence: GPL, same as PukiWiki
12 * This plugin needs 'PHP xml extension'
15 // Show this plugin is enable or not for this PukiWiki
16 function plugin_showrss_action()
18 $xml_extension = extension_loaded('xml');
19 $mbstring_extension = extension_loaded('mbstring');
21 $xml_msg = $xml_extension ? 'xml extension is loaded' : 'COLOR(RED){xml extension is not loaded}';
22 $mbstring_msg = $mbstring_extension ? 'mbstring extension is loaded' : 'COLOR(RED){mbstring extension is not loaded}';
24 '| xml parser | ' . $xml_msg . ' |' . "\n" .
25 '| multibyte | ' . $mbstring_msg . ' |' . "\n";
27 return array('msg' => 'showrss_info', 'body' => convert_html($showrss_info));
30 function plugin_showrss_convert()
32 if (func_num_args() == 0) {
33 return '<p>showrss: no parameter(s).</p>' . "\n";
34 } else if (! extension_loaded('xml')) {
35 return '<p>showrss: xml extension is not loaded</p>' . "\n";
38 $array = func_get_args();
39 $rssurl = $tmplname = $usecache = $usetimestamp = '';
41 switch (func_num_args()) {
42 case 4: $usetimestamp = trim($array[3]);
43 case 3: $usecache = $array[2];
44 case 2: $tmplname = strtolower(trim($array[1]));
45 case 1: $rssurl = trim($array[0]);
48 if (! is_url($rssurl))
49 return '<p>showrss: syntax error. ' . htmlspecialchars($rssurl) . '</p>' . "\n";
51 $class = 'ShowRSS_html_' . $tmplname;
52 if (! class_exists($class)) $class = 'ShowRSS_html';
54 list($rss, $time) = plugin_showrss_get_rss($rssurl, $usecache);
56 return '<p>showrss: cannot get rss from server.</p>' . "\n";
58 $obj = new $class($rss);
61 if ($usetimestamp > 0) {
62 $time = get_date('Y/m/d H:i:s',$time);
63 $timestamp = '<p style="font-size:10px; font-weight:bold">Last-Modified:' . $time . '</p>';
65 return $obj->toString($timestamp);
68 // Create HTML from RSS array()
74 function ShowRSS_html($rss)
76 foreach ($rss as $date=>$items) {
77 foreach ($items as $item) {
78 $link = $item['LINK'];
79 $title = $item['TITLE'];
80 $passage = get_passage($item['_TIMESTAMP']);
81 $link = '<a href="' . $link . '" title="' . $title . ' ' .
82 $passage . '" rel="nofollow">' . $title . '</a>';
83 $this->items[$date][] = $this->format_link($link);
88 function format_link($link)
90 return $link . '<br />' . "\n";
93 function format_list($date, $str)
98 function format_body($str)
103 function toString($timestamp)
106 foreach ($this->items as $date=>$items)
107 $retval .= $this->format_list($date, join('', $items));
108 $retval = $this->format_body($retval);
117 class ShowRSS_html_menubar extends ShowRSS_html
119 var $class = ' class="small"';
121 function format_link($link) {
122 return '<li>' . $link . '</li>' . "\n";
125 function format_body($str) {
126 return '<ul class="recent_list">' . "\n" . $str . '</ul>' . "\n";
130 class ShowRSS_html_recent extends ShowRSS_html
132 var $class = ' class="small"';
134 function format_link($link) {
135 return '<li>' . $link . '</li>' . "\n";
138 function format_list($date, $str) {
139 return '<strong>' . $date . '</strong>' . "\n" .
140 '<ul class="recent_list">' . "\n" . $str . '</ul>' . "\n";
145 function plugin_showrss_get_rss($target, $usecache)
150 // Remove expired cache
151 plugin_showrss_cache_expire($usecache);
153 // Get the cache not expired
154 $filename = CACHE_DIR . encode($target) . '.tmp';
155 if (is_readable($filename)) {
156 $buf = join('', file($filename));
157 $time = filemtime($filename) - LOCALZONE;
161 if ($time === NULL) {
163 $data = http_request($target);
164 if ($data['rc'] !== 200)
165 return array(FALSE, 0);
167 $buf = $data['data'];
170 // Save RSS into cache
172 $fp = fopen($filename, 'w');
179 $obj = new ShowRSS_XML();
180 return array($obj->parse($buf),$time);
183 // Remove cache if expired limit exeed
184 function plugin_showrss_cache_expire($usecache)
186 $expire = $usecache * 60 * 60; // Hour
187 $dh = dir(CACHE_DIR);
188 while (($file = $dh->read()) !== FALSE) {
189 if (substr($file, -4) != '.tmp') continue;
190 $file = CACHE_DIR . $file;
191 $last = time() - filemtime($file);
192 if ($last > $expire) unlink($file);
197 // Get RSS and array() them
208 $this->items = array();
209 $this->item = array();
210 $this->is_item = FALSE;
214 $this->encoding = mb_detect_encoding($buf);
215 if (! in_array(strtolower($this->encoding), array('us-ascii', 'iso-8859-1', 'utf-8'))) {
216 $buf = mb_convert_encoding($buf, 'utf-8', $this->encoding);
217 $this->encoding = 'utf-8';
219 $xml_parser = xml_parser_create($this->encoding);
220 xml_set_element_handler($xml_parser, array(& $this, 'start_element'), array(& $this, 'end_element'));
221 xml_set_character_data_handler($xml_parser, array(& $this, 'character_data'));
223 if (! xml_parse($xml_parser, $buf, 1)) {
224 return(sprintf('XML error: %s at line %d in %s',
225 xml_error_string(xml_get_error_code($xml_parser)),
226 xml_get_current_line_number($xml_parser), $buf));
228 xml_parser_free($xml_parser);
233 function escape($str)
235 // Unescape already-escaped chars (<, >, &, ...) in RSS body before htmlspecialchars()
236 $str = strtr($str, array_flip(get_html_translation_table(ENT_COMPAT)));
238 $str = htmlspecialchars($str);
239 // Encoding conversion
240 $str = mb_convert_encoding($str, SOURCE_ENCODING, $this->encoding);
245 function start_element($parser, $name, $attrs)
247 if ($this->is_item) {
249 } else if ($name == 'ITEM') {
250 $this->is_item = TRUE;
255 function end_element($parser, $name)
257 if (! $this->is_item || $name != 'ITEM') return;
259 $item = array_map(array(& $this, 'escape'), $this->item);
260 $this->item = array();
262 if (isset($item['DC:DATE'])) {
263 $time = plugin_showrss_get_timestamp($item['DC:DATE']);
265 } else if (isset($item['PUBDATE'])) {
266 $time = plugin_showrss_get_timestamp($item['PUBDATE']);
268 } else if (isset($item['DESCRIPTION']) &&
269 ($description = trim($item['DESCRIPTION'])) != '' &&
270 ($time = strtotime($description)) != -1) {
274 $time = time() - LOCALZONE;
276 $item['_TIMESTAMP'] = $time;
277 $date = get_date('Y-m-d', $item['_TIMESTAMP']);
279 $this->items[$date][] = $item;
280 $this->is_item = FALSE;
283 function character_data($parser, $data)
285 if (! $this->is_item) return;
286 if (! isset($this->item[$this->tag])) $this->item[$this->tag] = '';
287 $this->item[$this->tag] .= $data;
291 function plugin_showrss_get_timestamp($str)
293 if (($str = trim($str)) == '')
297 if (! preg_match('/(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(([+-])(\d{2}):(\d{2}))?/', $str, $matches)) {
298 $time = strtotime($str);
299 return ($time == -1) ? UTIME : $time - LOCALZONE;
302 $time = strtotime($matches[1] . ' ' . $matches[2]);
303 if (! empty($matches[3])) {
304 $diff = ($matches[5] * 60 + $matches[6]) * 60;
305 $time += ($matches[4] == '-' ? $diff : -$diff);