wp_update_nav_menu_item

The timeline below displays how wordpress function wp_update_nav_menu_item has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.3

/**
 * Saves the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly to APIs that expect slashed data.
 *
 * @since 3.0.0
 * @since 5.9.0 Added the `$fire_after_hooks` parameter.
 *
 * @param int   $menu_id          The ID of the menu. If 0, makes the menu item a draft orphan.
 * @param int   $menu_item_db_id  The ID of the menu item. If 0, creates a new menu item.
 * @param array $menu_item_data   The menu item's data.
 * @param bool  $fire_after_hooks Whether to fire the after insert hooks. Default true.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array(), $fire_after_hooks = true)
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '', 'menu-item-post-date' => '', 'menu-item-post-date-gmt' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' === $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' === $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' === $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if (wp_unslash($args['menu-item-title']) === wp_specialchars_decode($original_title)) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' === $args['menu-item-title'] && '' === $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $post_date = wp_resolve_post_date($args['menu-item-post-date'], $args['menu-item-post-date-gmt']);
    if ($post_date) {
        $post['post_date'] = $post_date;
    }
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' === $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post, true, $fire_after_hooks);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    /*
     * Associate the menu item with the menu term.
     * Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
     */
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        $update_terms = wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
        if (is_wp_error($update_terms)) {
            return $update_terms;
        }
    }
    if ('custom' === $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    // Reset invalid `menu_item_parent`.
    if ((int) $args['menu-item-parent-id'] === $menu_item_db_id) {
        $args['menu-item-parent-id'] = 0;
    }
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', (string) (int) $args['menu-item-parent-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object_id', (string) (int) $args['menu-item-object-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', sanitize_url($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' === $args['menu-item-status']) ? 'draft' : 'publish';
        $update_post = wp_update_post($post, true);
        if (is_wp_error($update_post)) {
            return $update_post;
        }
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 6.2

/**
 * Saves the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly to APIs that expect slashed data.
 *
 * @since 3.0.0
 * @since 5.9.0 Added the `$fire_after_hooks` parameter.
 *
 * @param int   $menu_id          The ID of the menu. If 0, makes the menu item a draft orphan.
 * @param int   $menu_item_db_id  The ID of the menu item. If 0, creates a new menu item.
 * @param array $menu_item_data   The menu item's data.
 * @param bool  $fire_after_hooks Whether to fire the after insert hooks. Default true.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array(), $fire_after_hooks = true)
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '', 'menu-item-post-date' => '', 'menu-item-post-date-gmt' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' === $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' === $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' === $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if (wp_unslash($args['menu-item-title']) === wp_specialchars_decode($original_title)) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' === $args['menu-item-title'] && '' === $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $post_date = wp_resolve_post_date($args['menu-item-post-date'], $args['menu-item-post-date-gmt']);
    if ($post_date) {
        $post['post_date'] = $post_date;
    }
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' === $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post, true, $fire_after_hooks);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term.
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        $update_terms = wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
        if (is_wp_error($update_terms)) {
            return $update_terms;
        }
    }
    if ('custom' === $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    // Reset invalid `menu_item_parent`.
    if ((int) $args['menu-item-parent-id'] === $menu_item_db_id) {
        $args['menu-item-parent-id'] = 0;
    }
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', (string) (int) $args['menu-item-parent-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object_id', (string) (int) $args['menu-item-object-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', sanitize_url($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' === $args['menu-item-status']) ? 'draft' : 'publish';
        $update_post = wp_update_post($post, true);
        if (is_wp_error($update_post)) {
            return $update_post;
        }
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 6.1

/**
 * Saves the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly to APIs that expect slashed data.
 *
 * @since 3.0.0
 * @since 5.9.0 Added the `$fire_after_hooks` parameter.
 *
 * @param int   $menu_id          The ID of the menu. If 0, makes the menu item a draft orphan.
 * @param int   $menu_item_db_id  The ID of the menu item. If 0, creates a new menu item.
 * @param array $menu_item_data   The menu item's data.
 * @param bool  $fire_after_hooks Whether to fire the after insert hooks. Default true.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array(), $fire_after_hooks = true)
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '', 'menu-item-post-date' => '', 'menu-item-post-date-gmt' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' === $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' === $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' === $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if (wp_unslash($args['menu-item-title']) === wp_specialchars_decode($original_title)) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' === $args['menu-item-title'] && '' === $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $post_date = wp_resolve_post_date($args['menu-item-post-date'], $args['menu-item-post-date-gmt']);
    if ($post_date) {
        $post['post_date'] = $post_date;
    }
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' === $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post, true, $fire_after_hooks);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term.
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        $update_terms = wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
        if (is_wp_error($update_terms)) {
            return $update_terms;
        }
    }
    if ('custom' === $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', (string) (int) $args['menu-item-parent-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object_id', (string) (int) $args['menu-item-object-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', sanitize_url($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' === $args['menu-item-status']) ? 'draft' : 'publish';
        $update_post = wp_update_post($post, true);
        if (is_wp_error($update_post)) {
            return $update_post;
        }
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 5.9

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly to APIs that expect slashed data.
 *
 * @since 3.0.0
 * @since 5.9.0 Added the `$fire_after_hooks` parameter.
 *
 * @param int   $menu_id          The ID of the menu. If 0, makes the menu item a draft orphan.
 * @param int   $menu_item_db_id  The ID of the menu item. If 0, creates a new menu item.
 * @param array $menu_item_data   The menu item's data.
 * @param bool  $fire_after_hooks Whether to fire the after insert hooks. Default true.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array(), $fire_after_hooks = true)
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '', 'menu-item-post-date' => '', 'menu-item-post-date-gmt' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' === $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' === $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' === $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if (wp_unslash($args['menu-item-title']) === wp_specialchars_decode($original_title)) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' === $args['menu-item-title'] && '' === $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $post_date = wp_resolve_post_date($args['menu-item-post-date'], $args['menu-item-post-date-gmt']);
    if ($post_date) {
        $post['post_date'] = $post_date;
    }
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' === $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post, true, $fire_after_hooks);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term.
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        $update_terms = wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
        if (is_wp_error($update_terms)) {
            return $update_terms;
        }
    }
    if ('custom' === $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', (string) (int) $args['menu-item-parent-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object_id', (string) (int) $args['menu-item-object-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' === $args['menu-item-status']) ? 'draft' : 'publish';
        $update_post = wp_update_post($post, true);
        if (is_wp_error($update_post)) {
            return $update_post;
        }
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 5.7

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '', 'menu-item-post-date' => '', 'menu-item-post-date-gmt' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' === $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' === $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' === $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if (wp_unslash($args['menu-item-title']) === wp_specialchars_decode($original_title)) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' === $args['menu-item-title'] && '' === $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $post_date = wp_resolve_post_date($args['menu-item-post-date'], $args['menu-item-post-date-gmt']);
    if ($post_date) {
        $post['post_date'] = $post_date;
    }
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' === $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term.
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' === $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', (string) (int) $args['menu-item-parent-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object_id', (string) (int) $args['menu-item-object-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' === $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 5.6

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' === $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' === $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' === $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if (wp_unslash($args['menu-item-title']) === wp_specialchars_decode($original_title)) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' === $args['menu-item-title'] && '' === $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' === $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term.
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' === $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', (string) (int) $args['menu-item-parent-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object_id', (string) (int) $args['menu-item-object-id']);
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' === $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 5.5

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' === $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' === $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' === $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if (wp_unslash($args['menu-item-title']) === wp_specialchars_decode($original_title)) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' === $args['menu-item-title'] && '' === $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' === $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term.
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' === $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' === $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 5.4

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // Make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects.
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' == $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // Hack to get wp to create a post object when too many properties are empty.
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object.
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status.
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term.
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms().
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status.
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: .20

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' == $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 2.2

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' != $args['menu-item-type']) {
        /* if non-custom menu item, then:
         * use original object's URL
         * blank default title to sync with original object's
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' == $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: .10

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' === $args['menu-item-type']) {
        // If custom menu item, trim the URL.
        $args['menu-item-url'] = trim($args['menu-item-url']);
    } else {
        /*
         * If non-custom menu item, then:
         * - use the original object's URL.
         * - blank default title to sync with the original object's title.
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' == $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 4.5

/**
 * Save the properties of a menu item or create a new one.
 *
 * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
 * to be pre-slashed since they are passed directly into `wp_insert_post()`.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' != $args['menu-item-type']) {
        /* if non-custom menu item, then:
         * use original object's URL
         * blank default title to sync with original object's
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' == $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            if ($original_object) {
                $original_title = $original_object->labels->archives;
            }
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 4.4

/**
 * Save the properties of a menu item or create a new one.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' != $args['menu-item-type']) {
        /* if non-custom menu item, then:
         * use original object's URL
         * blank default title to sync with original object's
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        } elseif ('post_type_archive' == $args['menu-item-type']) {
            $original_object = get_post_type_object($args['menu-item-object']);
            $original_title = $original_object->labels->archives;
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
        /**
         * Fires immediately after a new navigation menu item has been added.
         *
         * @since 4.4.0
         *
         * @see wp_update_nav_menu_item()
         *
         * @param int   $menu_id         ID of the updated menu.
         * @param int   $menu_item_db_id ID of the new menu item.
         * @param array $args            An array of arguments used to update/add the menu item.
         */
        do_action('wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 4.3

/**
 * Save the properties of a menu item or create a new one.
 *
 * @since 3.0.0
 *
 * @param int   $menu_id         The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int   $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data  The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' != $args['menu-item-type']) {
        /* if non-custom menu item, then:
         * use original object's URL
         * blank default title to sync with original object's
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 4.2

/**
 * Save the properties of a menu item or create a new one.
 *
 * @since 3.0.0
 *
 * @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' != $args['menu-item-type']) {
        /* if non-custom menu item, then:
         * use original object's URL
         * blank default title to sync with original object's
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_item()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 3.9

/**
 * Save the properties of a menu item or create a new one.
 *
 * @since 3.0.0
 *
 * @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data The menu item's data.
 * @return int|WP_Error The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id) {
        return new WP_Error('invalid_menu_id', __('Invalid menu ID.'));
    }
    if (is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' != $args['menu-item-type']) {
        /* if non-custom menu item, then:
         * use original object's URL
         * blank default title to sync with original object's
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
    }
    // Associate the menu item with the menu term
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        wp_set_object_terms($menu_item_db_id, array($menu->term_id), 'nav_menu');
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    /**
     * Fires after a navigation menu item has been updated.
     *
     * @since 3.0.0
     *
     * @see wp_update_nav_menu_items()
     *
     * @param int   $menu_id         ID of the updated menu.
     * @param int   $menu_item_db_id ID of the updated menu item.
     * @param array $args            An array of arguments used to update a menu item.
     */
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}

WordPress Version: 3.7

/**
 * Save the properties of a menu item or create a new one.
 *
 * @since 3.0.0
 *
 * @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan.
 * @param int $menu_item_db_id The ID of the menu item. If "0", creates a new menu item.
 * @param array $menu_item_data The menu item's data.
 * @return int The menu item's database ID or WP_Error object on failure.
 */
function wp_update_nav_menu_item($menu_id = 0, $menu_item_db_id = 0, $menu_item_data = array())
{
    $menu_id = (int) $menu_id;
    $menu_item_db_id = (int) $menu_item_db_id;
    // make sure that we don't convert non-nav_menu_item objects into nav_menu_item objects
    if (!empty($menu_item_db_id) && !is_nav_menu_item($menu_item_db_id)) {
        return new WP_Error('update_nav_menu_item_failed', __('The given object ID is not that of a menu item.'));
    }
    $menu = wp_get_nav_menu_object($menu_id);
    if (!$menu && 0 !== $menu_id || is_wp_error($menu)) {
        return $menu;
    }
    $defaults = array('menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 0, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => '', 'menu-item-xfn' => '', 'menu-item-status' => '');
    $args = wp_parse_args($menu_item_data, $defaults);
    if (0 == $menu_id) {
        $args['menu-item-position'] = 1;
    } elseif (0 == (int) $args['menu-item-position']) {
        $menu_items = (0 == $menu_id) ? array() : (array) wp_get_nav_menu_items($menu_id, array('post_status' => 'publish,draft'));
        $last_item = array_pop($menu_items);
        $args['menu-item-position'] = ($last_item && isset($last_item->menu_order)) ? 1 + $last_item->menu_order : count($menu_items);
    }
    $original_parent = (0 < $menu_item_db_id) ? get_post_field('post_parent', $menu_item_db_id) : 0;
    if ('custom' != $args['menu-item-type']) {
        /* if non-custom menu item, then:
         * use original object's URL
         * blank default title to sync with original object's
         */
        $args['menu-item-url'] = '';
        $original_title = '';
        if ('taxonomy' == $args['menu-item-type']) {
            $original_parent = get_term_field('parent', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
            $original_title = get_term_field('name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw');
        } elseif ('post_type' == $args['menu-item-type']) {
            $original_object = get_post($args['menu-item-object-id']);
            $original_parent = (int) $original_object->post_parent;
            $original_title = $original_object->post_title;
        }
        if ($args['menu-item-title'] == $original_title) {
            $args['menu-item-title'] = '';
        }
        // hack to get wp to create a post object when too many properties are empty
        if ('' == $args['menu-item-title'] && '' == $args['menu-item-description']) {
            $args['menu-item-description'] = ' ';
        }
    }
    // Populate the menu item object
    $post = array('menu_order' => $args['menu-item-position'], 'ping_status' => 0, 'post_content' => $args['menu-item-description'], 'post_excerpt' => $args['menu-item-attr-title'], 'post_parent' => $original_parent, 'post_title' => $args['menu-item-title'], 'post_type' => 'nav_menu_item');
    $update = 0 != $menu_item_db_id;
    // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms()
    if ($menu_id && (!$update || !is_object_in_term($menu_item_db_id, 'nav_menu', (int) $menu->term_id))) {
        $post['tax_input'] = array('nav_menu' => array(intval($menu->term_id)));
    }
    // New menu item. Default is draft status
    if (!$update) {
        $post['ID'] = 0;
        $post['post_status'] = ('publish' == $args['menu-item-status']) ? 'publish' : 'draft';
        $menu_item_db_id = wp_insert_post($post);
        if (!$menu_item_db_id || is_wp_error($menu_item_db_id)) {
            return $menu_item_db_id;
        }
    }
    if ('custom' == $args['menu-item-type']) {
        $args['menu-item-object-id'] = $menu_item_db_id;
        $args['menu-item-object'] = 'custom';
    }
    $menu_item_db_id = (int) $menu_item_db_id;
    update_post_meta($menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']));
    update_post_meta($menu_item_db_id, '_menu_item_menu_item_parent', strval((int) $args['menu-item-parent-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object_id', strval((int) $args['menu-item-object-id']));
    update_post_meta($menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']));
    update_post_meta($menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']));
    $args['menu-item-classes'] = array_map('sanitize_html_class', explode(' ', $args['menu-item-classes']));
    $args['menu-item-xfn'] = implode(' ', array_map('sanitize_html_class', explode(' ', $args['menu-item-xfn'])));
    update_post_meta($menu_item_db_id, '_menu_item_classes', $args['menu-item-classes']);
    update_post_meta($menu_item_db_id, '_menu_item_xfn', $args['menu-item-xfn']);
    update_post_meta($menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']));
    if (0 == $menu_id) {
        update_post_meta($menu_item_db_id, '_menu_item_orphaned', (string) time());
    } elseif (get_post_meta($menu_item_db_id, '_menu_item_orphaned')) {
        delete_post_meta($menu_item_db_id, '_menu_item_orphaned');
    }
    // Update existing menu item. Default is publish status
    if ($update) {
        $post['ID'] = $menu_item_db_id;
        $post['post_status'] = ('draft' == $args['menu-item-status']) ? 'draft' : 'publish';
        wp_update_post($post);
    }
    do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args);
    return $menu_item_db_id;
}