Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a custom post type with comments enabled. The comments metabox in the admin only appears when the post is published. I'm wanting to use the comments system as more of a discussion between certain authors (it will be hidden on the front end) so I would like the commenting system to be active when the posts are draft, pending or published. Is this possible?

I should note that I have tried the edit flow plugin which has the "editorial comments" feature, however it introduces more issues with capabilities etc and doesn't suit what I am trying to achieve.

share|improve this question
1  
I ended up making a plugin. Answer updated :) –  brasofilo Nov 29 '12 at 23:29

1 Answer 1

up vote 5 down vote accepted

The following enables the default meta box for draft and pending posts (in the portfolio post_type):

add_action( 'admin_init', 'wpse_74018_enable_draft_comments' );

/**
 * Add Comments Meta Box if CPT is 'draft' or 'pending'
 */
function wpse_74018_enable_draft_comments()
{
    if( isset( $_GET['post'] ) ) 
    {
        $post_id = absint( $_GET['post'] ); 
        $post = get_post( $post_id ); 
        if ( 'draft' == $post->post_status || 'pending' == $post->post_status )
            add_meta_box(
                'commentsdiv', 
                __('Comments'), 
                'post_comment_meta_box', 
                'portfolio', // CHANGE FOR YOUR CPT
                'normal', 
                'core'
            );
    }
}

But, we cannot comment... error commenting in draft post

The error is produced in /wp-admin/includes/ajax-actions.php, line 736:


To correct this, the Ajax call must be intercepted with:

add_action( 'admin_init', 'wpse_74018_enable_custom_ajax_comments' );

function wpse_74018_enable_custom_ajax_comments()
{
    add_action( 'wp_ajax_replyto-comment', 'wpse_74018_custom_callback', 0 );
}

/**
 * Copy of wp_ajax_replyto_comment()
 * /wp-admin/includes/ajax-actions.php
 *
 * Adjust the CPT that defines $diff_status   
 */
function wpse_74018_custom_callback( $action ) {
    global $wp_list_table, $wpdb;
    if ( empty( $action ) )
        $action = 'replyto-comment';

    check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );

    set_current_screen( 'edit-comments' );

    $comment_post_ID = (int) $_POST['comment_post_ID'];
    if ( !current_user_can( 'edit_post', $comment_post_ID ) )
        wp_die( -1 );

    $status = $wpdb->get_var( $wpdb->prepare("SELECT post_status FROM $wpdb->posts WHERE ID = %d", $comment_post_ID) );

    if( 'portfolio' == get_post_type( $comment_post_ID ) )
        $diff_status = array('trash');
    else
        $diff_status = array('draft','pending','trash');

    if ( empty($status) )
        wp_die( 1 );
    elseif ( in_array($status, $diff_status ) )
        wp_die( __('ERROR: you are replying to a comment on a draft post.') );

    $user = wp_get_current_user();
    if ( $user->exists() ) {
        $user_ID = $user->ID;
        $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']);
        if ( current_user_can( 'unfiltered_html' ) ) {
            if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
                kses_remove_filters(); // start with a clean slate
                kses_init_filters(); // set up the filters
            }
        }
    } else {
        wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
    }

    if ( '' == $comment_content )
        wp_die( __( 'ERROR: please type a comment.' ) );

    $comment_parent = absint($_POST['comment_ID']);
    $comment_auto_approved = false;
    $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');

    $comment_id = wp_new_comment( $commentdata );
    $comment = get_comment($comment_id);
    if ( ! $comment ) wp_die( 1 );

    $position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';

    // automatically approve parent comment
    if ( !empty($_POST['approve_parent']) ) {
        $parent = get_comment( $comment_parent );

        if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
            if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) )
                $comment_auto_approved = true;
        }
    }

    ob_start();
        if ( 'dashboard' == $_REQUEST['mode'] ) {
            require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
            _wp_dashboard_recent_comments_row( $comment );
        } else {
            if ( 'single' == $_REQUEST['mode'] ) {
                $wp_list_table = _get_list_table('WP_Post_Comments_List_Table');
            } else {
                $wp_list_table = _get_list_table('WP_Comments_List_Table');
            }
            $wp_list_table->single_row( $comment );
        }
        $comment_list_item = ob_get_contents();
    ob_end_clean();

    $response =  array(
        'what' => 'comment',
        'id' => $comment->comment_ID,
        'data' => $comment_list_item,
        'position' => $position
    );

    if ( $comment_auto_approved )
        $response['supplemental'] = array( 'parent_approved' => $parent->comment_ID );

    $x = new WP_Ajax_Response();
    $x->add( $response );
    $x->send();
}

Alternatives

Editorially, I understand that the comments system and interface would be much better. An alternative is to create a custom meta box with repeatable fields, where messages can be left within the post.

Basic implementation:

Plugins of interest:


Further developments

I went ahead and made a plugin with more features.
Kudos @toscho, that pointed an entry point in the Ajax query.

Private Comments for CPT
Enables internal comments for a given Custom Post Type when Editing Draft or Pending posts. The comments are only visible in the backend. And marked as internal in the dashboard.

share|improve this answer
    
@kaiser, yes, tested and working fine on my end. Re: $_POST, that's verbatim from the core. I'll be quite happy to see what mods you'd do to this code :) –  brasofilo Nov 27 '12 at 16:20
    
No mods :) Simply don't need it at the moment, was just interested in that one, as I got one project in my mind where this one would be handy. –  kaiser Nov 27 '12 at 16:34
    
Hey nice work! +10 I actually went with your original advice and built what I needed using custom meta boxes + ajax in the backend. Also needed a form on the front end to submit comments so that worked out nicely as well. I'll be checking this out though. Thanks –  Andrew Nov 30 '12 at 3:11
    
@brasofilo Mind me plugging. I have opened a new question dealing with enabling commenting on pending posts on the front-end preview page (rather than the post edit page which this answer solves): wordpress.stackexchange.com/questions/121001/… –  Christine Cooper Nov 2 '13 at 16:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.