Prevent custom user role to add new pages

Post types in WordPress have a list of capabilities that govern permissions surrounding them. These are:

edit_post
read_post
delete_post
edit_posts
edit_others_posts
publish_posts
read_private_posts
read
delete_posts
delete_private_posts
delete_published_posts
delete_others_posts
edit_private_posts
edit_published_posts
create_posts

Internally each post type matches these to the actual capabilities that can be given in WordPress. Most of the time these have the exact same name. So the edit_posts capability of the post post type is edit_posts, while the edit_posts capability for the page post type is edit_pages.

The one exception to this is create_posts. This is the post type capability that WordPress checks to decide whether a user can create a new post of that type. It checks this:

if ( current_user_can( get_post_type_object( 'page' )->cap->create_posts ) ) {}

Unlike the other capabilities, for posts and pages create_posts is actually mapped to edit_posts and edit_pages respectively, not create_posts or create_pages, which don’t exist.

So if you printed get_post_type_object( 'page' )->cap->create_posts you’d see that the value is edit_pages, and users with that capability can see the Add New button. Because this is edit_pages and not publish_pages, it allows users to create new pages and posts even if they can’t publish them, they’ll just be put into pending review, which is the behaviour you want to prevent.

For custom post types you can control this behaviour by setting create_posts in the capabilities argument to something else:

register_post_type(
    'my_custom_type',
    [
        'capabilities' => [
            'create_posts' => 'manage_options',
        ],
    ]
);

For that custom post types, only users with manage_options will be able to add new posts.

For the built in post types you can use the register_post_type_args filter to set this capability however you’d like for the default post types:

function wpse_342743_create_page_capability( $args, $post_type ) {
    if ( 'page' === $post_type ) {
        $args['capabilities'] = [ 
            'create_posts' => 'manage_options',
        ];
    }

    return $args;
}
add_filter( 'register_post_type_args', 'wpse_342743_create_page_capability', 10, 2 );

With that code only users with manage_options will be able to create new pages, but they will still be able to update them without review if they otherwise have edit_pages and publish_pages. You can change this capability to be delete_pages so that only users who can delete pages can create them, or you could pass your own custom capability that you’ll give to users to give them the ability to create pages.