<?php
/* 
 * $Id: kinowiki.inc.php,v 1.15 2005/02/26 08:58:38 youka Exp $
 */

ini_set('include_path', './' . PATH_SEPARATOR . './pear/' . PATH_SEPARATOR . ini_get('include_path'));

require_once('page.inc.php');
require_once('wiki.inc.php');
require_once('attach.inc.php');
require_once('autolink.inc.php');
require_once('backlink.inc.php');
require_once('backup.inc.php');
require_once('charentityref.inc.php');
require_once('diff.inc.php');
require_once('database.inc.php');
require_once('exception.inc.php');
require_once('func.inc.php');
require_once('fuzzylink.inc.php');
require_once('htmlconverter.inc.php');
require_once('mail.inc.php');
require_once('parser.inc.php');
require_once('plugin.inc.php');
require_once('smarty.inc.php');
require_once('search.inc.php');
require_once('trackback.inc.php');
require_once('version.inc.php');

define('EXP_URL', '(?:s?https?|ftp|file):\/\/[-a-zA-Z0-9_:@&?=+,.!\/~*%$\'();#]+');	//URLの正規表現
define('EXP_MAIL', '[a-zA-Z0-9_][-.a-zA-Z0-9_]*\@[-a-zA-Z0-9]+(?:\.[-a-zA-Z0-9_]+)+');	//メールアドレスの正規表現

header('Content-Type: text/html; charset=UTF-8');
mb_internal_encoding('UTF-8');
mb_regex_encoding('UTF-8');


/**
 * アプリケーションを表すクラス。
 */
class KinoWiki
{
	protected $pagename = null;	//現在実行中のページ名
	
	protected $post = null;	//デコード済みのQueryString
	protected $get = null;	//デコード済みのQueryString
	protected $cookie = null;	//デコード済みのcookie
	
	protected $skinfile;	//使用するスキン
	protected $theme;	//使用するテーマ
	protected $noframe;	//ページ本文に枠をつけるか否か
	
	
	/**
	 * インスタンスを取得する。シングルトン。
	 */
	static function getinstance()
	{
		static $ins = null;
		
		if($ins == null){
			$ins = new KinoWiki();
		}
		return $ins;
	}
	
	
	/**
	 * コンストラクタ。
	 */
	protected function KinoWiki()
	{
		$this->post = $_POST;
		$this->get = $_GET;
		$this->cookie = $_COOKIE;
		
		if(get_magic_quotes_gpc()){
			$this->post = map($this->post, 'stripslashes');
			$this->get = map($this->get, 'stripslashes');
			$this->cookie = map($this->cookie, 'stripslashes');
		}
		$this->get = map($this->get, 'rawurldecode');
		$encode = mb_http_input('P');
		if($encode !== false && $encode != 'UTF-8'){
			$proc = "return mb_convert_encoding(\$str, 'UTF-8', '$encode');";
			$this->post = map($this->post, create_function('$str', $proc));
		}
		
		$this->skinfile = SKINFILE;
		$this->theme = THEME;
		
		$this->init();
	}
	
	
	/**
	 * アプリケーションの初期化。
	 */
	protected function init()
	{
		define('TIME', time());	//起動時の時間。
		
		if($_SERVER['SERVER_PORT'] == 443){
			$protocol = 'https';
			$port = '';
		}
		else{
			$protocol = strtolower(array_shift(explode('/', $_SERVER['SERVER_PROTOCOL'])));
			$port = $_SERVER['SERVER_PORT'] != 80 ? ":{$_SERVER['SERVER_PORT']}" : '';
		}
		define('SCRIPTPATH', $protocol . '://' . $_SERVER['SERVER_NAME'] . $port . $_SERVER['SCRIPT_NAME']);	//自分自身のパス
	}
	
	
	/**
	 * 実行中のページ名を取得する。
	 */
	function getpagename()
	{
		return $this->pagename;
	}
	
	
	/**
	 * スキンを変更する。
	 */
	function setskinfile($filename)
	{
		$this->filename = $filename;
	}
	
	
	/**
	 * テーマを変更する。
	 */
	function settheme($themename)
	{
		$this->theme = $themename;
	}
	
	
	/**
	 * ページ本文の枠の有無を変更する。
	 * 
	 * @param	bool	$use	trueなら枠を使う。falseなら使わない。
	 */
	function setframe($use)
	{
		$this->noframe = !$use;
	}
	
	
	/**
	 * 実行。
	 */
	function run()
	{
		$starttime = mtime();
		
		try{
			if(isset($this->get['cmd']) && $this->get['cmd'] != ''){
				$ret = $this->callcmd($this->get['cmd']);
			}
			else if(isset($this->get['plugin']) && $this->get['plugin'] != ''){
				$plugin = Plugin::getPlugin($this->get['plugin']);
				$ret = $plugin->do_url($this->get['plugin']);
			}
			else{
				if(isset($this->get['page']) && $this->get['page'] != ''){
					$this->pagename = $this->get['page'];
				}
				else if(isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != ''){
					$this->pagename = rawurldecode($_SERVER['PATH_INFO']);
				}
				else{
					$this->pagename = $_SERVER['QUERY_STRING'] == '' ? DEFAULTPAGE : rawurldecode($_SERVER['QUERY_STRING']);
				}
				$this->pagename = resolvepath($this->pagename);
				
				$ret = $this->showpage($this->pagename);
			}
		}
		catch(MyException $exc){
			$ret['title'] = 'error';
			$ret['body'] = nl2br(htmlspecialchars($exc->message()));
		}
		
		$smarty = new MySmarty(SKIN_DIR);
		$smarty->assign('version', KINOWIKI_VERSION);
		$smarty->assign('theme', $this->theme);
		$smarty->assign('noframe', $this->noframe);
		$smarty->assign($ret);
		$endtime = mtime();
		$smarty->assign('runningtime', $endtime - $starttime);
		$smarty->display($this->skinfile);
	}
	
	
	/**
	 * コマンドを呼び出す。
	 * 
	 * @return	array('title' => string, 'body' => string)	呼び出せなかったときはその旨を返す。
	 */
	protected function callcmd($cmd)
	{
		$file = CMD_DIR . $cmd . '/' . $cmd . '.inc.php';
		if(is_file($file)){
			require_once($file);
			$class = eval("return Cmd_${cmd}::getinstance();");
			return $class->run();
		}
		else{
			$ret['title'] = 'error';
			$smarty = new MySmarty(TPL_DIR);
			$smarty->assign('commandname', $this->get['cmd']);
			$ret['body'] = $smarty->fetch('cmdnotfound.tpl.htm');
			return $ret;
		}
	}
	
	
	/**
	 * ページを表示する。
	 * 
	 * @return	array('title' => string, 'body' => string)	呼び出せなかったときはその旨を返す。
	 */
	protected function showpage($pagename)
	{
		$page = Page::getinstance($pagename);
		if($page->getsource() == ''){
			$ret['title'] = htmlspecialchars("$pagename は存在しません");
			$smarty = new MySmarty(TPL_DIR);
			$smarty->assign('pagename', $pagename);
			$ret['body'] = $smarty->fetch('notexist.tpl.htm');
		}
		else{
			$ret['title'] = htmlspecialchars($pagename);
			$ret['body'] = convert_block($page->getsource(), $pagename);
			$ret['pagename'] = $pagename;
			$ret['lastmodified'] = $page->gettimestamp();
			$ret['lastmodified_old'] = getold($page->gettimestamp());
			$ret['footnote'] = Footnote::getinstance()->getnote();
			$_backlink = BackLink::getinstance()->getlist($pagename);
			$backlink = array();
			foreach($_backlink as $i){
				if(!ishiddenpage($i['pagename'])){
					$backlink[] = $i;
				}
			}
			if($backlink != array()){
				$smarty = new MySmarty(TPL_DIR);
				$smarty->assign('backlink', $backlink);
				$ret['backlink'] = $smarty->fetch('backlink.tpl.htm');
			}
			$attach = Attach::getinstance($pagename)->getlist();
			if($attach != array()){
				$smarty = new MySmarty(TPL_DIR);
				$smarty->assign('attach', $attach);
				$smarty->assign('pagename', $pagename);
				$ret['attach'] = $smarty->fetch('attach.tpl.htm');
			}
			$ret['trackbackrdf'] = TrackBack::getinstance($pagename)->getpingurlrdf();
		}
		return $ret;
	}
	
	
	/**
	 * POSTされたデータをデコードしたものを取得する。
	 */
	function getPOST()
	{
		return $this->post;
	}
	
	
	/**
	 * GETされたデータをデコードしたものを取得する。
	 */
	function getGET()
	{
		return $this->get;
	}
	
	
	/**
	 * cookie（デコード済み）を取得する。
	 */
	function getCOOKIE()
	{
		return $this->cookie;
	}
}



?>
