<?php
/* 
 * $Id: attach.inc.php,v 1.2 2004/09/23 09:31:33 youka Exp $
 */



class Cmd_attach
{
	static function getinstance()
	{
		return new Cmd_attach;
	}
	
	
	function run()
	{
		$get = KinoWiki::getinstance()->getGET();
		if(isset($get['param'])){
			switch($get['param']){
				case 'upload':
					return $this->upload();
				case 'download':
					return $this->download();
				case 'rename':
					return $this->rename();
				case 'delete':
					return $this->delete();
				case 'show':
					return $this->show();
				case 'list':
					return $this->listfile();
				case 'listpage':
					return $this->listpage();
			}
		}
		else{
			return $this->showform();
		}
	}
	
	
	protected function upload()
	{
		$post = KinoWiki::getinstance()->getPOST();
		if(!isset($post['page'])){
			return $this->error('パラメータが足りません。');
		}
		if($post['page'] == ''){
			return $this->error('ページ名に空文字列は使えません。');
		}
		
		if(!is_uploaded_file($_FILES['uploadfile']['tmp_name'])){
			return $this->error('ファイルアップロード攻撃をされた可能性があります。');
		}
		
		if($_FILES['uploadfile']['error'] != UPLOAD_ERR_OK){
			switch($_FILES['uploadfile']['error']){
				case UPLOAD_ERR_INI_SIZE:
					return $this->error('アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています。');
				case UPLOAD_ERR_FORM_SIZE:
					return $this->error('アップロードされたファイルは、HTMLフォームで指定された MAX_FILE_SIZE を超えています。');
				case UPLOAD_ERR_PARTIAL:
					return $this->error('アップロードされたファイルは一部のみしかアップロードされていません。');
				case UPLOAD_ERR_NO_FILE:
					return $this->error('ファイルはアップロードされませんでした。');
				default:
					return $this->error('何らかの理由でアップロードが失敗しました。');
			}
		}
		
		$file = AttachedFile::getinstance($_FILES['uploadfile']['name'], $post['page']);
		$r = $file->set(file_get_contents($_FILES['uploadfile']['tmp_name']));
		$smarty = new CMDSmarty('attach');
		$smarty->assign('filename', $_FILES['uploadfile']['name']);
		$smarty->assign('pagename', $post['page']);
		if($r){
			$ret['body'] = $smarty->fetch('success.tpl.htm');
			$ret['title'] = htmlspecialchars($post['page']) . ' にファイルを添付しました';
		}
		else{
			$ret['body'] = $smarty->fetch('failed.tpl.htm');
			$ret['title'] = htmlspecialchars($post['page']) . ' にファイルを添付できませんでした';
		}
		$ret['pagename'] = $post['page'];
		return $ret;
	}
	
	
	protected function download()
	{
		$get = KinoWiki::getinstance()->getGET();
		if(!isset($get['page']) || !isset($get['file'])){
			return $this->error('パラメータが足りません。');
		}
		if($get['page'] == '' || $get['file'] == ''){
			return $this->error('ページ名およびファイル名に空文字列は使えません。');
		}
		
		$file = AttachedFile::getinstance($get['file'], $get['page']);
		header('Content-Type: application/octet-stream');
		header("Content-Disposition: attachment; filename=\"{$get['file']}\"");
		header('Content-Length: ' . $file->getsize());
		echo $file->getdata(true);
		exit();
	}
	
	
	protected function rename()
	{
		$get = KinoWiki::getinstance()->getGET();
		if(!isset($get['page']) || !isset($get['file'])){
			return $this->error('パラメータが足りません。');
		}
		if($get['page'] == '' || $get['file'] == ''){
			return $this->error('ページ名およびファイル名に空文字列は使えません。');
		}
		
		$smarty = new CMDSmarty('attach');
		$smarty->assign('filename', $get['file']);
		$smarty->assign('pagename', $get['page']);
		$ret['title'] = '添付ファイル名の変更';
		$ret['pagename'] = $get['page'];
		$post = KinoWiki::getinstance()->getPOST();
		if(!isset($post['password']) || !isset($post['newname']) || $post['newname'] == ''){
			$ret['body'] = $smarty->fetch('rename.tpl.htm');
		}
		else{
			if(md5($post['password']) == ADMINPASS){
				$r = Attach::getinstance($get['page'])->rename($get['file'], $post['newname']);
				if($r){
					$ret['body'] = $smarty->fetch('rename_success.tpl.htm');
				}
				else{
					$ret['body'] = $smarty->fetch('rename_failed.tpl.htm');
				}
			}
			else{
				$smarty->assign('newname', $post['newname']);
				$ret['body'] = $smarty->fetch('rename.tpl.htm');
			}
		}
		return $ret;
	}
	
	
	protected function delete()
	{
		$get = KinoWiki::getinstance()->getGET();
		if(!isset($get['page']) || !isset($get['file'])){
			return $this->error('パラメータが足りません。');
		}
		if($get['page'] == '' || $get['file'] == ''){
			return $this->error('ページ名およびファイル名に空文字列は使えません。');
		}
		
		$smarty = new CMDSmarty('attach');
		$smarty->assign('filename', $get['file']);
		$smarty->assign('pagename', $get['page']);
		$ret['title'] = '添付ファイルの削除';
		$ret['pagename'] = $get['page'];
		$post = KinoWiki::getinstance()->getPOST();
		if(!isset($post['password'])){
			$ret['body'] = $smarty->fetch('delete.tpl.htm');
		}
		else{
			if(md5($post['password']) == ADMINPASS){
				AttachedFile::getinstance($get['file'], $get['page'])->delete();
				$smarty->assign('filename', $get['file']);
				$ret['body'] = $smarty->fetch('delete_success.tpl.htm');
			}
			else{
				$smarty->assign('failed', true);
				$ret['body'] = $smarty->fetch('delete.tpl.htm');
			}
		}
		return $ret;
	}
	
	
	protected function show()
	{
		$get = KinoWiki::getinstance()->getGET();
		if(!isset($get['page']) || !isset($get['file'])){
			return $this->error('パラメータが足りません。');
		}
		if($get['page'] == '' || $get['file'] == ''){
			return $this->error('ページ名およびファイル名に空文字列は使えません。');
		}
		
		$smarty = new CMDSmarty('attach');
		$smarty->assign('filename', $get['file']);
		$smarty->assign('pagename', $get['page']);
		$file = AttachedFile::getinstance($get['file'], $get['page']);
		$smarty->assign('size', $file->getsize());
		$smarty->assign('count', $file->getcount());
		$smarty->assign('timestamp', $file->gettimestamp());
		$smarty->assign('md5', md5($file->getdata()));
		$ret['title'] = htmlspecialchars($get['page'] . ' の添付ファイル ' . $get['file']);
		$ret['pagename'] = $get['page'];
		$ret['body'] = $smarty->fetch('show.tpl.htm');
		return $ret;
	}
	
	
	protected function listfile()
	{
		$get = KinoWiki::getinstance()->getGET();
		if(!isset($get['page'])){
			return $this->error('パラメータが足りません。');
		}
		if($get['page'] == ''){
			return $this->error('ページ名に空文字列は使えません。');
		}
		
		$smarty = new CMDSmarty('attach');
		$smarty->assign('pagename', $get['page']);
		$smarty->assign('list', Attach::getinstance($get['page'])->getlist());
		$ret['title'] = htmlspecialchars($get['page']) . ' の添付ファイル一覧';
		$ret['pagename'] = $get['page'];
		$ret['body'] = $smarty->fetch('list.tpl.htm');
		return $ret;
	}
	
	
	protected function listpage()
	{
		$db = DataBase::getinstance();
		$smarty = new CMDSmarty('attach');
		
		$query = "SELECT pagename FROM attach GROUP BY pagename ORDER BY pagename ASC";
		$result = $db->query($query);
		while($row = $db->fetch($result)){
			$smarty->append('list', $row['pagename']);
		}
		$ret['title'] = '添付ファイルを持つページ一覧';
		$ret['body'] = $smarty->fetch('listpage.tpl.htm');
		return $ret;
	}
	
	
	protected function showform()
	{
		$get = KinoWiki::getinstance()->getGET();
		if(!isset($get['page'])){
			return $this->error('パラメータが足りません。');
		}
		if($get['page'] == ''){
			return $this->error('ページ名に空文字列は使えません。');
		}
		$smarty = new CmdSmarty('attach');
		$smarty->assign('pagename', $get['page']);
		$smarty->assign('maxfilesize', $this->maxsize());
		$ret['body'] = $smarty->fetch('attach.tpl.htm');
		$ret['title'] = htmlspecialchars($get['page']) . ' への添付';
		$ret['pagename'] = $get['page'];
		return $ret;
	}
	
	
	protected function maxsize()
	{
		static $search = array('K', 'M');
		static $replace = array('000', '000000');
		$postmax = str_replace($search, $replace, ini_get('post_max_size'));
		$uploadmax = str_replace($search, $replace, ini_get('upload_max_filesize'));
		return min($postmax, $uploadmax, ATTACH_MAXSIZE);
	}
	
	
	protected function error($mes)
	{
		$ret['title'] = 'error';
		$ret['body'] = '<p class="error">' . $mes . '</p>';
		return $ret;
	}
}

?>