WordPress.org

Make WordPress Core

Opened 11 months ago

Last modified 11 months ago

#45394 new defect (bug)

get_posts fails to return results when accessing admin with a custom user role

Reported by: tonydjukic Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.9.8
Component: Query Keywords: reporter-feedback
Focuses: Cc:
PR Number:

Description

Not sure if this is intentional or not, or if there are some capabilities required for custom user roles for 'get_posts' to work, but I'm finding that using 'get_posts' in a CPT metabox works exactly as expected and returns the correct results when accessing the admin as an admin or editor, however, accessing the same screen as any number of custom user roles results in 'get_posts' not returning any data.

There are no error messages and no indication anywhere online that get_posts() is somehow dependent on user role.

To my best estimation this appears to be a bug - get_posts() would work on the front end without a user being logged in, so the user level/role on the back end shouldn't be relevant to whether or not results are returned.

Here's an example:

<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>

To recap:

  • In wp-admin, logged in as Admin or editor, the dropdown is populated with results
  • On front end, logged in with custom user role (most basic level, almost equivalent to a subscriber), the dropdown is populated with results
  • in wp-admin, logged in as custom user role, (consistent with editor caps), the dropdown is empty

Change History (2)

#1 @SergeyBiryukov
11 months ago

  • Keywords reporter-feedback added

Hi @tonydjukic, welcome to WordPress Trac! Thanks for the report.

  1. Could you share the code that creates the seasonal_sessions post type? Does it use any specific capability_type, capabilities, or map_meta_cap arguments?
  2. Does the issue still happen with all plugins disabled and a default theme (Twenty Seventeen) activated?

#2 @tonydjukic
11 months ago

@SergeyBiryukov The site doesn't run any plugins other than the custom one I've built for the surveying system - switching themes makes no difference. The issue only occurs in the back end - if I apply the same methodology to the front end in a template it works for all user levels.

<?php
function register_session_posttype() {
                $labels = array(
                        'name'              => _x( 'Sessions', 'post type general name', 'mwss' ),
                        'singular_name'     => _x( 'Submission', 'post type singular name', 'mwss' ),
                        'add_new'           => __( 'Add Session', 'seasonal_session', 'mwss' ),
                        'add_new_item'      => __( 'Add New Session', 'seasonal_session', 'mwss' ),
                        'edit_item'         => __( 'Edit Session', 'mwss' ),
                        'new_item'          => __( 'New Session', 'mwss' ),
                        'view_item'         => __( 'View Session', 'mwss' ),
                        'search_items'      => __( 'Search Sessions', 'mwss' ),
                        'not_found'         => __( 'No Sessions found.', 'mwss' ),
                        'not_found_in_trash'=> __( 'No Sessions found in trash.', 'mwss' ),
                        'parent_item_colon' => __( 'Parent Sessions:', 'mwss' ),
                        'menu_name'         => __( 'Sessions', 'mwss' )
                );
                $taxonomies = array();
             $supports = array(
                'title'
             );
                $post_type_args = array(
                        'labels'                => $labels,
                        'singular_label'        => __('Session', 'post type singular name', 'mwss'),
                        'public'                => true,
                        'show_ui'               => true,
                        'publicly_queryable'    => true,
                        'query_var'             => true,
                        'capability_type'               => 'post',
                        'has_archive'           => false,
                        'hierarchical'          => false,
                        'rewrite'               => array( 'slug' => 'seasonal_sessions', 'with_front' => false ),
                        'supports'              => $supports,
                        'menu_position'         => 5,
                        'menu_icon'             => 'dashicons-calendar',
                        'taxonomies'            => $taxonomies,
                        'register_meta_box_cb'  => 'mwss_add_session_metaboxes',
                        'map_meta_cap'                  => true
                );
                register_post_type( 'seasonal_sessions', $post_type_args );
        }
        add_action('init', 'register_session_posttype');

I did actually try multiple variations to apply capabilities and map_meta_cap, but they made no difference whatsoever.

Here's an example of my last, desperate, attempt:

// 'capability_type'   	=> array('post','seasonal_session','seasonal_sessions'),
			// 'capabilities'			=> array(
			// 	'edit_post' 			=> 'edit_seasonal_session',
			// 	'edit_posts' 			=> 'edit_seasonal_sessions',
			// 	'edit_others_posts' 	=> 'edit_others_seasonal_sessions',
			// 	'publish_posts' 		=> 'publish_seasonal_sessions',
			// 	'read_post' 			=> 'read_seasonal_session',
			// 	'read_posts'			=> 'read_seasonal_sessions',
			// 	'read_private_posts' 	=> 'read_private_seasonal_sessions',
			// 	'delete_post' 			=> 'delete_seasonal_session',
			// ),

I genuinely don't understand why it would work for all user levels on the front end, but only editor or higher on the back end - that's what led me to start wondering if there was some sort of bug.

I've also repeatedly worked through the custom user roles and tried to ensure that they have all the correct permissions, but that had no effect on the behavior either. (I first attempted it through code, but then even went and installed capability plugins to cross check my code changes - according to each plugin I tested with, every user role had the correct permissions to be able to edit and update the post type.)

Note: See TracTickets for help on using tickets.