(root)/comment_handler.php - Rev 497
Rev 441 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
<?PHP
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This file is part of Travelsized CMS
* A content management system with modules, based on wiki syntax
*
* Author: Dan Jensen <admin@leinir.dk>
* Copyright 2003/2004
*
* This program is free software; you can redistribute it 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.
*
* The GNU General Public License is available at: http://www.gnu.org/copyleft/
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* Class to hangle recursive comments. Use instructions as follows:
*
* $commenthandler = new commentHandler($yourCommentsArray, $yourCommentsOwner, $commentingAllowanceLevel, $editingAllowanceLevel); // This is where you input the comments data (to start it off, simply pass an empty array)
* $commenthandler->renderComments(); // Put this where you wish to show the actual comments
* $commenthandler->renderCommentsAdder(); // Put this where you wish to show the form for adding a new comment
* if ($commenthandler->commentsChanged) { // If the comments have changed... You don't actually have to check, but it's good for efficiency
* $yourCommentsArray = $commenthandler->comments; // Remember to save your comments again, commentHandler does not do that for you!
* fileSave($commentfilename, array_export($yourCommentsArray, "yourCommentsArray")); // Use for example array_export for saving it to file
* }
*/
class commentHandler
{
var $commentsOwner; ///< Who owns that which is being edited? Used to check commenting and editing allowance levels against
var $commentLevel; ///< The access level for editing the comments
var $editLevel; ///< The access level for editing the comments data
var $comments; ///< The array containing blog data. Just let commentHandler handle this - black box stuff, no need to know what's inside ;)
var $thisPageURL; ///< This can be set by the user, in case thisPageURL() doesn't return enough information (such as sub-items in a blog entry or gallery items or...)
var $commentsChanged = false; ///< This starts false, and will be set to true if the comments have changed (edited, hidden/shown, added, removed...)
var $lastCommenter; ///< The person who made a comment (set if commentsChanged == true)
var $lastComment; ///< The last comment
var $allowNesting = true; ///< Do we allow nesting the comments?
/**
* Constructor for the comments handler. Use the comments handler as described in the class documentation
*
* @param comments Comments data array. If you have no array to begin with, simply pass an empty array.
* @param commentsOwner String comtaining the user id of the parent data
* @param commentLevel Integer containing an allowance level relative to commentsOwner for who is allowed to comment
* @param editLevel Integer containing an allowance level relative to commentsOwner for who is allowed to edit the comments
*
* @return void
*/
function commentHandler
($comments, $commentsOwner, $commentLevel, $editLevel)
{
$this->comments = $comments;
$this->commentsOwner = $commentsOwner;
$this->commentLevel = $commentLevel;
$this->editLevel = $editLevel;
$this->thisPageURL = thisPageURL
();
if( userAllows
( $this->commentsOwner, $this->editLevel ) ) { // Only ever do this if, of course, the user is allowed to actually well... do this :)
if( array_key_exists( "deletecomment", $_REQUEST) )
{
if ( array_key_exists( "confirm_delete", $_REQUEST ) && $_REQUEST["confirm_delete"] == "true" )
$new_comment = $this->deleteComment();
}
else if( array_key_exists( "editcomment", $_REQUEST ) )
{
if ( array_key_exists( "save_comment", $_POST ) )
$new_comment = $this->editComment();
}
else if( array_key_exists( "hideshow", $_REQUEST ) && array_key_exists( "commentid", $_REQUEST ) )
{
if( $_REQUEST["hideshow"] == "hide" )
$hidden = "true";
if( $_REQUEST["hideshow"] == "show" )
$hidden = "";
$new_comment = $_REQUEST["commentid"] . "[hidden]=" . $hidden;
$new_comment = $new_comment;
parse_str($new_comment, $new_comment);
$new_comment = $new_comment["comments"];
}
if( ( array_key_exists( "deletecomment", $_REQUEST ) && array_key_exists( "confirm_delete", $_REQUEST ) ) || ( array_key_exists( "editcomment", $_REQUEST ) && array_key_exists( "save_comment", $_POST ) ) || ( array_key_exists( "hideshow", $_REQUEST ) && array_key_exists( "commentid", $_REQUEST) ) )
{
$this->comments = array_merge_n
($this->comments, $new_comment); // Merge the newly created, edited, deleted, hidden, shown comment into the comments array data
$this->comments = $this->cleanComments($this->comments); // Clean up the comments data - we need to do this to get rid of empty items (for example deleted entries)
$this->commentsChanged = true; // Make sure to tell the caller that the comments have, in fact, changed
header("Location: " . thisPageURL
(true) );
}
}
if( userAllows
( $this->commentsOwner, $this->commentLevel ) && array_key_exists( "newname", $_POST ) && array_key_exists( "newemail", $_POST ) && array_key_exists( "newcomment", $_POST ) )
{
$new_comment = $this->addComment();
$this->comments = array_merge_n
($this->comments, $new_comment); // Merge the newly created, edited, deleted, hidden, shown comment into the comments array data
$this->comments = $this->cleanComments($this->comments); // Clean up the comments data - we need to do this to get rid of empty items (for example deleted entries)
$this->lastCommenter = stripslashes($_POST["newname"]);
$this->lastComment = stripslashes($_POST["newcomment"]);
$this->commentsChanged = true; // Make sure to tell the caller that the comments have, in fact, changed
header("Location: " . thisPageURL
(true) );
}
}
/**
* Internal function used for adding a new comment
*
* @return array The new comments data array, ready for merging
*/
function addComment
()
{
$replyto = str_replace($_REQUEST["newcommentid"], time(), stripslashes($_REQUEST["replyto"]));
$new_commentname = $replyto . "[name]=" . str_replace("%", "%25", stripslashes($_POST["newname"]));
$new_commentemail = $replyto . "[email]=" . str_replace("%", "%25", stripslashes($_POST["newemail"]));
$new_commentcomment = $replyto ."[comment]=" . str_replace("%", "%25", stripslashes($_POST["newcomment"]));
parse_str($new_commentname, $new_commentname);
parse_str($new_commentemail, $new_commentemail);
parse_str($new_commentcomment, $new_commentcomment);
$new_comment = array();
array_merge_2
($new_comment, $new_commentname);
array_merge_2
($new_comment, $new_commentemail);
array_merge_2
($new_comment, $new_commentcomment);
return $new_comment["comments"];
}
/**
* Internal function used for editing an existing comment
*
* @return array The new comments data array, ready for merging
*/
function editComment
()
{
$edit_comment = $_REQUEST["editcomment"];
$edit_commentname = $edit_comment . "[name]=" . str_replace("%", "%25", stripslashes($_POST["editcommentname"]));
$edit_commentemail = $edit_comment . "[email]=" . str_replace("%", "%25", stripslashes($_POST["editcommentemail"]));
$edit_commentcomment = $edit_comment ."[comment]=" . str_replace("%", "%25", stripslashes($_POST["editcommentcomment"]));
$edit_commenthidden = $edit_comment ."[hidden]=" . str_replace("%", "%25", stripslashes($_POST["edit_commenthidden"]));
parse_str($edit_commentname, $edit_commentname);
parse_str($edit_commentemail, $edit_commentemail);
parse_str($edit_commentcomment, $edit_commentcomment);
parse_str($edit_commenthidden, $edit_commenthidden);
$new_comment = array();
array_merge_2
($new_comment, $edit_commentname);
array_merge_2
($new_comment, $edit_commentemail);
array_merge_2
($new_comment, $edit_commentcomment);
array_merge_2
($new_comment, $edit_commenthidden);
return $new_comment["comments"];
}
/**
* Internal function used for deleting an existing comment
*
* @return array The new comments data array, ready for merging
*/
function deleteComment
()
{
$new_comment = $_REQUEST["deletecomment"];
$new_commentname = $new_comment . "[name]=";
$new_commentemail = $new_comment . "[email]=";
$new_commentcomment = $new_comment ."[comment]=";
$new_commenthidden = $new_comment . "[hidden]=";
parse_str($new_commentname, $new_commentname);
parse_str($new_commentemail, $new_commentemail);
parse_str($new_commentcomment, $new_commentcomment);
parse_str($new_commenthidden, $new_commenthidden);
$new_comment = array();
array_merge_2
($new_comment, $new_commentname);
array_merge_2
($new_comment, $new_commentemail);
array_merge_2
($new_comment, $new_commentcomment);
array_merge_2
($new_comment, $new_commenthidden);
return $new_comment["comments"];
}
/**
* Internal function used for cleaning up comments data
*
* @param comments Uncleaned comments data array
*
* @return array Cleaned up comments data array
*/
function cleanComments
($comments)
{
$result = array();
if( is_array( $comments ) )
{
foreach( $comments as $key => $value )
{
$value["name"] = stripslashes($value["name"]);
$value["email"] = stripslashes($value["email"]);
$value["comment"] = stripslashes($value["comment"]);
if ( !( $value["name"] == "" && $value["email"] == "" && $value["comment"] == "" ) )
$result[$key] = $value;
if( is_array( $value["comments"] ) && count( $value["comments"] ) > 0)
$result[$key]["comments"] = $this->cleanComments($value["comments"]);
}
}
return $result;
}
/**
* Internal function used for creating the replyto targets
*/
function replyto
($comments, $depth = "", $commentlink, $newcommentid)
{
$i = 1;
$data = "";
if( is_array( $comments ) )
{
foreach( $comments as $key => $value )
{
$data .= "<option value=\"{$commentlink}[$key][comments][$newcommentid]\">#$depth$i - " . parse_profilelinks
($value['name']) . "</option>";
if( array_key_exists( "comments", $value) && is_array( $value["comments"] ) && count( $value["comments"] ) > 0 )
$data .= $this->replyto($value["comments"], "$depth$i.", $commentlink . "[$key][comments]", $newcommentid);
$i++;
}
}
return $data;
}
/**
* Function which returns the number of comments in the current instance
*
* @return int Number of comments
*/
function numberOfComments
()
{
return $this->countComments($this->comments);
}
/**
* Internal function used above for counting the comments (the numberOfComments function is a dummy function created to make the API a little prettier)
*
* @param comments Input a comments data array
*
* @return int Number of comments in the comments data array
*/
function countComments
($comments)
{
$data = 0;
if( !is_array($comments) )
return 0;
foreach( $comments as $key => $value )
{
$data++;
if( array_key_exists( "comments", $value ) && is_array( $value["comments"] ) && count( $value["comments"] ) > 0 )
$data += $this->countComments($value["comments"]);
}
return $data;
}
/**
* Internal function used to get a single comment's data
*
* @param whatcomment Which comment do you want to grab?
* @param comments A comments data structure to get the comment from
*
* @return array An array containing the single comment
*/
function getComment
($whatcomment, $comments)
{
foreach( $whatcomment as $key => $value )
{
if( is_array( $value["comments"] ) )
$thecomment = $this->getComment($value["comments"], $comments[$key]["comments"]);
else
$thecomment = $comments[$key];
}
return $thecomment;
}
/**
* renderComments renders the comments
*
* @return string The rendered comments
*/
function renderComments
()
{
$listid = 0;
if( count($this->comments) < 1 )
return "";
return $this->renderCommentsActual($this->comments, $listid, "comments", "");
}
/**
* The actual comments rendering function. The renderComments function is a dummy function that makes the API a little more pleasant
*
* @param $comments The comments data
* @param $commentlink The link... Just pass "" to this - used internally for recursion
* @param $depth How deep are we? Just pass "" to this - used internally for recursion
* @param $listid The comment index. Pass a variable $listid = 0 to this - used internally for recursion, for javascript replyto links
*
* @return string The rendered comments
*/
function renderCommentsActual
($comments, &$listid, $commentlink = "", $depth = "")
{
$data = "<ul class=\"comments\">";
$i = 1;
foreach($comments as $key => $value)
{
$listid++;
if( ($value["name"] != "" && $value["email"] != "" && $value["comment"] != "") || is_array($value["comments"]) && count($value["comments"]) > 0 )
{
$data .= "
<li class=\"comment\">";
// Are we deleting the comment?
if( $_REQUEST["deletecomment"] == $commentlink . "[$key]" )
$data .= $this->renderCommentsDelete();
// Are we editing the comment?
if ($_REQUEST["editcomment"] == $commentlink . "[$key]")
$data .= $this->renderCommentEditor();
// If not, just show it
else
{
$data .= "<div style=\"float: right;\" class=\"comment-commands\">";
if( userAllows
( $this->commentsOwner, $this->editLevel ) )
{
$data .= "
<a class=\"command\" href=\"" . $this->thisPageURL . "&deletecomment=" . $commentlink . "[$key]#deletecomment\">[" . i18n
("Delete") . "]</a>
";
if( $value["hidden"] != true )
$data .= "
<a class=\"command\" href=\"" . $this->thisPageURL . "&hideshow=hide&commentid=" . $commentlink . "[$key]#" . $commentlink . "[comments][$key]\">[" . i18n
("Hide") . "]</a>";
else
$data .= "
<a class=\"command\" href=\"" . $this->thisPageURL . "&hideshow=show&commentid=" . $commentlink . "[$key]#" . $commentlink . "[comments][$key]\">[" . i18n
("Show") . "]</a>";
$data .= "
<a class=\"command\" href=\"" . $this->thisPageURL . "&editcomment=" . $commentlink . "[$key]#editcomment\">[" . i18n
("Edit") . "]</a>";
}
if( userAllows
( $this->commentsOwner, $this->commentLevel ) )
{
$data .= "
<script language=\"javascript\">
document.write('<a class=\"command\" href=\"#comment\" onClick=\"document.getElementById(\\'replyto\\').selectedIndex=$listid;\">[" . i18n
("Reply") . "]</a>');
</script>";
}
$data .= "</div>";
if( $value["hidden"] != true )
{
$data .= parse_page_data
($value["comment"]) . "<div class=\"comment-name\">
<a class=\"comment-link\" name=\"comment$depth$i\" href=\"" . $this->thisPageURL . "#comment$depth$i\">#$depth$i</a>
" . parse_profilelinks
($value["name"]) . " (" . $value["email"] . ") - " . formatTime
( $key ) . "
</div>";
}
else
{
$data .= "<div class=\"comment-name\">
<a class=\"comment-link\" name=\"comment$depth$i\" href=\"" . $this->thisPageURL . "#comment$depth$i\">#$depth$i</a>
<small class=\"comment\">" . i18n
("This comment has been hidden") . "</small></div>";
}
}
if( array_key_exists( "comments", $value) && is_array($value["comments"]) && count($value["comments"]) > 0 )
$data .= $this->renderCommentsActual($value["comments"], $listid, $commentlink . "[$key][comments]", "$depth$i.");
$data .= "</li>";
$i++;
}
}
$data .= "</ul>";
return $data;
}
function renderCommentsAdder
()
{
global $formatting_toolbar, $permissionlevels_array, $systemOptions;
if (userAllows
($this->commentsOwner, $this->commentLevel))
{
$commenting_username = currentUser
();
if ($commenting_username != "")
{
$commenting_email = str_replace(".", " dot ", str_replace("@", " ad ", getUserInfo
($commenting_username, "email")));
$commenting_username = "%%$commenting_username%%";
}
$newcommentid = time() + 1; //Add one to the time, otherwise it will break when adding a comment to the comment a user added now
$commenting_replyto = "<option value=\"comments[$newcommentid]\">" . i18n
("Top level") . "</option>";
if( $this->allowNesting )
$commenting_replyto .= $this->replyto($this->comments, "", "comments", $newcommentid);
$data = "
<form name=\"commentform\" method=\"post\" action=\"" . $this->thisPageURL . "\">
<input type=\"hidden\" name=\"newcommentid\" value=\"$newcommentid\" />
<table class=\"editcomment\">
<tr class=\"editcomment\">
<td class=\"editcomment\" width=\"50%\">" . i18n
("Reply to") . ":<a class=\"namedanchor\" name=\"comment\"> </a></td>
<td class=\"editcomment\" width=\"50%\"><select style=\"width: 100%\" id=\"replyto\" name=\"replyto\">$commenting_replyto</select></td>
</tr>
<tr class=\"editcomment\">
<td class=\"editcomment\">" . i18n
("Your name") . ":</td>
<td class=\"editcomment\"><input style=\"width: 100%\" type=\"text\" name=\"newname\" value=\"$commenting_username\" /></td>
</tr>
<tr class=\"editcomment\">
<td class=\"editcomment\">" . i18n
("Your email address") . ":</td>
<td class=\"editcomment\"><input style=\"width: 100%\" type=\"text\" name=\"newemail\" value=\"$commenting_email\" /></td>
</tr>
<tr class=\"editcomment\">
<td class=\"editcomment\" colspan=\"2\">" . i18n
("Your comment") . ":
</tr>
$formatting_toolbar
<tr class=\"editcomment\">
<td class=\"editcomment\" colspan=\"2\">
<textarea rows=\"10\" cols=\"70\" style=\"width: 100%;\" id=\"edit\" name=\"newcomment\">\n\n---\n" . getUserInfo
(currentUser
(), "signature", getUserInfo
(currentUser
(), "name", i18n
("Posted by Anonymous on ##0##", array(formatTime
(time())))) ) . "</textarea>
</td>
</tr>
<tr class=\"editcomment\">
<td class=\"editcommentbottom\"><input type=\"submit\" value=\"" . i18n
("Create comment") . "\" /></td>
<td class=\"editcommentbottom wikirightalign\"><input type=\"reset\" value=\"" . i18n
("Reset") . "\" /></td>
</tr>
</table>
</form>
";
$data = renderInformationBox
( i18n
("New Comment"), $data, false );
}
else if( $systemOptions["permissionmessages"] == 1 )
$data = "<p><small class=\"comment\">" . i18n
("##0## has disallowed commenting for users that do not fit the following description", array(getUserInfo
($this->commentsOwner, "name"))) . ": <strong>" . $permissionlevels_array[$this->commentLevel] . "</strong></small></p>";
return $data;
}
/**
* Internal function used for showing the inline comment deletion comfirmation dialog
*
* @return string The dialog
*/
function renderCommentsDelete
()
{
if( !$_REQUEST["confirm_delete"] )
{
$question = "<p><a class=\"namedanchor\" name=\"deletecomment\"> </a>" . i18n
("Please confirm that you wish to delete this comment. Please note - this will delete ALL sub-comments. If you wish to allow people to still see the sub-comments, simply hide the comment in stead.") . "</p>
<div class=\"wikicenteralign\">
<a class=\"command\" href=\"" . $this->thisPageURL . "&deletecomment={$_REQUEST['deletecomment']}&confirm_delete=true\">[" . i18n
("Confirm delete") . "]</a>
<a class=\"command\" href=\"" . $this->thisPageURL . "\">[" . i18n
("Abort delete") . "]</a>
</div>";
$data = renderQuestionBox
( i18n
("Delete comment?"), $question, false );
}
return $data;
}
/**
* Internal function used for showing the inline comment editing dialog
*
* @return string The dialog
*/
function renderCommentEditor
()
{
global $formatting_toolbar;
if( !$_POST["save_comment"] )
{
$edit_comment = $_REQUEST["editcomment"];
parse_str($edit_comment, $edit_comment);
$edit_comment = $this->getComment($edit_comment["comments"], $this->comments);
$data .= "
<form action=\"" . $this->thisPageURL . "&editcomment={$_REQUEST['editcomment']}\" method=\"post\">
<table class=\"editcomment\">
<tr class=\"editcomment\"><th class=\"editcomment\" colspan=\"2\"><a class=\"namedanchor\" name=\"editcomment\"> </a>" . i18n
("Edit comment") . "</th></tr>
<tr class=\"editcomment\">
<td class=\"editcomment\">" . i18n
("Commenter's name") . ":</td>
<td class=\"editcomment\"><input style=\"width: 100%\" type=\"text\" name=\"editcommentname\" value=\"{$edit_comment['name']}\" /></td>
</tr>
<tr class=\"editcomment\">
<td class=\"editcomment\">" . i18n
("Commentor's email address") . ":</td>
<td class=\"editcomment\"><input style=\"width: 100%\" type=\"text\" name=\"editcommentemail\" value=\"{$edit_comment['email']}\" /></td>
</tr>
<tr class=\"editcomment\">
<td class=\"editcomment\" colspan=\"2\">" . i18n
("The comment") . ":
</tr>
$formatting_toolbar
<tr class=\"editcomment\">
<td class=\"editcomment\" colspan=\"2\">
<textarea rows=\"10\" cols=\"70\" style=\"width: 100%;\" id=\"edit\" name=\"editcommentcomment\">{$edit_comment['comment']}</textarea>
</td>
</tr>
<tr class=\"editcomment\">
<td class=\"editcommentbottom\"><input type=\"submit\" name=\"save_comment\" value=\"" . i18n
("Save comment") . "\" /></td>
<td class=\"editcommentbottom wikirightalign\"><input type=\"reset\" value=\"" . i18n
("Reset") . "\" /></td>
</tr>
</table>
</form>";
}
return $data;
}
}
?>