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

class Plugin_blog extends Plugin
{
	//カテゴリ別の目次を格納するディレクトリ
	protected $category_prefix = 'カテゴリ';
	
	//blog別のパスワード。このリストにない場合はKinoWiki本体の管理者パスワードを使う。
	protected $passwordlist = array('example' => 'pass');
	
	//クッキーを使ってパスワードを覚えさせるときは有効期限（秒数）を、そうでないときは0を。
	protected $cookie = 2592000;	//60*60*24*30
	
	
	protected $blogname;
	protected $categorypagename;
	protected $password;
	protected $subject = '';
	protected $text = '';
	protected $categories = array();
	protected $continuefrom = '';
	protected $date = '';
	protected $pagename = '';
	protected $datepagename = '';
	
	
	function do_block($pagename, $param1, $param2)
	{
		if(trim($param1) == ''){
			throw new PluginException('引数がありません。', 'blog');
		}
		
		$cookie = KinoWiki::getinstance()->getCOOKIE();
		$this->blogname = trim($param1);
		$this->categorypagename = $this->blogname . '/' . $this->category_prefix;
		$this->password = isset($cookie['plugin_blog']) ? $cookie['plugin_blog'] : '';
		return $this->getform();
	}
	
	
	function do_url()
	{
		$get = KinoWiki::getinstance()->getGET();
		$post = KinoWiki::getinstance()->getPOST();
		$cookie = KinoWiki::getinstance()->getCOOKIE();
		
		if(isset($get['continue'])){
			if(mb_ereg('^(.+?)/\d{4}-\d{2}-\d{2}/.+$', $get['continue'], $m)){
				$this->blogname = $m[1];
				$this->categorypagename = $this->blogname . '/' . $this->category_prefix;
				$this->password = isset($cookie['plugin_blog']) ? $cookie['plugin_blog'] : '';
				$this->continuefrom = $get['continue'];
				$ret['title'] = htmlspecialchars($this->blogname) . ' への追加';
				$ret['body'] = $this->getform();
				return $ret;
			}
			else{
				throw new PluginException('つづき元のページ名が正しくありません。', 'blog');
			}
		}
		else{
			if(isset($post['blogname']) && $post['blogname'] != ''){
				$this->blogname = $post['blogname'];
				$this->categorypagename = $this->blogname . '/' . $this->category_prefix;
				$this->password = isset($cookie['plugin_blog']) ? $cookie['plugin_blog'] : '';
				return $this->post();
			}
			else{
				throw new PluginException('パラメータが足りません。', 'blog');
			}
		}
	}
	
	
	/**
	 * 投稿用フォームを取得する。
	 */
	protected function getform()
	{
		$db = DataBase::getinstance();
		$_categorypagename = $db->escape($this->categorypagename);
		$query  = "SELECT pagename FROM page";
		$query .= " WHERE pagename like '{$_categorypagename}/%'";
		$query .= " ORDER BY pagename ASC";
		$result = $db->query($query);
		$categorybutton = array();
		$prefix = mb_ereg_quote($this->categorypagename);
		$exp = "^{$prefix}/(([^/]+).*)$";
		while($row = $db->fetch($result)){
			mb_ereg($exp, $row['pagename'], $m);
			$categorybutton[$m[2]][] = $m[1];
		}
		
		$smarty = new PluginSmarty('blog');
		$smarty->assign('blogname', $this->blogname);
		$smarty->assign('continue', $this->continuefrom);
		$smarty->assign('text', $this->text);
		$smarty->assign('date', $this->date);
		$smarty->assign('subject', $this->subject);
		$smarty->assign('category', join('|', $this->categories));
		$smarty->assign('password', $this->password);
		$smarty->assign('categorybutton', $categorybutton);
		return $smarty->fetch('form.tpl.htm');
	}
	
	
	/**
	 * ポストされたデータを処理する。
	 */
	protected function post()
	{
		$ret = $this->checkpostdata();
		if($ret != array()){
			$mes = '<p class="warning">' . join("<br />\n", $ret) . "</p>\n";
			$ret['title'] = htmlspecialchars($this->blogname) . ' への追加';
			$ret['body'] = $mes . $this->getform();
			return $ret;
		}
		
		$this->write();
		redirect($this->pagename);
	}
	
	
	function checkpostdata()
	{
		$post = KinoWiki::getinstance()->getPOST();
		$error = array();
		
		//タイトルの入力チェック
		if(!isset($post['subject']) || trim($post['subject']) == ''){
			$error[] = 'タイトルがありません。';
		}
		else{
			$this->subject = $post['subject'];
		}
		
		//本文の入力チェック
		if(!isset($post['text']) || trim($post['text']) == ''){
			$error[] = '本文がありません。';
		}
		else{
			$this->text = $post['text'];
		}
		
		//カテゴリの入力チェック
		if(!isset($post['category']) || !mb_ereg("[^　\s\t\n\r\x0b|]", $post['category'])){
			$error[] = 'カテゴリがありません。';
		}
		else{
			$this->categories = array_unique(array_map('trim', explode('|', $post['category'])));
			$i = array_search('', $this->categories);
			if($i !== false){
				unset($this->categories[$i]);
			}
		}
		
		//「続き」の元記事のチェック
		if(!isset($post['continue']) || (trim($post['continue']) != '' && !Wiki::getinstance()->ispage(trim($post['continue'])))){
			$error[] = 'つづきの元のページがありません。';
		}
		else{
			$this->continuefrom = trim($post['continue']);
		}
		
		//入力された日付のチェック
		if(!isset($post['date']) || trim($post['date']) == ''){
			$error[] = '日付がありません。';
		}
		else{
			if(!mb_ereg('^(\d{4})[-/](\d{1,2})[-/](\d{1,2})\s*$', $post['date'], $m)){
				$error []= '日付の書式が正しくありません。';
			}
			else{
				if(!checkdate($m[2], $m[3], $m[1])){
					$error[] = '日付が正しくありません。';
				}
				else{
					$this->date = sprintf('%4d-%02d-%02d', $m[1], $m[2], $m[3]);
				}
			}
		}
		
		//パスワードのチェック
		if(!isset($post['password'])){
			$error[] = 'パスワードがありません。';
			setcookie('plugin_blog', '', -3600);	//パスワードが無いときはクッキーを削除
		}
		else{
			$pass = isset($this->passwordlist[$this->blogname]) ? md5($this->passwordlist[$this->blogname]) : ADMINPASS;
			if(md5($post['password']) != $pass){
				$error[] = 'パスワードが正しくありません。';
			}
			else{
				$this->password = $post['password'];
				if($this->cookie > 0){
					setcookie('plugin_blog', $post['password'], time() + $this->cookie);
				}
			}
		}
		
		
		//入力から他変数の組み立て
		if($this->date != ''){
			$this->datepagename = $this->blogname . '/' . $this->date;
			if($this->subject != ''){
				$this->pagename = $this->datepagename . '/' . $this->subject;
			}
		}
		
		//すでに存在するページに書くのはNG
		if(Wiki::getinstance()->ispage($this->pagename)){
			$error[] = 'ページがすでに存在します。タイトルを変更してください。';
		}
		
		return $error;
	}
	
	
	
	/**
	 * 投稿記事の保存。
	 */
	protected function write()
	{
		if(mb_ereg('^.+?/.+?/(.+)$', $this->continuefrom, $m)){
			$continuefrom = "[[{$m[1]}>{$this->continuefrom}]]";
		}
		else{
			$continuefrom = '';
		}
		
		$catlist = '';
		foreach($this->categories as $c){
			$catlist .= "&#x5b;[[$c>{$this->categorypagename}/$c]]&#x5d;";
		}
		
		$smarty = new PluginSmarty('blog');
		$smarty->assign('subject', $this->subject);
		$smarty->assign('text', $this->text);
		$smarty->assign('categorylist', $catlist);
		$smarty->assign('timestamp', TIME);
		$smarty->assign('continuefrom', $continuefrom);
		$smarty->assign('pagename', $this->pagename);
		$source = $smarty->fetch('blog.tpl');
		Page::getinstance($this->pagename)->write($source);
		
		$this->_write_category();
		$this->_write_datepage();
		$this->_write_continue();
	}
	
	
	/**
	 * 日付ページに登録する。
	 */
	protected function _write_datepage()
	{
		$page = Page::getinstance($this->datepagename);
		$old = $page->getsource();
		if($old == ''){
			$old = "#blognavi\n\n<bloginclude>\n</bloginclude>\n\n#blognavi";
		}
		$old = mb_ereg_replace("<bloginclude>\n", "<bloginclude>\n{$this->pagename}\n", $old);
		$page->write($old, true);
	}
	
	
	/**
	 * カテゴリに登録する。
	 */
	protected function _write_category()
	{
		foreach($this->categories as $c){
			$list = "-({$this->date})&nbsp;&nbsp;[[{$this->subject}>{$this->pagename}]]\n";
			$page = Page::getinstance($this->categorypagename . '/' . $c);
			$old = $page->getsource();
			$page->write($list . $old, true);
		}
	}
	
	
	/**
	 * つづき元のページに登録する。
	 */
	protected function _write_continue()
	{
		if(!mb_ereg('^.+?/.+?/.+$', $this->continuefrom)){
			return;
		}
		
		$continueon = "[[{$this->subject}>{$this->pagename}]]";
		$page = Page::getinstance($this->continuefrom);
		$old = $page->getsource();
		$old = mb_ereg_replace("(#right{\n)(.+?}\n----\n)", "\\1&#x5b;{$continueon}&#x5d;につづく\n\\2", $old, 'm');
		$page->write($old, true);
	}
}


?>