",
"function:PrintText ''$[Comments]''"
));
SDV($NoCommentsFmt, array(
"",
"function:PrintText ''$[No comments]''"
));
SDV($CommentEditFmt, array("
", &$CommentsFooterFmt));
SDV($NewCommentButtonsFmt, "
");
SDV($EditCommentButtonsFmt, "
");
SDV($CommentsFooterFmt, "wiki:$[PmWiki.CommentsFooter]");
}
// Initializes structures with styled content
function InitCommentsStyled() {
global $CommentFmt, $CommentStartFmt, $NoCommentsFmt, $CommentEditFmt,
$NewCommentButtonsFmt, $EditCommentButtonsFmt, $CommentsFooterFmt;
SDV($CommentFmt, array(
"",
"
\$Author\$Time [X]",
"function:PrintText \$Text",
"
"
));
SDV($CommentStartFmt, "$[Comments]
");
SDV($NoCommentsFmt, "$[No comments]
");
SDV($CommentEditFmt, array("", &$CommentsFooterFmt));
SDV($NewCommentButtonsFmt, "
");
SDV($EditCommentButtonsFmt, "
");
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($_REQUEST['remove']) >= 6 ) {
RetrieveAuthPage($pagename, 'removecomment');
RemoveComment($pagename, $_REQUEST['remove']);
}
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") ) {
$idx = 0;
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];
$remove_id = $idx.'-'.substr($comment[0],0,4);
$remove_url = FmtPageName('$PageUrl?action=comments&remove='.$remove_id.'#comments',$pagename);
$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);
$com_template = str_replace("\$RemoveURL", $remove_url, $com_template);
if( !$wascomment ) {
PrintFmt($pagename, $CommentStartFmt);
$wascomment = true;
}
PrintFmt($pagename, $com_template);
}
$idx++;
}
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, str_replace("\r","",stripmagic($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, str_replace("\r","",stripmagic($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");
}
}
fclose($comfile);
}
if( !$CommentText ) {
$CommentUid = 0;
} else {
CommentsNotify($pagename);
}
}
// Counts comments for the current page
function CommentsCount($pagename) {
global $CommentsFileName;
$lines = 0;
if( $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 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);
}
}
// Removes specified comment on the page.
// Comments are numbered from top starting at 0.
function RemoveComment($pagename, $id) {
global $CommentsFileName;
Lock(2);
$idx = explode('-',$id);
if( count($idx) != 2 || strlen($idx[1]) != 4 ) return; // $id must be like '4-f2a8'
$comments = file($CommentsFileName($pagename));
$cline = explode("|",$comments[$idx[0]]);
$idcheck = substr($cline[0], 0, 4);
if( $idx[1] != $idcheck ) return;
if( !($comfile = @fopen($CommentsFileName($pagename), "w")) ) {
return;
}
array_splice($comments, $idx[0], 1);
fputs($comfile, implode("", $comments));
fclose($comfile);
}
?>