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 run a multiple author platform and to improve the moderation, I want to add a couple of assisting editors. I want to add a custom box to the Post page where the assisting editor can confirm which tasks they have completed.

So, this box would contain a checklist of options, for example:

    1 => ' Proofread ',
    2 => ' Graphics Added ',
    3 => ' SEO Fixed ',
    4 => ' Ready for Publish '

And then contain a checklist that lists all assisting editors (users that can edit_published_posts) and there the user can mark themselves as they have contributed to the edit.

The box could look like this:

Editorial Tasks

Then finally, on the front end post page, I want to list which user(s) that have edited the post.

In an attempt to do this, I have this code:

add_action( 'add_meta_boxes', 'assisting_editor' );
function assisting_editor() {
    add_meta_box(
        'assisting_editor', // id, used as the html id att
        __( 'Editorial Tasks' ), // meta box title
        'editor_tasks', // callback function, spits out the content
        'post', // post type or page. This adds to posts only
        'side', // context, where on the screen
        'low' // priority, where should this go in the context
    );

}

function editor_tasks( $post ) {
    global $wpdb;
    $value = get_post_meta($post->ID, 'rating', true);
    echo '<div class="misc-pub-section misc-pub-section-last"><span id="timestamp"><label>Editorial tasks: </label>';

    $ratings = array(
        1 => ' Proofread ',
        2 => ' Graphics Added ',
        3 => ' SEO Fixed ',
        4 => ' Ready for Publish '
    );

    echo '<select name="rating">';
    echo '<option value=""' . ((($value == '') || !isset($ratings[$value])) ? ' selected="selected"' : '') . '> Untouched </option>';

    // output each rating as an option
    foreach ($ratings as $id => $text) {
        echo '<option value="' . $id . '"' . (($value == $id) ? ' selected="selected"' : '') . '">' . $text. '</option>';
    }
    echo '</select>';

    echo '</span></div>';
}

add_action( 'save_post', 'save_metadata');

function save_metadata($postid)
{   
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return false;
    if ( !current_user_can( 'edit_page', $postid ) ) return false;
    if( empty($postid) ) return false;


    if ( is_null($_REQUEST["rating"]) ) {
        delete_post_meta($postid, 'rating');
    } else {
        update_post_meta($postid, 'rating', $_REQUEST['rating']);
    }

}

However, this code adds a drop-down list, not a check-list, and more importantly, it does not list the editor users.

My question is: how can I make a box like the picture above and with those features, and how do I echo the list of users that have edited the post?

share|improve this question
    
You want checkbox, but have select in your above code. Question: Do you know basic HTML? –  kaiser Nov 13 '12 at 14:15
    
@kaiser I am self-taught and learning as we speak. I only know what I have practiced so far which is limited. I would not know how to adjust that example code to make it do what I want, especially listing the editor users in the front end. –  Amanda Duke Nov 13 '12 at 14:22
add comment

1 Answer

up vote 4 down vote accepted

add_meta_box should give you the box container like your have pictured.

You have a select drop-down because that is what you created here:

echo '<select name="rating">';
echo '<option value=""' . ((($value == '') || !isset($ratings[$value])) ? ' selected="selected"' : '') . '> Untouched </option>';

// output each rating as an option
foreach ($ratings as $id => $text) {
    echo '<option value="' . $id . '"' . (($value == $id) ? ' selected="selected"' : '') . '">' . $text. '</option>';
}
echo '</select>';

You need a series of checkboxes. Of the code above you only need the foreach. Checkboxes work differently that selects. The following will give you four different values that you need to save, one for each element of your $ratings array.

foreach ($ratings as $id => $text) {
    echo '<input type="checkbox" name="'.strtolower($text).'" value="' . $id . '"' . (($value == $id) ? ' selected="selected"' : '') . '"/><label for"'.strtolower($text).'">'.$text.'</label>';
}

You can put all of the checkboxes in an array by naming them like this:

foreach ($ratings as $id => $text) {
    echo '<input type="checkbox" name="ratings[]" value="' . $id . '"' . (($value == $id) ? ' selected="selected"' : '') . '"/><label for"ratings[]">'.$text.'</label>';
}

In the first case you will have to modify your update function. In the second, I believe your function will work but I am not 100% sure.

To get your list of authors you want to use get_users with the who parameter set to 'authors' which will, per the codex, return "user level greater than 0". That is, everyone who isn't a subscriber-- authors, editors, contributors, etc. So...

$alleds = get_users('who=authors');

Another check to see if any any authors are already selected.

$currenteds = get_post_meta($post->ID, 'currenteds', true);

And then a foreach to create the checkboxes, much like the one above for $ratings. You want that last parameter true only if you save as a single entry in the DB, which probably makes sense in this case.

foreach ($alleds as $ed) {
    $checked = (in_array($ed->ID,$currenteds)) ? 'checked="checked"' : '';
    echo '<input type="checkbox" name="currenteds[]" value="' . $ed->ID . '"' . $checked . '"/><label for"ratings[]">'.$ed->user_nicename.'</label>';
}

And of course another update_post_meta block to save the fields.

if ( is_null($_REQUEST["currenteds"]) ) {
    delete_post_meta($postid, 'currenteds');
} else {
    update_post_meta($postid, 'currenteds', $_REQUEST['currenteds']);
}

I think that's got it.

Also, you are passing dirty data into these function. I won't lecture but look up "data validation" and "data sanitization" . :)

Here is the whole thing with a couple of typo corrections and bug fixes. Our editors have bugged me for something similar so I mocked it up :). The formatting is non-existent but it works. I tested it as a plugin, so build yourself a plugin header. I don't know if it will work from function.php.

// author checkboxes
add_action( 'add_meta_boxes', 'assisting_editor' );
function assisting_editor() {
    add_meta_box(
        'assisting_editor', // id, used as the html id att
        __( 'Editorial Tasks' ), // meta box title
        'editor_tasks', // callback function, spits out the content
        'post', // post type or page. This adds to posts only
        'side', // context, where on the screen
        'low' // priority, where should this go in the context
    );

}

function editor_tasks( $post ) {
    global $wpdb;
    $value = get_post_meta($post->ID, 'ratings', true);

    echo '<div class="misc-pub-section misc-pub-section-last"><span id="timestamp"><label>Editorial tasks: </label>';

    $ratings = array(
        1 => ' Proofread ',
        2 => ' Graphics Added ',
        3 => ' SEO Fixed ',
        4 => ' Ready for Publish '
    );

    foreach ($ratings as $id => $text) {
    $checked = (in_array($id,(array)$value)) ? ' checked="checked"' : '';
    echo '<input type="checkbox" name="ratings[]" value="' . $id . '"'.  $checked . '/><label for="ratings[]">'.$text.'</label>';
    }

    $qry['relation'] = 'OR';
    $qry[] = array(
      'key' => $wpdb->prefix.'capabilities',
      'value' => 'editor',
      'compare' => 'like'
    );
    $qry[] = array(
      'key' => $wpdb->prefix.'capabilities',
      'value' => 'administrator',
      'compare' => 'like'
    );
    $qry = array('fields' => 'all_with_meta','meta_query'=>$qry);

    $alleds = get_users($qry);

    $currenteds = get_post_meta($post->ID, 'currenteds', true);

    foreach ($alleds as $ed) {
    $checked = (in_array($ed->ID,(array)$currenteds)) ? ' checked="checked"' : '';
    echo '<input type="checkbox" name="currenteds[]" value="' . $ed->ID . '"' .$checked . '"/><label for="ratings[]">'.$ed->user_nicename.'</label>';
    }
    echo '</span></div>';
}

add_action( 'save_post', 'save_metadata');

function save_metadata($postid)
{   
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return false;
    if ( !current_user_can( 'edit_page', $postid ) ) return false;
    if( empty($postid) ) return false;

    if ( is_null($_REQUEST["ratings"]) ) {
        delete_post_meta($postid, 'ratings');
    } else {
        update_post_meta($postid, 'ratings', $_REQUEST['ratings']);
    }

    if ( is_null($_REQUEST["currenteds"]) ) {
    delete_post_meta($postid, 'currenteds');
    } else {
    update_post_meta($postid, 'currenteds', $_REQUEST['currenteds']);
    }
}

function display_current_eds($ID = '') {
  if (empty($ID)) {
    global $post;
    if (!empty($post)) {
      $ID = $post->ID;
    }
  }
  if (empty($ID)) return false;
  $eds = get_post_meta($post->ID,'currenteds',true);
  if (!empty($eds)) {
    foreach ($eds as $e) {
      $edu = get_userdata($e);
      $edusers[] = sprintf(
        '<a href="%1$s" title="%2$s" rel="author">%3$s</a>',
        get_author_posts_url( $edu->ID, $edu->user_nicename ),
        esc_attr( sprintf( __( 'Posts by %s' ), $edu->user_nicename ) ),
        $edu->user_nicename
      );
    }
    return $edusers;
  }
  return false;
}

function authors_content_filter($content) {
  $authors = display_current_eds();
  if (false !== $authors) {
    $content .= implode(', ',$authors);
  }
  return $content;
}
add_filter('the_content','authors_content_filter');

    // add author checkboxes

The add_filter will display authors automatically. To display the authors manually use the following inside the Loop:

$edusers = display_current_eds();
if (false !== $edusers) {
    echo implode(', ',$edusers);
}

I am going to leave it to you to work out formatting and other bells and whistles. I think this question has now been more than adequately answered.

share|improve this answer
1  
If I am not mistaken, your answer did not include how I list all assisting editors in a checklist and how I echo these in the front end post page. Do you know how to do this? (thank you regardless for your input) –  Amanda Duke Nov 13 '12 at 14:57
    
yes... your are right. I'll edit the answer. –  s_ha_dum Nov 13 '12 at 15:00
    
I look forward to the edit. Ideally, if you could post the whole function and I will be able to test it instantly and report back. –  Amanda Duke Nov 13 '12 at 15:30
    
Can you please edit your answer and paste the whole code there as I tried to piece it together but I must have made a mistake as it did not work as proposed. –  Amanda Duke Nov 13 '12 at 15:51
1  
I used your '$edusers = display_current_eds();'... code and it echoed the usernames twice. Why? Is there a typo there? I can read the code but can't find why it is behaving like that. –  Amanda Duke Nov 25 '12 at 18:47
show 7 more comments

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.