Customized role that allows users to “Submit for Review” instead of “Publish”

It really depends on whether you want to restrict these new roles to a particular post type. If you search for “workflow plugins” you can find several ready-made solutions. Some only let the new roles edit Pages, some allow them to edit any post type.

I built a site that needed users who could only impact a particular CPT. So for example, we had “Editors” for CPT1 who could only “submit for review” and then “Approvers” for CPT1 who could edit and publish. We also had “Editors” for CPT2 and “Approvers” for CPT2, and so on and so forth, so people could only make changes to their assigned CPT.

The first step there was to use map_meta_cap when registering the CPTs, which created a whole new set of permissions for each CPT. The second step was more complicated and a bit hacky. First, I added a noscript tag to the admin so anyone with JS turned off couldn’t get around and edit or publish things. I removed Quick Edit, and disabled Autosave, so the only way to update CPTs was to go to the full editor screen with JS enabled.

From there, I hooked into admin_footer-post.php and checked permissions. If the current user could not publish or edit the particular CPT they were currently editing, I used jQuery to change the “Publish” button to say “Save Changes,” and changed the form action to my own plugin URL. The plugin takes all the POST data and programmatically inserts a new post with a custom status, then fires an email to the “Approvers” for that CPT with instructions on how to review – it takes them to the revision comparison screen.

I don’t like that it relies on JS and I don’t like overriding Core publishing features, but so far, other than another plugin that basically does the same thing, that’s the only way I’ve found to handle multiple custom workflows.