array( 'comments_statuses' => array('approve'), 'css_style' => 'wp-default', 'edit_comm_effect' => 'fade', 'delete_button' => 'no', 'delete_group' => 'admins', 'show_actions_on_hover' => 'no', 'timer' => 'yes', 'time_to_edit' => 5, 'highlight_comments' => 'yes', 'highlight_colors' => array( 'spam' => '#fff1cc', 'trash' => '#ffaaaa', 'unapproved' => '#ffffe0' ) ), 'messages' => array( 'pos_not_logged' => 'comment_form_before_fields', 'pos_logged' => 'comment_form_logged_in_after', 'remove_message' => 3, 'show_effect' => 'fade', 'hide_effect' => 'fade', 'css_style' => 'wp-default' ) ); private $styles = array(); private $rem_msgs = array(); private $positions = array(); private $comments_statuses = array(); private $comments = array(); private $tabs = array(); private $statuses = array(); private $choice = array(); private $amount_of_comments = ''; private $timer = FALSE; private $time_left = 0; public function __construct() { register_activation_hook(__FILE__, array(&$this, 'activation')); register_deactivation_hook(__FILE__, array(&$this, 'deactivation')); //actions add_action('plugins_loaded', array(&$this, 'load_textdomain')); add_action('plugins_loaded', array(&$this, 'load_defaults')); add_action('admin_init', array(&$this, 'register_settings')); add_action('admin_menu', array(&$this, 'admin_menu_options')); add_action('wp_ajax_ac-add-new-comment', array(&$this, 'ajax_add_new_comment'), 1000); add_action('wp_ajax_nopriv_ac-add-new-comment', array(&$this, 'ajax_add_new_comment'), 1000); add_action('wp_ajax_ac-save-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_nopriv_ac-save-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_ac-trash-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_ac-untrash-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_ac-spam-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_ac-unspam-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_ac-approve-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_ac-unapprove-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_ac-delete-comment', array(&$this, 'ajax_comments')); add_action('wp_ajax_nopriv_ac-delete-comment', array(&$this, 'ajax_comments')); add_action('wp_enqueue_scripts', array(&$this, 'front_comments_scripts_styles')); add_action('admin_enqueue_scripts', array(&$this, 'admin_comments_scripts_styles')); add_action('comments_array', array(&$this, 'get_specified_comments'), 10, 2); //filters add_filter('comment_id_fields', array(&$this, 'comment_form_spinner')); add_filter('comment_text', array(&$this, 'get_comment_text'), 1); add_filter('comment_text', array(&$this, 'add_section_to_comment'), 1000); add_filter('comment_class', array(&$this, 'add_comment_class')); add_filter('get_comments_number', array(&$this, 'get_comments_amount'), 10, 2); add_filter('plugin_action_links', array(&$this, 'plugin_settings_link'), 10, 2); add_filter('plugin_row_meta', array(&$this, 'plugin_extend_links'), 10, 2); add_filter('edit_comment_link', array(&$this, 'add_inline_actions'), 10, 2); add_filter('user_has_cap', array(&$this, 'force_edit_comments'), 10, 3); } public function add_comment_class($classes) { global $comment; $classes[] = 'ac-top-comment'; $classes[] = 'ac-full-'.$this->statuses[$comment->comment_approved]; return $classes; } private function sort_comments_desc($element_a, $element_b) { return strnatcasecmp($element_b->comment_date, $element_a->comment_date); } private function sort_comments_asc($element_a, $element_b) { return strnatcasecmp($element_a->comment_date, $element_b->comment_date); } public function get_specified_comments($comments, $post_id) { if(!current_user_can('moderate_comments')) { return $comments; } else { $option = get_option('ac_inline_edit'); $array = array_merge( (in_array('approve', $option['comments_statuses']) ? (array)get_comments(array('post_id' => $post_id, 'status' => 'approve')) : array()), (in_array('hold', $option['comments_statuses']) ? (array)get_comments(array('post_id' => $post_id, 'status' => 'hold')) : array()), (in_array('trash', $option['comments_statuses']) ? (array)get_comments(array('post_id' => $post_id, 'status' => 'trash')) : array()), (in_array('spam', $option['comments_statuses']) ? (array)get_comments(array('post_id' => $post_id, 'status' => 'spam')) : array()) ); usort($array, array(&$this, 'sort_comments_'.get_option('comment_order'))); return $array; } } /** * Gets proper number of visible comments */ public function get_comments_amount($amount, $post_id) { if(!current_user_can('moderate_comments')) { return $amount; } else { if(isset($this->amount_of_comments[$post_id])) { return $this->amount_of_comments[$post_id]; } else { global $wp_query; $option = get_option('ac_inline_edit'); if(isset($wp_query->comments) && !empty($wp_query->comments)) { $amount = 0; foreach($wp_query->comments as $comment) { $amount += in_array($this->statuses[$comment->comment_approved], $option['comments_statuses']) ? 1 : 0; } return ($this->amount_of_comments[$post_id] = $amount); } else { global $wpdb; $statuses = array(); foreach($option['comments_statuses'] as $status) { if($status === 'hold') { $statuses[] = '\'0\''; } else { $statuses[] = '\''.$status.'\''; } } $statuses[] = '\'1\''; $comments = (array)$wpdb->get_results('SELECT COUNT(comment_ID) as amount FROM '.$wpdb->comments.' WHERE comment_post_ID = '.$post_id.' AND comment_approved IN ('.implode(',', $statuses).')'); return ($this->amount_of_comments[$post_id] = $comments[0]->amount); } } } } /** * Loads defaults */ public function load_defaults() { $this->statuses = array( '0' => 'hold', '1' => 'approve', 'spam' => 'spam', 'trash' => 'trash' ); $this->positions = array( 'pos_not_logged' => array( 'comment_form_before' => __('before form', 'ajaxed-comments'), 'comment_form_top' => __('form top', 'ajaxed-comments'), 'comment_form_before_fields' => __('before form fields', 'ajaxed-comments'), 'comment_form' => __('form bottom', 'ajaxed-comments'), 'comment_form_after' => __('after form', 'ajaxed-comments') ), 'pos_logged' => array( 'comment_form_before' => __('before form', 'ajaxed-comments'), 'comment_form_top' => __('form top', 'ajaxed-comments'), 'comment_form_logged_in_after' => __('before form fields', 'ajaxed-comments'), 'comment_form' => __('inside form', 'ajaxed-comments'), 'comment_form_after' => __('after form', 'ajaxed-comments') ) ); $this->styles = array( 'none' => __('none', 'ajaxed-comments'), 'wp-default' => __('WordPress default', 'ajaxed-comments'), 'bootstrap' => __('Bootstrap', 'ajaxed-comments') ); $this->rem_msgs = array( 0 => __('do not hide', 'ajaxed-comments'), 1 => __('1 second', 'ajaxed-comments'), 2 => __('2 seconds', 'ajaxed-comments'), 3 => __('3 seconds', 'ajaxed-comments'), 5 => __('5 seconds', 'ajaxed-comments'), 10 => __('10 seconds', 'ajaxed-comments') ); $this->effects = array( 'fade' => __('fade', 'ajaxed-comments'), 'slide' => __('slide', 'ajaxed-comments'), ); $this->comments_statuses = array( 'approve' => __('approved', 'ajaxed-comments'), 'hold' => __('unapproved', 'ajaxed-comments'), 'trash' => __('trash', 'ajaxed-comments'), 'spam' => __('spam', 'ajaxed-comments') ); $this->tabs = array( 'inline-edit' => array( 'name' => __('Editing', 'ajaxed-comments'), 'metakey' => 'ac_inline_edit', 'submit' => 'save_inline_edit' ), 'messages' => array( 'name' => __('Messages', 'ajaxed-comments'), 'metakey' => 'ac_messages', 'submit' => 'save_messages' ) ); $this->choice = array( 'yes' => __('yes', 'ajaxed-comments'), 'no' => __('no', 'ajaxed-comments'), ); $this->delete_groups = array( 'admins' => __('admins only', 'ajaxed-comments'), 'users' => __('logged in users', 'ajaxed-comments'), 'everyone' => __('all commenters', 'ajaxed-comments') ); } /** * Activation */ public function activation() { add_option('ac_inline_edit', $this->options['inline-edit'], '', 'no'); add_option('ac_messages', $this->options['messages'], '', 'no'); } /** * Deactivation */ public function deactivation() { delete_option('ac_inline_edit'); delete_option('ac_messages'); } /** * Turns off add-comment redirect */ function comment_redirect($location) { echo json_encode(array('loc' => $location, 'info' => 'AC_COMMENT_ADDED')); exit; } /** * Adds comment using AJAX */ public function ajax_add_new_comment() { if(isset($_POST['form'], $_POST['action'], $_POST['nonce']) && $_POST['action'] === 'ac-add-new-comment' && check_ajax_referer('new-comm-ajax-sec-check', 'nonce', FALSE)) { global $wpdb; //parses serialized form-string parse_str($_POST['form'], $post_form); $_POST = array_merge($_POST, $post_form); //antispam bee plugin fix if(is_plugin_active('antispam-bee/antispam_bee.php')) $_POST['comment'] = $post_form[substr(md5(get_bloginfo('url')), 0, 5).'-comment']; //bws captcha fix if(is_plugin_active('captcha/captcha.php')) $_REQUEST = array_merge($_REQUEST, $_POST); //we have to add user id manually $user_ID = get_current_user_id(); //turns off errors due to wp-load.php notice error_reporting(0); //turns off redirect add_filter('comment_post_redirect', array(&$this, 'comment_redirect')); //adds comment require_once(dirname(__FILE__).'/../../../wp-comments-post.php'); } exit; } /** * Manages comment actions with AJAX */ public function ajax_comments() { if(isset($_POST['comm_id'], $_POST['action'], $_POST['nonce'])) { $comm_id = (int)$_POST['comm_id']; $opt = get_option('ac_inline_edit'); $err_lvl = error_reporting(); $approve_delete = FALSE; //is delete button active? if($opt['delete_button'] === 'yes') { $delete_group = (isset($opt['delete_group']) ? $opt['delete_group'] : $this->options['inline-edit']['delete_group']); if($delete_group === 'admins' && current_user_can('manage_options')) $approve_delete = TRUE; elseif($delete_group === 'users' && is_user_logged_in()) $approve_delete = TRUE; elseif($delete_group === 'everyone') $approve_delete = TRUE; } //disables errors due to current_user_can() notices error_reporting(0); if(current_user_can('edit_comment', $comm_id) && $_POST['action'] === 'ac-save-comment' && check_ajax_referer('save-comm-ajax-sec-check', 'nonce', FALSE) && isset($_POST['form'])) { error_reporting($err_lvl); if(wp_update_comment(array('comment_ID' => $comm_id, 'comment_content' => $_POST['form']))) { remove_filter('comment_text', array(&$this, 'get_comment_text'), 1); remove_filter('comment_text', array(&$this, 'add_section_to_comment'), 1000); comment_text($comm_id); add_filter('comment_text', array(&$this, 'add_section_to_comment'), 1000); add_filter('comment_text', array(&$this, 'get_comment_text'), 1); } else echo ''; } elseif(current_user_can('moderate_comments')) { error_reporting($err_lvl); if($_POST['action'] === 'ac-approve-comment' && check_ajax_referer('approve-comm-ajax-sec-check', 'nonce', FALSE)) echo (wp_set_comment_status($comm_id, 'approve') ? 'AC_OK' : ''); elseif($_POST['action'] === 'ac-unapprove-comment' && check_ajax_referer('approve-comm-ajax-sec-check', 'nonce', FALSE)) echo (wp_set_comment_status($comm_id, 'hold') ? 'AC_OK' : ''); elseif($_POST['action'] === 'ac-spam-comment' && check_ajax_referer('spam-comm-ajax-sec-check', 'nonce', FALSE)) echo (wp_spam_comment($comm_id) ? 'AC_OK' : ''); elseif($_POST['action'] === 'ac-unspam-comment' && check_ajax_referer('spam-comm-ajax-sec-check', 'nonce', FALSE)) echo (wp_unspam_comment($comm_id) ? 'AC_OK' : ''); elseif($_POST['action'] === 'ac-trash-comment' && check_ajax_referer('trash-comm-ajax-sec-check', 'nonce', FALSE)) echo (wp_trash_comment($comm_id) ? 'AC_OK' : ''); elseif($_POST['action'] === 'ac-untrash-comment' && check_ajax_referer('trash-comm-ajax-sec-check', 'nonce', FALSE)) echo (wp_untrash_comment($comm_id) ? 'AC_OK' : ''); elseif($_POST['action'] === 'ac-delete-comment' && check_ajax_referer('delete-comm-ajax-sec-check', 'nonce', FALSE) && $approve_delete === TRUE) echo (wp_delete_comment($comm_id, TRUE) ? 'AC_OK' : ''); } elseif($_POST['action'] === 'ac-delete-comment' && check_ajax_referer('delete-comm-ajax-sec-check', 'nonce', FALSE) && $approve_delete === TRUE) echo (wp_delete_comment($comm_id, TRUE) ? 'AC_OK' : ''); } exit; } /** * Adds little spinner next to comment submit button */ public function comment_form_spinner($result) { $result .= ''; return $result; } /** * Force editing comment for comment authors */ public function force_edit_comments($allcaps, $cap, $args) { $this->timer = FALSE; // Break if we're not asking to edit a comment if('edit_comment' != $args[0]) return $allcaps; // Brak if user already can moderate comments if(!empty($allcaps['moderate_comments'])) return $allcaps; $comment = get_comment($args[2]); // Break if the user is the post author (post authors can edit comments in their posts) if($args[1] == $comment->comment_author && is_user_logged_in()) // doesn't work for not logged in return $allcaps; $post_type = get_post_type($comment->comment_post_ID) == 'page' ? $post_type = 'page' : 'post'; // comment post post type // Frontend only if(!is_admin() || DOING_AJAX) { $opt = get_option('ac_inline_edit'); if($opt['timer'] === 'yes') { $time_left = strtotime($comment->comment_date) + $opt['time_to_edit'] * 60 - current_time('timestamp'); // Editing comments for logged in users if(is_user_logged_in()) { if($comment->user_id == get_current_user_id() && $time_left > 0) { $this->timer = TRUE; $this->time_left = $time_left; $allcaps['edit_others_'.$post_type.'s'] = TRUE; // enable edit comment $allcaps['edit_published_'.$post_type.'s'] = TRUE; // enable edit comment } } // Editing comments for anonymous commenters else { $current_commenter = wp_get_current_commenter(); if($comment->comment_author == $current_commenter['comment_author'] && $comment->comment_author_email == $current_commenter['comment_author_email'] && $time_left > 0 && $comment->comment_author_IP === preg_replace('/[^0-9a-fA-F:., ]/', '', $_SERVER['REMOTE_ADDR'])) { $this->timer = TRUE; $this->time_left = $time_left; $allcaps['edit_others_'.$post_type.'s'] = TRUE; // enable edit comment $allcaps['edit_published_'.$post_type.'s'] = TRUE; // enable edit comment } } } } return $allcaps; } /** * Adds new links after 'Edit' comment link */ public function add_inline_actions($link, $cid) { $options_m = get_option('ac_messages'); $options_ie = get_option('ac_inline_edit'); $del_nonce = wp_create_nonce('delete-comment_'.$cid); $app_nonce = wp_create_nonce('approve-comment_'.$cid); //need to make sure these values will not be changed after using current_user_can() function $timer = $this->timer; $time_left = $this->time_left; $show_delete = FALSE; //is delete button active? if($options_ie['delete_button'] === 'yes') { $delete_group = (isset($options_ie['delete_group']) ? $options_ie['delete_group'] : $this->options['inline-edit']['delete_group']); if($delete_group === 'admins' && current_user_can('manage_options')) $show_delete = TRUE; elseif($delete_group === 'users' && is_user_logged_in()) $show_delete = TRUE; elseif($delete_group === 'everyone') $show_delete = TRUE; } $permalink = 'href="'.get_permalink().'"'; $adminlink = 'href="'.esc_url(admin_url('comment.php?c='.$cid.'&action=%s&_wpnonce=%s')).'"'; $actionlink = '<%s class="comment-%s-link'.($options_ie['css_style'] !== 'none' ? ' '.$options_ie['css_style'] : '').' ac-button %s" %s rel="'.$cid.'|%s">%s%s>'; $returnlink = '
'; $deletelink = ($options_ie['delete_button'] === 'yes' && $show_delete === TRUE ? sprintf($actionlink, 'a', 'ac-delete', '', sprintf($adminlink, 'deletecomment', $del_nonce), wp_create_nonce('delete-comm-ajax-sec-check'), __('Delete', 'ajaxed-comments'), 'a') : ''); //gets old status of comment $old_status = get_comment_meta($cid, '_wp_trash_meta_status', TRUE); switch(wp_get_comment_status($cid)) { case 'approved': if($show_delete === TRUE && !current_user_can('manage_options')) return sprintf($returnlink, $deletelink); else return sprintf($returnlink, sprintf($actionlink, 'a', 'ac-unapprove', '', sprintf($adminlink, 'unapprovecomment', $app_nonce), wp_create_nonce('approve-comm-ajax-sec-check'), __('Unapprove', 'ajaxed-comments'), 'a'), sprintf($actionlink, 'a', 'ac-spam', '', sprintf($adminlink, 'spamcomment', $del_nonce), wp_create_nonce('spam-comm-ajax-sec-check'), __('Spam', 'ajaxed-comments'), 'a'), sprintf($actionlink, 'a', 'ac-trash', '', sprintf($adminlink, 'trashcomment', $del_nonce), wp_create_nonce('trash-comm-ajax-sec-check'), __('Trash', 'ajaxed-comments'), 'a'), $deletelink); case 'unapproved': if($show_delete === TRUE && !current_user_can('manage_options')) return sprintf($returnlink, $deletelink); else return sprintf($returnlink, sprintf($actionlink, 'a', 'ac-approve', '', sprintf($adminlink, 'approvecomment', $app_nonce), wp_create_nonce('approve-comm-ajax-sec-check'), __('Approve', 'ajaxed-comments'), 'a'), sprintf($actionlink, 'a', 'ac-spam', '', sprintf($adminlink, 'spamcomment', $del_nonce), wp_create_nonce('spam-comm-ajax-sec-check'), __('Spam', 'ajaxed-comments'), 'a'), sprintf($actionlink, 'a', 'ac-trash', '', sprintf($adminlink, 'trashcomment', $del_nonce), wp_create_nonce('trash-comm-ajax-sec-check'), __('Trash', 'ajaxed-comments'), 'a'), $deletelink); case 'trash': if($show_delete === TRUE && !current_user_can('manage_options')) return sprintf($returnlink, $deletelink); else return sprintf($returnlink, sprintf($actionlink, 'span', 'ac-'.($old_status === '1' ? 'unapprove' : 'approve'), 'disabled', sprintf($adminlink, 'unapprovecomment', $app_nonce), wp_create_nonce('approve-comm-ajax-sec-check'), __(($old_status === '1' ? 'Unapprove' : 'Approve'), 'ajaxed-comments'), 'span'), sprintf($actionlink, 'span', 'ac-spam', 'disabled', sprintf($adminlink, 'spamcomment', $del_nonce), wp_create_nonce('spam-comm-ajax-sec-check'), __('Spam', 'ajaxed-comments'), 'span'), sprintf($actionlink, 'a', 'ac-untrash', '', sprintf($adminlink, 'untrashcomment', $del_nonce), wp_create_nonce('trash-comm-ajax-sec-check'), __('Restore', 'ajaxed-comments'), 'a'), $deletelink); case 'spam': if($show_delete === TRUE && !current_user_can('manage_options')) return sprintf($returnlink, $deletelink); else return sprintf($returnlink, sprintf($actionlink, 'span', 'ac-'.($old_status === '1' ? 'unapprove' : 'approve'), 'disabled', sprintf($adminlink, 'unapprovecomment', $app_nonce), wp_create_nonce('approve-comm-ajax-sec-check'), __(($old_status === '1' ? 'Unapprove' : 'Approve'), 'ajaxed-comments'), 'span'), sprintf($actionlink, 'a', 'ac-unspam', '', sprintf($adminlink, 'unspamcomment', $del_nonce), wp_create_nonce('spam-comm-ajax-sec-check'), __('Unspam', 'ajaxed-comments'), 'a'), sprintf($actionlink, 'span', 'ac-trash', 'disabled', sprintf($adminlink, 'trashcomment', $del_nonce), wp_create_nonce('trash-comm-ajax-sec-check'), __('Trash', 'ajaxed-comments'), 'span'), $deletelink); default: return $link; } } /** * Gets comment's text */ public function get_comment_text($text) { global $comment; $this->comments[$comment->comment_ID] = $text; return $text; } /** * Adds section to comment's text */ public function add_section_to_comment($text) { global $comment; return ''.__('Comment timer allows users to edit their comments for specified time', 'ajaxed-comments').'
'.__('How much time (in minutes) a user has to edit a published comment', 'ajaxed-comments').'
'.__('Highlight comments with specific colors', 'ajaxed-comments').'
'.__('Show inline edit actions only on hovering over a comment', 'ajaxed-comments').'
'.__('Select comments of which statuses will be available for moderation on the front-end of your site', 'ajaxed-comments').'
'.__('This will add Delete to edit buttons that allows you to permanently delete comments', 'ajaxed-comments').'
'.__('Select animation for showing messages', 'ajaxed-comments').'
'.__('Select animation for hiding messages', 'ajaxed-comments').'
'.__('Select animation effect for edit comment', 'ajaxed-comments').'
'.__('Choose your message box style', 'ajaxed-comments').'
'.__('Select style for edit buttons', 'ajaxed-comments').'
'.__('Select for how long message box should be displayed', 'ajaxed-comments').'
'.__('Select message box position for logged in users', 'ajaxed-comments').'
'.__('Select message box position for logged out users', 'ajaxed-comments').'
'.__('If you are having problems with this plugin, please talk about them in the', 'ajaxed-comments').' '.__('Support forum', 'ajaxed-comments').'
'.__('Rate it 5', 'ajaxed-comments').' '.__('on WordPress.org', 'ajaxed-comments').'
'.
__('Blog about it & link to the', 'ajaxed-comments').' '.__('plugin page', 'ajaxed-comments').'
'.
__('Check out our other', 'ajaxed-comments').' '.__('WordPress plugins', 'ajaxed-comments').'