make post_submit_meta_box more generic

Description

Currently there isn't a way to modify the meta boxes which set the post status. The function post_submit_meta_box in wp-admin/includes/meta-boxes.php is a closed function with post statuses hard coded. A new post status registered using register_post_status is available to the query object and plugins but cannot be added to the post status select box in the publish meta box.

A lot of the post_submit_meta_box is hardcoded to the default post status types.

Consider the use case where you want posts to only be visible to logged in users. A custom post status selectable by the user in add/edit post could be used which is then added or excluded in the query (filtered by posts_where) depending on whether the user is logged in or not. This way core can handle the non-visible posts the way private or future posts are handled.

Ok, I've attached a diff of what I've been working on. It's not quite done yet, but I wanted to post it for others (aka @ptahdunbar) to see if I'm headed in the right direction.

It adds two new arguments to register_post_status that allow it to be attached to a particular post, and determines if it's explicitely shown in the status drop down box.

I also added an optional extra argument to register_post_type that lets the post type explicitly declare what post types it handles. If not set, it handles all the default post types, plus those declared to it by register_post_status.

This is a pretty early version. I still need to make the meta box handle these better, but I'd like any feed back from those more knowledgeable then I.

For anyone who cares, and partly for my own review, I'm going go through the changes I've made. I'm sure there will be a few bugs and some more work that needs to be done to get this working, but this is what I've got so far.

File: post.php

post_type: holds an array of post types that the status can be explicitly declared to. Defaults to 'false', which means its available for all post typesedit_cap: changing the post status can be limited by capability. If set, users must have the declared capability to change change posts to this capability. Defaults to NULLshow_in_select_ui: is set to true, the status is displayed in the select boxes on edit.php and post-new.php. Defaults to falsedisplay_label: an additional label that can be used in the select box. Defaults to label or the status name

I also created a new function: post_type_can_have_status($post_type, $status)
This function takes a post type and a status and returns trueif the status is available for that post type

I added a new argument to register_post_type(): allowed_status

allowed_status: holds an array of status names that are allowed for the registered post type. If set, only these status types will be allowed for this post type. Defaults to false, meaning it uses the default post types.

File: meta-boxes.php

I adjusted the submit box to check if the post type handles specific statuses, and only shows what is appropriate. The status dropdown now shows statuses that have either assigned to the post type or the default statuses. May need some tweaking.

File: template.php

Added a helper function output_post_status_select(), which echos the available post types as option values for the select boxes.

Modified the inline editor of inline_edit_row() to use the helper function

File: script-loader.php & post.dev.js

Altered the javascript to handle the new post types. Still needs some work

The current diff does not support a type-specific edit_cap. Why not define the custom edit_cap as a new element of the $post_type_object->cap array instead?

I'd also prefer $post_type_object->statuses rather than $status_object->post_type.

A more debatable distinction would be type-specific values for the show_in_select_ui and display_label properties. To me they do belong in the status object. You could make them array properties keyed by post type.