OSDN Git Service

Simplify only. Remove unused grobal
[pukiwiki/pukiwiki.git] / file.php
1 <?php
2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
4 //
5 // $Id: file.php,v 1.42 2004/07/01 14:52:30 henoheno Exp $
6 //
7
8 // ¥½¡¼¥¹¤ò¼èÆÀ
9 function get_source($page=NULL)
10 {
11         if (!is_page($page))
12         {
13                 return array();
14         }
15         return str_replace("\r",'',file(get_filename($page)));
16 }
17
18 // ¥Ú¡¼¥¸¤Î¹¹¿·»þ¹ï¤òÆÀ¤ë
19 function get_filetime($page)
20 {
21         if (!is_page($page))
22         {
23                 return 0;
24         }
25         return filemtime(get_filename($page)) - LOCALZONE;
26 }
27
28 // ¥Ú¡¼¥¸¤Î¥Õ¥¡¥¤¥ë̾¤òÆÀ¤ë
29 function get_filename($page)
30 {
31         return DATA_DIR.encode($page).'.txt';
32 }
33
34 // ¥Ú¡¼¥¸¤Î½ÐÎÏ
35 function page_write($page,$postdata,$notimestamp=FALSE)
36 {
37         $postdata = make_str_rules($postdata);
38         
39         // º¹Ê¬¥Õ¥¡¥¤¥ë¤ÎºîÀ®
40         $oldpostdata = is_page($page) ? join('',get_source($page)) : '';
41         $diffdata = do_diff($oldpostdata,$postdata);
42         file_write(DIFF_DIR,$page,$diffdata);
43         
44         // ¥Ð¥Ã¥¯¥¢¥Ã¥×¤ÎºîÀ®
45         make_backup($page,$postdata == '');
46         
47         // ¥Õ¥¡¥¤¥ë¤Î½ñ¤­¹þ¤ß
48         file_write(DATA_DIR,$page,$postdata,$notimestamp);
49         
50         // TrackBack Ping ¤ÎÁ÷¿®
51         // ¡ÖÄɲá׹ԤòÃê½Ð
52         $lines = join("\n",preg_replace('/^\+/','',preg_grep('/^\+/',explode("\n",$diffdata))));
53         tb_send($page,$lines);
54         
55         // link¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¹¹¿·
56         links_update($page);
57 }
58
59 // ¥æ¡¼¥¶ÄêµÁ¥ë¡¼¥ë(¥½¡¼¥¹¤òÃÖ´¹¤¹¤ë)
60 function make_str_rules($str)
61 {
62         global $str_rules,$fixed_heading_anchor;
63         
64         $arr = explode("\n",$str);
65         
66         $retvars = array();
67         foreach ($arr as $str)
68         {
69                 if ($str != '' and $str{0} != ' ' and $str{0} != "\t")
70                 {
71                         foreach ($str_rules as $rule => $replace)
72                         {
73                                 $str = preg_replace("/$rule/",$replace,$str);
74                         }
75                 }
76                 // ¸«½Ð¤·¤Ë¸ÇÍ­ID¤òÉÕÍ¿¤¹¤ë
77                 if ($fixed_heading_anchor and
78                         preg_match('/^(\*{1,3}(.(?!\[#[A-Za-z][\w-]+\]))+)$/',$str,$matches))
79                 {
80                         // ¸ÇÍ­ID¤òÀ¸À®¤¹¤ë
81                         // ¥é¥ó¥À¥à¤Ê±Ñ»ú(1ʸ»ú)+md5¥Ï¥Ã¥·¥å¤Î¥é¥ó¥À¥à¤ÊÉôʬʸ»úÎó(7ʸ»ú)
82                         $anchor = chr(mt_rand(ord('a'),ord('z'))).
83                                 substr(md5(uniqid(substr($matches[1],0,100),1)),mt_rand(0,24),7);
84                         $str = rtrim($matches[1])." [#$anchor]";
85                 }
86                 $retvars[] = $str;
87         }
88         
89         return join("\n",$retvars);
90 }
91
92 // ¥Õ¥¡¥¤¥ë¤Ø¤Î½ÐÎÏ
93 function file_write($dir,$page,$str,$notimestamp=FALSE)
94 {
95         global $update_exec;
96         global $_msg_invalidiwn;
97         global $notify,$notify_diff_only,$notify_to,$notify_from,$notify_subject,$notify_header;
98         global $smtp_server,$smtp_auth;
99         
100         if (!is_pagename($page))
101         {
102                 die_message(
103                         str_replace('$1',htmlspecialchars($page),
104                                 str_replace('$2','WikiName',$_msg_invalidiwn)
105                         )
106                 );
107         }
108         $page = strip_bracket($page);
109         $timestamp = FALSE;
110         $file = $dir.encode($page).'.txt';
111         
112         if ($dir == DATA_DIR and $str == '' and file_exists($file))
113         {
114                 unlink($file);
115                 put_recentdeleted($page);
116         }
117         if ($str != '')
118         {
119                 $str = preg_replace("/\r/",'',$str);
120                 $str = rtrim($str)."\n";
121                 
122                 if ($notimestamp and file_exists($file))
123                 {
124                         $timestamp = filemtime($file) - LOCALZONE;
125                 }
126                 
127                 $fp = fopen($file,'w')
128                         or die_message('cannot write page file or diff file or other'.htmlspecialchars($page).'<br />maybe permission is not writable or filename is too long');
129                 set_file_buffer($fp, 0);
130                 flock($fp,LOCK_EX);
131                 rewind($fp);
132                 fputs($fp,$str);
133                 flock($fp,LOCK_UN);
134                 fclose($fp);
135                 if ($timestamp)
136                 {
137                         touch($file,$timestamp + LOCALZONE);
138                 }
139         }
140         
141         // is_page¤Î¥­¥ã¥Ã¥·¥å¤ò¥¯¥ê¥¢¤¹¤ë¡£
142         is_page($page,TRUE);
143         
144         if (!$timestamp and $dir == DATA_DIR)
145         {
146                 put_lastmodified();
147         }
148         
149         if ($update_exec and $dir == DATA_DIR)
150         {
151                 system($update_exec.' > /dev/null &');
152         }
153         
154         if ($notify and $dir == DIFF_DIR)
155         {
156                 if ($notify_diff_only)
157                 {
158                         // º¹Ê¬¤À¤±¤òÁ÷¿®¤¹¤ë
159                         $str = preg_replace('/^[^-+].*\n/m','',$str);
160                 }
161                 if ($smtp_auth)
162                 {
163                         pop_before_smtp();
164                 }
165                 $subject = str_replace('$page',$page,$notify_subject);
166                 ini_set('SMTP',$smtp_server);
167                 mb_language(LANG);
168                 mb_send_mail($notify_to,$subject,$str,$notify_header);
169         }
170 }
171
172 // ºï½üÍúÎò¥Ú¡¼¥¸¤Î¹¹¿·
173 function put_recentdeleted($page)
174 {
175         global $whatsdeleted,$maxshow_deleted;
176         
177         if ($maxshow_deleted == 0)
178         {
179                 return;
180         }
181         // update RecentDeleted
182         $lines = array();
183         foreach (get_source($whatsdeleted) as $line)
184         {
185                 if (preg_match('/^-(.+) - (\[\[.+\]\])$/',$line,$matches))
186                 {
187                         $lines[$matches[2]] = $line;
188                 }
189         }
190         $_page = "[[$page]]";
191         if (array_key_exists($_page,$lines))
192         {
193                 unset($lines[$_page]);
194         }
195         array_unshift($lines,'-'.format_date(UTIME)." - $_page\n");
196         $lines = array_splice($lines,0,$maxshow_deleted);
197         $fp = fopen(get_filename($whatsdeleted),'w')
198                 or die_message('cannot write page file '.htmlspecialchars($whatsdeleted).'<br />maybe permission is not writable or filename is too long');
199         set_file_buffer($fp, 0);
200         flock($fp,LOCK_EX);
201         rewind($fp);
202         fputs($fp,join('',$lines));
203         fputs($fp,"#norelated\n"); // :)
204         flock($fp,LOCK_UN);
205         fclose($fp);
206 }
207
208 // ºÇ½ª¹¹¿·¥Ú¡¼¥¸¤Î¹¹¿·
209 function put_lastmodified()
210 {
211         global $maxshow,$whatsnew,$non_list,$autolink;
212
213         $pages = get_existpages();
214         $recent_pages = array();
215         foreach($pages as $page)
216         {
217                 if ($page != $whatsnew and !preg_match("/$non_list/",$page))
218                 {
219                         $recent_pages[$page] = get_filetime($page);
220                 }
221         }
222         
223         //»þ¹ï¹ß½ç¤Ç¥½¡¼¥È
224         arsort($recent_pages,SORT_NUMERIC);
225         
226         // create recent.dat (for recent.inc.php)
227         $fp = fopen(CACHE_DIR.'recent.dat','w')
228                 or die_message('cannot write cache file '.CACHE_DIR.'recent.dat<br />maybe permission is not writable or filename is too long');
229         set_file_buffer($fp, 0);
230         flock($fp,LOCK_EX);
231         rewind($fp);
232         foreach ($recent_pages as $page=>$time)
233         {
234                 fputs($fp,"$time\t$page\n");
235         }
236         flock($fp,LOCK_UN);
237         fclose($fp);
238
239         // create RecentChanges
240         $fp = fopen(get_filename($whatsnew),'w')
241                 or die_message('cannot write page file '.htmlspecialchars($whatsnew).'<br />maybe permission is not writable or filename is too long');
242         set_file_buffer($fp, 0);
243         flock($fp,LOCK_EX);
244         rewind($fp);
245         foreach (array_splice(array_keys($recent_pages),0,$maxshow) as $page)
246         {
247                 $time = $recent_pages[$page];
248                 $s_lastmod = htmlspecialchars(format_date($time));
249                 $s_page = htmlspecialchars($page);
250                 fputs($fp, "-$s_lastmod - [[$s_page]]\n");
251         }
252         fputs($fp,"#norelated\n"); // :)
253         flock($fp,LOCK_UN);
254         fclose($fp);
255         
256         // for autolink
257         if ($autolink)
258         {
259                 list($pattern,$pattern_a,$forceignorelist) = get_autolink_pattern($pages);
260                 
261                 $fp = fopen(CACHE_DIR.'autolink.dat','w')
262                         or die_message('cannot write autolink file '.CACHE_DIR.'/autolink.dat<br />maybe permission is not writable');
263                 set_file_buffer($fp, 0);
264                 flock($fp,LOCK_EX);
265                 rewind($fp);
266                 fputs($fp,$pattern."\n");
267                 fputs($fp,$pattern_a."\n");
268                 fputs($fp,join("\t",$forceignorelist)."\n");
269                 flock($fp,LOCK_UN);
270                 fclose($fp);
271         }
272 }
273
274 // »ØÄꤵ¤ì¤¿¥Ú¡¼¥¸¤Î·Ð²á»þ¹ï
275 function get_pg_passage($page,$sw=TRUE)
276 {
277         global $show_passage;
278         static $pg_passage = array();
279         
280         if (!$show_passage)
281         {
282                 return '';
283         }
284         
285         if (!array_key_exists($page,$pg_passage))
286         {
287                 $pg_passage[$page] = (is_page($page) and $time = get_filetime($page)) ?
288                         get_passage($time) : '';
289         }
290         
291         return $sw ? "<small>{$pg_passage[$page]}</small>" : " {$pg_passage[$page]}";
292 }
293
294 // Last-Modified ¥Ø¥Ã¥À
295 function header_lastmod($page=NULL)
296 {
297         global $lastmod;
298         
299         if ($lastmod and is_page($page))
300         {
301                 header('Last-Modified: '.date('D, d M Y H:i:s',get_filetime($page)).' GMT');
302         }
303 }
304
305 // Á´¥Ú¡¼¥¸Ì¾¤òÇÛÎó¤Ë
306 function get_existpages($dir=DATA_DIR,$ext='.txt')
307 {
308         $aryret = array();
309         
310         $pattern = '^((?:[0-9A-F]{2})+)';
311         if ($ext != '')
312         {
313                 $pattern .= preg_quote($ext,'/').'$';
314         }
315         $dp = @opendir($dir)
316                 or die_message($dir. ' is not found or not readable.');
317         while ($file = readdir($dp))
318         {
319                 if (preg_match("/$pattern/",$file,$matches))
320                 {
321                         $aryret[$file] = decode($matches[1]);
322                 }
323         }
324         closedir($dp);
325         return $aryret;
326 }
327 // ¥Ú¡¼¥¸Ì¾¤ÎÆɤߤòÇÛÎó¤Ë
328 function get_readings()
329 {
330         global $pagereading_enable, $pagereading_kanji2kana_converter;
331         global $pagereading_kanji2kana_encoding, $pagereading_chasen_path;
332         global $pagereading_kakasi_path, $pagereading_config_page;
333         global $pagereading_config_dict;
334         
335         $pages = get_existpages();
336         
337         $readings = array();
338         foreach ($pages as $page) {
339                 $readings[$page] = '';
340         }
341         $deletedPage = FALSE;
342         foreach (get_source($pagereading_config_page) as $line) {
343                 $line = chop($line);
344                 if(preg_match('/^-\[\[([^]]+)\]\]\s+(.+)$/', $line, $matches)) {
345                         if(isset($readings[$matches[1]])) {
346                                 // Æɤߤ¬ÉÔÌÀ¤Î¥Ú¡¼¥¸
347                                 $readings[$matches[1]] = $matches[2];
348                         } else {
349                                 // ºï½ü¤µ¤ì¤¿¥Ú¡¼¥¸
350                                 $deletedPage = TRUE;
351                         }
352                 }
353         }
354         if($pagereading_enable) {
355                 // ChaSen/KAKASI ¸Æ¤Ó½Ð¤·¤¬Í­¸ú¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç
356                 $unknownPage = FALSE;
357                 // Æɤߤ¬ÉÔÌÀ¤Î¥Ú¡¼¥¸¤¬¤¢¤ë¤«¥Á¥§¥Ã¥¯
358                 foreach ($readings as $page => $reading) {
359                         if($reading=='') {
360                                 $unknownPage = TRUE;
361                                 break;
362                         }
363                 }
364                 if($unknownPage) {
365                         // Æɤߤ¬ÉÔÌÀ¤Î¥Ú¡¼¥¸¤¬¤¢¤ë¾ì¹ç¡¢ChaSen/KAKASI ¤ò¼Â¹Ô
366                         switch(strtolower($pagereading_kanji2kana_converter)) {
367                         case 'chasen':
368                                 $tmpfname = tempnam(CACHE_DIR, 'PageReading');
369                                 $fp = fopen($tmpfname, "w")
370                                         or die_message("cannot write temporary file '$tmpfname'.\n");
371                                 foreach ($readings as $page => $reading) {
372                                         if($reading=='') {
373                                                 fputs($fp, mb_convert_encoding("$page\n", $pagereading_kanji2kana_encoding, SOURCE_ENCODING));
374                                         }
375                                 }
376                                 fclose($fp);
377                                 if(!file_exists($pagereading_chasen_path)) {
378                                         unlink($tmpfname);
379                                         die_message("CHASEN not found: $pagereading_chasen_path");
380                                 }
381                                 $fp = popen("$pagereading_chasen_path -F %y $tmpfname", "r");
382                                 if(!$fp) {
383                                         unlink($tmpfname);
384                                         die_message("ChaSen execution failed: $pagereading_chasen_path -F %y $tmpfname");
385                                 }
386                                 foreach ($readings as $page => $reading) {
387                                         if($reading=='') {
388                                                 $line = fgets($fp);
389                                                 $line = mb_convert_encoding($line, SOURCE_ENCODING, $pagereading_kanji2kana_encoding);
390                                                 $line = chop($line);
391                                                 $readings[$page] = $line;
392                                         }
393                                 }
394                                 pclose($fp);
395                                 unlink($tmpfname) or die_message("temporary file can not be removed: $tmpfname");
396                                 break;
397                         case 'kakasi':
398                         case 'kakashi':
399                                 $tmpfname = tempnam(CACHE_DIR, 'PageReading');
400                                 $fp = fopen($tmpfname, "w")
401                                         or die_message("cannot write temporary file '$tmpfname'.\n");
402                                 foreach ($readings as $page => $reading) {
403                                         if($reading=='') {
404                                                 fputs($fp, mb_convert_encoding("$page\n", $pagereading_kanji2kana_encoding, SOURCE_ENCODING));
405                                         }
406                                 }
407                                 fclose($fp);
408                                 if(!file_exists($pagereading_kakasi_path)) {
409                                         unlink($tmpfname);
410                                         die_message("KAKASI not found: $pagereading_kakasi_path");
411                                 }                                       
412                                 $fp = popen("$pagereading_kakasi_path -kK -HK -JK <$tmpfname", "r");
413                                 if(!$fp) {
414                                         unlink($tmpfname);
415                                         die_message("KAKASI execution failed: $pagereading_kakasi_path -kK -HK -JK <$tmpfname");
416                                 }
417                                 foreach ($readings as $page => $reading) {
418                                         if($reading=='') {
419                                                 $line = fgets($fp);
420                                                 $line = mb_convert_encoding($line, SOURCE_ENCODING, $pagereading_kanji2kana_encoding);
421                                                 $line = chop($line);
422                                                 $readings[$page] = $line;
423                                         }
424                                 }
425                                 pclose($fp);
426                                 unlink($tmpfname) or die_message("temporary file can not be removed: $tmpfname");
427                                 break;
428                         case 'none':
429                                 $patterns = array();
430                                 $replacements = array();
431                                 foreach (get_source($pagereading_config_dict) as $line) {
432                                         $line = chop($line);
433                                         if(preg_match('|^ /([^/]+)/,\s*(.+)$|', $line, $matches)) {
434                                                 $patterns[] = $matches[1];
435                                                 $replacements[] = $matches[2];
436                                         }
437                                 }
438                                 foreach ($readings as $page => $reading) {
439                                         if($reading=='') {
440                                                 $readings[$page] = $page;
441                                                 foreach ($patterns as $no => $pattern) {
442                                                         $readings[$page] = mb_convert_kana(mb_ereg_replace($pattern, $replacements[$no], $readings[$page]), "aKCV");
443                                                 }
444                                         }
445                                 }
446                                 break;
447                         default:
448                                 die_message("unknown kanji-kana converter: $pagereading_kanji2kana_converter.");
449                                 break;
450                         }
451                 }
452                 if($unknownPage or $deletedPage) {
453                         // Æɤߤǥ½¡¼¥È
454                         asort($readings);
455                         
456                         // ¥Ú¡¼¥¸¤ò½ñ¤­¹þ¤ß
457                         $body = '';
458                         foreach ($readings as $page => $reading) {
459                                 $body .= "-[[$page]] $reading\n";
460                         }
461                         page_write($pagereading_config_page, $body);
462                 }
463         }
464         
465         // ÆɤßÉÔÌÀ¤Î¥Ú¡¼¥¸¤Ï¡¢¤½¤Î¤Þ¤Þ¥Ú¡¼¥¸Ì¾¤òÊÖ¤¹ (ChaSen/KAKASI ¸Æ
466         // ¤Ó½Ð¤·¤¬Ìµ¸ú¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤ä¡¢ChaSen/KAKASI ¸Æ¤Ó½Ð¤·¤Ë
467         // ¼ºÇÔ¤·¤¿»þ¤Î°Ù)
468         foreach ($pages as $page) {
469                 if($readings[$page]=='') {
470                         $readings[$page] = $page;
471                 }
472         }
473         
474         return $readings;
475 }
476 //¥Õ¥¡¥¤¥ë̾¤Î°ìÍ÷¤òÇÛÎó¤Ë(¥¨¥ó¥³¡¼¥ÉºÑ¤ß¡¢³ÈÄ¥»Ò¤ò»ØÄê)
477 function get_existfiles($dir,$ext)
478 {
479         $aryret = array();
480         
481         $pattern = '^(?:[0-9A-F]{2})+'.preg_quote($ext,'/').'$';
482         $dp = @opendir($dir)
483                 or die_message($dir. ' is not found or not readable.');
484         while ($file = readdir($dp)) {
485                 if (preg_match("/$pattern/",$file)) {
486                         $aryret[] = $dir.$file;
487                 }
488         }
489         closedir($dp);
490         return $aryret;
491 }
492 //¤¢¤ë¥Ú¡¼¥¸¤Î´ØÏ¢¥Ú¡¼¥¸¤òÆÀ¤ë
493 function links_get_related($page)
494 {
495         global $vars,$related;
496         static $links = array();
497         
498         if (array_key_exists($page,$links))
499         {
500                 return $links[$page];
501         }
502         
503         // ²Äǽ¤Ê¤émake_link()¤ÇÀ¸À®¤·¤¿´ØÏ¢¥Ú¡¼¥¸¤ò¼è¤ê¹þ¤à
504         $links[$page] = ($page == $vars['page']) ? $related : array();
505         
506         // ¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤é´ØÏ¢¥Ú¡¼¥¸¤òÆÀ¤ë
507         $links[$page] += links_get_related_db($vars['page']);
508         
509         return $links[$page];
510 }
511 ?>