OSDN Git Service

Please use abstruct method $vars instead of $get or $post
[pukiwiki/pukiwiki.git] / trackback.php
1 <?php
2 // $Id: trackback.php,v 1.17 2004/07/09 23:47:48 henoheno Exp $
3 /*
4  * PukiWiki TrackBack ¥×¥í¥°¥é¥à
5  * (C) 2003, Katsumi Saito <katsumi@jo1upk.ymt.prug.or.jp>
6  * License: GPL
7  *
8  * http://localhost/pukiwiki/pukiwiki.php?FrontPage ¤ÈÌÀ³Î¤Ë»ØÄꤷ¤Ê¤¤¤È
9  * TrackBack ID ¤Î¼èÆÀ¤Ï¤Ç¤­¤Ê¤¤
10  *
11  * tb_get_id($page)       TrackBack Ping ID¤ò¼èÆÀ
12  * tb_id2page($tb_id)     TrackBack Ping ID ¤«¤é¥Ú¡¼¥¸Ì¾¤ò¼èÆÀ
13  * tb_get_filename($page) TrackBack Ping ¥Ç¡¼¥¿¥Õ¥¡¥¤¥ë̾¤ò¼èÆÀ
14  * tb_count($page)        TrackBack Ping ¥Ç¡¼¥¿¸Ä¿ô¼èÆÀ  // pukiwiki.skin.LANG.php
15  * tb_send($page,$data)   TrackBack Ping Á÷¿®  // file.php
16  * tb_delete($page)       TrackBack Ping ¥Ç¡¼¥¿ºï½ü  // edit.inc.php
17  * tb_get($file,$key=1)   TrackBack Ping ¥Ç¡¼¥¿ÆþÎÏ
18  * tb_get_rdf($page)      Ê¸¾ÏÃæ¤ËËä¤á¹þ¤à¤¿¤á¤Îrdf¤ò¥Ç¡¼¥¿¤òÀ¸À® // pukiwiki.php
19  * tb_get_url($url)       Ê¸½ñ¤òGET¤·¡¢Ëä¤á¹þ¤Þ¤ì¤¿TrackBack Ping URL¤ò¼èÆÀ
20  * class TrackBack_XML    XML¤«¤éTrackBack Ping ID¤ò¼èÆÀ¤¹¤ë¥¯¥é¥¹
21  * == Referer Âбþʬ ==
22  * ref_save($page)        Referer ¥Ç¡¼¥¿Êݸ(¹¹¿·) // pukiwiki.php
23  */
24
25 // TrackBack Ping ID¤ò¼èÆÀ
26 function tb_get_id($page)
27 {
28         return md5($page);
29 }
30
31 // TrackBack Ping ID ¤«¤é¥Ú¡¼¥¸Ì¾¤ò¼èÆÀ
32 function tb_id2page($tb_id)
33 {
34         static $pages,$cache = array();
35         
36         if (array_key_exists($tb_id,$cache))
37         {
38                 return $cache[$tb_id];
39         }
40         if (!isset($pages))
41         {
42                 $pages = get_existpages();
43         }
44         foreach ($pages as $page)
45         {
46                 $_tb_id = tb_get_id($page);
47                 $cache[$_tb_id] = $page;
48                 unset($pages[$page]);
49                 if ($_tb_id == $tb_id)
50                 {
51                         return $page;
52                 }
53         }
54         return FALSE; // ¸«¤Ä¤«¤é¤Ê¤¤¾ì¹ç
55 }
56
57 // TrackBack Ping ¥Ç¡¼¥¿¥Õ¥¡¥¤¥ë̾¤ò¼èÆÀ
58 function tb_get_filename($page,$ext='.txt')
59 {
60         return TRACKBACK_DIR.encode($page).$ext;
61 }
62
63 // TrackBack Ping ¥Ç¡¼¥¿¸Ä¿ô¼èÆÀ
64 function tb_count($page,$ext='.txt')
65 {
66         $filename = tb_get_filename($page,$ext);
67         return file_exists($filename) ? count(file($filename)) : 0;
68 }
69
70 // TrackBack Ping Á÷¿®
71 function tb_send($page,$data)
72 {
73         global $script,$trackback;
74         
75         if (!$trackback)
76         {
77                 return;
78         }
79
80         // ½èÍý¼Â¹Ô»þ´ÖÀ©¸Â(php.ini ¥ª¥×¥·¥ç¥ó max_execution_time )
81         if (ini_get('safe_mode') == '0') set_time_limit(0);
82         
83         $data = convert_html($data);
84         
85         // convert_html() ÊÑ´¹·ë²Ì¤Î <a> ¥¿¥°¤«¤é URL Ãê½Ð
86         preg_match_all('#href="(https?://[^"]+)"#',$data,$links,PREG_PATTERN_ORDER);
87         
88         // ¼«¥Û¥¹¥È($script¤Ç»Ï¤Þ¤ëurl)¤ò½ü¤¯
89         $links = preg_grep("/^(?!".preg_quote($script,'/')."\?)./",$links[1]);
90                 
91         // ¥ê¥ó¥¯Ìµ¤·¤Ï½ªÎ»
92         if (!is_array($links) or count($links) == 0)
93         {
94                 return;
95         }
96         
97         $r_page = rawurlencode($page);
98         $excerpt = strip_htmltag(convert_html(get_source($page)));
99         
100         // ¼«Ê¸½ñ¤Î¾ðÊó
101         $putdata = array(
102                 'title'     => $page, // ¥¿¥¤¥È¥ë¤Ï¥Ú¡¼¥¸Ì¾
103                 'url'       => "$script?$r_page", // Á÷¿®»þ¤ËºÆÅÙ¡¢rawurlencode ¤µ¤ì¤ë
104                 'excerpt'   => mb_strimwidth(preg_replace("/[\r\n]/",' ',$excerpt),0,255,'...'),
105                 'blog_name' => 'PukiWiki/TrackBack 0.1',
106                 'charset'   => SOURCE_ENCODING // Á÷¿®Â¦Ê¸»ú¥³¡¼¥É(̤´ûÄê)
107         );
108         foreach ($links as $link)
109         {
110                 // URL ¤«¤é TrackBack ID ¤ò¼èÆÀ¤¹¤ë
111                 $tb_id = tb_get_url($link);
112                 if (empty($tb_id)) // TrackBack ¤ËÂбþ¤·¤Æ¤¤¤Ê¤¤
113                 {
114                         continue;
115                 }
116                 $result = http_request($tb_id,'POST','',$putdata);
117                 // FIXME: ¥¨¥é¡¼½èÍý¤ò¹Ô¤Ã¤Æ¤â¡¢¤¸¤ã¡¢¤É¤¦¤¹¤ë¡©¤À¤·¤Ê¤¡...
118         }
119 }
120
121 // TrackBack Ping ¥Ç¡¼¥¿ºï½ü
122 function tb_delete($page)
123 {
124         $filename = tb_get_filename($page);
125         if (file_exists($filename))
126         {
127                 @unlink($filename);
128         }
129 }
130
131 // TrackBack Ping ¥Ç¡¼¥¿ÆþÎÏ
132 function tb_get($file,$key=1)
133 {
134         if (!file_exists($file))
135         {
136                 return array();
137         }
138         
139         $result = array();
140         $fp = @fopen($file,'r');
141         set_file_buffer($fp, 0);
142         flock($fp,LOCK_EX);
143         rewind($fp);
144         while ($data = @fgetcsv($fp,8192,','))
145         {
146                 // $data[$key] = URL
147                 $result[rawurldecode($data[$key])] = $data;
148         }
149         flock($fp,LOCK_UN);
150         fclose ($fp);
151         
152         return $result;
153 }
154
155 // Ê¸¾ÏÃæ¤Ë trackback:ping ¤òËä¤á¹þ¤à¤¿¤á¤Î¥Ç¡¼¥¿¤òÀ¸À®
156 function tb_get_rdf($page)
157 {
158         global $script,$trackback;
159         
160         if (!$trackback)
161         {
162                 return '';
163         }
164         
165         $r_page = rawurlencode($page);
166         $tb_id = tb_get_id($page);
167         // $dcdate = substr_replace(get_date('Y-m-d\TH:i:sO',$time),':',-2,0);
168         // dc:date="$dcdate"
169         
170         return <<<EOD
171 <!--
172 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
173   xmlns:dc="http://purl.org/dc/elements/1.1/"
174   xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
175  <rdf:Description
176    rdf:about="$script?$r_page"
177    dc:identifier="$script?$r_page"
178    dc:title="$page"
179    trackback:ping="$script?tb_id=$tb_id" />
180 </rdf:RDF>
181 -->
182 EOD;
183 }
184
185 // Ê¸½ñ¤òGET¤·¡¢Ëä¤á¹þ¤Þ¤ì¤¿TrackBack Ping url¤ò¼èÆÀ
186 function tb_get_url($url)
187 {
188         // ¥×¥í¥­¥·¤ò·Ðͳ¤¹¤ëɬÍפ¬¤¢¤ë¥Û¥¹¥È¤Ë¤Ïping¤òÁ÷¿®¤·¤Ê¤¤
189         $parse_url = parse_url($url);
190         if (empty($parse_url['host']) or via_proxy($parse_url['host']))
191         {
192                 return '';
193         }
194         
195         $data = http_request($url);
196         
197         if ($data['rc'] !== 200)
198         {
199                 return '';
200         }
201         
202         if (!preg_match_all('#<rdf:RDF[^>]*>(.*?)</rdf:RDF>#si',$data['data'],$matches,PREG_PATTERN_ORDER))
203         {
204                 return '';
205         }
206         
207         $obj = new TrackBack_XML();
208         foreach ($matches[1] as $body)
209         {
210                 $tb_url = $obj->parse($body,$url);
211                 if ($tb_url !== FALSE)
212                 {
213                         return $tb_url;
214                 }
215         }
216         return '';
217 }
218
219 // Ëä¤á¹þ¤Þ¤ì¤¿¥Ç¡¼¥¿¤«¤é TrackBack Ping url¤ò¼èÆÀ¤¹¤ë¥¯¥é¥¹
220 class TrackBack_XML
221 {
222         var $url;
223         var $tb_url;
224         
225         function parse($buf,$url)
226         {
227                 // ½é´ü²½
228                 $this->url = $url;
229                 $this->tb_url = FALSE;
230                 
231                 $xml_parser = xml_parser_create();
232                 if ($xml_parser === FALSE)
233                 {
234                         return FALSE;
235                 }
236                 xml_set_element_handler($xml_parser,array(&$this,'start_element'),array(&$this,'end_element'));
237                 
238                 if (!xml_parse($xml_parser,$buf,TRUE))
239                 {
240 /*                      die(sprintf('XML error: %s at line %d in %s',
241                                 xml_error_string(xml_get_error_code($xml_parser)),
242                                 xml_get_current_line_number($xml_parser),
243                                 $buf
244                         ));
245 */
246                         return FALSE;
247                 }
248                 
249                 return $this->tb_url;
250         }
251         function start_element($parser,$name,$attrs)
252         {
253                 if ($name !== 'RDF:DESCRIPTION')
254                 {
255                         return;
256                 }
257                 
258                 $about = $url = $tb_url = '';
259                 foreach ($attrs as $key=>$value)
260                 {
261                         switch ($key)
262                         {
263                                 case 'RDF:ABOUT':
264                                         $about = $value;
265                                         break;
266                                 case 'DC:IDENTIFER':
267                                 case 'DC:IDENTIFIER':
268                                         $url = $value;
269                                         break;
270                                 case 'TRACKBACK:PING':
271                                         $tb_url = $value;
272                                         break;
273                         }
274                 }
275                 if ($about == $this->url or $url == $this->url)
276                 {
277                         $this->tb_url = $tb_url;
278                 }
279         }
280         function end_element($parser,$name)
281         {
282                 // do nothing
283         }
284 }
285
286 // Referer ¥Ç¡¼¥¿Êݸ(¹¹¿·)
287 function ref_save($page)
288 {
289         global $referer;
290         
291         if (!$referer or empty($_SERVER['HTTP_REFERER']))
292         {
293                 return;
294         }
295         
296         $url = $_SERVER['HTTP_REFERER'];
297         
298         // URI ¤ÎÂÅÅöÀ­É¾²Á
299         // ¼«¥µ¥¤¥ÈÆâ¤Î¾ì¹ç¤Ï½èÍý¤·¤Ê¤¤
300         $parse_url = parse_url($url);
301         if (empty($parse_url['host']) or $parse_url['host'] == $_SERVER['HTTP_HOST'])
302         {
303                 return;
304         }
305         
306         // TRACKBACK_DIR ¤Î¸ºß¤È½ñ¤­¹þ¤ß²Äǽ¤«¤Î³Îǧ
307         if (!is_dir(TRACKBACK_DIR))
308         {
309                 die(TRACKBACK_DIR.': No such directory');
310         }
311         if (!is_writable(TRACKBACK_DIR))
312         {
313                 die(TRACKBACK_DIR.': Permission denied');
314         }
315         
316         // Referer ¤Î¥Ç¡¼¥¿¤ò¹¹¿·
317         if (ereg("[,\"\n\r]",$url))
318         {
319                 $url = '"'.str_replace('"', '""', $url).'"';
320         }
321         $filename = tb_get_filename($page,'.ref');
322         $data = tb_get($filename, 3);
323         $d_url = rawurldecode($url);
324         if (!array_key_exists($d_url,$data))
325         {
326                 // 0:ºÇ½ª¹¹¿·Æü»þ, 1:½é²óÅÐÏ¿Æü»þ, 2:»²¾È¥«¥¦¥ó¥¿, 3:Referer ¥Ø¥Ã¥À, 4:ÍøÍѲÄÈݥե饰(1¤ÏÍ­¸ú)
327                 $data[$d_url] = array(UTIME,UTIME,0,$url,1);
328         }
329         $data[$d_url][0] = UTIME;
330         $data[$d_url][2]++;
331         
332         if (!($fp = fopen($filename,'w')))
333         {
334                 return 1;
335         }
336         set_file_buffer($fp, 0);
337         flock($fp, LOCK_EX);
338         rewind($fp);
339         foreach ($data as $line)
340         {
341                 fwrite($fp,join(',',$line)."\n");
342         }
343         flock($fp, LOCK_UN);
344         fclose($fp);
345         
346         return 0;
347 }
348 ?>