List all private pages user has access rights to read

I have made the following code for you to copy and paste in to your functions.php file.

I’m sure there is a simpler solution, however this is the working solution I came up with.

The first part of the section adds the new roles.

function anakeme_custom_roles() {

    add_role(
        'level_1',
        'Level 1',
        [
            'read_private_pages' => true,
            'read_level_1' => true,
        ]
    );

    add_role(
        'level_2',
        'Level 2',
        [
            'read_private_pages' => true,
            'read_level_2' => true,
        ]
    );

}
add_action( 'init', 'anakeme_custom_roles' );

The second part of the code creates the foreach loop and adds conditions depending on the users capabilities and page level.

function anakeme_shortcode_level() {

    $pages = get_pages(
        array(
            'post_status' => array( 'private' ),
        )
    );

    foreach ( $pages as $page ) {

        $page_level = get_post_meta( $page->ID, 'visibility_level', true );
        $read_1 = current_user_can( 'read_level_1', $page->ID );
        $read_2 = current_user_can( 'read_level_2', $page->ID );

        if ( $read_1 && $page_level == 1 ) {

            echo $page->post_title . "<br/>";

        } else if( $read_2 && $page_level >= 1 ) {

            echo $page->post_title . "<br/>";

        }

    }

}
add_shortcode( 'list_pages_level', 'anakeme_shortcode_level' );

Now for this to work, you must create a custom field in the pages you want to remain exclusive for certain roles/levels. The roles I created in my example use a numbering system.

So for Level 1 users to access level 1 pages, I simply added the custom field visibility_level and the value 1. Same goes for Level 2 users, just swapping the value 1 for 2.

Once that numbering system was established, I used a condition to check if the number was equal to 1 or more, then displayed the results accordingly.

To implement this anywhere in your site, use the shortcode list_pages_level.

If you would like further help in understanding the above code, or help expanding on the code, please reply with your questions(s)

EDIT

The above code will work without using third party plugins, however as the OP requires a code to work in conjunction with a plugin known as ‘MembersPress’, the below code should satisfy the OP’s requirements of displaying pages that the currently logged in user has access to.

function anakeme_shortcode_level() {
    
    global $current_user;

    /**
      *
      * Get 'private' pages as array.
      *
      */
    $pages = get_pages(
        array(
            'post_status' => 'private',
        )
    );
    
    /**
      *
      * Loop through all pages.
      *
      */
    foreach ( $pages as $page ) {
        
        /**
          *
          * Get current users role.
          *
          */
        $user_roles = $current_user->roles;
        $user_role = array_shift( $user_roles );
        
        /**
          *
          * Check the current user can read private pages.
          *
          */
        $private = current_user_can( 'read_private_pages', $page->ID );
        
        /**
          *
          * Get the roles that have access to the associated page.
          *
          */
        $restricted = get_post_meta( $page->ID, '_members_access_role' );
        
        /**
          *
          * Find and echo only pages where the user has access to private pages and the `users role` is equal to the `role` restriction on the page set by MembersPress.
          *
          */
        if( ( $private ) && ( $user_role == in_array( $user_role, $restricted ) ) ) {
                
            echo $page->post_title . "<br/>";
            
        }

    }

}
add_shortcode( 'list_pages_level', 'anakeme_shortcode_level' );

Please note that the code provided above is NOT normally provided by StackOverflow members as it is relating to a 3rd party plugin (MembersPress). Please be sure to contact the plugin’s customer support in the future for any coding requests.

Please be sure to mark the answer as correct if this is what you required and to also upvote the answer as a kind-of thank you 🙂