2 // $Id: tb.inc.php,v 1.21 2005/06/15 15:57:11 henoheno Exp $
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>
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
17 case 'ja': define('PLUGIN_TB_LANGUAGE', 'ja-jp'); break;
18 default : define('PLUGIN_TB_LANGUAGE', 'en-us'); break;
23 define('PLUGIN_TB_ERROR', 1);
24 define('PLUGIN_TB_NOERROR', 0);
26 function plugin_tb_action()
28 global $trackback, $vars;
30 if ($trackback && isset($vars['url'])) {
31 // Receive and save a TrackBack Ping (both GET and POST)
33 $tb_id = isset($vars['tb_id']) ? $vars['tb_id'] : '';
34 list($error, $message) = plugin_tb_save($url, $tb_id);
36 // Output the response
37 plugin_tb_output_response($error, $message);
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;
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));
56 return array('msg'=>'', 'body'=>'');
62 // Save or update TrackBack Ping data
63 function plugin_tb_save($url, $tb_id)
65 global $vars, $trackback;
66 static $fields = array( /* UTIME, */ 'url', 'title', 'excerpt', 'blog_name');
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);
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');
77 $page = tb_id2page($tb_id);
78 if ($page === FALSE) return array(PLUGIN_TB_ERROR, 'TrackBack ID is invalid.');
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.');
84 // Update TrackBack Ping data
85 $filename = tb_get_filename($page);
86 $data = tb_get($filename);
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;
95 $data[rawurldecode($items['url'])] = $items;
97 $fp = fopen($filename, 'w');
98 set_file_buffer($fp, 0);
101 foreach ($data as $line) {
102 $line = preg_replace('/[\r\n]/s', '', $line); // One line, one ping
103 fwrite($fp, join(',', $line) . "\n");
108 return array(PLUGIN_TB_NOERROR, '');
111 // Show a response code of the ping via HTTP/XML (then exit)
112 function plugin_tb_output_response($rc, $msg = '')
114 if ($rc == PLUGIN_TB_NOERROR) {
115 $rc = 0; // for PLUGIN_TB_NOERROR
117 $rc = 1; // for PLUGIN_TB_ERROR
120 pkwk_common_headers();
121 header('Content-Type: text/xml');
122 echo '<?xml version="1.0" encoding="iso-8859-1"?>';
124 echo ' <error>' . $rc . '</error>';
125 if ($rc) echo '<message>' . $msg . '</message>';
130 // Show pings for the page via RSS
131 function plugin_tb_output_rsslist($tb_id)
133 global $script, $vars, $entity_pattern;
135 $page = tb_id2page($tb_id);
136 if ($page === FALSE) return FALSE;
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);
147 <title>$title</title>
149 <description>$excerpt</description>
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;
163 <?xml version="1.0" encoding="utf-8" ?>
168 <title>$title</title>
170 <description>$excerpt</description>
171 <language>$lang</language>$items
177 pkwk_common_headers();
178 header('Content-Type: text/xml');
179 echo mb_convert_encoding($rc, 'UTF-8', SOURCE_ENCODING);
183 // Show pings for the page via XHTML
184 function plugin_tb_output_htmllist($tb_id)
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.';
197 $page = tb_id2page($tb_id);
198 if ($page === FALSE) return FALSE;
200 $data = tb_get(tb_get_filename($page));
202 // Sort: The first is the latest
203 usort($data, create_function('$a,$b', 'return $b[0] - $a[0];'));
206 foreach ($data as $x) {
207 if (count($x) != 5) continue; // Ignore incorrect record
209 list ($time, $url, $title, $excerpt, $blog_name) = $x;
210 if ($title == '') $title = 'no title';
212 $time = date($_tb_date, $time + LOCALZONE); // May 2, 2003 11:25 AM
218 pkwk_common_headers();
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
225 $meta_content_type = pkwk_output_dtd(PKWK_DTD_XHTML_1_0_TRANSITIONAL, 'UTF-8');
231 $script?tb_id=$tb_id<br /><br />
236 echo mb_convert_encoding($msg, 'UTF-8', SOURCE_ENCODING);