Skip to content

Commit 29ccf1e

Browse files
committed
New pending menu item behavior. props filosofo, see #13579.
git-svn-id: https://develop.svn.wordpress.org/trunk@15008 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 7ed6bc6 commit 29ccf1e

4 files changed

Lines changed: 88 additions & 33 deletions

File tree

wp-admin/admin-ajax.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -816,14 +816,9 @@ function _wp_ajax_add_hierarchical_term() {
816816

817817
require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
818818

819-
$menu_id = (int) $_POST['menu'];
820-
if ( isset( $_POST['menu-item'] ) ) {
821-
$item_ids = wp_save_nav_menu_items( $menu_id, $_POST['menu-item'] );
822-
if ( is_wp_error( $item_ids ) )
823-
die('-1');
824-
} else {
825-
$item_ids = array();
826-
}
819+
$item_ids = wp_save_nav_menu_items( 0, $_POST['menu-item'] );
820+
if ( is_wp_error( $item_ids ) )
821+
die('-1');
827822

828823
foreach ( (array) $item_ids as $menu_item_id ) {
829824
$menu_obj = get_post( $menu_item_id );

wp-admin/includes/nav-menu.php

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,26 @@ function start_el(&$output, $item, $depth, $args) {
5858
$original_object = get_post( $item->object_id );
5959
$original_title = $original_object->post_title;
6060
}
61+
62+
$classes = array(
63+
'menu-item menu-item-depth-' . $depth,
64+
'menu-item-' . esc_attr( $item->object ),
65+
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'),
66+
);
67+
68+
$title = $item->title;
69+
70+
if ( isset( $item->post_status ) && 'draft' == $item->post_status ) {
71+
$classes[] = 'pending';
72+
/* translators: %s: title of menu item in draft status */
73+
$title = sprintf( __('%s (Pending)'), $item->title );
74+
}
75+
6176
?>
62-
<li id="menu-item-<?php echo $item_id; ?>" class="menu-item menu-item-depth-<?php echo $depth; ?> menu-item-<?php echo esc_attr( $item->object ); ?> menu-item-edit-<?php echo ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'; ?>">
77+
<li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode(' ', $classes ); ?>">
6378
<dl class="menu-item-bar">
6479
<dt class="menu-item-handle">
65-
<span class="item-title"><?php echo esc_html( $item->title ); ?></span>
80+
<span class="item-title"><?php echo esc_html( $title ); ?></span>
6681
<span class="item-controls">
6782
<span class="item-type"><?php echo esc_html( $item->type_label ); ?></span>
6883
<span class="item-order">
@@ -865,15 +880,15 @@ function wp_nav_menu_item_taxonomy_meta_box( $object, $taxonomy ) {
865880
*
866881
* @since 3.0.0
867882
*
868-
* @param int $menu_id The menu ID for which to save this item.
883+
* @param int $menu_id The menu ID for which to save this item. $menu_id of 0 makes a draft, orphaned menu item.
869884
* @param array $menu_data The unsanitized posted menu item data.
870885
* @return array The database IDs of the items saved
871886
*/
872887
function wp_save_nav_menu_items( $menu_id = 0, $menu_data = array() ) {
873888
$menu_id = (int) $menu_id;
874889
$items_saved = array();
875890

876-
if ( is_nav_menu( $menu_id ) ) {
891+
if ( 0 == $menu_id || is_nav_menu( $menu_id ) ) {
877892

878893
// Loop through all the menu items' POST values
879894
foreach( (array) $menu_data as $_possible_db_id => $_item_object_data ) {
@@ -882,7 +897,7 @@ function wp_save_nav_menu_items( $menu_id = 0, $menu_data = array() ) {
882897
(
883898
! isset( $_item_object_data['menu-item-type'] ) || // and item type either isn't set
884899
in_array( $_item_object_data['menu-item-url'], array( 'http://', '' ) ) || // or URL is the default
885-
'custom' != $_item_object_data['menu-item-type'] || // or it's not a custom menu item
900+
! ( 'custom' == $_item_object_data['menu-item-type'] && ! isset( $_item_object_data['menu-item-db-id'] ) ) || // or it's not a custom menu item (but not the custom home page)
886901
! empty( $_item_object_data['menu-item-db-id'] ) // or it *is* a custom menu item that already exists
887902
)
888903
) {
@@ -998,6 +1013,15 @@ function wp_get_nav_menu_to_edit( $menu_id = 0 ) {
9981013
else
9991014
return new WP_Error( 'menu_walker_not_exist', sprintf( __('The Walker class named <strong>%s</strong> does not exist.'), $walker_class_name ) );
10001015

1016+
$some_pending_menu_items = false;
1017+
foreach( (array) $menu_items as $menu_item ) {
1018+
if ( isset( $menu_item->post_status ) && 'draft' == $menu_item->post_status )
1019+
$some_pending_menu_items = true;
1020+
}
1021+
1022+
if ( $some_pending_menu_items )
1023+
$result .= '<div class="updated inline"><p>' . __('Click <em>Save Menu</em> to make pending menu items public.') . '</p></div>';
1024+
10011025
$result .= walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $menu_items), 0, (object) array('walker' => $walker ) );
10021026
return $result;
10031027
} elseif ( is_wp_error( $menu ) ) {
@@ -1026,4 +1050,24 @@ function wp_nav_menu_manage_columns() {
10261050
);
10271051
}
10281052

1053+
/**
1054+
* Deletes orphaned draft menu items
1055+
*
1056+
* @access private
1057+
* @since 3.0.0
1058+
*
1059+
*/
1060+
function _wp_delete_orphaned_draft_menu_items() {
1061+
global $wpdb;
1062+
$delete_timestamp = time() - (60*60*24*EMPTY_TRASH_DAYS);
1063+
1064+
// delete orphaned draft menu items
1065+
$menu_items_to_delete = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS m ON p.ID = m.post_id WHERE post_type = 'nav_menu_item' AND post_status = 'draft' AND meta_key = '_menu_item_orphaned' AND meta_value < '%d'", $delete_timestamp ) );
1066+
1067+
foreach( (array) $menu_items_to_delete as $menu_item_id )
1068+
wp_delete_post( $menu_item_id, true );
1069+
}
1070+
1071+
add_action('admin_head-nav-menus.php', '_wp_delete_orphaned_draft_menu_items');
1072+
10291073
?>

wp-admin/nav-menus.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -543,23 +543,23 @@
543543
<br class="clear" />
544544
<div class="publishing-action">
545545
<input class="button-primary menu-save" name="save_menu" type="submit" value="<?php empty($nav_menu_selected_id) ? esc_attr_e('Create Menu') : esc_attr_e('Save Menu'); ?>" />
546-
</div><!--END .publishing-action-->
546+
</div><!-- END .publishing-action -->
547547

548548
<?php if ( ! empty( $nav_menu_selected_id ) ) : ?>
549549
<div class="delete-action">
550550
<a class="submitdelete deletion menu-delete" href="<?php echo esc_url( wp_nonce_url( admin_url('nav-menus.php?action=delete&amp;menu=' . $nav_menu_selected_id), 'delete-nav_menu-' . $nav_menu_selected_id ) ); ?>"><?php _e('Delete Menu'); ?></a>
551-
</div><!--END .delete-action-->
551+
</div><!-- END .delete-action -->
552552
<?php endif; ?>
553-
</div><!--END .major-publishing-actions-->
554-
</div><!--END #submitpost .submitbox-->
553+
</div><!-- END .major-publishing-actions -->
554+
</div><!-- END #submitpost .submitbox -->
555555
<?php
556556
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
557557
wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
558558
wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' );
559559
?>
560560
<input type="hidden" name="action" value="update" />
561561
<input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
562-
</div><!--END #nav-menu-header-->
562+
</div><!-- END #nav-menu-header -->
563563
<div id="post-body">
564564
<div id="post-body-content">
565565
<?php if ( is_nav_menu( $nav_menu_selected_id ) ) : ?>
@@ -580,13 +580,13 @@
580580
echo '<p>' . sprintf( __('For more information on this feature, see the <a href="%s">Custom Menus</a> article in the Codex.'), _x('http://codex.wordpress.org/Custom_Menus', 'Custom Menus codex page') ) . '</p>';
581581
echo '</div>';
582582
endif; ?>
583-
</div><!-- /#post-body-content-->
584-
</div><!--- /#post-body -->
585-
</form><!--/#update-nav-menu-->
583+
</div><!-- /#post-body-content -->
584+
</div><!-- /#post-body -->
585+
</form><!-- /#update-nav-menu -->
586586
</div><!-- /.menu-edit -->
587587
</div><!-- /#menu-management -->
588588
</div><!-- /#menu-management-liquid -->
589-
</div><!-- /#nav-menus-frame-->
589+
</div><!-- /#nav-menus-frame -->
590590
</div><!-- /.wrap-->
591591

592592

wp-includes/nav-menu.php

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
247247
*
248248
* @since 3.0.0
249249
*
250-
* @param int $menu_id The ID of the menu. Required.
250+
* @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan.
251251
* @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
252252
* @param array $menu_item_data The menu item's data.
253253
* @return int The menu item's database ID or WP_Error object on failure.
@@ -257,17 +257,15 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item
257257
$menu_item_db_id = (int) $menu_item_db_id;
258258

259259
// make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
260-
if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) {
260+
if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) )
261261
return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
262-
}
263262

264263
$menu = wp_get_nav_menu_object( $menu_id );
265264

266-
if ( ! $menu || is_wp_error( $menu ) ) {
265+
if ( ( ! $menu && 0 !== $menu_id ) || is_wp_error( $menu ) )
267266
return $menu;
268-
}
269267

270-
$menu_items = (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
268+
$menu_items = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );
271269

272270
$count = count( $menu_items );
273271

@@ -289,8 +287,10 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item
289287
);
290288

291289
$args = wp_parse_args( $menu_item_data, $defaults );
292-
293-
if ( 0 == (int) $args['menu-item-position'] ) {
290+
291+
if ( 0 == $menu_id ) {
292+
$args['menu-item-position'] = 1;
293+
} elseif ( 0 == (int) $args['menu-item-position'] ) {
294294
$last_item = array_pop( $menu_items );
295295
$args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : $count;
296296
}
@@ -339,9 +339,11 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item
339339
'post_parent' => $original_parent,
340340
'post_title' => $args['menu-item-title'],
341341
'post_type' => 'nav_menu_item',
342-
'tax_input' => array( 'nav_menu' => array( intval( $menu->term_id ) ) ),
343342
);
344343

344+
if ( 0 != $menu_id )
345+
$post['tax_input'] = array( 'nav_menu' => array( intval( $menu->term_id ) ) );
346+
345347
// New menu item. Default is draft status
346348
if ( 0 == $menu_item_db_id ) {
347349
$post['ID'] = 0;
@@ -374,9 +376,12 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item
374376
$args['menu-item-xfn'] = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-xfn'] ) ) );
375377
update_post_meta( $menu_item_db_id, '_menu_item_classes', $args['menu-item-classes'] );
376378
update_post_meta( $menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn'] );
377-
378-
// @todo: only save custom link urls.
379379
update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) );
380+
381+
if ( 0 == $menu_id )
382+
update_post_meta( $menu_item_db_id, '_menu_item_orphaned', time() );
383+
else
384+
delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' );
380385

381386
do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args );
382387
}
@@ -740,6 +745,17 @@ function _wp_delete_tax_menu_item( $object_id = 0 ) {
740745
}
741746
}
742747

748+
/**
749+
* Automatically add newly published page objects to menus with that as an option.
750+
*
751+
* @since 3.0.0
752+
* @access private
753+
*
754+
* @param string $new_status The new status of the post object.
755+
* @param string $old_status The old status of the post object.
756+
* @param object $post The post object being transitioned from one status to another.
757+
* @return void
758+
*/
743759
function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) {
744760
if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type )
745761
return;

0 commit comments

Comments
 (0)