OSDN Git Service

rss取得に失敗したときのエラー処理を追加
[pukiwiki/pukiwiki.git] / plugin / showrss.inc.php
1 <?php
2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
4 //
5 // $Id: showrss.inc.php,v 1.11 2003/12/03 12:30:02 arino Exp $
6 //
7 // modified by PANDA <panda@arino.jp>
8 //
9
10 /**
11  *
12  * showrss ¥×¥é¥°¥¤¥ó
13  * 
14  * ¥é¥¤¥»¥ó¥¹¤Ï PukiWiki ËÜÂΤÈƱ¤¸¤¯ GNU General Public License (GPL) ¤Ç¤¹¡£
15  * http://www.gnu.org/licenses/gpl.txt
16  *
17  * pukiwikiÍѤΥץ饰¥¤¥ó¤Ç¤¹¡£
18  * pukiwiki1.3.2°Ê¾å¤ÇÆ°¤¯¤È»×¤¤¤Þ¤¹¡£
19  * 
20  * º£¤Î¤È¤³¤íÆ°ºî¤µ¤»¤ë¤¿¤á¤Ë¤ÏPHP ¤Î xml extension ¤¬É¬¿Ü¤Ç¤¹¡£PHP¤ËÁȤ߹þ¤Þ¤ì¤Æ¤Ê¤¤¾ì¹ç¤Ï¤½¤Ã¤±¤Ê¤¤¥¨¥é¡¼¤¬½Ð¤ë¤È»×¤¤¤Þ¤¹¡£
21  * Àµµ¬É½¸½ or Ê¸»úÎó´Ø¿ô¤Ç¤Ê¤ó¤È¤«¤Ê¤é¤Ê¤¯¤â¤Ê¤µ¤²¤Ê¤ó¤Ç¤¹¤¬¼ûÍפäƤɤ줯¤é¤¤¤¢¤ë¤Î¤«¤ï¤«¤é¤¤¤Î¤ÇÊÝα¤Ç¤¹¡£
22  * mbstring ¤â¤¢¤ë¤Û¤¦¤¬¤¤¤¤¤Ç¤¹¡£
23  * 
24  * ¤Ê¤¤¾ì¹ç¤Ï¡¢ jcode.phps ¤ò¤Á¤ç¤³¤Ã¤È¤¤¤¸¤Ã¤Æ mb_convert_encoding ¤È¤¤¤¦´Ø¿ô¤òÀë¸À¤·¤Æ¤ª¤±¤Ð¤È¤ê¤¢¤¨¤º¤½¤ì¤Ã¤Ý¤¯ÊÑ´¹¤Ç¤­¤ë¤«¤â¤Ç¤¹¡£
25  * http://www.spencernetwork.org/
26  * 
27  * ¤´Ï¢ÍíÀè:
28  * do3ob wiki   ->   http://do3ob.com/
29  * email        ->   hiro_do3ob@yahoo.co.jp
30  * 
31  * ÈòÆñ½ê       ->   http://do3ob.s20.xrea.com/
32  *
33  * version: Id:showrss.inc.php,v 1.40 2003/03/18 11:52:58 hiro Exp
34  * 
35  */
36
37 // showrss¥×¥é¥°¥¤¥ó¤¬»ÈÍѲÄǽ¤«¤É¤¦¤«¤òɽ¼¨
38 function plugin_showrss_action()
39 {
40         $xml_extension = extension_loaded('xml');
41         $mbstring_extension = extension_loaded('mbstring');
42
43         $xml_msg      = $xml_extension      ? 'xml extension is loaded' : 'COLOR(RED){xml extension is not loaded}';
44         $mbstring_msg = $mbstring_extension ? 'mbstring extension is loaded' : 'COLOR(RED){mbstring extension is not loaded}';
45
46         $showrss_info = '';
47         $showrss_info .= "| xml parser | $xml_msg |\n";
48         $showrss_info .= "| multibyte | $mbstring_msg |\n";
49
50         return array('msg' => 'showrss_info', 'body' => convert_html($showrss_info));
51 }
52
53 function plugin_showrss_convert()
54 {
55         if (func_num_args() == 0)
56         {
57                 // °ú¿ô¤¬¤Ê¤¤¾ì¹ç¤Ï¥¨¥é¡¼
58                 return "<p>showrss: no parameter(s).</p>\n";
59         }
60         if (!extension_loaded('xml'))
61         {
62                 // xml ³ÈÄ¥µ¡Ç½¤¬Í­¸ú¤Ç¤Ê¤¤¾ì¹ç¡£
63                 return "<p>showrss: xml extension is not loaded</p>\n";
64         }
65
66         $array = func_get_args();
67         $rssurl = $tmplname = $usecache = $usetimestamp = '';
68
69         switch (func_num_args())
70         {
71                 case 4:
72                         $usetimestamp = trim($array[3]);
73                 case 3:
74                         $usecache = $array[2];
75                 case 2:
76                         $tmplname = strtolower(trim($array[1]));
77                 case 1:
78                         $rssurl = trim($array[0]);
79         }
80
81         // RSS ¥Ñ¥¹¤ÎÃÍ¥Á¥§¥Ã¥¯
82         if (!is_url($rssurl))
83         {
84                 return '<p>showrss: syntax error. '.htmlspecialchars($rssurl)."</p>\n";
85         }
86
87         $class = "ShowRSS_html_$tmplname";
88         if (!class_exists($class))
89         {
90                 $class = 'ShowRSS_html';
91         }
92
93         list($rss,$time) = plugin_showrss_get_rss($rssurl,$usecache);
94         if ($rss === FALSE)
95         {
96                 return "<p>showrss: cannot get rss from server.</p>\n";
97         }
98
99         $obj = new $class($rss);
100
101         $timestamp = '';
102         if ($usetimestamp > 0)
103         {
104                 $time = get_date('Y/m/d H:i:s',$time);
105                 $timestamp = "<p style=\"font-size:10px; font-weight:bold\">Last-Modified:$time</p>";
106         }
107         return $obj->toString($timestamp);
108 }
109 // rssÇÛÎ󤫤éhtml¤òºî¤ë
110 class ShowRSS_html
111 {
112         var $items = array();
113         var $class = '';
114
115         function ShowRSS_html($rss)
116         {
117                 foreach ($rss as $date=>$items)
118                 {
119                         foreach ($items as $item)
120                         {
121                                 $link = $item['LINK'];
122                                 $title = $item['TITLE'];
123                                 $passage = get_passage($item['_TIMESTAMP']);
124                                 $link = "<a href=\"$link\" title=\"$title $passage\">$title</a>";
125                                 $this->items[$date][] = $this->format_link($link);
126                         }
127                 }
128         }
129         function format_link($link)
130         {
131                 return "$link<br />\n";
132         }
133         function format_list($date,$str)
134         {
135                 return $str;
136         }
137         function format_body($str)
138         {
139                 return $str;
140         }
141         function toString($timestamp)
142         {
143                 $retval = '';
144                 foreach ($this->items as $date=>$items)
145                 {
146                         $retval .= $this->format_list($date,join('',$items));
147                 }
148                 $retval = $this->format_body($retval);
149                 return <<<EOD
150 <div{$this->class}>
151 $retval$timestamp
152 </div>
153 EOD;
154         }
155 }
156 class ShowRSS_html_menubar extends ShowRSS_html
157 {
158         var $class = ' class="small"';
159
160         function format_link($link)
161         {
162                 return "<li>$link</li>\n";
163         }
164         function format_body($str)
165         {
166                 return "<ul class=\"recent_list\">\n$str</ul>\n";
167         }
168 }
169 class ShowRSS_html_recent extends ShowRSS_html
170 {
171         var $class = ' class="small"';
172
173         function format_link($link)
174         {
175                 return "<li>$link</li>\n";
176         }
177         function format_list($date,$str)
178         {
179                 return "<strong>$date</strong>\n<ul class=\"recent_list\">\n$str</ul>\n";
180         }
181 }
182 // rss¤ò¼èÆÀ¤¹¤ë
183 function plugin_showrss_get_rss($target,$usecache)
184 {
185         $buf = '';
186         $time = NULL;
187         if ($usecache)
188         {
189                 // ´ü¸ÂÀÚ¤ì¤Î¥­¥ã¥Ã¥·¥å¤ò¥¯¥ê¥¢
190                 plugin_showrss_cache_expire($usecache);
191
192                 // ¥­¥ã¥Ã¥·¥å¤¬¤¢¤ì¤Ð¼èÆÀ¤¹¤ë
193                 $filename = CACHE_DIR . encode($target) . '.tmp';
194                 if (is_readable($filename))
195                 {
196                         $buf = join('',file($filename));
197                         $time = filemtime($filename) - LOCALZONE;
198                 }
199         }
200         if ($time === NULL)
201         {
202                 // rssËÜÂΤò¼èÆÀ
203                 $data = http_request($target);
204                 if ($data['rc'] !== 200)
205                 {
206                         return array(FALSE,0);
207                 }
208                 $buf = $data['data'];
209                 $time = UTIME;
210                 // ¥­¥ã¥Ã¥·¥å¤òÊݸ
211                 if ($usecache)
212                 {
213                         $fp = fopen($filename, 'w');
214                         fwrite($fp,$buf);
215                         fclose($fp);
216                 }
217         }
218
219         // parse
220         $obj = new ShowRSS_XML();
221         return array($obj->parse($buf),$time);
222 }
223 // ´ü¸ÂÀÚ¤ì¤Î¥­¥ã¥Ã¥·¥å¤ò¥¯¥ê¥¢
224 function plugin_showrss_cache_expire($usecache)
225 {
226         $expire = $usecache * 60 * 60; // Hour
227
228         $dh = dir(CACHE_DIR);
229         while (($file = $dh->read()) !== FALSE)
230         {
231                 if (substr($file,-4) != '.tmp')
232                 {
233                         continue;
234                 }
235                 $file = CACHE_DIR.$file;
236                 $last = time() - filemtime($file);
237
238                 if ($last > $expire)
239                 {
240                         unlink($file);
241                 }
242         }
243         $dh->close();
244 }
245 // rss¤ò¼èÆÀ¡¦ÇÛÎó²½
246 class ShowRSS_XML
247 {
248         var $items;
249         var $item;
250         var $is_item;
251         var $tag;
252
253         function parse($buf)
254         {
255                 // ½é´ü²½
256                 $this->items = array();
257                 $this->item = array();
258                 $this->is_item = FALSE;
259                 $this->tag = '';
260
261                 $xml_parser = xml_parser_create();
262                 xml_set_element_handler($xml_parser,array(&$this,'start_element'),array(&$this,'end_element'));
263                 xml_set_character_data_handler($xml_parser,array(&$this,'character_data'));
264
265                 if (!xml_parse($xml_parser,$buf,1))
266                 {
267                         return(sprintf('XML error: %s at line %d in %s',
268                                 xml_error_string(xml_get_error_code($xml_parser)),
269                                 xml_get_current_line_number($xml_parser),$buf));
270                 }
271                 xml_parser_free($xml_parser);
272
273                 return $this->items;
274         }
275         function escape($str)
276         {
277                 // RSSÃæ¤Î "&lt; &gt; &amp;" ¤Ê¤É¤ò °ìö "< > &" ¤ËÌᤷ¡¢ ¡ã "&amp;" ¤¬ "&amp;amp;" ¤Ë¤Ê¤Ã¤Á¤ã¤¦¤ÎÂкö
278                 // ¤½¤Î¸å¤â¤Ã¤«¤¤"< > &"¤Ê¤É¤ò"&lt; &gt; &amp;"¤Ë¤¹¤ë  ¡ã XSSÂкö¡©
279                 $str = strtr($str, array_flip(get_html_translation_table(ENT_COMPAT)));
280                 $str = htmlspecialchars($str);
281
282                 // Ê¸»ú¥³¡¼¥ÉÊÑ´¹
283                 $str = mb_convert_encoding($str, SOURCE_ENCODING, 'auto');
284
285                 return trim($str);
286         }
287
288         // ¥¿¥°³«»Ï
289         function start_element($parser,$name,$attrs)
290         {
291                 if ($this->is_item)
292                 {
293                         $this->tag = $name;
294                 }
295                 else if ($name == 'ITEM')
296                 {
297                         $this->is_item = TRUE;
298                 }
299         }
300         // ¥¿¥°½ªÎ»
301         function end_element($parser,$name)
302         {
303                 if (!$this->is_item or $name != 'ITEM')
304                 {
305                         return;
306                 }
307                 $item = array_map(array(&$this,'escape'),$this->item);
308
309                 $this->item = array();
310
311                 if (array_key_exists('DC:DATE',$item))
312                 {
313                         $time = plugin_showrss_get_timestamp($item['DC:DATE']);
314                 }
315                 else if (array_key_exists('PUBDATE',$item))
316                 {
317                         $time = plugin_showrss_get_timestamp($item['PUBDATE']);
318                 }
319                 else if (array_key_exists('DESCRIPTION',$item)
320                         and ($description = trim($item['DESCRIPTION'])) != ''
321                         and ($time = strtotime($description)) != -1)
322                 {
323                         $time -= LOCALZONE;
324                 }
325                 else
326                 {
327                         $time = time() - LOCALZONE;
328                 }
329                 $item['_TIMESTAMP'] = $time;
330                 $date = get_date('Y-m-d',$item['_TIMESTAMP']);
331
332                 $this->items[$date][] = $item;
333                 $this->is_item = FALSE;
334         }
335         // ¥­¥ã¥é¥¯¥¿
336         function character_data($parser,$data)
337         {
338                 if (!$this->is_item)
339                 {
340                         return;
341                 }
342                 if (!array_key_exists($this->tag,$this->item))
343                 {
344                         $this->item[$this->tag] = '';
345                 }
346                 $this->item[$this->tag] .= $data;
347         }
348 }
349 function plugin_showrss_get_timestamp($str)
350 {
351         if (($str = trim($str)) == '')
352         {
353                 return UTIME;
354         }
355         if (!preg_match('/(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(([+-])(\d{2}):(\d{2}))?/',$str,$matches))
356         {
357                 $time = strtotime($str);
358                 return ($time == -1) ? UTIME : $time - LOCALZONE;
359         }
360         $str = $matches[1];
361         $time = strtotime($matches[1].' '.$matches[2]);
362         if (!empty($matches[3]))
363         {
364                 $diff = ($matches[5]*60+$matches[6])*60;
365                 $time += ($matches[4] == '-' ? $diff : -$diff);
366         }
367         return $time;
368 }
369 ?>