0

I've stumbled across something that I can't seem to find any documentation on regarding WP 'get_posts' function.

I've got a web application that has multiple custom post-types and multiple custom user roles. They're all necessary for an assortment of reasons. Different users types within the organization need to see different things and be able to edit different aspects of the custom post-types.

In the custom post-type edit screens, I have metaboxes that display user provided data, however, users with backend access, using different custom user roles, need to be able to correct or modify the data that users have supplied or to manually create an entry.

I use the following 'get_posts()' method to generate dropdowns based on entries from other custom post-types:

<select name="mwss_session">
    <option value="">Please select a Session</option>
    <?php
        $get_sessions = get_posts( array(
            'post_type'         => 'seasonal_sessions',
            'post_status'       => 'publish',
            'posts_per_page'    => -1,
            'meta_key'          => 'mwss_session_status',
            'meta_value'        => 'true',
            'meta_compare'      => '='
        ) );
        $selected_session = $mwss_session;
        foreach( $get_sessions as $active_session ) {
            $session_name = get_the_title( $active_session->ID );
            echo '<option value="' . $session_name . '"';
            if( $selected_session === $session_name ){ echo 'selected'; }
            echo '>' . $session_name . '</option>';
        }
    ?>
</select>

It works as you'd expect it to. You visit the edit screen and the dropdown is populated with 'Sessions' whose 'status' is set to 'true'. This same get_posts() method works on the front end as well, logged in or not.

However, when visiting the edit.php screen for this post type using one of the custom user roles I created, this dropdown and others using the same method, all fail to return results.

Here's an example of one of the custom user roles capabilities:

$result = add_role(
    'mwss_sitesuper', __('Site Supervisor'),
    array(
        //WordPress Capabilities
        'level_9'                       => false,
        'level_8'                       => true,
        'level_7'                       => true,
        'level_6'                       => true,
        'level_5'                       => true,
        'level_4'                       => true,
        'level_3'                       => true,
        'level_2'                       => true,
        'level_1'                       => true,
        'level_0'                       => true,
        'read'                          => true,
        'read_private_pages'            => true,
        'read_private_posts'            => true,
        'create_posts'                  => true,
        'publish_posts'                 => true,
        'edit_users'                    => true,
        'edit_posts'                    => true,
        'edit_pages'                    => true,
        'edit_published_posts'          => true,
        'edit_published_pages'          => true,
        'edit_private_pages'            => true,
        'edit_private_posts'            => true,
        'edit_others_posts'             => true,
        'edit_others_pages'             => true,
        'publish_posts'                 => true,
        'publish_pages'                 => true,
        'delete_posts'                  => true,
        'delete_pages'                  => true,
        'delete_private_pages'          => true,
        'delete_private_posts'          => true,
        'delete_published_pages'        => true,
        'delete_published_posts'        => true,
        'delete_others_posts'           => true,
        'delete_others_pages'           => true,
        'manage_options'                => false,
        'manage_categories'             => false,
        'manage_links'                  => false,
        'moderate_comments'             => true,
        'unfiltered_html'               => false,
        'upload_files'                  => false,
        'export'                        => false,
        'import'                        => false,
        'list_users'                    => true,
        'edit_themes'                   => false,
        'install_plugins'               => false,
        'update_plugin'                 => false,
        'update_core'                   => false
    )
);

Any idea why get_posts() only works with Administrator or Editor roles in the back end, but works for all user roles on the front end?

Update: After delving pretty deeply into capabilities, I've come to the conclusion that this is something unrelated. On the front end, regardless of the user's capabilities or role, the same 'get_posts' function is returning results. So if a user role as low as subscriber, or if all of the custom user roles are able to view the dropdown on the front end populated with the expected 'sessions', they then theoretically have the capability to do so, right? Or am I missing something? The issue appears to be isolated to metaboxes within CPT. If I use WP_Query, it works, but WP_Query will disrupt the rest of the admin loop.

  • A sidenote but your querying for mwss_session_status is super expensive/slow, mwss_session_status should really have been a taxonomy with 2 terms, 'true` and false, it could be 100x faster to query – Tom J Nowell Nov 21 '18 at 18:02
  • I hear you @tomjnowell, that was my original plan but there's a lot more data in the sessions than just the status and it wouldn't have worked as a taxonomy. For this purpose however I only need to check the status. At any given time there shouldn't be more than 4 or 5 sessions in the system, and usually no more than 2 active. So it's a really quick query. – Tony Djukic Nov 21 '18 at 18:08
  • You don't have to put everything in taxonomies, storing the status by assigning terms doesn't stop you using post meta for other fields – Tom J Nowell Nov 21 '18 at 22:15
0

Try adding read_seasonal_sessions to your capabilities array and setting that to true. Each new CPT gets 7 new capabilities to add to user roles. (see capability_type on register_post_type())

OR

Add map_meta_cap to your register_post_type function (if you have it) and set it to true. (see map_meta_cap under register_post_type())

By default, map_meta_cap is null, so I don't think it's mapping the post capabilities directly to your CPT.

  • Thanks for this @socki03... ...didn't seem to change anything. I added the capabilities to each user role, then output a print_r of the capabilities to confirm they were there, but that didn't change the results. Next, I added 'map_meta_cap' => true, but that didn't have any effect. And finally, I added capabilities to post_type because I just want them to behave like regular posts, but that didn't work. I have capability_type set to 'seasonal_session'. Then added capabilities as follows: 'capabilities' => array('read_seasonal_session', 'read_seasonal_sessions'), – Tony Djukic Nov 21 '18 at 19:46
  • Update: I've installed several capability management plugins and all of the custom post-types have all of the requisite capabilities enabled now, however, the end result is still the same and the get_posts() still returns no results. So frustrating. – Tony Djukic Nov 21 '18 at 20:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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