<?php if (!defined('PmWiki')) exit();

/*  Copyright 2004 Ilya Zverev (zverik@int.spb.ru)
    You can redistribute this file and/or modify
    it under the terms of the GNU General Public License as published
    by the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.  

    This file enables commenting of pages in PmWiki.
	Tested with PmWiki 1.0.8.
	Simply copy this file into the 'local/' subdirectory or some other
    suitable place and then do

        include_once('local/comments.php');

*/

SDV($HandleActions['comments'], 'HandleComments');
SDV($CommentsFileName, 'CommentsFileName');

// feel free to choose :)
# InitComments();
InitCommentsStyled();

// Initializes $RecentComments array.
if( !isset($RecentComments) ) {
	// Mindlessly stolen from Cookbook.ChangeSummary
	$RecentComments['$Group.RecentComments'] = 
	  "* [[\$PageUrl?action=comments#comments \$Group/\$Title]] . . . \$CurrentTime by \$AuthorLink";
	$RecentComments['Main.AllRecentComments'] = 
	  "* [[\$PageUrl?action=comments#comments \$Group.\$Title]] . . . \$CurrentTime by \$AuthorLink";
}

// thought it'd be better here
BasicCommentSetup();


// Initializes structures with plain content
function InitComments() {
	global $CommentFmt, $CommentStartFmt, $NoCommentsFmt, $CommentEditFmt,
		$NewCommentButtonsFmt, $EditCommentButtonsFmt, $CommentsFooterFmt;

	SDV($CommentFmt, "function:PrintText ----\n'''\$Author''' %color=green%[-(\$Time)-]%%\n\n\$Text\n\n");
	SDV($CommentStartFmt, array(
		"<a name=\"comments\"></a>",
		"function:PrintText ''$[Comments]''"
	));
	SDV($NoCommentsFmt, array(
		"<a name=\"comments\"></a>",
		"function:PrintText ''$[No comments]''"
	));
	SDV($CommentEditFmt, array("<form action='\$PageUrl' method='post'>
		<input type='hidden' name='pagename' value='\$PageName' />
		<input type='hidden' name='action' value='comments' />
		<input type='hidden' name='uid' value='\$CommentUid' />
		$[Enter your comment]:<br />
		<textarea name='text' rows='8' cols='60'>\$CommentText</textarea><br />
		$[Author]: <input type='text' name='author' value='\$Author' />
		\$CommentButtonsFmt
		</form>", &$CommentsFooterFmt));
	SDV($NewCommentButtonsFmt, "
		<input type='submit' name='post' value=' $[Submit] ' />
	");
	SDV($EditCommentButtonsFmt, "
		<input type='submit' name='post' value=' $[Update] ' />
		<input type='submit' name='delete' value=' $[Delete] ' onclick='javascript:text.value=\"\";' />
		<input type='button' value=' $[Reset] ' onclick='javascript:text.value=\"\"; uid.value=\"0\"'/>
	");
	SDV($CommentsFooterFmt, "wiki:$[PmWiki.CommentsFooter]");
}

// Initializes structures with styled content
function InitCommentsStyled() {
	global $CommentFmt, $CommentStartFmt, $NoCommentsFmt, $CommentEditFmt,
		$NewCommentButtonsFmt, $EditCommentButtonsFmt, $CommentsFooterFmt;

	SDV($CommentFmt, array(
		"<div style='padding: 4px; border-bottom: 1px dotted gray;'>",
		"<span style='font-weight: bold; float: left;'>\$Author</span><span style='float: right; font-style: italic; font-size: x-small; color: green;'>\$Time</span><br>",
		"function:PrintText \$Text",
		"</div>"
	));
	SDV($CommentStartFmt, "<a name=\"comments\"></a><div style='margin-top: 2em; text-align: center; font-weight: bold; border: 1px black solid; background-color: #DDD;'>$[Comments]</div>");
	SDV($NoCommentsFmt, "<a name=\"comments\"></a><div style='margin-top: 2em; text-align: center; font-weight: bold; border: 1px black solid; background-color: #DDD;'>$[No comments]</div>");
	SDV($CommentEditFmt, array("<form action='\$PageUrl' method='post'>
		<input type='hidden' name='pagename' value='\$PageName' />
		<input type='hidden' name='action' value='comments' />
		<input type='hidden' name='uid' value='\$CommentUid' />
		$[Enter your comment]:<br />
		<textarea name='text' rows='8' cols='60'>\$CommentText</textarea><br />
		$[Author]: <input type='text' name='author' value='\$Author' />
		\$CommentButtonsFmt
		</form>", &$CommentsFooterFmt));
	SDV($NewCommentButtonsFmt, "
		<input type='submit' name='post' value=' $[Submit] ' />
	");
	SDV($EditCommentButtonsFmt, "
		<input type='submit' name='post' value=' $[Update] ' />
		<input type='submit' name='delete' value=' $[Delete] ' onclick='javascript:text.value=\"\";' />
		<input type='button' value=' $[Reset] ' onclick='javascript:text.value=\"\"; uid.value=\"0\"'/>
	");
	SDV($CommentsFooterFmt, "wiki:$[PmWiki.CommentsFooter]");
}

// aquires special params (uid & text) and initializes buttons.
// useful when PatchCommentBrowseFmt() is called from outside.
function BasicCommentSetup() {
	global $CommentText, $Author, $CommentUid,
		$CommentButtonsFmt, $NewCommentButtonsFmt;

	$CommentText = $_REQUEST['text'];
	SDV($Author, $_REQUEST['author']); // should I?
	$CommentUid = $_REQUEST['uid'];

	if( !isset($CommentUid) ) {
		// always must be not empty.
		$CommentUid = 0;
	}

	// edit buttons are displayed only right after posting.
	$CommentButtonsFmt = $NewCommentButtonsFmt;
}

// Handles action=comments
function HandleComments( $pagename ) {
	global $CommentUid,
		$CommentButtonsFmt, $NewCommentButtonsFmt, $EditCommentButtonsFmt;

	if( strlen($CommentUid) > 0 ) {
		// uid is either 0 or md5 of something
		HandlePostComment($pagename);
	}

	if( strlen($CommentUid) > 1 ) {
		// uid is not 0
		$CommentButtonsFmt = $EditCommentButtonsFmt;
	} else {
		$CommentButtonsFmt = $NewCommentButtonsFmt;
	}

	// cheat! cheat! :)
	PatchCommentBrowseFmt();
	HandleBrowse($pagename);
}

// Prints out all the comments
function PrintComments($pagename) {
	global $CommentFmt, $NoCommentsFmt, $CommentStartFmt, $TimeFmt,
		$Newline, $CommentsFileName;

	// Actually I don't know how to use Lock() function.
	Lock(0);
	$wascomment = false;
	if( $comfile = @fopen($CommentsFileName($pagename), "r") ) {
		while(!feof($comfile)) {
			// Note: $Newline is not stored in the comments file.
			$comment = explode("|",str_replace($Newline, "\n", rtrim(fgets($comfile, 4096))));
			if( count($comment) == 5 ) {
				$com_template = $CommentFmt;
				// either author name or ip. Wish it was prettier :)
				$author = $comment[2] ? $comment[2] : $comment[1];
				$com_template = str_replace("\$Author", $author, $com_template);
				$com_template = str_replace("\$Time", strftime($TimeFmt, $comment[3]), $com_template);
				$com_template = str_replace("\$Text", $comment[4], $com_template);
				if( !$wascomment ) {
					PrintFmt($pagename, $CommentStartFmt);
					$wascomment = true;
				}
				PrintFmt($pagename, $com_template);
			}
		}
		fclose($comfile);
	}

	if( !$wascomment ) {
		// no comments =)
		PrintFmt($pagename, $NoCommentsFmt);
	}
}

// Returns file name for the comments for current page
// You may want to alter this function.
// Then do so :)
function CommentsFileName($pagename) {
	global $WikiDir;
	return $WikiDir.'/'.$pagename.".Comments";
}

// Creates/updates/deletes comments
function HandlePostComment( $pagename ) {
	global $CommentText, $CommentUid, $Author, $Now, $Newline, $CommentsFileName;

	// Have I said that I have no idea how does Lock() work? :)
	Lock(2);
	if( !$CommentUid ) {
		// new comment
		// note that condition is either uid is not set, empty string or numeric 0.
		if( !($comfile = @fopen($CommentsFileName($pagename), "a")) ) {
			// major total super mega crash: cannot create file.
			return;
		}
		// major total super mega unique id :)
		$CommentUid = md5(uniqid(rand(), 1));
		$line = $CommentText ? join("|", array($CommentUid, $_SERVER['REMOTE_ADDR'], $Author, $Now, $CommentText)) : "";
		fputs($comfile, str_replace("\n", $Newline, $line)."\n");
		fclose($comfile);
	} else {
		// change comment
		// note that this assignment is exactly line the one above.
		// if you have any idea how to beautify this, please mail me.
		$line = $CommentText ? join("|", array($CommentUid, $_SERVER['REMOTE_ADDR'], $Author, $Now, $CommentText)) : "";
		$comments = file($CommentsFileName($pagename));
		if( !($comfile = @fopen($CommentsFileName($pagename), "w")) ) {
			return;
		}
		foreach( $comments as $idx => $cmt ) {
			$cmt = str_replace($Newline, "\n", rtrim($cmt));
			$comment = explode("|",$cmt);
			if( count($comment) == 5 ) {
				if( $comment[0] == $CommentUid ) {
					$cmt = $line;
					$comments[$idx] = $cmt;
				}
				fputs($comfile, str_replace("\n", $Newline, $cmt)."\n");
			}
		}
	}

	if( !$CommentText ) {
		$CommentUid = 0;
	} else {
		CommentsNotify($pagename);
	}
}

// Counts comments for the current page
function CommentsCount($pagename) {
	global $CommentsFileName;

	$lines = 0;
	$comments = file($CommentsFileName($pagename));
	// count($comments) is not enough: there may be empty lines
	foreach( $comments as $cmt ) {
		$comment = explode("|",rtrim($cmt));
		if( count($comment) == 5 ) {
			$lines++;
		}
	}
	return $lines;
}

// Displays comments count. Useful in <!--function:...-->
function DisplayCommentsCount($pagename) {
	echo CommentsCount($pagename);
}

// Displays comments underneath the page
function PatchCommentBrowseFmt() {
	global $HandleBrowseFmt, $PageStartFmt, $PageRedirectFmt,
		$PageEndFmt, $CommentEditFmt;

	// todo: upgrade it to find 'function:PrintText' and to
	// include my two lines right after it.
	// todo2: think over if todo1 is really needed.
	$HandleBrowseFmt = array(&$PageStartFmt,
		&$PageRedirectFmt,'function:PrintText',
		'function:PrintComments',
		&$CommentEditFmt,
		&$PageEndFmt);
}

// Updates RecentComments pages
function CommentsNotify($pagename) {
	global $RecentComments, $RCDelimPattern;

	// copy-n-paste from pmwiki.php, version 1.0.8
	foreach($RecentComments as $rcfmt => $pgfmt) {
		$rcname=FmtPageName($rcfmt,$pagename); if (!$rcname) continue;
		$pgtext=FmtPageName($pgfmt,$pagename); if (!$pgtext) continue;
		if (@$seen[$rcname]++) continue;
		$rcpage = ReadPage($rcname,"");
		$rcelim = preg_quote(preg_replace("/$RCDelimPattern.*$/",' ',$pgtext),'/');
		$rcpage['text'] = preg_replace("/[^\n]*$rcelim.*\n/","",$rcpage['text']);
		if (!preg_match("/$RCDelimPattern/",$rcpage['text'])) 
			$rcpage['text'] .= "$pgtext\n";
		else 
			$rcpage['text'] = preg_replace("/([^\n]*$RCDelimPattern.*\n)/",
				"$pgtext\n$1",$rcpage['text'],1);
		WritePage($rcname,$rcpage);
	}
}

?>