Flag post statuses as public, private, protected, or internal. Add flags for showing the type in the admin all query and the admin status list. see #9674

git-svn-id: http://svn.automattic.com/wordpress/trunk@13172 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2010-02-16 21:13:44 +00:00
parent 88f317209e
commit f18f34ead8
3 changed files with 100 additions and 39 deletions

View File

@ -232,7 +232,7 @@ $total_posts = array_sum( (array) $num_posts ) - $num_posts->trash;
$class = empty($class) && empty($_GET['post_status']) ? ' class="current"' : '';
$status_links[] = "<li><a href='edit.php?post_type=$post_type{$allposts}'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_posts, 'posts' ), number_format_i18n( $total_posts ) ) . '</a>';
foreach ( get_post_stati(array('show_in_admin_edit' => true), 'objects') as $status ) {
foreach ( get_post_stati(array('show_in_admin_status_list' => true), 'objects') as $status ) {
$class = '';
$status_name = $status->name;

View File

@ -70,33 +70,38 @@ function create_initial_post_types() {
) );
register_post_status( 'future', array( 'label' => _x('Scheduled', 'post'),
'public' => true,
'protected' => true,
'_builtin' => true,
'label_count' => _n_noop('Scheduled <span class="count">(%s)</span>', 'Scheduled <span class="count">(%s)</span>')
) );
register_post_status( 'draft', array( 'label' => _x('Draft', 'post'),
'public' => true,
'protected' => true,
'_builtin' => true,
'label_count' => _n_noop('Draft <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>')
) );
register_post_status( 'pending', array( 'label' => _x('Pending', 'post'),
'protected' => true,
'_builtin' => true,
'label_count' => _n_noop('Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>')
) );
register_post_status( 'private', array( 'label' => _x('Private', 'post'),
'public' => true,
'private' => true,
'_builtin' => true,
'label_count' => _n_noop('Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>')
) );
register_post_status( 'trash', array( 'label' => _x('Trash', 'post'),
'public' => true,
'exclude_from_search' => true,
'internal' => true,
'show_in_admin_status_list' => true,
'_builtin' => true,
'label_count' => _n_noop('Trash <span class="count">(%s)</span>', 'Trash <span class="count">(%s)</span>')
) );
register_post_status( 'auto-draft', array( 'label' => _x('Auto-Draft', 'post'),
'public' => false,
'exclude_from_search' => true,
'internal' => true,
'_builtin' => true,
'label_count' => _n_noop('Auto-Draft <span class="count">(%s)</span>', 'Auto-Drafts <span class="count">(%s)</span>')
) );
@ -526,24 +531,42 @@ function register_post_status($post_status, $args = array()) {
$wp_post_statuses = array();
// Args prefixed with an underscore are reserved for internal use.
$defaults = array('label' => false, 'label_count' => false, 'exclude_from_search' => null, '_builtin' => false, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'post', 'hierarchical' => false, 'public' => false, 'publicly_queryable' => null, 'show_in_admin_edit' => null);
$defaults = array('label' => false, 'label_count' => false, 'exclude_from_search' => null, '_builtin' => false, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'post', 'hierarchical' => false, 'public' => null, 'internal' => null, 'protected' => null, 'private' => null, 'show_in_admin_all' => null, 'publicly_queryable' => null, 'show_in_admin_status_list' => null, 'show_in_admin_all_list' => null, 'single_view_cap' => null);
$args = wp_parse_args($args, $defaults);
$args = (object) $args;
$post_status = sanitize_user($post_status, true);
$args->name = $post_status;
// If not set, default to the setting for public.
if ( null === $args->public && null === $args->internal && null === $args->protected && null === $args->private )
$args->internal = true;
if ( null === $args->public )
$args->public = false;
if ( null === $args->private )
$args->private = false;
if ( null === $args->protected )
$args->protected = false;
if ( null === $args->internal )
$args->internal = false;
if ( null === $args->publicly_queryable )
$args->publicly_queryable = $args->public;
// If not set, default to true if not public, false if public.
if ( null === $args->exclude_from_search )
$args->exclude_from_search = !$args->public;
$args->exclude_from_search = $args->internal;
// If not set, default to the setting for public.
if ( null === $args->show_in_admin_edit )
$args->show_in_admin_edit = $args->public;
if ( null === $args->show_in_admin_all_list )
$args->show_in_admin_all_list = !$args->internal;
if ( null === $args->show_in_admin_status_list )
$args->show_in_admin_status_list = !$args->internal;
if ( null === $args->single_view_cap )
$args->single_view_cap = $args->public ? '' : 'edit';
if ( false === $args->label )
$args->label = $post_status;
@ -591,15 +614,21 @@ function get_post_status_object( $post_status ) {
* @param array|string $args An array of key => value arguments to match against the post statuses.
* Only post statuses having attributes that match all arguments are returned.
* @param string $output The type of output to return, either post status 'names' or 'objects'. 'names' is the default.
* @param string $operator Whether the elements in $args should be logicallly 'or'ed or 'and'ed together. 'or' means only one element from the array needs to match. 'and' means all elements must match. The default is 'or'.
* @return array A list of post type names or objects
*/
function get_post_stati( $args = array(), $output = 'names' ) {
function get_post_stati( $args = array(), $output = 'names', $operator = 'or' ) {
global $wp_post_statuses;
$do_names = false;
if ( 'names' == $output )
$do_names = true;
if ( 'and' == $operator )
$arg_count = count($args);
else
$arg_count = 0;
$post_statuses = array();
foreach ( (array) $wp_post_statuses as $post_status ) {
if ( empty($args) ) {
@ -607,7 +636,9 @@ function get_post_stati( $args = array(), $output = 'names' ) {
$post_statuses[] = $post_status->name;
else
$post_statuses[] = $post_status;
} elseif ( array_intersect_assoc((array) $post_status, $args) ) {
} elseif ( $intersect = array_intersect_assoc((array) $post_status, $args) ) {
if ( $arg_count && ( $arg_count != count($intersect) ) )
continue;
if ( $do_names )
$post_statuses[] = $post_status->name;
else
@ -787,6 +818,8 @@ function register_post_type($post_type, $args = array()) {
$args->publish_cap = 'publish_' . $args->capability_type . 's';
if ( empty($args->read_cap) )
$args->read_cap = 'read_' . $args->capability_type;
if ( empty($args->read_private_cap) )
$args->read_private_cap = 'read_private_' . $args->capability_type . 's';
if ( empty($args->delete_cap) )
$args->delete_cap = 'delete_' . $args->capability_type;

View File

@ -2061,9 +2061,9 @@ class WP_Query {
$q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
}
if ( is_array($post_type) )
if ( is_array($post_type) ) {
$post_type_cap = 'multiple_post_type';
else {
} else {
$post_type_object = get_post_type_object ( $post_type );
if ( !empty($post_type_object) )
$post_type_cap = $post_type_object->capability_type;
@ -2081,15 +2081,29 @@ class WP_Query {
$where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')";
} elseif ( ! empty( $post_type ) ) {
$where .= " AND $wpdb->posts.post_type = '$post_type'";
$post_type_object = get_post_type_object ( $post_type );
} elseif ( $this->is_attachment ) {
$where .= " AND $wpdb->posts.post_type = 'attachment'";
$post_type_cap = 'post';
$post_type_object = get_post_type_object ( 'attachment' );
} elseif ($this->is_page) {
$where .= " AND $wpdb->posts.post_type = 'page'";
$post_type_cap = 'page';
$post_type_object = get_post_type_object ( 'page' );
} else {
$where .= " AND $wpdb->posts.post_type = 'post'";
$post_type_cap = 'post';
$post_type_object = get_post_type_object ( 'post' );
}
if ( !empty($post_type_object) ) {
$post_type_cap = $post_type_object->capability_type;
$edit_cap = $post_type_object->edit_cap;
$read_cap = $post_type_object->read_cap;
$edit_others_cap = $post_type_object->edit_others_cap;
$read_private_cap = $post_type_object->read_private_cap;
} else {
$edit_cap = 'edit_' . $post_type_cap;
$read_cap = 'read_' . $post_type_cap;
$edit_others_cap = 'edit_others_' . $post_type_cap . 's';
$read_private_cap = 'read_private_' . $post_type_cap . 's';
}
if ( isset($q['post_status']) && '' != $q['post_status'] ) {
@ -2121,13 +2135,13 @@ class WP_Query {
$statuswheres[] = "(" . join( ' AND ', $e_status ) . ")";
}
if ( !empty($r_status) ) {
if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can("edit_others_{$post_type_cap}s") )
if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can($edit_others_cap) )
$statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $r_status ) . "))";
else
$statuswheres[] = "(" . join( ' OR ', $r_status ) . ")";
}
if ( !empty($p_status) ) {
if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can("read_private_{$post_type_cap}s") )
if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can($read_private_cap) )
$statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $p_status ) . "))";
else
$statuswheres[] = "(" . join( ' OR ', $p_status ) . ")";
@ -2142,11 +2156,26 @@ class WP_Query {
} elseif ( !$this->is_singular ) {
$where .= " AND ($wpdb->posts.post_status = 'publish'";
if ( is_admin() )
$where .= " OR $wpdb->posts.post_status = 'future' OR $wpdb->posts.post_status = 'draft' OR $wpdb->posts.post_status = 'pending'";
// Add public states.
$public_states = get_post_stati( array('public' => true) );
foreach ( (array) $public_states as $state ) {
if ( 'publish' == $state ) // Publish is hard-coded above.
continue;
$where .= " OR $wpdb->posts.post_status = '$state'";
}
if ( is_admin() ) {
// Add protected states that should show in the admin all list.
$admin_all_states = get_post_stati( array('protected' => true, 'show_in_admin_all_list' => true), 'names', 'and' );
foreach ( (array) $admin_all_states as $state )
$where .= " OR $wpdb->posts.post_status = '$state'";
}
if ( is_user_logged_in() ) {
$where .= current_user_can( "read_private_{$post_type_cap}s" ) ? " OR $wpdb->posts.post_status = 'private'" : " OR $wpdb->posts.post_author = $user_ID AND $wpdb->posts.post_status = 'private'";
// Add private states that are limited to viewing by the author of a post or someone who has caps to read private states.
$private_states = get_post_stati( array('private' => true) );
foreach ( (array) $private_states as $state )
$where .= current_user_can( $read_private_cap ) ? " OR $wpdb->posts.post_status = '$state'" : " OR $wpdb->posts.post_author = $user_ID AND $wpdb->posts.post_status = '$state'";
}
$where .= ')';
@ -2296,33 +2325,32 @@ class WP_Query {
// Check post status to determine if post should be displayed.
if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
$status = get_post_status($this->posts[0]);
$post_status_obj = get_post_status_object($status);
//$type = get_post_type($this->posts[0]);
if ( ('publish' != $status) ) {
if ( !$post_status_obj->public ) {
if ( ! is_user_logged_in() ) {
// User must be logged in to view unpublished posts.
$this->posts = array();
} else {
if (in_array($status, array('draft', 'pending', 'trash')) ) {
if ( $post_status_obj->protected ) {
// User must have edit permissions on the draft to preview.
if (! current_user_can("edit_$post_type_cap", $this->posts[0]->ID)) {
if (! current_user_can($edit_cap, $this->posts[0]->ID)) {
$this->posts = array();
} else {
$this->is_preview = true;
$this->posts[0]->post_date = current_time('mysql');
if ('future' != $status)
$this->posts[0]->post_date = current_time('mysql');
}
} else if ('future' == $status) {
$this->is_preview = true;
if (!current_user_can("edit_$post_type_cap", $this->posts[0]->ID)) {
$this->posts = array ( );
}
} else {
if (! current_user_can("read_$post_type_cap", $this->posts[0]->ID))
} elseif ( $post_status_obj->private ) {
if ( ! current_user_can($read_cap, $this->posts[0]->ID) )
$this->posts = array();
} else {
$this->posts = array();
}
}
}
if ( $this->is_preview && current_user_can( "edit_{$post_type_cap}", $this->posts[0]->ID ) )
if ( $this->is_preview && current_user_can( $edit_cap, $this->posts[0]->ID ) )
$this->posts[0] = apply_filters('the_preview', $this->posts[0]);
}