| 1 | Index: wp-includes/nav-menu.php |
|---|
| 2 | =================================================================== |
|---|
| 3 | --- wp-includes/nav-menu.php (revision 15001) |
|---|
| 4 | +++ wp-includes/nav-menu.php (working copy) |
|---|
| 5 | @@ -247,7 +247,7 @@ |
|---|
| 6 | * |
|---|
| 7 | * @since 3.0.0 |
|---|
| 8 | * |
|---|
| 9 | - * @param int $menu_id The ID of the menu. Required. |
|---|
| 10 | + * @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan. |
|---|
| 11 | * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item. |
|---|
| 12 | * @param array $menu_item_data The menu item's data. |
|---|
| 13 | * @return int The menu item's database ID or WP_Error object on failure. |
|---|
| 14 | @@ -257,17 +257,15 @@ |
|---|
| 15 | $menu_item_db_id = (int) $menu_item_db_id; |
|---|
| 16 | |
|---|
| 17 | // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects |
|---|
| 18 | - if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) { |
|---|
| 19 | + if ( ! empty( $menu_item_db_id ) && ! is_nav_menu_item( $menu_item_db_id ) ) |
|---|
| 20 | return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.')); |
|---|
| 21 | - } |
|---|
| 22 | |
|---|
| 23 | $menu = wp_get_nav_menu_object( $menu_id ); |
|---|
| 24 | |
|---|
| 25 | - if ( ! $menu || is_wp_error( $menu ) ) { |
|---|
| 26 | + if ( ( ! $menu && 0 !== $menu_id ) || is_wp_error( $menu ) ) |
|---|
| 27 | return $menu; |
|---|
| 28 | - } |
|---|
| 29 | |
|---|
| 30 | - $menu_items = (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); |
|---|
| 31 | + $menu_items = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); |
|---|
| 32 | |
|---|
| 33 | $count = count( $menu_items ); |
|---|
| 34 | |
|---|
| 35 | @@ -289,8 +287,10 @@ |
|---|
| 36 | ); |
|---|
| 37 | |
|---|
| 38 | $args = wp_parse_args( $menu_item_data, $defaults ); |
|---|
| 39 | - |
|---|
| 40 | - if ( 0 == (int) $args['menu-item-position'] ) { |
|---|
| 41 | + |
|---|
| 42 | + if ( 0 == $menu_id ) { |
|---|
| 43 | + $args['menu-item-position'] = 1; |
|---|
| 44 | + } elseif ( 0 == (int) $args['menu-item-position'] ) { |
|---|
| 45 | $last_item = array_pop( $menu_items ); |
|---|
| 46 | $args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : $count; |
|---|
| 47 | } |
|---|
| 48 | @@ -339,9 +339,11 @@ |
|---|
| 49 | 'post_parent' => $original_parent, |
|---|
| 50 | 'post_title' => $args['menu-item-title'], |
|---|
| 51 | 'post_type' => 'nav_menu_item', |
|---|
| 52 | - 'tax_input' => array( 'nav_menu' => array( intval( $menu->term_id ) ) ), |
|---|
| 53 | ); |
|---|
| 54 | |
|---|
| 55 | + if ( 0 != $menu_id ) |
|---|
| 56 | + $post['tax_input'] = array( 'nav_menu' => array( intval( $menu->term_id ) ) ); |
|---|
| 57 | + |
|---|
| 58 | // New menu item. Default is draft status |
|---|
| 59 | if ( 0 == $menu_item_db_id ) { |
|---|
| 60 | $post['ID'] = 0; |
|---|
| 61 | @@ -374,9 +376,12 @@ |
|---|
| 62 | $args['menu-item-xfn'] = implode( ' ', array_map( 'sanitize_html_class', explode( ' ', $args['menu-item-xfn'] ) ) ); |
|---|
| 63 | update_post_meta( $menu_item_db_id, '_menu_item_classes', $args['menu-item-classes'] ); |
|---|
| 64 | update_post_meta( $menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn'] ); |
|---|
| 65 | - |
|---|
| 66 | - // @todo: only save custom link urls. |
|---|
| 67 | update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) ); |
|---|
| 68 | + |
|---|
| 69 | + if ( 0 == $menu_id ) |
|---|
| 70 | + update_post_meta( $menu_item_db_id, '_menu_item_orphaned', time() ); |
|---|
| 71 | + else |
|---|
| 72 | + delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' ); |
|---|
| 73 | |
|---|
| 74 | do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args ); |
|---|
| 75 | } |
|---|
| 76 | @@ -740,6 +745,17 @@ |
|---|
| 77 | } |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | +/** |
|---|
| 81 | + * Automatically add newly published page objects to menus with that as an option. |
|---|
| 82 | + * |
|---|
| 83 | + * @since 3.0.0 |
|---|
| 84 | + * @access private |
|---|
| 85 | + * |
|---|
| 86 | + * @param string $new_status The new status of the post object. |
|---|
| 87 | + * @param string $old_status The old status of the post object. |
|---|
| 88 | + * @param object $post The post object being transitioned from one status to another. |
|---|
| 89 | + * @return void |
|---|
| 90 | + */ |
|---|
| 91 | function _wp_auto_add_pages_to_menu( $new_status, $old_status, $post ) { |
|---|
| 92 | if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type ) |
|---|
| 93 | return; |
|---|
| 94 | Index: wp-admin/admin-ajax.php |
|---|
| 95 | =================================================================== |
|---|
| 96 | --- wp-admin/admin-ajax.php (revision 15001) |
|---|
| 97 | +++ wp-admin/admin-ajax.php (working copy) |
|---|
| 98 | @@ -816,14 +816,9 @@ |
|---|
| 99 | |
|---|
| 100 | require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; |
|---|
| 101 | |
|---|
| 102 | - $menu_id = (int) $_POST['menu']; |
|---|
| 103 | - if ( isset( $_POST['menu-item'] ) ) { |
|---|
| 104 | - $item_ids = wp_save_nav_menu_items( $menu_id, $_POST['menu-item'] ); |
|---|
| 105 | - if ( is_wp_error( $item_ids ) ) |
|---|
| 106 | - die('-1'); |
|---|
| 107 | - } else { |
|---|
| 108 | - $item_ids = array(); |
|---|
| 109 | - } |
|---|
| 110 | + $item_ids = wp_save_nav_menu_items( 0, $_POST['menu-item'] ); |
|---|
| 111 | + if ( is_wp_error( $item_ids ) ) |
|---|
| 112 | + die('-1'); |
|---|
| 113 | |
|---|
| 114 | foreach ( (array) $item_ids as $menu_item_id ) { |
|---|
| 115 | $menu_obj = get_post( $menu_item_id ); |
|---|
| 116 | Index: wp-admin/includes/nav-menu.php |
|---|
| 117 | =================================================================== |
|---|
| 118 | --- wp-admin/includes/nav-menu.php (revision 15001) |
|---|
| 119 | +++ wp-admin/includes/nav-menu.php (working copy) |
|---|
| 120 | @@ -58,11 +58,26 @@ |
|---|
| 121 | $original_object = get_post( $item->object_id ); |
|---|
| 122 | $original_title = $original_object->post_title; |
|---|
| 123 | } |
|---|
| 124 | + |
|---|
| 125 | + $classes = array( |
|---|
| 126 | + 'menu-item menu-item-depth-' . $depth, |
|---|
| 127 | + 'menu-item-' . esc_attr( $item->object ), |
|---|
| 128 | + 'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'), |
|---|
| 129 | + ); |
|---|
| 130 | + |
|---|
| 131 | + $title = $item->title; |
|---|
| 132 | + |
|---|
| 133 | + if ( isset( $item->post_status ) && 'draft' == $item->post_status ) { |
|---|
| 134 | + $classes[] = 'pending'; |
|---|
| 135 | + /* translators: %s: title of menu item in draft status */ |
|---|
| 136 | + $title = sprintf( __('%s (Pending)'), $item->title ); |
|---|
| 137 | + } |
|---|
| 138 | + |
|---|
| 139 | ?> |
|---|
| 140 | - <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'; ?>"> |
|---|
| 141 | + <li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode(' ', $classes ); ?>"> |
|---|
| 142 | <dl class="menu-item-bar"> |
|---|
| 143 | <dt class="menu-item-handle"> |
|---|
| 144 | - <span class="item-title"><?php echo esc_html( $item->title ); ?></span> |
|---|
| 145 | + <span class="item-title"><?php echo esc_html( $title ); ?></span> |
|---|
| 146 | <span class="item-controls"> |
|---|
| 147 | <span class="item-type"><?php echo esc_html( $item->type_label ); ?></span> |
|---|
| 148 | <span class="item-order"> |
|---|
| 149 | @@ -871,7 +886,7 @@ |
|---|
| 150 | * |
|---|
| 151 | * @since 3.0.0 |
|---|
| 152 | * |
|---|
| 153 | - * @param int $menu_id The menu ID for which to save this item. |
|---|
| 154 | + * @param int $menu_id The menu ID for which to save this item. $menu_id of 0 makes a draft, orphaned menu item. |
|---|
| 155 | * @param array $menu_data The unsanitized posted menu item data. |
|---|
| 156 | * @return array The database IDs of the items saved |
|---|
| 157 | */ |
|---|
| 158 | @@ -879,7 +894,7 @@ |
|---|
| 159 | $menu_id = (int) $menu_id; |
|---|
| 160 | $items_saved = array(); |
|---|
| 161 | |
|---|
| 162 | - if ( is_nav_menu( $menu_id ) ) { |
|---|
| 163 | + if ( 0 == $menu_id || is_nav_menu( $menu_id ) ) { |
|---|
| 164 | |
|---|
| 165 | // Loop through all the menu items' POST values |
|---|
| 166 | foreach( (array) $menu_data as $_possible_db_id => $_item_object_data ) { |
|---|
| 167 | @@ -888,7 +903,7 @@ |
|---|
| 168 | ( |
|---|
| 169 | ! isset( $_item_object_data['menu-item-type'] ) || // and item type either isn't set |
|---|
| 170 | in_array( $_item_object_data['menu-item-url'], array( 'http://', '' ) ) || // or URL is the default |
|---|
| 171 | - 'custom' != $_item_object_data['menu-item-type'] || // or it's not a custom menu item |
|---|
| 172 | + ! ( '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) |
|---|
| 173 | ! empty( $_item_object_data['menu-item-db-id'] ) // or it *is* a custom menu item that already exists |
|---|
| 174 | ) |
|---|
| 175 | ) { |
|---|
| 176 | @@ -1004,6 +1019,15 @@ |
|---|
| 177 | else |
|---|
| 178 | return new WP_Error( 'menu_walker_not_exist', sprintf( __('The Walker class named <strong>%s</strong> does not exist.'), $walker_class_name ) ); |
|---|
| 179 | |
|---|
| 180 | + $some_pending_menu_items = false; |
|---|
| 181 | + foreach( (array) $menu_items as $menu_item ) { |
|---|
| 182 | + if ( isset( $menu_item->post_status ) && 'draft' == $menu_item->post_status ) |
|---|
| 183 | + $some_pending_menu_items = true; |
|---|
| 184 | + } |
|---|
| 185 | + |
|---|
| 186 | + if ( $some_pending_menu_items ) |
|---|
| 187 | + $result .= '<div class="updated">' . __('Click <em>Save Menu</em> to make pending menu items public.') . '</div>'; |
|---|
| 188 | + |
|---|
| 189 | $result .= walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $menu_items), 0, (object) array('walker' => $walker ) ); |
|---|
| 190 | return $result; |
|---|
| 191 | } elseif ( is_wp_error( $menu ) ) { |
|---|
| 192 | @@ -1032,4 +1056,24 @@ |
|---|
| 193 | ); |
|---|
| 194 | } |
|---|
| 195 | |
|---|
| 196 | +/** |
|---|
| 197 | + * Deletes orphaned draft menu items |
|---|
| 198 | + * |
|---|
| 199 | + * @access private |
|---|
| 200 | + * @since 3.0.0 |
|---|
| 201 | + * |
|---|
| 202 | + */ |
|---|
| 203 | +function _wp_delete_orphaned_draft_menu_items() { |
|---|
| 204 | + global $wpdb; |
|---|
| 205 | + $delete_timestamp = time() - (60*60*24*EMPTY_TRASH_DAYS); |
|---|
| 206 | + |
|---|
| 207 | + // delete orphaned draft menu items |
|---|
| 208 | + $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 ) ); |
|---|
| 209 | + |
|---|
| 210 | + foreach( (array) $menu_items_to_delete as $menu_item_id ) |
|---|
| 211 | + wp_delete_post( $menu_item_id, true ); |
|---|
| 212 | +} |
|---|
| 213 | + |
|---|
| 214 | +add_action('admin_head-nav-menus.php', '_wp_delete_orphaned_draft_menu_items'); |
|---|
| 215 | + |
|---|
| 216 | ?> |
|---|
| 217 | Index: wp-admin/nav-menus.php |
|---|
| 218 | =================================================================== |
|---|
| 219 | --- wp-admin/nav-menus.php (revision 15001) |
|---|
| 220 | +++ wp-admin/nav-menus.php (working copy) |
|---|
| 221 | @@ -543,15 +543,15 @@ |
|---|
| 222 | <br class="clear" /> |
|---|
| 223 | <div class="publishing-action"> |
|---|
| 224 | <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'); ?>" /> |
|---|
| 225 | - </div><!--END .publishing-action--> |
|---|
| 226 | + </div><!-- END .publishing-action --> |
|---|
| 227 | |
|---|
| 228 | <?php if ( ! empty( $nav_menu_selected_id ) ) : ?> |
|---|
| 229 | <div class="delete-action"> |
|---|
| 230 | <a class="submitdelete deletion menu-delete" href="<?php echo esc_url( wp_nonce_url( admin_url('nav-menus.php?action=delete&menu=' . $nav_menu_selected_id), 'delete-nav_menu-' . $nav_menu_selected_id ) ); ?>"><?php _e('Delete Menu'); ?></a> |
|---|
| 231 | - </div><!--END .delete-action--> |
|---|
| 232 | + </div><!-- END .delete-action --> |
|---|
| 233 | <?php endif; ?> |
|---|
| 234 | - </div><!--END .major-publishing-actions--> |
|---|
| 235 | - </div><!--END #submitpost .submitbox--> |
|---|
| 236 | + </div><!-- END .major-publishing-actions --> |
|---|
| 237 | + </div><!-- END #submitpost .submitbox --> |
|---|
| 238 | <?php |
|---|
| 239 | wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); |
|---|
| 240 | wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); |
|---|
| 241 | @@ -559,7 +559,7 @@ |
|---|
| 242 | ?> |
|---|
| 243 | <input type="hidden" name="action" value="update" /> |
|---|
| 244 | <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" /> |
|---|
| 245 | - </div><!--END #nav-menu-header--> |
|---|
| 246 | + </div><!-- END #nav-menu-header --> |
|---|
| 247 | <div id="post-body"> |
|---|
| 248 | <div id="post-body-content"> |
|---|
| 249 | <?php if ( is_nav_menu( $nav_menu_selected_id ) ) : ?> |
|---|
| 250 | @@ -580,13 +580,13 @@ |
|---|
| 251 | 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>'; |
|---|
| 252 | echo '</div>'; |
|---|
| 253 | endif; ?> |
|---|
| 254 | - </div><!-- /#post-body-content--> |
|---|
| 255 | - </div><!--- /#post-body --> |
|---|
| 256 | - </form><!--/#update-nav-menu--> |
|---|
| 257 | + </div><!-- /#post-body-content --> |
|---|
| 258 | + </div><!-- /#post-body --> |
|---|
| 259 | + </form><!-- /#update-nav-menu --> |
|---|
| 260 | </div><!-- /.menu-edit --> |
|---|
| 261 | </div><!-- /#menu-management --> |
|---|
| 262 | </div><!-- /#menu-management-liquid --> |
|---|
| 263 | - </div><!-- /#nav-menus-frame--> |
|---|
| 264 | + </div><!-- /#nav-menus-frame --> |
|---|
| 265 | </div><!-- /.wrap--> |
|---|
| 266 | |
|---|
| 267 | |
|---|