'', 1 => _x('Approve', 'Review left by Reviewer', 'anno'), 2 => _x('Revisions', 'Review left by Reviewer', 'anno'), 3 => _x('Reject', 'Review left by Reviewer', 'anno'), ); /** * Register meta boxes */ function anno_internal_comments_add_meta_boxes() { if (anno_user_can('view_general_comments')) { add_meta_box('general-comment', _x('Internal Comments', 'Meta box title', 'anno'), 'anno_internal_comments_general_comments', 'article', 'advanced'); } if (anno_user_can('view_review_comments')) { add_meta_box('reviewer-comment', _x('Reviews', 'Meta box title', 'anno'), 'anno_internal_comments_reviewer_comments', 'article', 'advanced'); } } // We don't want to add them for new-posts add_action('admin_head-post.php', 'anno_internal_comments_add_meta_boxes'); /** * Get a list of comments for a given type * * @param string $type Type of comments to fetch * @return array Array of comment objects */ function anno_internal_comments_get_comments($type, $post_id) { remove_filter('comments_clauses', 'anno_internal_comments_clauses'); $comments = get_comments( array( 'type' => $type, 'post_id' => $post_id, )); add_filter('comments_clauses', 'anno_internal_comments_clauses'); return $comments; } /** * Display the content for internal comment meta boxes * @param $type The comment type base * @return void */ function anno_internal_comments_display($type) { global $post; $comments = anno_internal_comments_get_comments('article_'.$type, $post->ID); ?> ID, $comment->comment_ID)) { anno_internal_comment_table_row($comment); } } } if (anno_user_can('add_'.$type.'_comment')) { anno_internal_comments_form($type); } ?>
comment_author_url; if ( 'http://' == $author_url ) { $author_url = ''; } $author_url_display = preg_replace( '|http://(www\.)?|i', '', $author_url ); if ( strlen( $author_url_display ) > 50 ) { $author_url_display = substr( $author_url_display, 0, 49 ) . '...'; } echo ''.get_avatar($comment->comment_author_email, '32').$comment->comment_author.'
'; if ( !empty( $author_url ) ) { echo "$author_url_display
"; } if ( !empty( $comment->comment_author_email ) ) { echo ''.esc_html($comment->comment_author_email).''; echo '
'; } echo ''.esc_html($comment->comment_author_IP).''; ?> '; printf( _x('Submitted on %2$s at %3$s', 'Internal comment date', 'anno'), esc_url(get_comment_link($comment)), get_comment_date(_x( 'Y/m/d', 'Date format for internal comments', 'anno')), get_comment_date(get_option('time_format'))); if ( $comment->comment_parent ) { $parent = get_comment($comment->comment_parent); $parent_link = esc_url(get_comment_link($comment->comment_parent)); $name = get_comment_author( $parent->comment_ID ); printf( ' | '._x( 'In reply to %2$s.', 'Internal Comment reply text' , 'anno'), $parent_link, $name ); } echo '

'. $comment->comment_content .'

'; $actions = array(); if (anno_user_can('add_'.str_replace('article_', '', $comment->comment_type).'_comment')) { $actions['reply'] = ''._x('Reply', 'Internal comment action link text', 'anno').''; } if (anno_user_can('edit_comment', null, null, $comment->comment_ID )) { $actions['edit'] = ''._x('Edit', 'Internal comment action link text', 'anno').''; $actions['delete'] = ''._x('Trash', 'Internal comment action link text', 'anno').''; } echo '
'; $i = 1; foreach ($actions as $action) { if ($i == count($actions)) { $sep = ''; } else { $sep = ' | '; } echo $action.$sep; $i++; } echo '
'; ?> ID, $current_user->ID); $reviewers = anno_get_reviewers($post->ID); if (anno_user_can('leave_review', $current_user->ID, $post->ID)) { ?>

comment_type, array('article_review', 'article_general'))) { $link = get_edit_post_link($comment->comment_post_ID).'#comment-'.$comment->comment_ID; } return $link; } add_filter('get_comment_link', 'anno_internal_comments_get_comment_link', 10, 2); /** * Filter to prevent front end display of our comments */ function anno_internal_comments_clauses($clauses) { $clauses['where'] .= " AND comment_type NOT IN ('article_general', 'article_review')"; return $clauses; } // Never display internal comments on the front-end if (!is_admin()) { add_filter('comments_clauses', 'anno_internal_comments_clauses'); } /** * Don't allow non editor/admin to see internal comments on comment listing page. */ function anno_filter_edit_comments_page() { global $pagenow; if ($pagenow == 'edit-comments.php' && !(current_user_can('editor') || current_user_can('administrator'))) { add_filter('comments_clauses', 'anno_internal_comments_clauses'); } } add_action('admin_init', 'anno_filter_edit_comments_page'); /** * Modify the comment count stored in the wp_post comment_count column, so internal comments don't show up there. * Based on code in the WP Core function wp_update_comment_count */ function anno_internal_comments_update_comment_count($post_id) { global $wpdb; $post_id = (int) $post_id; if ( !$post_id ) return false; if ( !$post = get_post($post_id) ) return false; $old = (int) $post->comment_count; $internal_count = (int) $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_type IN ('article_general', 'article_review')", $post_id) ); $wpdb->update( $wpdb->posts, array('comment_count' => max($old - $internal_count, 0)), array('ID' => $post_id) ); } add_action('wp_update_comment_count', 'anno_internal_comments_update_comment_count'); /** * Processes an AJAX request when submitting an internal comment * Based on code in the WP Core * * @todo handle comment errors instead of just dying. */ function anno_internal_comments_ajax() { check_ajax_referer('anno_comment', '_ajax_nonce-anno-comment-'.$_POST['type']); //Check to make sure user can post comments on this post global $wpdb; $user = wp_get_current_user(); if ($user->ID) { $comment_base_type = $wpdb->escape(trim($_POST['type'])); $comment_author = $wpdb->escape($user->display_name); $comment_author_email = $wpdb->escape($user->user_email); $comment_author_url = $wpdb->escape($user->user_url); $comment_content = trim($_POST['content']); $comment_type = 'article_'.$comment_base_type; $comment_post_ID = $wpdb->escape(intval($_POST['post_id'])); $user_ID = $user->ID; } else { die(); } if ( '' == $comment_content ) { die(); } $comment_parent = absint($_POST['parent_id']); $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID'); // Create the comment and automatically approve it add_filter('pre_comment_approved', 'anno_internal_comments_pre_comment_approved'); add_filter('pre_option_comments_notify', 'anno_internal_comments_surpress_notification'); $comment_id = wp_new_comment($commentdata); remove_filter('pre_option_comments_notify', 'anno_internal_comments_surpress_notification'); remove_filter('pre_comment_approved', 'anno_internal_comments_pre_comment_approved'); $comment = get_comment($comment_id); if (!$comment) { die(); } // Save in the audit log if ($comment->comment_type == 'article_general') { annowf_save_audit_item($comment->comment_post_ID, $user->ID, 5, array($comment->comment_ID)); } else if ($comment->comment_type = 'article_review') { annowf_save_audit_item($comment->comment_post_ID, $user->ID, 3, array($comment->comment_ID)); } // Send email notifications of new commment if (anno_workflow_enabled('notifications')) { $post = get_post($comment_post_ID); $recipients = array(); if ($comment_base_type == 'review') { $recipients[] = $user->user_email; } annowf_send_notification($comment_base_type.'_comment', $post, $comment, $recipients); } // Attach a 'round' to a comment, marking which revision number this is $round = annowf_get_round($comment_post_ID); update_comment_meta($comment->comment_ID, '_round', $round); //Display markup for AJAX anno_internal_comment_table_row($comment); } add_action('wp_ajax_anno-internal-comment', 'anno_internal_comments_ajax'); /** * Processes an AJAX request when submitting a review from the dropdown. */ function anno_internal_comments_review_ajax() { check_ajax_referer('anno_review', '_ajax_nonce-review'); if (isset($_POST['post_id']) && isset($_POST['review'])) { global $current_user; $post_id = absint($_POST['post_id']); $review = $_POST['review']; $post_round = annowf_get_round($post_id); update_user_attribute($current_user->ID, '_'.$post_id.'_review_'.$post_round, $review); $reviewed = get_post_meta($post_id, '_round_'.$post_round.'_reviewed', true); if (!is_array($reviewed)) { $reviewed = array(); } // If review is set to none, remove the user from reviewed, otherwise update it with the current user. if ($review != 0) { // Keep track that this user has left a review on the post if (!in_array($current_user->ID, $reviewed)) { $reviewed[] = $current_user->ID; update_post_meta($post_id, '_round_'.$post_round.'_reviewed', array_unique($reviewed)); } // Send notification $post = get_post(intval($post_id)); annowf_send_notification('review_recommendation', $post, null, null, $current_user->ID); annowf_save_audit_item($post_id, $current_user->ID, 4, array($review)); } else { $key = array_search($current_user->ID, $reviewed); if ($key !== false) { unset($reviewed[$key]); update_post_meta($post_id, '_round_'.$post_round.'_reviewed', array_unique($reviewed)); } } echo $review; } die(); } add_action('wp_ajax_anno-review', 'anno_internal_comments_review_ajax'); /** * Filter to automatically approve internal comments */ function anno_internal_comments_pre_comment_approved($approved) { return 1; } /** * Dropdown filter to display only our internal comment types in the admin screen */ function anno_internal_comment_types_dropdown($comment_types) { if (current_user_can('editor') || current_user_can('administrator')) { $comment_types['article_general'] = _x('Article General', 'Dropdown comment type selector', 'anno'); $comment_types['article_review'] = _x('Article Review', 'Dropdown comment type selector', 'anno'); } return $comment_types; } add_filter('admin_comment_types_dropdown', 'anno_internal_comment_types_dropdown'); /** * Get the top level comment of a series of comment replies. * * @param int|object ID of the comment or the comment object itself * @return bool|obj Comment object, or false if the comment could not be found. */ function anno_internal_comments_get_comment_root($comment) { $comment = null; if (is_numeric($comment)) { $comment = get_comment($comment); } if ($commment !== false) { while($comment->comment_parent != 0) { $comment = get_comment($comment->comment_parent); } } return $comment; } /** * Filter for removing WP action that sends emails when comments are created. Added to internal comments. */ function anno_internal_comments_surpress_notification() { return 0; } /** * Enforce general comment capabilities */ function anno_internal_comments_capabilities($allcaps, $caps, $args) { // $args are an array => 'capability_name' , 'user_id', 'additional args (obj id)' if ($args[0] == 'edit_comment') { $comment = get_comment($args[2]); if (!empty($comment) && ($comment->comment_type == 'article_general' || $comment->comment_type == 'article_review')) { if (anno_workflow_enabled()) { if (!anno_user_can('edit_comment', $args[1], '', $args[2])) { $allcaps = array(); } } //No internal comments should be editable if the workflow is disabled else { $allcaps = array(); } } } return $allcaps; } add_action('user_has_cap', 'anno_internal_comments_capabilities', 1, 3); ?>