2 // $Id: trackback.php,v 1.4 2003/06/22 05:39:07 arino Exp $
4 * PukiWiki TrackBack ¥×¥í¥°¥é¥à
5 * (C) 2003, Katsumi Saito <katsumi@jo1upk.ymt.prug.or.jp>
8 * http://localhost/pukiwiki/pukiwiki.php?FrontPage ¤ÈÌÀ³Î¤Ë»ØÄꤷ¤Ê¤¤¤È
9 * TrackBack ID ¤Î¼èÆÀ¤Ï¤Ç¤¤Ê¤¤
11 * tb_count($page) TrackBack Ping ¥Ç¡¼¥¿¸Ä¿ô¼èÆÀ // pukiwiki.skin.LANG.php
12 * tb_send($page,$data) TrackBack Ping Á÷¿® // file.php
13 * tb_ScanLink($data) convert_html() ÊÑ´¹·ë²Ì¤Î <a> ¥¿¥°¤«¤é URL Ãê½Ð
14 * tb_PageInfo($page) ¥Ú¡¼¥¸¾ðÊó¼èÆÀ
15 * tb_xml_msg($rc,$msg) XML ·ë²Ì½ÐÎÏ
16 * tb_save() TrackBack Ping ¥Ç¡¼¥¿Êݸ(¹¹¿·)
17 * tb_delete($page) TrackBack Ping ¥Ç¡¼¥¿ºï½ü // edit.inc.php
18 * tb_get($file) TrackBack Ping ¥Ç¡¼¥¿ÆþÎÏ
19 * tb_put($file,$data) TrackBack Ping ¥Ç¡¼¥¿½ÐÎÏ
20 * tb_mode_rss($file) ?__mode=rss ½èÍý
21 * tb_mode_view($id) ?__mode=view ½èÍý
22 * tb_body($file) TrackBack Ping ÌÀºÙ¹ÔÊÔ½¸
23 * tb_sort_by_date_d($p1, $p2) ¥Ç¡¼¥¿¤òÆüÉÕ½ç¡Ê¹ß½ç¡Ë¤ÇÀ°Îó
24 * tb_id2page($id) TrackBack ID ¤«¤é¥Ú¡¼¥¸Ì¾¼èÆÀ
25 * tb_http($url, $method="GET", $headers="", $post=array(""))
26 * GET, POST, HEAD ¤Ê¤É¤Î»ØÄê½èÍý¤ª¤è¤Ó ¥ì¥¹¥Ý¥ó¥¹¥³¡¼¥É¼èÆÀ
27 * tb_PutID($page) ʸ¾ÏÃæ¤Ë trackback:ping ¤òËä¤á¹þ¤à¤¿¤á¤Î¥Ç¡¼¥¿¤òÀ¸À® // pukiwiki.php
28 * tb_GetID($url) ʸ½ñ¤ò GET ¤·¡¢Ëä¤á¹þ¤Þ¤ì¤¿ TrackBack ID ¤ò¼èÆÀ
29 * tb_xml_GetId($data) Ëä¤á¹þ¤Þ¤ì¤¿¥Ç¡¼¥¿¤«¤é TrackBack ID ¤ò¼èÆÀ
30 * tb_startElementHandler_GetId($parser, $name, $attribs)
31 * xml_set_element_handler´Ø¿ô¤Ç¥»¥Ã¥È¤·¤¿ startElementHandler
32 * tb_xg_dummy($parser, $name) xml_set_element_handler´Ø¿ô¤Ç¥»¥Ã¥È¤·¤¿ EndElementHandler
36 if (!defined('TRACKBACK_DIR')) {
37 define('TRACKBACK_DIR','./trackback/');
40 // TrackBack Ping ¥Ç¡¼¥¿¸Ä¿ô¼èÆÀ
41 function tb_count($page) {
43 $page_enc = md5($page);
44 $file = TRACKBACK_DIR.$page_enc.".txt";
46 // TRACKBACK_DIR ¤Î¸ºß¤È½ñ¤¹þ¤ß²Äǽ¤«¤Î³Îǧ
47 if (file_exists($file) === false) {
50 return count( file($file) );
53 // TrackBack Ping Á÷¿®
54 function tb_send($page,$data) {
55 global $script, $trackback;
57 if (!$trackback) return;
58 set_time_limit( 0 ); // ½èÍý¼Â¹Ô»þ´ÖÀ©¸Â(php.ini ¥ª¥×¥·¥ç¥ó max_execution_time )
60 $link = tb_ScanLink($data);
61 if (!is_array($link)) return; // ¥ê¥ó¥¯Ìµ¤·¤Ï½ªÎ»
62 $r_page = rawurlencode($page);
66 $putdata["title"] = $page; // ¥¿¥¤¥È¥ë¤Ï¥Ú¡¼¥¸Ì¾
67 $putdata["url"] = $script."?".$r_page; // Á÷¿®»þ¤ËºÆÅÙ¡¢rawurlencode ¤µ¤ì¤ë
68 $putdata["excerpt"] = tb_PageInfo($page);
69 $putdata["blog_name"] = "PukiWiki/TrackBack 0.1";
70 $putdata["charset"] = SOURCE_ENCODING; // Á÷¿®Â¦Ê¸»ú¥³¡¼¥É(̤´ûÄê)
72 foreach ($link as $x) {
73 // URL ¤«¤é TrackBack ID ¤ò¼èÆÀ¤¹¤ë
75 if (empty($tbid)) continue; // TrackBack ¤ËÂбþ¤·¤Æ¤¤¤Ê¤¤
76 list($resp,$header,$data,$query) = tb_http($tbid,"POST","",$putdata);
77 // FIXME: ¥¨¥é¡¼½èÍý¤ò¹Ô¤Ã¤Æ¤â¡¢¤¸¤ã¡¢¤É¤¦¤¹¤ë¡©¤À¤·¤Ê¤¡...
82 // convert_html() ÊÑ´¹·ë²Ì¤Î <a> ¥¿¥°¤«¤é URL Ãê½Ð
83 function tb_ScanLink($data) {
85 $string = convert_html($data);
88 while (preg_match("'(href=)(\"|\')(http:?[^\"^\'^\>]+)'si", $string, $regs)) {
90 $string = str_replace($regs[3], "", $string);
96 function tb_PageInfo($page) {
97 // ÍøÍÑ¥Ú¡¼¥¸¤Î°ú¿ô¤Ê¤·
98 if (empty($page)) return "";
103 $body = get_source($page);
104 foreach ($body as $x) {
105 if ($x[0] == '/' && $x[1] == '/') continue; // PukiWiki ¤È¤·¤Æ¤Ï¡¢¥³¥á¥ó¥È¹Ô
106 $excerpt .= trim($x);
107 $ctr_len += strlen(trim($x));
108 if ($ctr_len > 255) break; // 255 ¤òĶ²á¤·¤¿»þÅÀ¤Ç½ªÎ»
114 function tb_xml_msg($rc,$msg) {
115 $x = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n".
117 "<error>".$rc."</error>\n";
118 if (!empty($msg)) $x .= "<message>".$msg."</message>\n";
119 $x .= "</response>\n";
120 header('Content-Type: text/xml');
125 // TrackBack Ping ¥Ç¡¼¥¿Êݸ(¹¹¿·)
127 global $script,$vars,$post;
129 // TrackBack Ping ¤Ë¤ª¤±¤ë URL ¥Ñ¥é¥á¡¼¥¿¤Ïɬ¿Ü¤Ç¤¢¤ë¡£
130 if (empty($post["url"])) {
131 tb_xml_msg(1,"It is an indispensable parameter. URL is not set up.");
134 // URL ÂÅÅöÀ¥Á¥§¥Ã¥¯ (¤³¤ì¤òÆþ¤ì¤ë¤È½èÍý»þ´Ö¤ËÌäÂ꤬¤Ç¤ë)
135 list($res,$hed,$dat,$query) = tb_http($post["url"],"HEAD");
137 tb_xml_msg(1,"URL is fictitious.");
140 // TRACKBACK_DIR ¤Î¸ºß¤È½ñ¤¹þ¤ß²Äǽ¤«¤Î³Îǧ
141 if (file_exists(TRACKBACK_DIR) === false) {
142 die(TRACKBACK_DIR.": No such directory");
144 if (is_writable(TRACKBACK_DIR) === false) {
145 die(TRACKBACK_DIR.": Permission denied");
148 // Query String ¤òÆÀ¤ë
149 if (empty($vars["tb_id"])) {
150 tb_xml_msg(1,"TrackBack Ping URL is inaccurate.");
153 // ¥Ú¡¼¥¸Â¸ºß¥Á¥§¥Ã¥¯
154 $page = tb_id2page($vars["tb_id"]);
155 if ($page == $vars["tb_id"]) {
156 tb_xml_msg(1,"TrackBack ID is invalid.");
159 // TrackBack Ping ¤Î¥Ç¡¼¥¿¤òÆɤ߹þ¤à
160 $rc = tb_put(TRACKBACK_DIR.$vars["tb_id"].".txt",tb_get(TRACKBACK_DIR.$vars["tb_id"].".txt"));
165 // TrackBack Ping ¥Ç¡¼¥¿ºï½ü
166 function tb_delete($page) { @unlink(TRACKBACK_DIR.md5($page).".txt"); }
168 // TrackBack Ping ¥Ç¡¼¥¿ÆþÎÏ
169 function tb_get($file) {
170 if (!file_exists($file)) {
177 $fp = @fopen ($file,"r");
178 while ($data = @fgetcsv($fp, 8192, ",")) {
185 // TrackBack Ping ¥Ç¡¼¥¿½ÐÎÏ
186 function tb_put($file,$data) {
187 global $script,$vars,$post;
190 if (empty($post["charset"])) $post["charset"] = "auto";
191 $post["title"] = mb_convert_encoding($post["title"],SOURCE_ENCODING,$post["charset"]);
192 $post["excerpt"] = mb_convert_encoding($post["excerpt"],SOURCE_ENCODING,$post["charset"]);
193 $post["blog_name"] = mb_convert_encoding($post["blog_name"],SOURCE_ENCODING,$post["charset"]);
195 if (!($fp = fopen($file,"w"))) return 1;
196 @flock($fp, LOCK_EX);
198 // ¥«¥ó¥Þ¤¬Æþ¤Ã¤Æ¤âÎɤ¤¤è¤¦¤Ë¡£(¤Ê¤ó¤«°ã¤¦¤È»×¤¦¤Ê¤¡)
199 $post["url"] = rawurlencode($post["url"]);
200 $post["title"] = rawurlencode($post["title"]);
201 $post["excerpt"] = rawurlencode($post["excerpt"]);
202 $post["blog_name"] = rawurlencode($post["blog_name"]);
204 $sw_put = 0; // ¹¹¿·ÍÑ
205 if ($data !== false) {
206 foreach ($data as $x) {
207 if ($x[1] == $post["url"]) {
210 $x[2] = $post["title"];
211 $x[3] = $post["excerpt"];
212 $x[4] = $post["blog_name"];
214 // UTIME, url, title, excerpt, blog_name
215 fwrite($fp, $x[0].",".$x[1].",".$x[2].",".$x[3].",".$x[4]."\n");
219 // ¹¹¿·¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢£±·ïÄɲ乤ë
221 fwrite($fp, UTIME.",".$post["url"].",".$post["title"].",".$post["excerpt"].",".$post["blog_name"]."\n");
224 @flock($fp, LOCK_UN);
231 function tb_mode_rss($file) {
233 $data = tb_get($file);
235 if ($data === false) {
236 tb_xml_msg(1,"TrackBack Ping data does not exist.");
240 <?xml version="1.0" encoding="utf-8" ?>
249 foreach ($data as $x) {
250 if ($sw_item) $rc .= "<item>\n";
251 $x[1] = rawurldecode($x[1]);
252 $x[2] = rawurldecode($x[2]);
253 $x[3] = rawurldecode($x[3]);
254 // UTIME, url, title, excerpt, blog_name
258 <description>$x[3]</description>
264 $rc .= "<language>ja-Jp</language>\n";
276 $rc = mb_convert_encoding($rc,"utf-8",SOURCE_ENCODING);
277 header('Content-Type: text/xml');
282 function tb_mode_view($tbid) {
283 global $script, $page_title;
284 global $_tb_title, $_tb_header, $_tb_entry, $_tb_refer;
286 // TrackBack ID ¤«¤é¥Ú¡¼¥¸Ì¾¤ò¼èÆÀ
287 $page = tb_id2page($tbid);
288 $r_page = rawurlencode($page);
289 $file = TRACKBACK_DIR.$tbid.".txt";
291 $tb_title = sprintf($_tb_title,$page);
292 $tb_refer = sprintf($_tb_refer,"<a href=\"$script?$r_page\">'$page'</a>","<a href=\"$script\">$page_title</a>");
295 <?xml version="1.0" encoding="UTF-8"?>
296 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
297 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
299 <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
300 <title>$tb_title</title>
301 <link rel="stylesheet" href="skin/trackback.css" type="text/css" />
304 <div id="banner-commentspop">$_tb_header</div>
307 <div class="trackback-url">
309 $script?plugin=tb&tb_id=$tbid <br /><br />
314 $msg .= tb_body($file);
321 $msg = mb_convert_encoding($msg,"UTF-8",SOURCE_ENCODING);
326 // TrackBack Ping ÌÀºÙ¹ÔÊÔ½¸
327 function tb_body($file) {
328 global $_tb_header_Excerpt, $_tb_header_Weblog, $_tb_header_Tracked, $_tb_date;
330 $data = tb_get($file);
331 if ($data === false) return;
334 usort($data, 'tb_sort_by_date_d');
337 foreach ($data as $x) {
338 // UTIME, url, title, excerpt, blog_name
339 $x[0] = date($_tb_date, $x[0]+LOCALZONE); // May 2, 2003 11:25 AM
340 $x[1] = rawurldecode($x[1]); // URL
341 $x[2] = rawurldecode($x[2]); // title
342 $x[3] = rawurldecode($x[3]); // excerpt
343 $x[4] = rawurldecode($x[4]); // blog_name
345 <div class="trackback-body">
346 <span class="trackback-post"><a href="$x[1]" target="new">$x[2]</a><br />
347 <strong>$_tb_header_Excerpt</strong> $x[3]<br />
348 <strong>$_tb_header_Weblog</strong> $x[4]<br />
349 <strong>$_tb_header_Tracked</strong> $x[0]</span>
357 // ¥Ç¡¼¥¿¤òÆüÉÕ½ç¡Ê¹ß½ç¡Ë¤ÇÀ°Îó
358 function tb_sort_by_date_d($p1, $p2) {
359 return ($p2['0'] - $p1['0']);
362 // TrackBack ID ¤«¤é¥Ú¡¼¥¸Ì¾¼èÆÀ
363 function tb_id2page($id) {
366 if (!is_array($tb_pages)) {
367 $tb_pages = get_existpages();
368 natcasesort($tb_pages);
371 foreach ($tb_pages as $x) {
372 if ($id == md5(rawurlencode($x))) return rawurldecode($x);
374 return $id; // ¸«¤Ä¤«¤é¤Ê¤¤¾ì¹ç
379 * $url : http://¤«¤é»Ï¤Þ¤ëURL( http://user:pass@host:port/path?query )
380 * $method : GET, POST, HEAD¤Î¤¤¤º¤ì¤«(¥Ç¥Õ¥©¥ë¥È¤ÏGET)
381 * $headers : Ǥ°Õ¤ÎÄɲåإåÀ
382 * $post : POST¤Î»þ¤ËÁ÷¿®¤¹¤ë¥Ç¡¼¥¿¤ò³ÊǼ¤·¤¿ÇÛÎó("ÊÑ¿ô̾"=>"ÃÍ")
384 function tb_http($url, $method="GET", $headers="", $post=array(""))
387 $url_arry = parse_url($url);
390 if (isset($url_arry['query'])) {
391 $url_arry['query'] = "?".$url_arry['query'];
393 $url_arry['query'] = "";
396 if (isset($url_arry['fragment'])) {
397 $url_arry['fragment'] = "#".$url_arry['fragment'];
399 $url_arry['fragment'] = "";
402 if (!isset($url_arry['port'])) $url_arry['port'] = 80;
404 $query = $method." ".
405 $url_arry['path'].$url_arry['query'].$url_arry['fragment'].
407 $query .= "Host: ".$url_arry['host']."\r\n";
408 $query .= "User-Agent: PukiWiki/TrackBack 0.1\r\n";
411 if (isset($url_arry['user']) && isset($url_arry['pass'])) {
412 $query .= "Authorization: Basic ".
413 base64_encode($url_arry['user'].":".$url_arry['pass'])."\r\n";
418 // POST »þ¤Ï¡¢urlencode ¤·¤¿¥Ç¡¼¥¿¤È¤¹¤ë
419 if (strtoupper($method) == "POST") {
420 while (list($name, $val) = each($post)) {
421 $POST[] = $name."=".urlencode($val);
423 $data = implode("&", $POST);
424 $query .= "Content-Type: application/x-www-form-urlencoded\r\n";
425 $query .= "Content-Length: ".strlen($data)."\r\n";
432 $fp = fsockopen($url_arry['host'], $url_arry['port'], $errno, $errstr, 30);
435 $rc[0] = 406; // Not Acceptable
436 $rc[1] = ""; // Header
438 $rc[3] = $query; // Query String
441 // Proxy ·Ðͳ¤Î¾ì¹ç¤Ï¡¢¼ºÇÔ¤·¡¢errno ¤Ï 0 ¤È¤Ê¤ë¡£
442 // Warning: fsockopen() [http://www.php.net/function.fsockopen]:
443 // php_network_getaddresses: gethostbyname failed in C:\var\www\html\pukiwiki\trackback.php on line 457
444 // Warning: fsockopen() [http://www.php.net/function.fsockopen]:
445 // unable to connect to xxxx.xx.xx:80 in C:\var\www\html\pukiwiki\trackback.php on line 457
446 // ¤³¤ÎÁàºî¤òÀµ¤·¤¯½ªÎ»¤·¤Þ¤·¤¿¡£
448 $rc[0] = $errno; // ¥¨¥é¡¼ÈÖ¹æ
449 $rc[1] = ""; // Header
450 $rc[2] = $errstr; // ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸
451 $rc[3] = $query; // Query String
453 // die("trackback.php: $errstr ($errno)\n");
460 $response .= fgets($fp, 4096);
464 $resp = split("\r\n\r\n", $response, 2);
465 $rccd = strtok($resp[0]," ");
466 $rc[0] = strtok(" "); // Response Code
467 $rc[0] = $rc[0] * 1; // ¿ô»ú·¿¤ËÊÑ´¹
468 $rc[1] = $resp[0]; // Header
469 $rc[2] = $resp[1]; // Data
470 $rc[3] = $query; // Query String
474 // ʸ¾ÏÃæ¤Ë trackback:ping ¤òËä¤á¹þ¤à¤¿¤á¤Î¥Ç¡¼¥¿¤òÀ¸À®
475 function tb_PutId($page) {
476 global $script,$trackback;
478 if (!$trackback) return "";
480 $r_page = rawurlencode($page);
481 $page_enc = md5($r_page);
482 // $dcdate = substr_replace(get_date('Y-m-d\TH:i:sO',$time),':',-2,0);
487 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
488 xmlns:dc="http://purl.org/dc/elements/1.1/"
489 xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
491 rdf:about="$script?$r_page"
492 dc:identifier="$script?$r_page"
494 trackback:ping="$script?plugin=tb&tb_id=$page_enc" />
501 // ʸ½ñ¤ò GET ¤·¡¢Ëä¤á¹þ¤Þ¤ì¤¿ TrackBack ID ¤ò¼èÆÀ
502 function tb_GetID($url) {
503 global $tb_get_url, $tb_get_id;
508 // 0: Response Code, 1:Header, 2:Data, 3:Query String
509 $data = tb_http($url);
510 if ($data[0] !== 200) return "";
513 while (preg_match("'(<rdf:RDF .*?>)(.*?)(</rdf:RDF>)'si",$data[2],$regs)) {
514 tb_xml_GetId($regs[1].$regs[2].$regs[3]);
515 if (!empty($tb_get_id)) return $tb_get_id;
516 $data[2] = str_replace($regs[1].$regs[2].$regs[3], "", $data[2]);
521 // Ëä¤á¹þ¤Þ¤ì¤¿¥Ç¡¼¥¿¤«¤é TrackBack ID ¤ò¼èÆÀ
522 function tb_xml_GetId($data) {
523 // XML ¥Ñ¡¼¥µ¤òºîÀ®¤¹¤ë
524 $xml_parser = xml_parser_create();
525 if (!$xml_parser) return;
527 // start ¤ª¤è¤Ó end Í×ÁǤΥϥó¥É¥é¤òÀßÄꤹ¤ë
528 xml_set_element_handler($xml_parser, "tb_startElementHandler_GetId", "tb_xg_dummy");
529 xml_parse($xml_parser, $data, 0);
530 xml_parser_free($xml_parser);
534 // xml_set_element_handler´Ø¿ô¤Ç¥»¥Ã¥È¤·¤¿ startElementHandler
535 function tb_startElementHandler_GetId($parser, $name, $attribs) {
536 global $tb_get_url, $tb_get_id;
538 if ($name !== "RDF:DESCRIPTION") return;
540 $tbid = $tburl = $tbabout = "";
541 foreach ($attribs as $key=>$value) {
542 // print "KEY=".$key." VAL=".$value."\n";
543 if ($key == "RDF:ABOUT") {
547 if ($key == "DC:IDENTIFER" || $key == "DC:IDENTIFIER") {
551 if ($key == "TRACKBACK:PING") {
557 // print "URL:".$tb_get_url."=".$tburl."\n";
558 // print "TBID:".$tbid."\n";
559 if ($tb_get_url == $tburl || $tb_get_url == $tbabout) $tb_get_id = $tbid;
562 // xml_set_element_handler´Ø¿ô¤Ç¥»¥Ã¥È¤·¤¿ EndElementHandler
563 function tb_xg_dummy($parser, $name) { return; }