Index: .
===================================================================
--- . (revision 20434)
+++ . (working copy)
Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
+wp-content/plugins/
Index: wp-comments-post.php
===================================================================
--- wp-comments-post.php (revision 20434)
+++ wp-comments-post.php (working copy)
@@ -37,7 +37,7 @@
} elseif ( 'trash' == $status ) {
do_action('comment_on_trash', $comment_post_ID);
exit;
-} elseif ( !$status_obj->public && !$status_obj->private ) {
+} elseif ( empty($status_obj->public) && empty($status_obj->private) ) {
do_action('comment_on_draft', $comment_post_ID);
exit;
} elseif ( post_password_required($comment_post_ID) ) {
Index: wp-includes/post-template.php
===================================================================
--- wp-includes/post-template.php (revision 20434)
+++ wp-includes/post-template.php (working copy)
@@ -107,12 +107,22 @@
$id = isset($post->ID) ? $post->ID : (int) $id;
if ( !is_admin() ) {
- if ( !empty($post->post_password) ) {
- $protected_title_format = apply_filters('protected_title_format', __('Protected: %s'));
+ if ( ! empty($post->post_password) ) {
+ $protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ) );
$title = sprintf($protected_title_format, $title);
- } else if ( isset($post->post_status) && 'private' == $post->post_status ) {
- $private_title_format = apply_filters('private_title_format', __('Private: %s'));
- $title = sprintf($private_title_format, $title);
+ } elseif ( isset($post->post_status) ) {
+ $post_status_obj = get_post_status_object( $post->post_status );
+ if ( $post_status_obj && $post_status_obj->private ) {
+ if ( 'private' == $post->post_status ) {
+ $format_string = __( 'Private: %s' ); // preserve existing translation string
+ $private_title_format = apply_filters( 'private_title_format', $format_string );
+ $title = sprintf( $private_title_format, $title );
+ } else {
+ $format_string = _x( '%1$s: %2$s', 'post status: title' );
+ $private_title_format = apply_filters( 'post_title_format', $format_string, $_status );
+ $title = sprintf( $private_title_format, $post_status_obj->labels->name, $title );
+ }
+ }
}
}
return apply_filters( 'the_title', $title, $id );
@@ -700,7 +710,7 @@
if ( 1 == $i ) {
$url = get_permalink();
} else {
- if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
+ if ( '' == get_option('permalink_structure') || in_array( $post->post_status, array('draft', 'auto-draft', 'pending') ) || ! empty( $GLOBALS['wp_post_statuses'][$post->post_status]->moderation ) )
$url = add_query_arg( 'page', $i, get_permalink() );
elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
$url = trailingslashit(get_permalink()) . user_trailingslashit("$wp_rewrite->pagination_base/" . $i, 'single_paged');
Index: wp-includes/taxonomy.php
===================================================================
--- wp-includes/taxonomy.php (revision 20434)
+++ wp-includes/taxonomy.php (working copy)
@@ -132,6 +132,9 @@
$field = ('names' == $output) ? 'name' : false;
+ if ( isset( $args['object_type'] ) )
+ $args['object_type'] = (array) $args['object_type'];
+
return wp_filter_object_list($wp_taxonomies, $args, $operator, $field);
}
@@ -2839,7 +2842,11 @@
// Get the object and term ids and stick them in a lookup table
$tax_obj = get_taxonomy($taxonomy);
$object_types = esc_sql($tax_obj->object_type);
- $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (" . implode(',', array_keys($term_ids)) . ") AND post_type IN ('" . implode("', '", $object_types) . "') AND post_status = 'publish'");
+
+ $public_stati = apply_filters( 'term_count_stati', get_post_stati( array( 'public' => true, 'object_type' => $tax_obj->object_type ) ) );
+ $public_csv = implode( "', '", $public_stati );
+
+ $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (" . implode(',', array_keys($term_ids)) . ") AND post_type IN ('" . implode("', '", $object_types) . "') AND post_status IN ('$public_csv')");
foreach ( $results as $row ) {
$id = $term_ids[$row->term_taxonomy_id];
$term_items[$id][$row->object_id] = isset($term_items[$id][$row->object_id]) ? ++$term_items[$id][$row->object_id] : 1;
@@ -2900,15 +2907,19 @@
if ( $object_types )
$object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
+ $public_stati = apply_filters( 'term_count_stati', get_post_stati( array( 'public' => true, 'object_type' => $taxonomy->object_type ) ) );
+ $public_csv = implode( "', '", $public_stati );
+
foreach ( (array) $terms as $term ) {
+
$count = 0;
// Attachments can be 'inherit' status, we need to base count off the parent's status if so
if ( $check_attachments )
- $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status = 'publish' OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) = 'publish' ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
+ $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status IN ('$public_csv') OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) IN ('$public_csv') ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
if ( $object_types )
- $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('" . implode("', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
+ $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status IN ('$public_csv') AND post_type IN ('" . implode("', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
do_action( 'edit_term_taxonomy', $term, $taxonomy );
$wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
Index: wp-includes/default-widgets.php
===================================================================
--- wp-includes/default-widgets.php (revision 20434)
+++ wp-includes/default-widgets.php (working copy)
@@ -562,6 +562,9 @@
if ( empty( $instance['number'] ) || ! $number = absint( $instance['number'] ) )
$number = 10;
+ $public_stati = apply_filters( 'recent_posts_stati', get_post_stati( array( 'public' => true ) ) );
+ $status_arg = implode( ',', $public_stati );
+
$r = new WP_Query( apply_filters( 'widget_posts_args', array( 'posts_per_page' => $number, 'no_found_rows' => true, 'post_status' => 'publish', 'ignore_sticky_posts' => true ) ) );
if ($r->have_posts()) :
?>
Index: wp-includes/link-template.php
===================================================================
--- wp-includes/link-template.php (revision 20434)
+++ wp-includes/link-template.php (working copy)
@@ -114,7 +114,7 @@
$permalink = apply_filters('pre_post_link', $permalink, $post, $leavename);
- if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
+ if ( '' != $permalink && ! in_array( $post->post_status, array('draft', 'auto-draft', 'pending') ) && empty( $GLOBALS['wp_post_statuses'][$post->post_status]->moderation ) ) {
$unixtime = strtotime($post->post_date);
$category = '';
@@ -185,7 +185,7 @@
$slug = $post->post_name;
- $draft_or_pending = isset($post->post_status) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) );
+ $draft_or_pending = isset($post->post_status) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) ) || ! empty( $GLOBALS['wp_post_statuses'][$post->post_status]->moderation );
$post_type = get_post_type_object($post->post_type);
@@ -275,7 +275,7 @@
$link = $wp_rewrite->get_page_permastruct();
- if ( !empty($link) && ( ( isset($post->post_status) && !$draft_or_pending ) || $sample ) ) {
+ if ( !empty($link) && ( ( isset($post->post_status) && !$draft_or_pending ) && empty( $GLOBALS['wp_post_statuses'][$post->post_status]->moderation ) ) || $sample ) {
if ( ! $leavename ) {
$link = str_replace('%pagename%', get_page_uri($id), $link);
}
Index: wp-includes/nav-menu.php
===================================================================
--- wp-includes/nav-menu.php (revision 20434)
+++ wp-includes/nav-menu.php (working copy)
@@ -482,8 +482,11 @@
if ( empty( $items ) )
return $items;
+ $public_stati = apply_filters( 'nav_menu_stati', get_post_stati( array( 'public' => true ) ), $menu );
+ $public_csv = implode( ',', $public_stati );
+
$defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item',
- 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true,
+ 'post_status' => $public_csv, 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true,
'update_post_term_cache' => false );
$args = wp_parse_args( $args, $defaults );
if ( count( $items ) > 1 )
Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php (revision 20434)
+++ wp-includes/post.php (working copy)
@@ -95,56 +95,82 @@
) );
register_post_status( 'publish', array(
- 'label' => _x( 'Published', 'post' ),
+ 'labels' => array(
+ 'name' => _x( 'Published', 'post' ),
+ 'publish' => esc_attr__('Publish'),
+ 'count' => _n_noop( 'Published (%s)', 'Published (%s)' ),
+ ),
'public' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Published (%s)', 'Published (%s)' ),
) );
register_post_status( 'future', array(
- 'label' => _x( 'Scheduled', 'post' ),
+ 'labels' => array(
+ 'name' => _x( 'Scheduled', 'post' ),
+ 'publish' => esc_attr__('Schedule'),
+ 'count' => _n_noop('Scheduled (%s)', 'Scheduled (%s)' ),
+ ),
'protected' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop('Scheduled (%s)', 'Scheduled (%s)' ),
) );
register_post_status( 'draft', array(
- 'label' => _x( 'Draft', 'post' ),
+ 'labels' => array(
+ 'name' => _x( 'Draft', 'post' ),
+ 'save_as' => esc_attr__('Save Draft'),
+ 'count' => _n_noop( 'Draft (%s)', 'Drafts (%s)' ),
+ ),
'protected' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Draft (%s)', 'Drafts (%s)' ),
) );
register_post_status( 'pending', array(
- 'label' => _x( 'Pending', 'post' ),
+ 'labels' => array(
+ 'name' => _x( 'Pending', 'post' ),
+ 'caption' => __( 'Pending Review' ),
+ 'publish' => esc_attr__('Submit for Review'),
+ 'count' => _n_noop( 'Pending (%s)', 'Pending (%s)' ),
+ ),
'protected' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Pending (%s)', 'Pending (%s)' ),
+ 'moderation' => true,
) );
register_post_status( 'private', array(
- 'label' => _x( 'Private', 'post' ),
+ 'labels' => array(
+ 'name' => _x( 'Private', 'post' ),
+ 'caption' => __( 'Privately Published' ),
+ 'count' => _n_noop( 'Private (%s)', 'Private (%s)' ),
+ ),
'private' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Private (%s)', 'Private (%s)' ),
) );
register_post_status( 'trash', array(
- 'label' => _x( 'Trash', 'post' ),
+ 'labels' => array(
+ 'name' => _x( 'Trash', 'post' ),
+ 'count' => _n_noop( 'Trash (%s)', 'Trash (%s)' ),
+ ),
'internal' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Trash (%s)', 'Trash (%s)' ),
'show_in_admin_status_list' => true,
) );
register_post_status( 'auto-draft', array(
- 'label' => 'auto-draft',
+ 'labels' => array(
+ 'name' => 'auto-draft',
+ 'caption' => __( 'Draft' ),
+ ),
'internal' => true,
'_builtin' => true, /* internal use only. */
+ 'show_in_admin_all_list' => false,
+ 'show_in_admin_status_list' => false,
) );
register_post_status( 'inherit', array(
- 'label' => 'inherit',
+ 'labels' => array(
+ 'name' => 'inherit',
+ ),
'internal' => true,
'_builtin' => true, /* internal use only. */
'exclude_from_search' => false,
@@ -632,6 +658,32 @@
}
/**
+ * Add an already registered post status to an object type.
+ *
+ * @package WordPress
+ * @subpackage Taxonomy
+ * @since 3.1.0
+ * @uses $wp_post_statuses Modifies post_type object
+ *
+ * @param string $post_status Name of post_status object
+ * @param array|string $object_type Name of the object type
+ * @return bool True if successful, false if not
+ */
+function register_status_for_object_type( $post_status, $object_type) {
+ global $wp_post_statuses;
+
+ if ( ! isset( $wp_post_statuses[$post_status] ) )
+ return false;
+
+ if ( ! get_post_type_object($object_type) )
+ return false;
+
+ $wp_post_statuses[$post_status]->object_type[] = $object_type;
+
+ return true;
+}
+
+/**
* Register a post type. Do not use before init.
*
* A simple function for creating or modifying a post status based on the
@@ -665,13 +717,20 @@
$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' => 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);
+ $defaults = array( 'object_type' => null, 'labels' => array(), '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, 'moderation' => 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_key($post_status);
$args->name = $post_status;
+ if ( null == $args->object_type ) {
+ $args->object_type = array_values( get_post_types( array( 'public' => true, 'show_ui' => true ) ) );
+ } else {
+ $args->object_type = (array) $args->object_type;
+ }
+
if ( null === $args->public && null === $args->internal && null === $args->protected && null === $args->private )
$args->internal = true;
@@ -681,6 +740,9 @@
if ( null === $args->private )
$args->private = false;
+ if ( null === $args->moderation )
+ $args->moderation = false;
+
if ( null === $args->protected )
$args->protected = false;
@@ -702,12 +764,38 @@
if ( null === $args->single_view_cap )
$args->single_view_cap = $args->public ? '' : 'edit';
- if ( false === $args->label )
- $args->label = $post_status;
+ $args->labels = (object) $args->labels;
- if ( false === $args->label_count )
- $args->label_count = array( $args->label, $args->label );
+ if ( empty( $args->labels->name ) )
+ $args->labels->name = ( ! empty( $args->label ) ) ? $args->label : $post_status;
+
+ if ( empty( $args->label ) )
+ $args->label = $args->labels->name;
+
+ if ( empty( $args->labels->caption ) )
+ $args->labels->caption = $args->label;
+ if ( empty( $args->labels->count ) )
+ $args->labels->count = ( ! empty( $args->label_count ) ) ? $args->label_count : array( $args->label, $args->label );
+
+ if ( empty( $args->label_count ) ) // TODO: need to support this for external API?
+ $args->label_count = $args->labels->count;
+
+ if ( empty( $args->labels->publish ) )
+ $args->labels->publish = esc_attr( sprintf( __( 'Set %s' ), $args->label ) );
+
+ if ( empty( $args->labels->save_as ) )
+ $args->labels->save_as = esc_attr( sprintf( __( 'Save as %s' ), $args->label ) );
+
+ if ( empty( $args->labels->visibility ) ) {
+ if ( 'publish' == $post_status )
+ $args->labels->visibility =__( 'Public' );
+ elseif ( $args->public )
+ $args->labels->visibility = esc_attr( sprintf( __( 'Public (%s)' ), $args->label ) );
+ elseif ( $args->private )
+ $args->labels->visibility = $args->label;
+ }
+
$wp_post_statuses[$post_status] = $args;
return $args;
@@ -753,13 +841,60 @@
*/
function get_post_stati( $args = array(), $output = 'names', $operator = 'and' ) {
global $wp_post_statuses;
+
+ $post_statuses = $wp_post_statuses;
$field = ('names' == $output) ? 'name' : false;
+
+ //wp_filter_object_list doesn't like nested arrays,
+ //so grab a subset of post stati that match the query, and THEN run through wp_list_filter
+ if ( ! empty( $args['object_type'] ) ) {
+ $post_statuses = get_object_stati( $args['object_type'], 'objects' );
+ unset( $args['object_type'] );
+ }
- return wp_filter_object_list($wp_post_statuses, $args, $operator, $field);
+ return wp_filter_object_list( $post_statuses, $args, $operator, $field );
}
/**
+ * Return all of the post_statuses that are of $object_type.
+ * *
+ * Should
+ * result in
Array('publish', 'future', 'pending', etc. )
+ *
+ * @package WordPress
+ * @subpackage Taxonomy
+ * @since 3.5
+ *
+ * @uses $wp_post_statuses
+ *
+ * @param array|string|object $object Name of the type of post_status object, or an object (row from posts)
+ * @param string $output The type of output to return, either status 'names' or 'objects'. 'names' is the default.
+ * @return array The names of all statuses of $object_type.
+ */
+
+function get_object_stati($object, $output = 'names') {
+ global $wp_post_statuses;
+
+ if ( is_object($object) )
+ $object = $object->post_type;
+
+ $object = (array) $object;
+
+ $stati = array();
+ foreach ( (array) $wp_post_statuses as $status_name => $status_obj ) {
+ if ( array_intersect($object, (array) $status_obj->object_type) ) {
+ if ( 'names' == $output )
+ $stati[] = $status_name;
+ else
+ $stati[ $status_name ] = $status_obj;
+ }
+ }
+
+ return $stati;
+}
+
+/**
* Whether the post type is hierarchical.
*
* A false return value might also mean that the post type does not exist.
@@ -928,7 +1063,7 @@
'_builtin' => false, '_edit_link' => 'post.php?post=%d', 'hierarchical' => false,
'public' => false, 'rewrite' => true, 'has_archive' => false, 'query_var' => true,
'supports' => array(), 'register_meta_box_cb' => null,
- 'taxonomies' => array(), 'show_ui' => null, 'menu_position' => null, 'menu_icon' => null,
+ 'taxonomies' => array(), 'statuses' => array(), 'show_ui' => null, 'menu_position' => null, 'menu_icon' => null,
'can_export' => true,
'show_in_nav_menus' => null, 'show_in_menu' => null, 'show_in_admin_bar' => null,
);
@@ -1049,6 +1184,10 @@
foreach ( $args->taxonomies as $taxonomy ) {
register_taxonomy_for_object_type( $taxonomy, $post_type );
}
+
+ foreach ( $args->statuses as $post_status ) {
+ register_status_for_object_type( $post_status, $post_type );
+ }
do_action( 'registered_post_type', $post_type, $args );
@@ -1823,13 +1962,17 @@
$query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
if ( 'readable' == $perm && is_user_logged_in() ) {
$post_type_object = get_post_type_object($type);
- if ( !current_user_can( $post_type_object->cap->read_private_posts ) ) {
- $cache_key .= '_' . $perm . '_' . $user->ID;
- $query .= " AND (post_status != 'private' OR ( post_author = '$user->ID' AND post_status = 'private' ))";
+ foreach( get_post_stati( array( 'private' => true, 'object_type' => $type ) ) as $_status ) {
+ $cap_name = "read_{$_status}_posts";
+ if ( ! empty($post_type_object->cap->$cap_name) && ! current_user_can( $post_type_object->cap->$cap_name ) ) {
+ $suffix = ( 'private' == $_status ) ? '' : $_status;
+ $cache_key .= '_' . $perm . $suffix . '_' . $user->ID;
+ $query .= " AND (post_status != '$_status' OR ( post_author = '$user->ID' AND post_status = '$_status' ))";
+ }
}
}
$query .= ' GROUP BY post_status';
-
+
$count = wp_cache_get($cache_key, 'counts');
if ( false !== $count )
return $count;
@@ -1837,7 +1980,7 @@
$count = $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
$stats = array();
- foreach ( get_post_stati() as $state )
+ foreach ( get_post_stati( array( 'object_type' => $type ) ) as $state )
$stats[$state] = 0;
foreach ( (array) $count as $row )
@@ -2320,13 +2463,16 @@
$args = array( 'numberposts' => absint( $args ) );
}
+ $status_names = get_post_stati( array( 'public' => true, 'object_type' => 'post' ) );
+ $status_names_csv = "'" . implode( "', '", $status_names ) . "'";
+
// Set default arguments
$defaults = array(
'numberposts' => 10, 'offset' => 0,
'category' => 0, 'orderby' => 'post_date',
'order' => 'DESC', 'include' => '',
'exclude' => '', 'meta_key' => '',
- 'meta_value' =>'', 'post_type' => 'post', 'post_status' => 'draft, publish, future, pending, private',
+ 'meta_value' =>'', 'post_type' => 'post', 'post_status' => $status_names_csv,
'suppress_filters' => true
);
@@ -2493,13 +2639,16 @@
}
// Don't allow contributors to set the post slug for pending review posts
- if ( 'pending' == $post_status && !current_user_can( 'publish_posts' ) )
+ $post_status_obj = get_post_status_object( $post_status );
+ $draft_or_pending = in_array( $post_status, array( 'draft', 'auto-draft' ) ) || ! empty( $post_status_obj->moderation );
+
+ if ( ! empty( $post_status_obj->moderation ) && ! current_user_can( 'publish_posts' ) )
$post_name = '';
// Create a valid post name. Drafts and pending posts are allowed to have an empty
// post name.
if ( empty($post_name) ) {
- if ( !in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) )
+ if ( ! $draft_or_pending )
$post_name = sanitize_title($post_title);
else
$post_name = '';
@@ -2517,7 +2666,7 @@
$post_date = current_time('mysql');
if ( empty($post_date_gmt) || '0000-00-00 00:00:00' == $post_date_gmt ) {
- if ( !in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) )
+ if ( ! $draft_or_pending )
$post_date_gmt = get_gmt_from_date($post_date);
else
$post_date_gmt = '0000-00-00 00:00:00';
@@ -2531,7 +2680,9 @@
$post_modified_gmt = $post_date_gmt;
}
- if ( 'publish' == $post_status ) {
+ $set_status = $post_status;
+
+ if ( $post_status_obj->public || $post_status_obj->private ) {
$now = gmdate('Y-m-d H:i:59');
if ( mysql2date('U', $post_date_gmt, false) > mysql2date('U', $now, false) )
$post_status = 'future';
@@ -2541,6 +2692,11 @@
$post_status = 'publish';
}
+ if ( ( 'future' == $post_status ) && ( 'publish' != $set_status ) ) {
+ update_post_meta( $post_ID, '_scheduled_status', $set_status );
+ } else
+ delete_post_meta( $post_ID, '_scheduled_status' );
+
if ( empty($comment_status) ) {
if ( $update )
$comment_status = 'closed';
@@ -2571,7 +2727,7 @@
else
$menu_order = 0;
- if ( !isset($post_password) || 'private' == $post_status )
+ if ( ! isset($post_password) || $post_status_obj->private )
$post_password = '';
$post_name = wp_unique_post_slug($post_name, $post_ID, $post_status, $post_type, $post_parent);
@@ -2612,7 +2768,10 @@
$where = array( 'ID' => $post_ID );
}
- if ( empty($data['post_name']) && !in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) ) {
+ $post_status_obj = get_post_status_object( $data['post_status'] );
+ $draft_or_pending = in_array( $data['post_status'], array('draft', 'auto-draft') ) || ! empty($post_status_obj->moderation);
+
+ if ( empty($data['post_name']) && ! $draft_or_pending ) {
$data['post_name'] = sanitize_title($data['post_title'], $post_ID);
$wpdb->update( $wpdb->posts, array( 'post_name' => $data['post_name'] ), $where );
}
@@ -2702,10 +2861,11 @@
$post_cats = $post['post_category'];
// Drafts shouldn't be assigned a date unless explicitly done so by the user
- if ( isset( $post['post_status'] ) && in_array($post['post_status'], array('draft', 'pending', 'auto-draft')) && empty($postarr['edit_date']) &&
- ('0000-00-00 00:00:00' == $post['post_date_gmt']) )
- $clear_date = true;
- else
+ if ( isset( $post['post_status'] ) && empty($postarr['edit_date']) && ('0000-00-00 00:00:00' == $post['post_date_gmt']) ) {
+ $post_status_obj = get_post_status_object( $post['post_status'] );
+
+ $clear_date = in_array( $post['post_status'], array('draft', 'auto-draft') ) || ! empty($post_status_obj->moderation);
+ } else
$clear_date = false;
// Merge old and new fields with new fields overwriting old ones.
@@ -2743,8 +2903,14 @@
if ( 'publish' == $post->post_status )
return;
- $wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post_id ) );
+ if ( 'future' == $post->post_status ) {
+ if ( ! $post_status = get_post_meta( $post_id, '_scheduled_status', true ) )
+ $post_status = 'publish';
+ } else
+ $post_status = 'publish';
+ $wpdb->update( $wpdb->posts, array( 'post_status' => $post_status ), array( 'ID' => $post_id ) );
+
$old_status = $post->post_status;
$post->post_status = 'publish';
wp_transition_post_status('publish', $old_status, $post);
@@ -2801,7 +2967,9 @@
* @return string unique slug for the post, based on $post_name (with a -1, -2, etc. suffix)
*/
function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent ) {
- if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) )
+ $post_status_obj = get_post_status_object( $post_status );
+
+ if ( in_array( $post_status, array('draft', 'auto-draft') ) || ! empty($post_status_obj->moderation) )
return $slug;
global $wpdb, $wp_rewrite;
@@ -3365,7 +3533,8 @@
// Make sure we have a valid post status
if ( !is_array( $post_status ) )
$post_status = explode( ',', $post_status );
- if ( array_diff( $post_status, get_post_stati() ) )
+ if ( array_diff( $post_status, get_post_stati( array( 'object_type' => $post_type ) ) ) )
+
return false;
$cache = array();
Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php (revision 20434)
+++ wp-includes/query.php (working copy)
@@ -2402,16 +2402,18 @@
$post_type_object = get_post_type_object ( 'post' );
}
+ $_post_type = ( $post_type ) ? $post_type : 'post'; // corresponds to hardcoded default for POST_TYPE clause
+ $type_arg = ( 'any' == $_post_type ) ? array() : array( 'object_type' => $_post_type );
+
if ( ! empty( $post_type_object ) ) {
+ $post_type_cap = $post_type_object->capability_type;
$edit_cap = $post_type_object->cap->edit_post;
$read_cap = $post_type_object->cap->read_post;
$edit_others_cap = $post_type_object->cap->edit_others_posts;
- $read_private_cap = $post_type_object->cap->read_private_posts;
} 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 ( ! empty( $q['post_status'] ) ) {
@@ -2421,24 +2423,36 @@
$q_status = explode(',', $q_status);
$r_status = array();
$p_status = array();
+ $p_status_owner = array();
$e_status = array();
if ( in_array('any', $q_status) ) {
foreach ( get_post_stati( array('exclude_from_search' => true) ) as $status )
$e_status[] = "$wpdb->posts.post_status <> '$status'";
} else {
- foreach ( get_post_stati() as $status ) {
+ $_args = array_merge( array(), $type_arg );
+ foreach ( get_post_stati( $_args, 'object' ) as $status => $status_obj ) {
if ( in_array( $status, $q_status ) ) {
- if ( 'private' == $status )
- $p_status[] = "$wpdb->posts.post_status = '$status'";
- else
+ if ( $status_obj->private ) {
+ if ( ! empty($post_type_object) ) {
+ $check_cap = "read_{$status}_posts";
+ $read_private_cap = ( ! empty( $post_type_object->cap->$check_cap ) ) ? $post_type_object->cap->$check_cap : $post_type_object->cap->read_private_posts;
+ } else
+ $read_private_cap = 'read_private_' . $post_type_cap . 's';
+
+ if ( ! empty($q['perm'] ) && 'readable' == $q['perm'] && ! current_user_can( $read_private_cap ) )
+ $p_status_owner[] = "$wpdb->posts.post_status = '$status'";
+ else
+ $p_status[] = "$wpdb->posts.post_status = '$status'";
+ } else
$r_status[] = "$wpdb->posts.post_status = '$status'";
}
}
}
if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) {
- $r_status = array_merge($r_status, $p_status);
+ $r_status = array_merge($r_status, $p_status, $p_status_owner);
unset($p_status);
+ unset($p_status_owner);
}
if ( !empty($e_status) ) {
@@ -2450,24 +2464,30 @@
else
$statuswheres[] = "(" . join( ' OR ', $r_status ) . ")";
}
- if ( !empty($p_status) ) {
+
+ if ( ! empty( $p_status ) ) {
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 ) . ")";
}
+ if ( ! empty( $p_status ) ) {
+ $statuswheres[] = "(" . join( ' OR ', $p_status ) . ")";
+ }
if ( $post_status_join ) {
$join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) ";
foreach ( $statuswheres as $index => $statuswhere )
$statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))";
}
foreach ( $statuswheres as $statuswhere )
- $where .= " AND $statuswhere";
+ $where .= " AND $statuswhere";
+
} elseif ( !$this->is_singular ) {
$where .= " AND ($wpdb->posts.post_status = 'publish'";
// Add public states.
- $public_states = get_post_stati( array('public' => true) );
+ $_args = array_merge( array( 'public' => true ), $type_arg );
+ $public_states = apply_filters_ref_array( 'posts_public_stati', array( get_post_stati( $_args ), &$this ) );
foreach ( (array) $public_states as $state ) {
if ( 'publish' == $state ) // Publish is hard-coded above.
continue;
@@ -2476,16 +2496,25 @@
if ( $this->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) );
+ $_args = array_merge( array( 'protected' => true, 'show_in_admin_all_list' => true ), $type_arg );
+ $admin_all_states = get_post_stati( $_args );
foreach ( (array) $admin_all_states as $state )
$where .= " OR $wpdb->posts.post_status = '$state'";
}
if ( is_user_logged_in() ) {
// 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 )
+ $_args = array_merge( array( 'private' => true ), $type_arg );
+ $private_states = apply_filters_ref_array( 'posts_private_stati', array( get_post_stati( $_args ), &$this ) );
+ foreach ( (array) $private_states as $state ) {
+ if ( ! empty($post_type_object) ) {
+ $check_cap = "read_{$state}_posts";
+ $read_private_cap = ( ! empty( $post_type_object->cap->$check_cap ) ) ? $post_type_object->cap->$check_cap : $post_type_object->cap->read_private_posts;
+ } else
+ $read_private_cap = 'read_private_' . $post_type_cap . 's';
+
$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 .= ')';
@@ -2526,8 +2555,11 @@
$cwhere = "WHERE comment_approved = '1' $where";
$cgroupby = "$wpdb->comments.comment_id";
} else { // Other non singular e.g. front
+ $public_stati = apply_filters( 'comment_feed_stati', get_post_stati( array( 'public' => true ) ) );
+ $public_csv = implode( "', '", $public_stati );
+
$cjoin = "JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID )";
- $cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'";
+ $cwhere = "WHERE post_status IN ( '$public_csv' ) AND comment_approved = '1'";
$cgroupby = '';
}
@@ -2738,11 +2770,13 @@
$stickies_where = "AND $wpdb->posts.post_type IN ('" . $post_types . "')";
}
+ $public_stati = apply_filters_ref_array( 'posts_sticky_stati', array( get_post_stati( array( 'public' => true ) ), &$this ) );
$stickies = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE $wpdb->posts.ID IN ($stickies__in) $stickies_where" );
foreach ( $stickies as $sticky_post ) {
// Ignore sticky posts the current user cannot read or are not published.
- if ( 'publish' != $sticky_post->post_status )
+ if ( ! in_array( $sticky_post->post_status, $public_stati ) )
continue;
+
array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
$sticky_offset++;
}
Index: wp-includes/general-template.php
===================================================================
--- wp-includes/general-template.php (revision 20434)
+++ wp-includes/general-template.php (working copy)
@@ -915,9 +915,12 @@
}
//filters
- $where = apply_filters( 'getarchives_where', "WHERE post_type = 'post' AND post_status = 'publish'", $r );
- $join = apply_filters( 'getarchives_join', '', $r );
+ $public_stati = apply_filters( 'getarchives_stati', get_post_stati( array( 'public' => true ) ) );
+ $public_csv = implode( "', '", $public_stati );
+ $where = apply_filters('getarchives_where', "WHERE post_type = 'post' AND post_status IN ('" . $public_csv . "')", $r );
+ $join = apply_filters('getarchives_join', "", $r);
+
$output = '';
if ( 'monthly' == $type ) {
Index: wp-includes/script-loader.php
===================================================================
--- wp-includes/script-loader.php (revision 20434)
+++ wp-includes/script-loader.php (working copy)
@@ -332,7 +332,7 @@
$scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array('jquery-ui-sortable'), false, 1 );
$scripts->add( 'post', "/wp-admin/js/post$suffix.js", array('suggest', 'wp-lists', 'postbox'), false, 1 );
- $scripts->localize( 'post', 'postL10n', array(
+ $arr = array(
'ok' => __('OK'),
'cancel' => __('Cancel'),
'publishOn' => __('Publish on:'),
@@ -352,9 +352,25 @@
'privatelyPublished' => __('Privately Published'),
'published' => __('Published'),
'comma' => _x( ',', 'tag delimiter' ),
- ) );
+ );
+
+ $custom = array();
+ foreach( get_post_stati( array( 'public' => true, 'private' => true ), 'object', 'or' ) as $_status => $_status_obj ) {
+ if ( 'publish' == $_status )
+ continue;
+ $custom[ $_status ] = $_status_obj->labels->visibility;
+
+ if ( $_status_obj->public )
+ $custom[ $_status . 'Sticky' ] = sprintf( __('%s, Sticky'), $_status_obj->label );
+ }
+
+ $arr = array_merge( $custom, $arr ); // note: 'publish' has existing value of 'Publish', cannot be used to reference status name
+
+ $scripts->localize( 'post', 'postL10n', $arr );
+
$scripts->add( 'link', "/wp-admin/js/link$suffix.js", array('wp-lists', 'postbox'), false, 1 );
+ $scripts->add_data( 'link', 'group', 1 );
$scripts->add( 'comment', "/wp-admin/js/comment$suffix.js", array('jquery') );
$scripts->add_data( 'comment', 'group', 1 );
Index: wp-content
===================================================================
--- wp-content (revision 20434)
+++ wp-content (working copy)
Property changes on: wp-content
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
+.
Index: wp-content/plugins
===================================================================
--- wp-content/plugins (revision 20434)
+++ wp-content/plugins (working copy)
Property changes on: wp-content/plugins
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
+.
Index: wp-admin/includes/post.php
===================================================================
--- wp-admin/includes/post.php (revision 20434)
+++ wp-admin/includes/post.php (working copy)
@@ -71,7 +71,7 @@
// What to do based on which button they pressed
if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] )
$post_data['post_status'] = 'draft';
- if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] )
+ if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] ) // TODO: is this set anywhere?
$post_data['post_status'] = 'private';
if ( isset($post_data['publish']) && ( '' != $post_data['publish'] ) && ( !isset($post_data['post_status']) || $post_data['post_status'] != 'private' ) )
$post_data['post_status'] = 'publish';
@@ -88,10 +88,20 @@
// Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
// Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
- if ( isset($post_data['post_status']) && ('publish' == $post_data['post_status'] && !current_user_can( $ptype->cap->publish_posts )) )
- if ( $previous_status != 'publish' || !current_user_can( 'edit_post', $post_id ) )
- $post_data['post_status'] = 'pending';
+ if ( isset($post_data['post_status']) && ('publish' == $post_data['post_status'] && !current_user_can( $ptype->cap->publish_posts )) ) {
+ if ( $previous_status != 'publish' || !current_user_can( 'edit_post', $post_id ) ) {
+ $moderation_status = apply_filters( 'post_moderation_status', 'pending', $post->ID );
+ $_status_obj = get_post_status_object( $moderation_status );
+ $cap_name = "set_{$moderation_status}_posts";
+
+ if ( empty($_status_obj) || ! $_status_obj->moderation || ( ! empty($ptype->cap->$cap_name) && ! current_user_can($ptype->cap->$cap_name) ) )
+ $moderation_status = 'pending';
+
+ $post_data['post_status'] = $moderation_status;
+ }
+ }
+
if ( ! isset($post_data['post_status']) )
$post_data['post_status'] = $previous_status;
@@ -182,11 +192,17 @@
case 'password' :
unset( $post_data['sticky'] );
break;
- case 'private' :
- $post_data['post_status'] = 'private';
- $post_data['post_password'] = '';
- unset( $post_data['sticky'] );
- break;
+ default:
+ $status_obj = get_post_status_object( $post_data['visibility'] );
+
+ if ( ! empty( $status_obj->private ) || ! empty( $status_obj->public ) ) {
+ $post_data['post_status'] = $status_obj->name;
+ $post_data['post_password'] = '';
+ }
+
+ if ( ! empty( $status_obj->private ) ) {
+ unset( $post_data['sticky'] );
+ }
}
}
@@ -568,11 +584,13 @@
case 'password' :
unset( $_POST['sticky'] );
break;
- case 'private' :
- $_POST['post_status'] = 'private';
- $_POST['post_password'] = '';
- unset( $_POST['sticky'] );
- break;
+ default:
+ $status_obj = get_post_status_object( $_POST['visibility'] );
+ if ( ! empty( $status_obj->private ) ) {
+ $_POST['post_status'] = $status_obj->name;
+ $_POST['post_password'] = '';
+ unset( $_POST['sticky'] );
+ }
}
}
@@ -862,7 +880,7 @@
if ( isset($q['orderby']) )
$orderby = $q['orderby'];
- elseif ( isset($q['post_status']) && in_array($q['post_status'], array('pending', 'draft')) )
+ elseif ( isset($q['post_status']) && ( in_array($q['post_status'], array('pending', 'draft')) || ! empty( $GLOBALS['wp_post_statuses'][$q['post_status']]->moderation ) ) )
$orderby = 'modified';
if ( isset($q['order']) )
@@ -1024,9 +1042,11 @@
$original_date = $post->post_date;
$original_name = $post->post_name;
+ $post_status_obj = get_post_status_object( $post->post_status );
+
// Hack: get_permalink would return ugly permalink for
// drafts, so we will fake, that our post is published
- if ( in_array($post->post_status, array('draft', 'pending')) ) {
+ if ( in_array($post->post_status, array('draft', 'pending')) || ! empty($post_status_obj->moderation) ) {
$post->post_status = 'publish';
$post->post_name = sanitize_title($post->post_name ? $post->post_name : $post->post_title, $post->ID);
}
@@ -1084,7 +1104,8 @@
list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug);
- if ( 'publish' == $post->post_status ) {
+ $public_stati = get_post_stati( array( 'public' => true ) );
+ if ( in_array( $post->post_status, $public_stati ) ) {
$ptype = get_post_type_object($post->post_type);
$view_post = $ptype->labels->view_item;
$title = __('Click to edit this part of the permalink');
Index: wp-admin/includes/template.php
===================================================================
--- wp-admin/includes/template.php (revision 20434)
+++ wp-admin/includes/template.php (working copy)
@@ -254,7 +254,16 @@
'.__('Title').' | '.__('Date').' | '.__('Status').' | |
---|---|---|---|
'; - $html .= ' | '.esc_html( $time ).' | '.esc_html( $stat ).' | '.esc_html( $time ).' | '.esc_html( $stat[$post->post_status] ).' | '."\n\n"; } $html .= '