2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
5 // $Id: attach.inc.php,v 1.17 2003/02/26 12:28:12 panda Exp $
11 changed by Y.MASUI <masui@hisec.co.jp> http://masui.net/pukiwiki/
12 modified by PANDA <panda@arino.jp> http://home.arino.jp/
15 // upload dir(must set end of /)
16 if (!defined('UPLOAD_DIR'))
18 define('UPLOAD_DIR','./attach/');
21 // max file size for upload on PHP(PHP default 2MB)
22 ini_set('upload_max_filesize','2M');
24 // max file size for upload on script of PukiWiki(default 1MB)
25 define('MAX_FILESIZE',1000000);
27 // ´ÉÍý¼Ô¤À¤±¤¬ÅºÉÕ¥Õ¥¡¥¤¥ë¤ò¥¢¥Ã¥×¥í¡¼¥É¤Ç¤¤ë¤è¤¦¤Ë¤¹¤ë
28 define('ATTACH_UPLOAD_ADMIN_ONLY',FALSE); // FALSE or TRUE
29 // ´ÉÍý¼Ô¤À¤±¤¬ÅºÉÕ¥Õ¥¡¥¤¥ë¤òºï½ü¤Ç¤¤ë¤è¤¦¤Ë¤¹¤ë
30 define('ATTACH_DELETE_ADMIN_ONLY',FALSE); // FALSE or TRUE
32 // ¥¢¥Ã¥×¥í¡¼¥É/ºï½ü»þ¤Ë¥Ñ¥¹¥ï¡¼¥É¤òÍ׵᤹¤ë(ADMIN_ONLY¤¬Í¥Àè)
33 define('ATTACH_PASSWORD_REQUIRE',FALSE); // FALSE or TRUE
36 if (!defined('FILE_ICON'))
38 define('FILE_ICON','<img src="./image/file.png" width="20" height="20" alt="file" style="border-width:0px" />');
42 function plugin_attach_init()
45 '_attach_messages'=>array(
46 'msg_uploaded' => '$1 ¤Ë¥¢¥Ã¥×¥í¡¼¥É¤·¤Þ¤·¤¿',
47 'msg_deleted' => '$1 ¤«¤é¥Õ¥¡¥¤¥ë¤òºï½ü¤·¤Þ¤·¤¿',
48 'msg_freezed' => 'źÉÕ¥Õ¥¡¥¤¥ë¤òÅà·ë¤·¤Þ¤·¤¿¡£',
49 'msg_unfreezed'=> 'źÉÕ¥Õ¥¡¥¤¥ë¤òÅà·ë²ò½ü¤·¤Þ¤·¤¿¡£',
50 'msg_upload' => '$1 ¤Ø¤ÎźÉÕ',
51 'msg_info' => 'źÉÕ¥Õ¥¡¥¤¥ë¤Î¾ðÊó',
52 'msg_confirm' => '<p>%s ¤òºï½ü¤·¤Þ¤¹¡£</p>',
53 'msg_list' => 'źÉÕ¥Õ¥¡¥¤¥ë°ìÍ÷',
54 'msg_listpage' => '$1 ¤ÎźÉÕ¥Õ¥¡¥¤¥ë°ìÍ÷',
55 'msg_listall' => 'Á´¥Ú¡¼¥¸¤ÎźÉÕ¥Õ¥¡¥¤¥ë°ìÍ÷',
56 'msg_file' => 'źÉÕ¥Õ¥¡¥¤¥ë',
57 'msg_maxsize' => '¥¢¥Ã¥×¥í¡¼¥É²ÄǽºÇÂç¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤Ï %s ¤Ç¤¹¡£',
58 'msg_count' => ' <span class="small">%s·ï</span>',
59 'msg_password' => '¥Ñ¥¹¥ï¡¼¥É',
60 'msg_adminpass'=> '´ÉÍý¼Ô¥Ñ¥¹¥ï¡¼¥É',
61 'msg_delete' => '¤³¤Î¥Õ¥¡¥¤¥ë¤òºï½ü¤·¤Þ¤¹¡£',
62 'msg_freeze' => '¤³¤Î¥Õ¥¡¥¤¥ë¤òÅà·ë¤·¤Þ¤¹¡£',
63 'msg_unfreeze' => '¤³¤Î¥Õ¥¡¥¤¥ë¤òÅà·ë²ò½ü¤·¤Þ¤¹¡£',
64 'msg_isfreeze' => '¤³¤Î¥Õ¥¡¥¤¥ë¤ÏÅà·ë¤µ¤ì¤Æ¤¤¤Þ¤¹¡£',
65 'msg_require' => '(´ÉÍý¼Ô¥Ñ¥¹¥ï¡¼¥É¤¬É¬ÍפǤ¹)',
66 'msg_filesize' => '¥µ¥¤¥º',
67 'msg_date' => 'ÅÐÏ¿Æü»þ',
68 'msg_dlcount' => '¥¢¥¯¥»¥¹¿ô',
69 'err_noparm' => '$1 ¤Ø¤Ï¥¢¥Ã¥×¥í¡¼¥É¡¦ºï½ü¤Ï¤Ç¤¤Þ¤»¤ó',
70 'err_exceed' => '$1 ¤Ø¤Î¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤¬Â礤¹¤®¤Þ¤¹',
71 'err_exists' => '$1 ¤ËƱ¤¸¥Õ¥¡¥¤¥ë̾¤¬Â¸ºß¤·¤Þ¤¹',
72 'err_notfound' => '$1 ¤Ë¤½¤Î¥Õ¥¡¥¤¥ë¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó',
73 'err_noexist' => 'źÉÕ¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó¡£',
74 'err_password' => '¥Ñ¥¹¥ï¡¼¥É¤¬°ìÃפ·¤Þ¤»¤ó¡£',
75 'err_adminpass'=> '´ÉÍý¼Ô¥Ñ¥¹¥ï¡¼¥É¤¬°ìÃפ·¤Þ¤»¤ó¡£',
76 'btn_upload' => '¥¢¥Ã¥×¥í¡¼¥É',
78 'btn_submit' => '¼Â¹Ô'
81 set_plugin_messages($messages);
85 function plugin_attach_convert()
89 if (!ini_get('file_uploads'))
91 return 'file_uploads disabled';
94 $nolist = $noform = FALSE;
96 if (func_num_args() > 0)
98 foreach (func_get_args() as $arg)
100 $arg = strtolower($arg);
101 $nolist |= ($arg == 'nolist');
102 $noform |= ($arg == 'noform');
108 $obj = &new AttachPages($vars['page']);
109 $ret .= $obj->to_string($vars['page'],TRUE);
113 $ret .= attach_form($vars['page']);
120 function plugin_attach_action()
122 global $vars,$HTTP_POST_FILES;
124 if (array_key_exists('openfile',$vars))
126 $vars['pcmd'] = 'open';
127 $vars['file'] = $vars['openfile'];
129 if (array_key_exists('delfile',$vars))
131 $vars['pcmd'] = 'delete';
132 $vars['file'] = $vars['delfile'];
134 if (array_key_exists('attach_file',$HTTP_POST_FILES) and
135 is_uploaded_file($HTTP_POST_FILES['attach_file']['tmp_name']))
137 return attach_upload();
140 $age = array_key_exists('age',$vars) ? $vars['age'] : 0;
141 $pcmd = array_key_exists('pcmd',$vars) ? $vars['pcmd'] : '';
145 case 'info': return attach_info();
146 case 'delete': return attach_delete();
147 case 'open': return attach_open($vars['refer'],$vars['file'],$age);
148 case 'list': return attach_list();
149 case 'freeze': return attach_freeze(TRUE);
150 case 'unfreeze':return attach_freeze(FALSE);
151 case 'upload': return attach_showform();
153 if ($vars['page'] == '' or !is_page($vars['page']))
155 return attach_list();
158 return attach_showform();
160 //-------- call from skin
161 function attach_filelist()
163 global $vars,$_attach_messages;
165 plugin_attach_init();
167 $obj = &new AttachPages($vars['page'],0);
169 if (!array_key_exists($vars['page'],$obj->pages))
173 return $_attach_messages['msg_file'].': '.$obj->to_string($vars['page'],TRUE)."\n";
176 //¥Õ¥¡¥¤¥ë¥¢¥Ã¥×¥í¡¼¥É
177 function attach_upload()
179 global $vars,$adminpass,$HTTP_POST_FILES;
180 global $_attach_messages;
182 if ($HTTP_POST_FILES['attach_file']['size'] > MAX_FILESIZE)
184 return array('msg'=>$_attach_messages['err_exceed']);
186 if (is_freeze($vars['refer']) || !is_editable($vars['refer']))
188 return array('msg'=>$_attach_messages['err_noparm']);
190 if (ATTACH_UPLOAD_ADMIN_ONLY and md5($vars['pass']) != $adminpass)
192 return array('msg'=>$_attach_messages['err_adminpass']);
195 $obj = &new AttachFile($vars['refer'],$HTTP_POST_FILES['attach_file']['name']);
199 return array('msg'=>$_attach_messages['err_exists']);
201 move_uploaded_file($HTTP_POST_FILES['attach_file']['tmp_name'],$obj->filename);
203 if (is_page($vars['refer']))
205 touch(get_filename($vars['refer']));
209 $obj->status['pass'] = array_key_exists('pass',$vars) ? md5($vars['pass']) : '';
212 return array('msg'=>$_attach_messages['msg_uploaded']);
215 function attach_info($err='')
217 global $script,$vars;
218 global $_attach_messages;
222 $obj = &new AttachFile($vars['refer'],$vars['file'],$vars['age']);
225 $s_file = htmlspecialchars($vars['file']);
226 $s_refer = htmlspecialchars($vars['refer']);
227 $r_refer = rawurlencode($vars['refer']);
229 $retval['msg'] = sprintf($_attach_messages['msg_info'],$s_file);
230 $retval['body'] = ($err == '') ? '' : '<p>'.$_attach_messages[$err].'</p>';
232 $retval['body'] .= <<<EOD
234 [<a href="$script?plugin=attach&pcmd=list&refer=$r_refer">{$_attach_messages['msg_list']}</a>]
235 [<a href="$script?plugin=attach&pcmd=list">{$_attach_messages['msg_listall']}</a>]
239 if ($obj->status['freeze'])
241 $msg_freezed = '<dd>'.$_attach_messages['msg_isfreeze'].'</dd>';
243 $msg_freeze = '<input type="hidden" name="pcmd" value="unfreeze" />'.$_attach_messages['msg_unfreeze'];
248 $msg_delete = '<input type="radio" name="pcmd" value="delete" />'.$_attach_messages['msg_delete'];
249 if (ATTACH_DELETE_ADMIN_ONLY)
251 $msg_delete .= $_attach_messages['msg_require'];
253 $msg_delete .= '<br />';
254 $msg_freeze = '<input type="radio" name="pcmd" value="freeze" />'.$_attach_messages['msg_freeze'];
256 $info = $obj->to_string(TRUE,FALSE);
257 $type = attach_mime_content_type($obj->filename);
258 $age = (array_key_exists('age',$vars) and is_numeric($vars['age'])) ? $vars['age'] : 0;
259 $retval['body'] .= <<< EOD
262 <dd>{$_attach_messages['msg_filesize']}:{$obj->size_str} ({$obj->size} bytes)</dd>
263 <dd>Content-type:$type</dd>
264 <dd>{$_attach_messages['msg_date']}:{$obj->time_str}</dd>
265 <dd>{$_attach_messages['msg_dlcount']}:{$obj->status['count'][$age]}</dd>
273 $retval['body'] .= <<< EOD
275 <form action="$script" method="post">
277 <input type="hidden" name="plugin" value="attach" />
278 <input type="hidden" name="refer" value="$s_refer" />
279 <input type="hidden" name="file" value="$s_file" />
281 $msg_freeze{$_attach_messages['msg_require']}<br />
282 {$_attach_messages['msg_password']}: <input type="password" name="pass" size="8" />
283 <input type="submit" value="{$_attach_messages['btn_submit']}" />
291 function attach_delete()
293 global $vars,$adminpass;
294 global $_attach_messages;
296 if (is_freeze($vars['refer']) or !is_editable($vars['refer']))
298 return array('msg' => $_attach_messages['err_noparm']);
301 $obj = &new AttachFile($vars['refer'],$vars['file']);
305 return array('msg' => $_attach_messages['err_notfound']);
310 if ($obj->status['freeze'])
312 return attach_info('msg_isfreeze');
315 if (md5($vars['pass']) != $adminpass)
317 if (ATTACH_DELETE_ADMIN_ONLY)
319 return attach_info('err_adminpass');
321 else if (ATTACH_PASSWORD_REQUIRE and md5($vars['pass']) != $obj->status['pass'])
323 return attach_info('err_password');
329 $age = ++$obj->status['age'];
331 while (file_exists($obj->basename.'.'.$age));
333 rename($obj->basename,$obj->basename.'.'.$age);
334 $obj->status['count'][$age] = $obj->status['count'][0];
335 $obj->status['count'][0] = 0;
338 if (is_page($vars['refer']))
340 touch(get_filename($vars['refer']));
343 return array('msg' => $_attach_messages['msg_deleted']);
346 function attach_freeze($freeze)
348 global $vars,$adminpass;
349 global $_attach_messages;
351 if (is_freeze($vars['refer']) or !is_editable($vars['refer']))
353 return array('msg' => $_attach_messages['err_noparm']);
356 $obj = &new AttachFile($vars['refer'],$vars['file']);
360 return array('msg' => $_attach_messages['err_notfound']);
362 if (md5($vars['pass']) != $adminpass)
364 return attach_info('err_adminpass');
368 $obj->status['freeze'] = $freeze;
371 return array('msg' => $_attach_messages[$freeze ? 'msg_freezed' : 'msg_unfreezed']);
374 function attach_open($page,$file,$age=0)
376 global $_attach_messages;
378 $obj = &new AttachFile($page,$file,$age);
382 return array('msg' => $_attach_messages['err_notfound']);
386 $obj->status['count'][$age]++;
389 $type = attach_mime_content_type($obj->file);
390 $name = htmlspecialchars($obj->file);
392 // for japanese (???)
393 if (function_exists('mb_convert_encoding'))
395 $name = mb_convert_encoding($name,'SJIS','auto');
398 header('Content-Disposition: inline; filename="'.$name.'"');
399 header('Content-Length: '.$obj->size);
400 header('Content-Type: '.$type);
402 @readfile($obj->filename);
406 function attach_list()
409 global $_attach_messages;
411 $refer = array_key_exists('refer',$vars) ? $vars['refer'] : '';
413 $obj = &new AttachPages($refer);
415 $msg = $_attach_messages[$refer == '' ? 'msg_listall' : 'msg_listpage'];
416 $body = ($refer == '' or array_key_exists($refer,$obj->pages)) ?
417 $obj->to_string($refer,FALSE) :
418 $_attach_messages['err_noexist'];
419 return array('msg'=>$msg,'body'=>$body);
421 //¥¢¥Ã¥×¥í¡¼¥É¥Õ¥©¡¼¥à¤òɽ¼¨
422 function attach_showform()
425 global $_attach_messages;
427 $vars['refer'] = $vars['page'];
428 $body = ini_get('file_uploads') ? attach_form($vars['page']) : 'file_uploads disabled.';
430 return array('msg'=>$_attach_messages['msg_upload'],'body'=>$body);
435 function attach_mime_content_type($filename)
437 $type = 'application/octet-stream'; //default
438 $config = ':config/plugin/attach/mime-type';
440 $size = getimagesize($filename);
452 return 'application/x-shockwave-flash';
456 if (!is_page($config))
461 if (!preg_match('/_([0-9A-Z]+)$/',$filename,$matches))
465 $filename = decode($matches[1]);
467 foreach (get_source($config) as $line)
469 if (!preg_match('/\|(.+)\|/',$line,$matches))
473 $cells = explode('|',$matches[1]);
474 $_type = trim($cells[0]);
475 $exts = preg_split('/\s+|,/',trim($cells[1]),-1,PREG_SPLIT_NO_EMPTY);
477 foreach ($exts as $ext)
479 if (preg_match("/\.$ext$/i",$filename))
488 //¥¢¥Ã¥×¥í¡¼¥É¥Õ¥©¡¼¥à
489 function attach_form($page)
491 global $script,$vars;
492 global $_attach_messages;
494 $r_page = rawurlencode($page);
495 $s_page = htmlspecialchars($page);
498 [<a href="$script?plugin=attach&pcmd=list&refer=$r_page">{$_attach_messages['msg_list']}</a>]
499 [<a href="$script?plugin=attach&pcmd=list">{$_attach_messages['msg_listall']}</a>]
503 if (!(bool)ini_get('file_uploads'))
508 $maxsize = MAX_FILESIZE;
509 $msg_maxsize = sprintf($_attach_messages['msg_maxsize'],number_format($maxsize/1000)."KB");
512 if (ATTACH_PASSWORD_REQUIRE or ATTACH_UPLOAD_ADMIN_ONLY)
514 $title = $_attach_messages[ATTACH_UPLOAD_ADMIN_ONLY ? 'msg_adminpass' : 'msg_password'];
515 $pass = '<br />'.$title.': <input type="password" name="pass" size="8" />';
518 <form enctype="multipart/form-data" action="$script" method="post">
520 <input type="hidden" name="plugin" value="attach" />
521 <input type="hidden" name="pcmd" value="post" />
522 <input type="hidden" name="refer" value="$s_page" />
523 <input type="hidden" name="max_file_size" value="$maxsize" />
528 {$_attach_messages['msg_file']}: <input type="file" name="attach_file" />
530 <input type="submit" value="{$_attach_messages['btn_upload']}" />
539 var $page,$file,$age,$basename,$filename,$logname;
540 var $time,$size,$time_str,$size_str;
541 var $status = array('count'=>array(0),'age'=>'','pass'=>'','freeze'=>FALSE);
543 function AttachFile($page,$file,$age=0)
549 $this->basename = UPLOAD_DIR.encode($page).'_'.encode($file);
550 $this->filename = $this->basename . ($age ? '.'.$age : '');
551 $this->logname = $this->basename.'.log';
552 $this->exist = file_exists($this->filename);
553 $this->time = $this->exist ? filemtime($this->filename) - LOCALZONE : 0;
559 if (file_exists($this->logname))
561 $data = file($this->logname);
562 foreach ($this->status as $key=>$value)
564 $this->status[$key] = chop(array_shift($data));
566 $this->status['count'] = explode(',',$this->status['count']);
568 $this->time_str = get_date('Y/m/d H:i:s',$this->time);
569 $this->size = filesize($this->filename);
570 $this->size_str = sprintf('%01.1f',round($this->size)/1000,1).'KB';
575 $this->status['count'] = join(',',$this->status['count']);
576 $fp = fopen($this->logname,'wb')
577 or die_message('cannot write '.$this->logname);
579 foreach ($this->status as $key=>$value)
581 fwrite($fp,$value."\n");
586 function datecomp($a,$b)
588 return ($a->time == $b->time) ? 0 : (($a->time > $b->time) ? -1 : 1);
590 function to_string($showicon,$showinfo)
592 global $script,$date_format,$time_format,$weeklabels;
593 global $_attach_messages;
596 $param = '&file='.rawurlencode($this->file).'&refer='.rawurlencode($this->page).
597 ($this->age ? '&age='.$this->age : '');
598 $title = $this->time_str.' '.$this->size_str;
599 $label = ($showicon ? FILE_ICON : '').htmlspecialchars($this->file);
602 $label .= ' (backup No.'.$this->age.')';
607 $_title = str_replace('$1',rawurlencode($this->file),$_attach_messages['msg_info']);
608 $info = "\n<span class=\"small\">[<a href=\"$script?plugin=attach&pcmd=info$param\" title=\"$_title\">{$_attach_messages['btn_info']}</a>]</span>";
609 $count = ($showicon and !empty($this->status['count'][$this->age])) ?
610 sprintf($_attach_messages['msg_count'],$this->status['count'][$this->age]) : '';
612 return "<a href=\"$script?plugin=attach&pcmd=open$param\" title=\"$title\">$label</a>$count$info";
620 var $files = array();
622 function AttachFiles($page)
626 function add($file,$age)
628 $this->files[$file][$age] = &new AttachFile($this->page,$file,$age);
630 // ¥Õ¥¡¥¤¥ë°ìÍ÷¤ò¼èÆÀ
631 function to_string($flat)
635 return $this->to_flat();
638 $files = array_keys($this->files);
640 foreach ($files as $file)
643 foreach (array_keys($this->files[$file]) as $age)
645 $_files[$age] = $this->files[$file][$age]->to_string(FALSE,TRUE);
647 if (!array_key_exists(0,$_files))
649 $_files[0] = htmlspecialchars($file);
654 $ret .= " <li>$_file\n";
657 $ret .= "<ul>\n<li>".join("</li>\n<li>",$_files)."</li>\n</ul>\n";
661 return make_pagelink($this->page)."\n<ul>\n$ret</ul>\n";
663 // ¥Õ¥¡¥¤¥ë°ìÍ÷¤ò¼èÆÀ(inline)
668 foreach (array_keys($this->files) as $file)
670 if (array_key_exists(0,$this->files[$file]))
672 $files[$file] = &$this->files[$file][0];
675 uasort($files,array('AttachFile','datecomp'));
676 foreach (array_keys($files) as $file)
678 $ret .= $files[$file]->to_string(TRUE,TRUE).' ';
687 var $pages = array();
689 function AttachPages($page='',$age=NULL)
692 $dir = opendir(UPLOAD_DIR)
693 or die('directory '.UPLOAD_DIR.' is not exist or not readable.');
695 $page_pattern = ($page == '') ? '[0-9A-F]+' : preg_quote(encode($page),'/');
696 $age_pattern = ($age === NULL) ?
697 '(?:\.([0-9]+))?' : ($age ? "\.($age)" : '');
698 $pattern = "/^({$page_pattern})_([0-9A-F]+){$age_pattern}$/";
700 while ($file = readdir($dir))
702 if (!preg_match($pattern,$file,$matches))
706 $_page = decode($matches[1]);
707 $_file = decode($matches[2]);
708 $_age = array_key_exists(3,$matches) ? $matches[3] : 0;
709 if (!array_key_exists($_page,$this->pages))
711 $this->pages[$_page] = &new AttachFiles($_page);
713 $this->pages[$_page]->add($_file,$_age);
717 function to_string($page='',$flat=FALSE)
721 if (!array_key_exists($page,$this->pages))
725 return $this->pages[$page]->to_string($flat);
728 $pages = array_keys($this->pages);
730 foreach ($pages as $page)
732 $ret .= '<li>'.$this->pages[$page]->to_string($flat)."</li>\n";
734 return "\n<ul>\n".$ret."</ul>\n";