6

I have created a custom post type called Event and I have enabled support for featured images in my functions.php file, but still my custom user role can not see the featured image meta box on the edit page for an event. If a user logges in as administrator the Featured Image meta box is displayed without any errors.

Here is my code to register the CPT:

add_action('init', 'event_post_init');

function event_post_init() {
  // array of all capabilities for our CPT
  $capabilities = array(
     'publish_posts' => 'publish_events',
     'edit_posts' => 'edit_events',
     'edit_others_posts' => 'edit_others_events',
     'delete_posts' => 'delete_events',
     'delete_published_posts' => 'delete_published_events',
     'delete_others_posts' => 'delete_others_events',
     'read_private_posts' => 'read_private_events',
     'edit_post' => 'edit_event',
     'delete_post' => 'delete_event',
     'read_post' => 'read_event',
   );

   // register the CPT
   register_post_type( 'event',
      array(
         'labels' => array(
            'name' => __('Event')
         ),
         'public' => true,
         'has_archive' => true,
         'show_ui' => true,
         'menu_position' => 8,
         'capability_type' => array('event', 'events'),
         'capabilities' => $capabilities,
         'supports' => array('title', 'thumbnail', 'page-attributes'),
         'map_meta_cap' => true,
         'hierarchical' => true,
      )
   );
}

and here is how I setup my custom user role:

function create_event_admin_role(){
   add_role('event_admin', 'Event Administrator', array(
     'publish_events' => false,
     'edit_events' => true,
     'edit_others_events' => false,
     'delete_events' => false,
     'delete_others_events' => false,
     'read_private_events' => true,
     'edit_published_events' => true,
     'read' => true,
     'assign_terms' => true,
     'edit_terms' => true,
     'manage_terms' => true,
     'read_private_pages' => true
   )
  );
}

The strange thing is that if I look at the markup for the edit page I can see the #postimagediv element but for some reason it is hidden. Here is the markup in the page:

<div class="postbox  hide-if-js" id="postimagediv" style="">
   <div title="Click to toggle" class="handlediv"><br></div>
   <h3 class="hndle ui-sortable-handle"><span>Featured Image</span></h3>
   <div class="inside">
     <p class="hide-if-no-js">
       <a class="thickbox" id="set-post-thumbnail" href="http://example.com/wp-admin/media-upload.php?post_id=662&amp;type=image&amp;TB_iframe=1&amp;width=753&amp;height=294" title="Set featured image">Set featured image</a>
      </p>
    </div>
</div>

and the css that actually hides the meta box:

#postimagediv {
   display: hidden !important;
}

Notice that I have enabled Featured Image under Screen Options.

Perhaps I also should point out that I have tried giving the above role the upload_files privilege using the following code:

function extend_event_admin_role() {
  $role = get_role('event_admin');

  $role->add_cap('upload_files');
}

Another thing to point out is that if I do add the upload_files permission, then Featured Image is visible under Screen Options and also other meta boxes which has support for media has a Add Media button, which if I set upload_files to false disappears.

enter image description here

enter image description here

If I change the code in wp-admin/edit-form-advanced.php which add the featured image metabox then I can tell that it's really calling add_metabox():

if ( $thumbnail_support && current_user_can( 'upload_files' ) ):
  add_meta_box('postimagediv', __('Featured Image'), 'post_thumbnail_meta_box', null, 'side', 'low');
  print 'Support for Featured Image';
  exit;
endif;
4
  • What exactly you are trying to achieve here I am confused? What problems you are facing please update one by one with source code so we understand.
    – Webloper
    Oct 4, 2015 at 16:38
  • The question should be pretty clear, users with the custom role event_admin cannot see Featured Image Oct 4, 2015 at 16:39
  • Have you tried my solution? because its working for me.
    – Webloper
    Oct 4, 2015 at 16:41
  • Since I'm using alot of special privileges such as edit_others_events, publish_events and so on, I think it will be complex to clone a role. Oct 4, 2015 at 16:43

3 Answers 3

4

Users that are only assigned to your event_admin role, don't have the upload_files capability, needed to display the featured image meta box.

Here's the relevant code from the core:

if ( $thumbnail_support && current_user_can( 'upload_files' ) )    // <-- Notice this check
    add_meta_box( 
        'postimagediv', 
        esc_html( $post_type_object->labels->featured_image ),             
        'post_thumbnail_meta_box', 
        null, 
       'side', 
       'low'
    );

Note that if you later try to add the option:

'upload_files' => true

to your add_role() setup, it might not update, since it's cached in the wp_user_roles option.

You therefore need to update the database to adjust it:

It might also be possible to use filters like user_has_cap to adjust this dynamically.

8
  • I have already tried to give the upload_files permission, but the issue remains. Oct 4, 2015 at 10:02
  • Can you share how you did that? Maybe you're still using the cached wp_user_roles option values?
    – birgire
    Oct 4, 2015 at 10:30
  • ... that's why the Codex recommends running add_role/remove_role on theme/plugin activation/deactivation. @Cyclone
    – birgire
    Oct 4, 2015 at 15:57
  • Checkout my updated answer, I have tried to delete the role using remove_role(). The strange thing is that current_user_can('upload_files)` should return true, since this permission is given to the user and he also has the ability to upload media files in other meta boxes? Oct 4, 2015 at 16:00
  • It sounds you haven't forgot to add add_theme_support( 'post-thumbnails' ); in your theme, since you can see the debug print. Any javascript errors? Did you try this on a clean install with the default theme? @Cyclone
    – birgire
    Oct 4, 2015 at 17:21
1

As per my understanding you need a custom-post type Event + featured_image + Custom Role, what I don't understand is capability_type event and events unless and until you are customizing to much, whats the reason here for such customization?

What I did here is cloned editor role to event_amdin with all its capabilities and make capability_type to page as you are using page-attributes in your question.

Test: Created two users test as contributor and cyclone as Event Administrator and its working fine. Please provide more information about your need so I update this answer. Thanks!

Edit 1 : Updated code, check edit 1 start/end section into cloneUserRole function.

Happy Coding!!

function cloneUserRole()
{
    global $wp_roles;

    if (!isset($wp_roles))
        $wp_roles = new WP_Roles();

        $editor      = $wp_roles->get_role('editor');
        // Adding a new role with all editor caps.
        $wp_roles->add_role('event_admin', 'Event Administrator', $editor->capabilities);

        // edit 1 start : updated to add cap to new user role
        $event_admin      = $wp_roles->get_role('event_admin');

        $event_admin->add_cap( 'read_event' );
        $event_admin->add_cap( 'delete_event' );
        $event_admin->add_cap( 'edit_event' );
        $event_admin->add_cap( 'read_private_events' );
        $event_admin->add_cap( 'delete_others_events' ); // don't add
        $event_admin->add_cap( 'delete_published_events' );
        $event_admin->add_cap( 'delete_events' ); // don't add
        $event_admin->add_cap( 'edit_others_events' ); // don't add
        $event_admin->add_cap( 'edit_events' );
        $event_admin->add_cap( 'publish_events' ); // don't add
        // edit 1 ends : 

        //echo '<pre>', print_r( $wp_roles, 1), '</pre>';
        //die;
}
add_action('init', 'cloneUserRole');


function stack_event_init() {
    $labels = array(
        'name'               => _x( 'Events', 'post type general name', 'stack' ),
        'singular_name'      => _x( 'Event', 'post type singular name', 'stack' ),
        'menu_name'          => _x( 'Events', 'admin menu', 'stack' ),
        'name_admin_bar'     => _x( 'Event', 'add new on admin bar', 'stack' ),
        'add_new'            => _x( 'Add New', 'event', 'stack' ),
        'add_new_item'       => __( 'Add New Event', 'stack' ),
        'new_item'           => __( 'New Event', 'stack' ),
        'edit_item'          => __( 'Edit Event', 'stack' ),
        'view_item'          => __( 'View Event', 'stack' ),
        'all_items'          => __( 'All Events', 'stack' ),
        'search_items'       => __( 'Search Events', 'stack' ),
        'parent_item_colon'  => __( 'Parent Events:', 'stack' ),
        'not_found'          => __( 'No events found.', 'stack' ),
        'not_found_in_trash' => __( 'No events found in Trash.', 'stack' )
    );

    $args = array(
        'labels'             => $labels,
        'description'        => __( 'Description.', 'stack' ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_nav_menus'  => true,
        'show_in_menu'       => true,
        'show_in_admin_bar'  => true,
        'query_var'          => true,
        'rewrite'            => array( 'slug' => 'event' ),
        'capability_type'    => 'page',
        'has_archive'        => true,
        'hierarchical'       => true,
        'menu_position'      => null,
        'supports'           => array( 'title', 'thumbnail', 'page-attributes' )
    );

    register_post_type( 'event', $args );
}
add_action('init', 'stack_event_init');

function my_rewrite_flush() {
    stack_event_init();
    flush_rewrite_rules();
}
add_action( 'after_switch_theme', 'my_rewrite_flush' );
  1. Roles and Capabilities
  2. Register post type
  3. Flush Rewrite Rules
1
  • I'm forced to grant only certain privileges to this role, since they should not be allowed to publish any content, only create drafts and so on. The role is one of many on a rather large site, where only certain accounts may delete, publish and create content of different types. Oct 4, 2015 at 14:26
1

I finally tracked the problem down to an activated plugin called Revisionary. The function that is responsible for hiding the postimagediv element is act_hide_admin_divs located in revisionary/admin/admin_rvy.php. What the function does is to hide metaboxes with content that doesn't support revisions.

In order to show the featured image for my specific role I used the rvy_hidden_meta_boxes filter:

add_filter('rvy_hidden_meta_boxes', 'revisor_show_featured_image_box');

function revisor_show_featured_image_box($unrevisable_css_ids) {
   $key = array_search('postimagediv', $unrevisable_css_ids, true);
   unset($unrevisable_css_ids[$key]);

   return $unrevisable_css_ids;
}
1
  • 1
    Glad to hear you found the problematic plugin, no wonder I couldn't re-create this behavior on a vanilla install ;-)
    – birgire
    Oct 5, 2015 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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