OSDN Git Service

BugTrack2/122: tempnam() fails when open_basedir is specified in php.ini
[pukiwiki/pukiwiki.git] / plugin / tb.inc.php
1 <?php
2 // $Id: tb.inc.php,v 1.21 2005/06/15 15:57:11 henoheno Exp $
3 /*
4  * PukiWiki/TrackBack: TrackBack Ping receiver and viewer
5  * (C) 2003-2005 PukiWiki Developers Team
6  * (C) 2003 Katsumi Saito <katsumi@jo1upk.ymt.prug.or.jp>
7  * License: GPL
8  *
9  * plugin_tb_action()    action
10  * plugin_tb_save($url, $tb_id)          Save or update TrackBack Ping data
11  * plugin_tb_output_response($rc, $msg)  Show a response code of the ping via HTTP/XML (then exit)
12  * plugin_tb_output_rsslist($tb_id)      Show pings for the page via RSS
13  * plugin_tb_output_htmllist($tb_id)     Show pings for the page via XHTML
14  */
15
16 switch(LANG){
17 case 'ja': define('PLUGIN_TB_LANGUAGE', 'ja-jp'); break;
18 default  : define('PLUGIN_TB_LANGUAGE', 'en-us'); break;
19 }
20
21 // ----
22
23 define('PLUGIN_TB_ERROR',   1);
24 define('PLUGIN_TB_NOERROR', 0);
25
26 function plugin_tb_action()
27 {
28         global $trackback, $vars;
29
30         if ($trackback && isset($vars['url'])) {
31                 // Receive and save a TrackBack Ping (both GET and POST)
32                 $url   = $vars['url'];
33                 $tb_id = isset($vars['tb_id']) ? $vars['tb_id'] : '';
34                 list($error, $message) = plugin_tb_save($url, $tb_id);
35
36                 // Output the response
37                 plugin_tb_output_response($error, $message);
38                 exit;
39
40         } else {
41                 if ($trackback && isset($vars['__mode']) && isset($vars['tb_id'])) {
42                         // Show TrackBacks received (and exit)
43                         switch ($vars['__mode']) {
44                         case 'rss' : plugin_tb_output_rsslist($vars['tb_id']);  break;
45                         case 'view': plugin_tb_output_htmllist($vars['tb_id']); break;
46                         }
47                         exit;
48
49                 } else {
50                         // Show List of pages that TrackBacks reached
51                         $pages = get_existpages(TRACKBACK_DIR, '.txt');
52                         if (! empty($pages)) {
53                                 return array('msg'=>'Trackback list',
54                                         'body'=>page_list($pages, 'read', FALSE));
55                         } else {
56                                 return array('msg'=>'', 'body'=>'');
57                         }
58                 }
59         }
60 }
61
62 // Save or update TrackBack Ping data
63 function plugin_tb_save($url, $tb_id)
64 {
65         global $vars, $trackback;
66         static $fields = array( /* UTIME, */ 'url', 'title', 'excerpt', 'blog_name');
67
68         $die = '';
69         if (! $trackback) $die .= 'TrackBack feature disabled. ';
70         if ($url   == '') $die .= 'URL parameter is not set. ';
71         if ($tb_id == '') $die .= 'TrackBack Ping ID is not set. ';
72         if ($die != '') return array(PLUGIN_TB_ERROR, $die);
73
74         if (! file_exists(TRACKBACK_DIR)) return array(PLUGIN_TB_ERROR, 'No such directory: TRACKBACK_DIR');
75         if (! is_writable(TRACKBACK_DIR)) return array(PLUGIN_TB_ERROR, 'Permission denied: TRACKBACK_DIR');
76
77         $page = tb_id2page($tb_id);
78         if ($page === FALSE) return array(PLUGIN_TB_ERROR, 'TrackBack ID is invalid.');
79
80         // URL validation (maybe worse of processing time limit)
81         $result = http_request($url, 'HEAD');
82         if ($result['rc'] !== 200) return array(PLUGIN_TB_ERROR, 'URL is fictitious.');
83
84         // Update TrackBack Ping data
85         $filename = tb_get_filename($page);
86         $data     = tb_get($filename);
87
88         $items = array(UTIME);
89         foreach ($fields as $key) {
90                 $value = isset($vars[$key]) ? $vars[$key] : '';
91                 if (preg_match('/[,"' . "\n\r" . ']/', $value))
92                         $value = '"' . str_replace('"', '""', $value) . '"';
93                 $items[$key] = $value;
94         }
95         $data[rawurldecode($items['url'])] = $items;
96
97         $fp = fopen($filename, 'w');
98         set_file_buffer($fp, 0);
99         flock($fp, LOCK_EX);
100         rewind($fp);
101         foreach ($data as $line) {
102                 $line = preg_replace('/[\r\n]/s', '', $line); // One line, one ping
103                 fwrite($fp, join(',', $line) . "\n");
104         }
105         flock($fp, LOCK_UN);
106         fclose($fp);
107
108         return array(PLUGIN_TB_NOERROR, '');
109 }
110
111 // Show a response code of the ping via HTTP/XML (then exit)
112 function plugin_tb_output_response($rc, $msg = '')
113 {
114         if ($rc == PLUGIN_TB_NOERROR) {
115                 $rc = 0; // for PLUGIN_TB_NOERROR
116         } else {
117                 $rc = 1; // for PLUGIN_TB_ERROR
118         }
119
120         pkwk_common_headers();
121         header('Content-Type: text/xml');
122         echo '<?xml version="1.0" encoding="iso-8859-1"?>';
123         echo '<response>';
124         echo ' <error>' . $rc . '</error>';
125         if ($rc) echo '<message>' . $msg . '</message>';
126         echo '</response>';
127         exit;
128 }
129
130 // Show pings for the page via RSS
131 function plugin_tb_output_rsslist($tb_id)
132 {
133         global $script, $vars, $entity_pattern;
134
135         $page = tb_id2page($tb_id);
136         if ($page === FALSE) return FALSE;
137
138         $items = '';
139         foreach (tb_get(tb_get_filename($page)) as $arr) {
140                 // _utime_, title, excerpt, _blog_name_
141                 array_shift($arr); // Cut utime
142                 list ($url, $title, $excerpt) = array_map(
143                         create_function('$a', 'return htmlspecialchars($a);'), $arr);
144                 $items .= <<<EOD
145
146    <item>
147     <title>$title</title>
148     <link>$url</link>
149     <description>$excerpt</description>
150    </item>
151 EOD;
152         }
153
154         $title = htmlspecialchars($page);
155         $link  = $script . '?' . rawurlencode($page);
156         $vars['page'] = $page;
157         $excerpt = strip_htmltag(convert_html(get_source($page)));
158         $excerpt = preg_replace("/&$entity_pattern;/", '', $excerpt);
159         $excerpt = mb_strimwidth(preg_replace("/[\r\n]/", ' ', $excerpt), 0, 255, '...');
160         $lang    = PLUGIN_TB_LANGUAGE;
161
162         $rc = <<<EOD
163 <?xml version="1.0" encoding="utf-8" ?>
164 <response>
165  <error>0</error>
166  <rss version="0.91">
167   <channel>
168    <title>$title</title>
169    <link>$link</link>
170    <description>$excerpt</description>
171    <language>$lang</language>$items
172   </channel>
173  </rss>
174 </response>
175 EOD;
176
177         pkwk_common_headers();
178         header('Content-Type: text/xml');
179         echo mb_convert_encoding($rc, 'UTF-8', SOURCE_ENCODING);
180         exit;
181 }
182
183 // Show pings for the page via XHTML
184 function plugin_tb_output_htmllist($tb_id)
185 {
186         pkwk_common_headers();
187         echo 'This function had been removed now. It will be created soon.<br />' . "\n";
188         echo 'Sorry for your inconvenience.';
189         exit;
190
191         // ----
192         // Skeleton Logic
193
194         global $script;
195         global $_tb_date;
196
197         $page = tb_id2page($tb_id);
198         if ($page === FALSE) return FALSE;
199
200         $data = tb_get(tb_get_filename($page));
201
202         // Sort: The first is the latest
203         usort($data, create_function('$a,$b', 'return $b[0] - $a[0];'));
204
205         $tb_body = '';
206         foreach ($data as $x) {
207                 if (count($x) != 5) continue; // Ignore incorrect record
208
209                 list ($time, $url, $title, $excerpt, $blog_name) = $x;
210                 if ($title == '') $title = 'no title';
211
212                 $time = date($_tb_date, $time + LOCALZONE); // May 2, 2003 11:25 AM
213                 $tb_body .= <<<EOD
214 EOD;
215         }
216
217         // Output start
218         pkwk_common_headers();
219
220         // BugTrack/466 Care for MSIE trouble
221         // Logically correct, but MSIE will treat the data like 'file downloading'
222         //header('Content-type: application/xhtml+xml; charset=UTF-8');
223         header('Content-type: text/html; charset=UTF-8'); // Works well
224
225         $meta_content_type = pkwk_output_dtd(PKWK_DTD_XHTML_1_0_TRANSITIONAL, 'UTF-8');
226         $msg = <<<EOD
227 <head>
228  $meta_content_type
229 </head>
230 <body>
231  $script?tb_id=$tb_id<br /><br />
232  $tb_body
233 </body>
234 </html>
235 EOD;
236         echo mb_convert_encoding($msg, 'UTF-8', SOURCE_ENCODING);
237         exit;
238 }
239 ?>