+
+ true, 'object_type' => $post_type ), 'object' ) as $_status => $_status_obj ) :
+ if ( 'publish' == $_status )
+ continue;
+
+ $post_cap = "set_{$_status}_posts";
+ if ( empty( $post_type_obj->cap->$post_cap ) || current_user_can( $post_type_obj->cap->$post_cap ) ) {
+?>
+
+ true, 'object_type' => $post_type ), 'object' ) as $_status => $_status_obj ) :
+ $post_cap = "set_{$_status}_posts";
+ if ( empty( $post_type_obj->cap->$post_cap ) || current_user_can( $post_type_obj->cap->$post_cap ) ) {
+?>
+
post_status, array('publish', 'future', 'private') ) || 0 == $post->ID ) {
+if ( ( ! $post_status_obj->public && ! $post_status_obj->private && ( 'future' != $post_status ) ) ) {
if ( $can_publish ) :
- if ( !empty($post->post_date_gmt) && time() < strtotime( $post->post_date_gmt . ' +0000' ) ) : ?>
-
- '5', 'accesskey' => 'p' ) ); ?>
-
-
- '5', 'accesskey' => 'p' ) ); ?>
+
+ if ( !empty($post->post_date_gmt) && time() < strtotime( $post->post_date_gmt . ' +0000' ) ) :
+ $future_status_obj = get_post_status_object( 'future' );
+ ?>
+
+ labels->publish, 'primary', 'publish', false, array( 'tabindex' => '5', 'accesskey' => 'p' ) ); ?>
+
+
+ labels->publish, 'primary', 'publish', false, array( 'tabindex' => '5', 'accesskey' => 'p' ) ); ?>
-
- '5', 'accesskey' => 'p' ) ); ?>
+ ID );
+
+ $status_obj = get_post_status_object( $moderation_button_status );
+ $cap_name = "set_{$moderation_button_status}_posts";
+
+ if ( ! $status_obj || ( ! empty($post_type_obj->cap->$cap_name) && ! current_user_can($post_type_obj->cap->$cap_name) ) )
+ $status_obj = get_post_status_object( 'pending' );
+ ?>
+
+ labels->publish, 'primary', 'publish', false, array( 'tabindex' => '5', 'accesskey' => 'p' ) ); ?>
diff --git wp-admin/includes/nav-menu.php wp-admin/includes/nav-menu.php
index 5fc73fc..1780b07 100644
--- wp-admin/includes/nav-menu.php
+++ wp-admin/includes/nav-menu.php
@@ -1039,17 +1039,19 @@ function wp_save_nav_menu_items( $menu_id = 0, $menu_data = array() ) {
*/
function _wp_nav_menu_meta_box_object( $object = null ) {
if ( isset( $object->name ) ) {
+ $public_stati = apply_filters( 'nav_menu_metabox_stati', get_post_stati( array( 'public' => true, 'object_type' => $object->name ) ), $object );
+ $public_csv = implode( ',', $public_stati );
if ( 'page' == $object->name ) {
$object->_default_query = array(
'orderby' => 'menu_order title',
- 'post_status' => 'publish',
+ 'post_status' => $public_csv,
);
- // posts should show only published items
+ // posts should show only public items
} elseif ( 'post' == $object->name ) {
$object->_default_query = array(
- 'post_status' => 'publish',
+ 'post_status' => $public_csv,
);
// cats should be in reverse chronological order
@@ -1059,10 +1061,10 @@ function _wp_nav_menu_meta_box_object( $object = null ) {
'order' => 'DESC',
);
- // custom post types should show only published items
+ // custom post types should show only public items
} else {
$object->_default_query = array(
- 'post_status' => 'publish',
+ 'post_status' => $public_csv,
);
}
}
diff --git wp-admin/includes/post.php wp-admin/includes/post.php
index 3bfea57..3762889 100644
--- wp-admin/includes/post.php
+++ wp-admin/includes/post.php
@@ -71,7 +71,7 @@ function _wp_translate_postdata( $update = false, $post_data = null ) {
// 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,9 +88,19 @@ function _wp_translate_postdata( $update = false, $post_data = null ) {
// 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 @@ function edit_post( $post_data = null ) {
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'] );
+ }
}
}
@@ -564,11 +580,13 @@ function wp_write_post() {
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'] );
+ }
}
}
@@ -849,7 +867,7 @@ function wp_edit_posts_query( $q = false ) {
else
$post_type = 'post';
- $avail_post_stati = get_available_post_statuses($post_type);
+ $avail_post_stati = get_available_post_statuses( $post_type );
if ( isset($q['post_status']) && in_array( $q['post_status'], $post_stati ) ) {
$post_status = $q['post_status'];
@@ -858,7 +876,7 @@ function wp_edit_posts_query( $q = false ) {
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']) )
@@ -1020,9 +1038,11 @@ function get_sample_permalink($id, $title = null, $name = null) {
$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);
}
@@ -1080,7 +1100,8 @@ function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
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');
diff --git wp-admin/includes/template.php wp-admin/includes/template.php
index 3834874..c7fc1bf 100644
--- wp-admin/includes/template.php
+++ wp-admin/includes/template.php
@@ -256,7 +256,16 @@ function get_inline_data($post) {
' . $post->post_author . '
' . esc_html( $post->ping_status ) . '
-
' . esc_html( $post->post_status ) . '
+
' . esc_html( $post->post_status ) . '
';
+
+ if ( 'future' == $post->post_status ) {
+ if ( ! $scheduled_status = get_post_meta( $post->ID, '_scheduled_status', true ) )
+ $scheduled_status = 'publish';
+ echo '
+
' . esc_html( $scheduled_status ). '
';
+ }
+
+ echo '
' . mysql2date( 'd', $post->post_date, false ) . '
' . mysql2date( 'm', $post->post_date, false ) . '
' . mysql2date( 'Y', $post->post_date, false ) . '
@@ -577,9 +586,11 @@ function meta_form() {
function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
global $wp_locale, $post, $comment;
- if ( $for_post )
- $edit = ! ( in_array($post->post_status, array('draft', 'pending') ) && (!$post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt ) );
-
+ if ( $for_post ) {
+ $post_status_obj = get_post_status_object($post->post_status);
+ $edit = ( ( 'draft' != $post->post_status ) && empty($post_status_obj->moderation) ) || ( $post->post_date_gmt && '0000-00-00 00:00:00' != $post->post_date_gmt );
+ }
+
$tab_index_attribute = '';
if ( (int) $tab_index > 0 )
$tab_index_attribute = " tabindex=\"$tab_index\"";
@@ -1469,17 +1480,25 @@ function _post_states($post) {
else
$post_status = '';
+ $post_status_obj = get_post_status_object($post->post_status);
+
if ( !empty($post->post_password) )
$post_states['protected'] = __('Password protected');
- if ( 'private' == $post->post_status && 'private' != $post_status )
- $post_states['private'] = __('Private');
- if ( 'draft' == $post->post_status && 'draft' != $post_status )
- $post_states['draft'] = __('Draft');
- if ( 'pending' == $post->post_status && 'pending' != $post_status )
- /* translators: post state */
- $post_states['pending'] = _x('Pending', 'post state');
- if ( is_sticky($post->ID) )
- $post_states['sticky'] = __('Sticky');
+
+ if ( $post_status_obj && ( 'publish' != $post->post_status ) ) {
+ if ( $post->post_status != $post_status ) {
+ $post_states[] = $post_status_obj->label;
+
+ if ( 'future' == $post->post_status ) {
+ if ( $scheduled_status = get_post_meta( $post->ID, '_scheduled_status', true ) ) {
+ if ( 'publish' != $scheduled_status ) {
+ if ( $_scheduled_status_obj = get_post_status_object( $scheduled_status ) )
+ $post_states[] = $_scheduled_status_obj->label;
+ }
+ }
+ }
+ }
+ }
$post_states = apply_filters( 'display_post_states', $post_states );
diff --git wp-admin/js/inline-edit-post.dev.js wp-admin/js/inline-edit-post.dev.js
index 4b0eb2e..69f8586 100644
--- wp-admin/js/inline-edit-post.dev.js
+++ wp-admin/js/inline-edit-post.dev.js
@@ -78,6 +78,12 @@ inlineEditPost = {
t.revert();
$('select[name^="action"]').val('-1');
});
+
+ $('.keep-private, .keep-private input').click(function() {
+ if ( $(this).attr('checked') ) {
+ $('.keep-private input').filter("[name!='" + $(this).attr('name') + "']").removeAttr('checked');
+ }
+ });
},
toggle : function(el){
@@ -129,7 +135,8 @@ inlineEditPost = {
if ( typeof(id) == 'object' )
id = t.getId(id);
- fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password', 'post_format', 'menu_order'];
+ fields = ['post_title', 'post_name', 'post_author', '_status', 'scheduled_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password', 'post_format', 'menu_order'];
+
if ( t.type == 'page' )
fields.push('post_parent', 'page_template');
@@ -198,12 +205,16 @@ inlineEditPost = {
// handle the post status
status = $('._status', rowData).text();
- if ( 'future' != status )
+
+ if ( 'future' == status ) {
+ status = $('.scheduled_status', rowData).text();
+ } else {
$('select[name="_status"] option[value="future"]', editRow).remove();
+ }
- if ( 'private' == status ) {
- $('input[name="keep_private"]', editRow).prop("checked", true);
- $('input.inline-edit-password-input').val('').prop('disabled', true);
+ if ( $('[name=keep_' + status + ']').length > 0) {
+ $('input[name="keep_' + status + '"]', editRow).prop("checked", "checked");
+ $('input.inline-edit-password-input').val('').prop('disabled', 'disabled');
}
// remove the current page and children from the parent dropdown
diff --git wp-admin/js/post.dev.js wp-admin/js/post.dev.js
index 42cd217..ba12f63 100644
--- wp-admin/js/post.dev.js
+++ wp-admin/js/post.dev.js
@@ -382,8 +382,8 @@ jQuery(document).ready( function($) {
}
function updateText() {
- var attemptedDate, originalDate, currentDate, publishOn, postStatus = $('#post_status'),
- optPublish = $('option[value="publish"]', postStatus), aa = $('#aa').val(),
+ var attemptedDate, originalDate, currentDate, publishOn,
+ postStatus = $('#post_status'), optPublish = $('option[value=publish]', postStatus), aa = $('#aa').val(),
mm = $('#mm').val(), jj = $('#jj').val(), hh = $('#hh').val(), mn = $('#mn').val();
attemptedDate = new Date( aa, mm - 1, jj, hh, mn );
@@ -407,6 +407,7 @@ jQuery(document).ready( function($) {
publishOn = postL10n.publishOnPast;
$('#publish').val( postL10n.update );
}
+
if ( originalDate.toUTCString() == attemptedDate.toUTCString() ) { //hack
$('#timestamp').html(stamp);
} else {
@@ -421,13 +422,16 @@ jQuery(document).ready( function($) {
}
if ( $('input:radio:checked', '#post-visibility-select').val() == 'private' ) {
+
$('#publish').val( postL10n.update );
if ( optPublish.length == 0 ) {
postStatus.append('
');
} else {
optPublish.html( postL10n.privatelyPublished );
}
+
$('option[value="publish"]', postStatus).prop('selected', true);
+
$('.edit-post-status', '#misc-publishing-actions').hide();
} else {
if ( $('#original_post_status').val() == 'future' || $('#original_post_status').val() == 'draft' ) {
@@ -441,17 +445,7 @@ jQuery(document).ready( function($) {
if ( postStatus.is(':hidden') )
$('.edit-post-status', '#misc-publishing-actions').show();
}
- $('#post-status-display').html($('option:selected', postStatus).text());
- if ( $('option:selected', postStatus).val() == 'private' || $('option:selected', postStatus).val() == 'publish' ) {
- $('#save-post').hide();
- } else {
- $('#save-post').show();
- if ( $('option:selected', postStatus).val() == 'pending' ) {
- $('#save-post').show().val( postL10n.savePending );
- } else {
- $('#save-post').show().val( postL10n.saveDraft );
- }
- }
+
return true;
}
@@ -463,7 +457,7 @@ jQuery(document).ready( function($) {
}
return false;
});
-
+
$('.cancel-post-visibility', '#post-visibility-select').click(function () {
$('#post-visibility-select').slideUp('fast');
$('#visibility-radio-' + $('#hidden-post-visibility').val()).prop('checked', true);
@@ -471,16 +465,15 @@ jQuery(document).ready( function($) {
$('#sticky').prop('checked', $('#hidden-post-sticky').prop('checked'));
$('#post-visibility-display').html(visibility);
$('.edit-visibility', '#visibility').show();
- updateText();
return false;
});
-
+
$('.save-post-visibility', '#post-visibility-select').click(function () { // crazyhorse - multiple ok cancels
var pvSelect = $('#post-visibility-select');
pvSelect.slideUp('fast');
$('.edit-visibility', '#visibility').show();
- updateText();
+
if ( $('input:radio:checked', pvSelect).val() != 'public' ) {
$('#sticky').prop('checked', false);
@@ -491,11 +484,11 @@ jQuery(document).ready( function($) {
} else {
sticky = '';
}
-
+
$('#post-visibility-display').html( postL10n[$('input:radio:checked', pvSelect).val() + sticky] );
return false;
});
-
+
$('input:radio', '#post-visibility-select').change(function() {
updateVisibility();
});
diff --git wp-admin/post.php wp-admin/post.php
index 035a185..85f6924 100644
--- wp-admin/post.php
+++ wp-admin/post.php
@@ -51,7 +51,11 @@ function redirect_post($post_id = '') {
$message = 9;
break;
default:
- $message = 6;
+ $status_obj = get_post_status_object( $status );
+ if ( ! empty($status_obj->moderation) )
+ $message = 11;
+ else
+ $message = 6;
}
} else {
$message = 'draft' == $status ? 10 : 1;
diff --git wp-comments-post.php wp-comments-post.php
index 194e00f..a71686b 100644
--- wp-comments-post.php
+++ wp-comments-post.php
@@ -37,7 +37,7 @@ if ( !comments_open($comment_post_ID) ) {
} 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) ) {
diff --git wp-includes/default-widgets.php wp-includes/default-widgets.php
index e4856da..85e4b2a 100644
--- wp-includes/default-widgets.php
+++ wp-includes/default-widgets.php
@@ -562,6 +562,9 @@ class WP_Widget_Recent_Posts extends WP_Widget {
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()) :
?>
diff --git wp-includes/general-template.php wp-includes/general-template.php
index 1972696..297ec99 100644
--- wp-includes/general-template.php
+++ wp-includes/general-template.php
@@ -915,8 +915,11 @@ function wp_get_archives($args = '') {
}
//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 = '';
diff --git wp-includes/link-template.php wp-includes/link-template.php
index ae8a9f1..17c59dd 100644
--- wp-includes/link-template.php
+++ wp-includes/link-template.php
@@ -114,7 +114,7 @@ function get_permalink($id = 0, $leavename = false) {
$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 @@ function get_post_permalink( $id = 0, $leavename = false, $sample = false ) {
$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 @@ function _get_page_link( $id = false, $leavename = false, $sample = false ) {
$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);
}
diff --git wp-includes/load.php wp-includes/load.php
index 94e6339..9d51e86 100644
--- wp-includes/load.php
+++ wp-includes/load.php
@@ -491,7 +491,7 @@ function wp_get_active_and_valid_plugins() {
$network_plugins = is_multisite() ? wp_get_active_network_plugins() : false;
- foreach ( $active_plugins as $plugin ) {
+ foreach ( $active_plugins as $plugin ) {
if ( ! validate_file( $plugin ) // $plugin must validate as file
&& '.php' == substr( $plugin, -4 ) // $plugin must end with '.php'
&& file_exists( WP_PLUGIN_DIR . '/' . $plugin ) // $plugin must exist
@@ -499,7 +499,7 @@ function wp_get_active_and_valid_plugins() {
&& ( ! $network_plugins || ! in_array( WP_PLUGIN_DIR . '/' . $plugin, $network_plugins ) )
)
$plugins[] = WP_PLUGIN_DIR . '/' . $plugin;
- }
+ }
return $plugins;
}
diff --git wp-includes/nav-menu.php wp-includes/nav-menu.php
index 361a8de..2cddd01 100644
--- wp-includes/nav-menu.php
+++ wp-includes/nav-menu.php
@@ -482,8 +482,11 @@ function wp_get_nav_menu_items( $menu, $args = array() ) {
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 )
diff --git wp-includes/post-template.php wp-includes/post-template.php
index 5a414ea..716790f 100644
--- wp-includes/post-template.php
+++ wp-includes/post-template.php
@@ -107,12 +107,22 @@ function get_the_title( $id = 0 ) {
$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 );
@@ -697,7 +707,7 @@ function _wp_link_page( $i ) {
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');
diff --git wp-includes/post.php wp-includes/post.php
index dee484e..392cbec 100644
--- wp-includes/post.php
+++ wp-includes/post.php
@@ -101,56 +101,82 @@ function create_initial_post_types() {
) );
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. */
+ 'a' => 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,
@@ -671,13 +697,20 @@ 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' => 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;
@@ -687,6 +720,9 @@ function register_post_status($post_status, $args = array()) {
if ( null === $args->private )
$args->private = false;
+ if ( null === $args->moderation )
+ $args->moderation = false;
+
if ( null === $args->protected )
$args->protected = false;
@@ -708,17 +744,69 @@ function register_post_status($post_status, $args = array()) {
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 ( 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 ( false === $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;
}
+ /**
+ * 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;
+}
+
/**
* Retrieve a post status object by name
*
@@ -759,10 +847,57 @@ function get_post_status_object( $post_status ) {
*/
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;
}
/**
@@ -966,7 +1101,7 @@ function register_post_type( $post_type, $args = array() ) {
'_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,
'delete_with_user' => null,
@@ -1088,6 +1223,10 @@ function register_post_type( $post_type, $args = array() ) {
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 );
@@ -1862,13 +2001,17 @@ function wp_count_posts( $type = 'post', $perm = '' ) {
$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;
@@ -1876,7 +2019,7 @@ function wp_count_posts( $type = 'post', $perm = '' ) {
$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 )
@@ -2351,13 +2494,16 @@ function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) {
$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
);
@@ -2524,13 +2670,16 @@ function wp_insert_post($postarr, $wp_error = false) {
}
// 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 = '';
@@ -2548,7 +2697,7 @@ function wp_insert_post($postarr, $wp_error = false) {
$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';
@@ -2562,7 +2711,9 @@ function wp_insert_post($postarr, $wp_error = false) {
$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';
@@ -2572,6 +2723,11 @@ function wp_insert_post($postarr, $wp_error = false) {
$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';
@@ -2602,7 +2758,7 @@ function wp_insert_post($postarr, $wp_error = false) {
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);
@@ -2643,7 +2799,10 @@ function wp_insert_post($postarr, $wp_error = false) {
$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 );
}
@@ -2733,10 +2892,11 @@ function wp_update_post($postarr = array()) {
$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.
@@ -2774,7 +2934,13 @@ function wp_publish_post($post_id) {
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';
@@ -2832,7 +2998,9 @@ function check_and_publish_future_post($post_id) {
* @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;
@@ -3370,7 +3538,7 @@ function get_page_uri($page) {
* @param mixed $args Optional. Array or string of options that overrides defaults.
* @return array List of pages matching defaults or $args
*/
-function &get_pages($args = '') {
+function &get_pages($args = '') {
global $wpdb;
$defaults = array(
@@ -3387,17 +3555,19 @@ function &get_pages($args = '') {
extract( $r, EXTR_SKIP );
$number = (int) $number;
$offset = (int) $offset;
-
+ $false = false;
+
// Make sure the post type is hierarchical
$hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
if ( !in_array( $post_type, $hierarchical_post_types ) )
- return false;
+ return $false;
// 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() ) )
- return false;
+
+ if ( array_diff( $post_status, get_post_stati( array( 'object_type' => $post_type ) ) ) )
+ return $false;
$cache = array();
$key = md5( serialize( compact(array_keys($defaults)) ) );
diff --git wp-includes/query.php wp-includes/query.php
index 5f6ccdd..35d3785 100644
--- wp-includes/query.php
+++ wp-includes/query.php
@@ -2403,16 +2403,18 @@ class WP_Query {
$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'] ) ) {
@@ -2422,24 +2424,36 @@ class WP_Query {
$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) ) {
@@ -2451,24 +2465,30 @@ class WP_Query {
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;
@@ -2477,16 +2497,25 @@ class WP_Query {
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( '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 .= ')';
@@ -2527,8 +2556,11 @@ class WP_Query {
$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 = '';
}
@@ -2742,11 +2774,13 @@ class WP_Query {
$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++;
}
diff --git wp-includes/script-loader.php wp-includes/script-loader.php
index dab5868..c54ccd9 100644
--- wp-includes/script-loader.php
+++ wp-includes/script-loader.php
@@ -339,7 +339,7 @@ function wp_default_scripts( &$scripts ) {
$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:'),
@@ -359,9 +359,27 @@ function wp_default_scripts( &$scripts ) {
'privatelyPublished' => __('Privately Published'),
'published' => __('Published'),
'comma' => _x( ',', 'tag delimiter' ),
- ) );
+ );
+
+ if ( function_exists( 'get_post_stati' ) ) {
+ $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 );
diff --git wp-includes/taxonomy.php wp-includes/taxonomy.php
index 8ea976f..25bd211 100644
--- wp-includes/taxonomy.php
+++ wp-includes/taxonomy.php
@@ -132,6 +132,9 @@ function get_taxonomies( $args = array(), $output = 'names', $operator = 'and' )
$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);
}
@@ -2840,7 +2843,11 @@ function _pad_term_counts(&$terms, $taxonomy) {
// 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;
@@ -2901,15 +2908,19 @@ function _update_post_term_count( $terms, $taxonomy ) {
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 ) );