Ronald Huereca Description: Allows you and your users to edit their comments inline. Admin and editors can edit all comments. Special Thanks: An extra special thanks goes out to Vivien from Inspiration Bit (http://www.inspirationbit.com). Without her, this plugin release wouldn't have been possible. Brett Terpstra from Circle Six Design (http://blog.circlesixdesign.com) helped fix a rather major bug as well during testing. Thank you Brett. Copyright 2007 Ronald Huereca (email : ron alfy [a t ] g m ail DOT com) 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ if (function_exists('wp_enqueue_script')) { wp_enqueue_script('ajax_edit_comments', get_bloginfo('wpurl') . '/wp-content/plugins/wp-ajax-edit-comments/js-includes/wp-ajax-edit-comments.js.php', array('jquery'), '1.0'); } class WPrapAjaxEditComments { var $commentClassName = "editComment"; //Do not edit this name var $commentAuthorName = "editAuthor"; //Do not edit this name var $skipDiv = false; var $minutes = 30; var $admin = "true"; var $cookieName = "WPrapAjaxEditCommentId";//Do not edit this name var $optionsName = "WPAjaxEditComments"; //Do not edit this name var $userOptionsName = "WPAjaxEditAuthorUserOptions"; var $adminOptions = false; var $userOptions = false; //Do not edit this name //constructor function WPrapAjaxEditComments() { } //Run when the plugin is first activated function init() { $this->getAdminOptions(); } //Returns an array of admin options function getAdminOptions() { if ($this->adminOptions == false) { $optionsName = $this->optionsName; $adminOptions = array( 'allow_editing' => 'true', 'minutes' => '30', 'edit_text' => 'You may click on your name and/or comment to edit.' ); $options = get_option($optionsName); if (!empty($options)) { foreach ($options as $key => $option) $adminOptions[$key] = $option; } update_option($optionsName, $adminOptions); $this->adminOptions = $adminOptions; } return $this->adminOptions; } //Returns an array of user options function getUserOptions() { global $user_email; if ($this->userOptions == false) { if (empty($user_email)) {get_currentuserinfo();} if (empty($user_email)) { return ''; } $optionsName = $this->userOptionsName; $defaults = array('author_editing' => 'true', 'comment_editing' => 'true', 'admin_editing' => 'false'); $userOptions = get_option($optionsName); if (!isset($userOptions)) { $userOptions = array(); } //See if an older version doesn't match the new defaults if (empty($userOptions[$user_email])) { $userOptions[$user_email] = $defaults; update_option(optionsName, $userOptions); } else { foreach ($userOptions[$user_email] as $key => $option) $defaults[$key] = $option; $userOptions[$user_email] = $defaults; //update_option(optionsName, $userOptions); } $this->userOptions = $userOptions; } return $this->userOptions; } //Adds a paragraph to the beginning of the text //Takes in the text, a comment ID, and a post ID function addEditParagraph($text, $id, $postId) { if (!$this->canEditPostsPage($postId)) { //todo - Add an option so admin can disable this $text = "

" . $text; return $text; } return $text; } //Adds a div to the comment text with a class name so that the AJAX can change the text to a textbox function addCommentDiv($text) { global $comment; if (empty($comment)) { return $text; } if (!$this->canEdit($comment->comment_ID, $comment->comment_post_ID) || !$this->canEditComment()) { return $text; } //Skip this if admin $text = $this->addEditParagraph($text, $comment->comment_ID, $comment->comment_post_ID); if ($this->skipDiv) { return $text; } //Regular expression to check if there is a div already added $pattern = '/div class=\"' . $this->commentClassName . '\"/i'; //If there is not a div already, add it in if (!preg_match($pattern, $text)) { $text = '
' . $text . '
'; } return $text; } //End function addCommentDiv() function addAuthorSpan($text) { global $comment; if (!$this->canEdit($comment->comment_ID, $comment->comment_post_ID) || !$this->canEditAuthor()) { return $text; } //Regular expression to check if there is a div already added $pattern = '/span class=\"' . $this->commentAuthorName . '\"/i'; //If there is not a div already, add it in if (!preg_match($pattern, $text)) { $text = '' . $text . ''; } return $text; } //End function addAuthorDiv() //Prints out the admin page function printAdminPage() { $WPAjaxEditComments = $this->getAdminOptions(); if (!empty($savedOptions)) { $WPAjaxEditComments = $savedOptions; } if (isset($_POST['update_wp_ajaxEditCommentSettings'])) { $error = false; $updated = false; //Validate the comment time entered if (isset($_POST['wpAJAXCommentTime'])) { $commentTimeErrorMessage = ''; $commentClass = 'error'; if (!preg_match('/^\d+$/i', $_POST['wpAJAXCommentTime'])) { $commentTimeErrorMessage = "Comment time must be a numerical value"; $error = true; } elseif($_POST['wpAJAXCommentTime'] < 1) { $commentTimeErrorMessage = "Comment time must be greater than one minute."; $error = true; } else { $WPAjaxEditComments['minutes'] = $_POST['wpAJAXCommentTime']; $updated = true; } if (!empty($commentTimeErrorMessage)) { ?>
">

optionsName, $WPAjaxEditComments); $this->adminOptions = $WPAjaxEditComments; ?>

Settings successfully updated.

">

WP AJAX Edit Comment


" id="edit_text"/>

Allow Anyone to Edit Their Own Comments?

Selecting "No" will turn off comment editing for everyone except admin types who have post and page editing permissions.

    

getUserOptions(); //Save the updated options to the database if (isset($_POST['wpAJAXAuthor']) && isset($_POST['wpAJAXComment']) && isset($_POST['wpAJAXAdminEdits'])) { if (isset($user_email)) { $author_options[$user_email]['author_editing'] = $_POST['wpAJAXAuthor']; $author_options[$user_email]['comment_editing'] = $_POST['wpAJAXComment']; $author_options[$user_email]['admin_editing'] = $_POST['wpAJAXAdminEdits']; ?>

Settings successfully updated.

userOptionsName, $author_options); $this->userOptions = $author_options; } } //Get the author options if (!empty($author_options[$user_email])) { $author = $author_options[$user_email]['author_editing']; $comment = $author_options[$user_email]['comment_editing']; $adminEdits = $author_options[$user_email]['admin_editing']; } ?>
">

WP AJAX Edit Comment - Individual User Options

Turn On Name Editing?

Selecting "Yes" will enable your ability to edit the author details.

    

Turn On Comment Editing?

Selecting "Yes" will enable your ability to edit a user's comment.

    

Turn Off Comment Editing in Admin Panel?

Selecting "Yes" will disable comment editing in the Admin Comments Panel.

    

JS(); } }//End function addHeaderJS function addAdminHeaderJS() { global $user_email; if (empty($user_email)) { get_currentuserinfo(); } if (empty($user_email)) { return; } $author_options = $this->getUserOptions(); //Get the author options if (!empty($author_options[$user_email])) { if ($author_options[$user_email]['admin_editing'] == "true") { return; } } $this->JS(); } function JS() { echo "\n"; } //Returns a comment for editing in a textbox //Takes in a comment id function getComment($id) { global $wpdb; if (!$this->canEdit($id, $post->ID)) { return 0; } //mysql_query("SET NAMES 'utf8'", $conn); $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = ".$id); if (!$comment) { return 0; } //Get the comment ready for the textbox $content = apply_filters('comment_edit_save', $comment->comment_content); return $content; }//End function getComment //Strips the ID to just numbers function getCommentID($id) { preg_match('/([0-9]+)$/i', $id, $matches); if (is_numeric($matches[1])) { return $matches[1]; } else { return 0; } } //End function getCommentID //Returns the text such as "You may click on author/comment to edit" function getEditText() { $options = $this->getAdminOptions(); return apply_filters('the_title',$options['edit_text']); } //Returns how much time is left to edit on a comment in a comma deliminated variable //Returns $minutes,$seconds //Takes in a comment ID function getTimeLeft($id) { global $wpdb; if (empty($id)) { return "0,0"; } $adminEdit = $this->getAdminOptions(); $adminMinutes = $adminEdit['minutes']; $query = "SELECT UNIX_TIMESTAMP(comment_date) time FROM $wpdb->comments where comment_ID = $id"; //Get the IP, Date, and Timestamp $comment = $wpdb->get_row($query, ARRAY_A); $timestamp = $comment['time']; //Check to see if there's a valid cookie //Get the time elapsed since making the comment $time = time()-$timestamp; $timeLeft = ($adminMinutes * 60) - $time; //seconds $minutesPassed = floor($timeLeft/60); $seconds = $timeLeft - ($minutesPassed*60); return "$minutesPassed,$seconds"; if (!$minutesPassed) { $minutesPassed = 0; } $minutesPassed = $adminMinutes - $minutesPassed; if (!$seconds) { $seconds = 0; } return "$minutesPassed,$seconds"; }//end function getTimeLeft //Saves the author to the database /*id = The comment id url = The author's url name = The author's name*/ function saveAuthor($id, $url, $name) { global $wpdb; if (!$this->canEdit($id, $post->ID)) { return 0; } if (!isset($name)) { return 0; } if (trim($name) == '') { return 0; } $url = urldecode($url); $name = urldecode($name); $url = trim(apply_filters('comment_url', $url)); $saveUrl = apply_filters('pre_comment_author_url', $url); $name = apply_filters('comment_author', $name); $saveName = apply_filters('pre_commment_author_name', $name); if(!$wpdb->query("UPDATE $wpdb->comments SET comment_author = '{$saveName}', comment_author_url = '{$saveUrl}' WHERE comment_ID = $id")) { return 0; } $url = stripslashes($url); $name = stripslashes($name); $returnText = ''; if (!empty($url)) { $returnText = '' . $name . ''; } else { $returnText = $name; } //For WP Cache if (function_exists("wp_cache_get_postid_from_comment")) { wp_cache_get_postid_from_comment($id); } return $returnText; } //End function saveAuthor //Saves the edited comment to the database function saveComment($id, $content) { global $wpdb, $post; if (trim($content) == '') { return 0; } if (!$this->canEdit($id, $post->ID)) { return 0; } $content = urldecode($content); $content = apply_filters('comment_save_pre', $content); $saveContent = apply_filters('pre_comment_content', $content); if(!$wpdb->query("UPDATE $wpdb->comments SET comment_content = '{$saveContent}' WHERE comment_ID = $id")) { return 0; } $this->skipDiv = true; $content = apply_filters('comment_text', $content); $content = $this->addEditParagraph($content, $id, $post->ID); $this->skipDiv = false; //For WP Cache if (function_exists("wp_cache_get_postid_from_comment")) { wp_cache_get_postid_from_comment($id); } return stripslashes($content); } //end function saveComment //Determines if a comment can be edited or not based on the ID and time elapsed //$id = The comment id //$postId = The post id for the comment //Returns true if the comment can be edited, false if not function canEdit($id, $postId) { global $wpdb; if (empty($id)) { return false; } //Return true if the user can edit the comment if ($this->canEditPostsPage($postId)) { return true; } //Checks to see if the admin has allowed comment editing $adminEdit = $this->getAdminOptions(); $adminEdit = $adminEdit['allow_editing']; if (empty($adminEdit)) { $adminEdit = $this->admin; } if ($adminEdit != 'true') { return false; } $query = "SELECT UNIX_TIMESTAMP(comment_date) time, comment_author_IP, comment_date_gmt FROM $wpdb->comments where comment_ID = $id"; //Get the IP, Date, and Timestamp $comment = $wpdb->get_row($query, ARRAY_A); $hash = md5($comment['comment_author_IP'] . $comment['comment_date_gmt']); $timestamp = $comment['time']; //Check to see if there's a valid cookie if (isset($_COOKIE[$this->cookieName . $id . $hash])) { //Get the time elapsed since making the comment $time = time()-$timestamp; $minutesPassed = round(((($time%604800)%86400)%3600)/60); //Get the time the admin has set for minutes $minutes = $this->getAdminOptions(); $minutes = $minutes['minutes']; if (!is_numeric($minutes)) { $minutes = $this->minutes; } if ($minutes < 1) { $minutes = $this->minutes; } //Compare the minutes passed to the admin minutes if ($minutesPassed) { if ($minutesPassed > $minutes) { return false; } } return true; } return false; }//end function canEdit //Returns true if a person can edit a post/page //Returns false otherwise //Called by canEdit() and setCommentCookie function canEditPostsPage($postId) { //Stolen, err, borrowed from edit_comment_link() if (!current_user_can('edit_page', $postId)) {return false; } if (!current_user_can('edit_post', $postId)) {return false; } return true; }//end function canEditPostsPage //Returns true unless the user has disabled author editing function canEditAuthor() { global $user_email; if (empty($user_email)) { get_currentuserinfo(); } if (empty($user_email)) { return true; } $author_options = $this->getUserOptions(); //Get the author options if (!empty($author_options[$user_email])) { if ($author_options[$user_email]['author_editing'] == "false") { return false; } } return true; } //end function canEditAuthor //Returns true unless the user has disabled comment editing function canEditComment() { global $user_email; if (empty($user_email)) { get_currentuserinfo(); } if (empty($user_email)) { return true; } $author_options = $this->getUserOptions(); //Get the author options if (!empty($author_options[$user_email])) { if ($author_options[$user_email]['comment_editing'] == "false") { return false; } } return true; } //Sets a comment cookie for the commentator (treat as a private function) function setCommentCookie($commentId) { global $comment, $wpdb; //Return if setting the cookie is unnecessary if ($this->canEditPostsPage($post->ID)) { return $commentId; } //Get the IP, Date, and Timestamp if (empty($comment)) { $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments where comment_ID = $commentId", ARRAY_A); } $hash = md5($comment['comment_author_IP'] . $comment['comment_date_gmt']); //Get the time the admin has set for minutes $minutes = $this->getAdminOptions(); $minutes = $minutes['minutes']; if (!is_numeric($minutes)) { $minutes = $this->minutes; } if ($minutes < 1) { $minutes = $this->minutes; } //Set the cookie $cookieName = $this->cookieName . $commentId . $hash; $value = $cookieName; $expire = time()+60*$minutes; if (!isset($_COOKIE[$cookieName])) { setcookie($cookieName, $value, $expire, COOKIEPATH, COOKIE_DOMAIN); } return $commentId; } //end function setCommentCookie }//End Class WPrapAjaxEditComments if (class_exists("WPrapAjaxEditComments")) { $rap_ajaxComment = new WPrapAjaxEditComments(); } //Initialize the admin panel function WPrapAjaxEditComments_ap() { global $rap_ajaxComment; if (!isset($rap_ajaxComment)) { return; } if (function_exists('add_options_page')) { add_options_page('AJAX Edit Comments', 'AJAX Edit Comments', 9, basename(__FILE__), array(&$rap_ajaxComment, 'printAdminPage')); } if (function_exists('add_submenu_page')) { add_submenu_page('profile.php', "AJAX Edit Comments Options","AJAX Edit Comments", 9, basename(__FILE__), array(&$rap_ajaxComment, 'printAuthorPage')); } } //Template tag WPrapAjaxEditComments_CanEdit //Returns true if a user can edit - False if they can't - Must be run within the loop //Also returns false if people are admins function WPrapAjaxEditComments_CanEdit() { global $comment, $rap_ajaxComment; //If we're not in the loop, return false if (!isset($comment) || !isset($rap_ajaxComment)) { return false; } //If admin, return false if ($rap_ajaxComment->canEditPostsPage($comment->comment_post_ID)) { return false; } //Find out if the user can edit if ($rap_ajaxComment->canEdit($comment->comment_ID, $comment->comment_post_ID)) { return true; } return false; } //Yay, actions. if (isset($rap_ajaxComment)) { add_action('admin_menu', 'WPrapAjaxEditComments_ap'); add_action('admin_head', array(&$rap_ajaxComment, 'addAdminHeaderJS')); add_action('wp_head', array(&$rap_ajaxComment, 'addHeaderJS')); add_action('comment_post', array(&$rap_ajaxComment, 'setCommentCookie')); add_action('activate_wp-ajax-edit-comments/wp-ajax-edit-comments.php', array(&$rap_ajaxComment, 'init')); //Yay, filters. add_filter('comment_text', array(&$rap_ajaxComment, 'addCommentDiv'), '1000'); //Low priority so other HTML can be added first add_filter('get_comment_author_link', array(&$rap_ajaxComment, 'addAuthorSpan'), '1000'); //Low priority so other HTML can be added first } ?>