bulk_edit_posts

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

WordPress Version: 6.5

/**
 * Processes the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|null $post_data Optional. The array of post data to process.
 *                              Defaults to the `$_POST` superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_ids = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_ids as $post_id) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_id));
        if (!isset($post_type_object) || isset($children) && in_array($post_id, $children, true) || !current_user_can('edit_post', $post_id)) {
            $skipped[] = $post_id;
            continue;
        }
        if (wp_check_post_lock($post_id)) {
            $locked[] = $post_id;
            continue;
        }
        $post = get_post($post_id);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (!$taxonomy_obj->show_in_quick_edit) {
                continue;
            }
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_id);
            if (isset($post_data['indeterminate_post_category']) && is_array($post_data['indeterminate_post_category'])) {
                $indeterminate_post_category = $post_data['indeterminate_post_category'];
            } else {
                $indeterminate_post_category = array();
            }
            $indeterminate_cats = array_intersect($cats, $indeterminate_post_category);
            $determinate_cats = array_diff($new_cats, $indeterminate_post_category);
            $post_data['post_category'] = array_unique(array_merge($indeterminate_cats, $determinate_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_id;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_id;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_id, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        // Reset post date of scheduled post to be published.
        if (in_array($post->post_status, array('future', 'draft'), true) && 'publish' === $post_data['post_status']) {
            $post_data['post_date'] = current_time('mysql');
            $post_data['post_date_gmt'] = '';
        }
        $post_id = wp_update_post($post_data);
        update_post_meta($post_id, '_edit_last', get_current_user_id());
        $updated[] = $post_id;
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_id);
            } else {
                unstick_post($post_id);
            }
        }
    }
    /**
     * Fires after processing the post data for bulk edit.
     *
     * @since 6.3.0
     *
     * @param int[] $updated          An array of updated post IDs.
     * @param array $shared_post_data Associative array containing the post data.
     */
    do_action('bulk_edit_posts', $updated, $shared_post_data);
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.1

/**
 * Processes the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|null $post_data Optional. The array of post data to process.
 *                              Defaults to the `$_POST` superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_ids = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_ids as $post_id) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_id));
        if (!isset($post_type_object) || isset($children) && in_array($post_id, $children, true) || !current_user_can('edit_post', $post_id)) {
            $skipped[] = $post_id;
            continue;
        }
        if (wp_check_post_lock($post_id)) {
            $locked[] = $post_id;
            continue;
        }
        $post = get_post($post_id);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (!$taxonomy_obj->show_in_quick_edit) {
                continue;
            }
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_id);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_id;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_id;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_id, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        // Reset post date of scheduled post to be published.
        if (in_array($post->post_status, array('future', 'draft'), true) && 'publish' === $post_data['post_status']) {
            $post_data['post_date'] = current_time('mysql');
            $post_data['post_date_gmt'] = '';
        }
        $post_id = wp_update_post($post_data);
        update_post_meta($post_id, '_edit_last', get_current_user_id());
        $updated[] = $post_id;
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_id);
            } else {
                unstick_post($post_id);
            }
        }
    }
    /**
     * Fires after processing the post data for bulk edit.
     *
     * @since 6.3.0
     *
     * @param int[] $updated          An array of updated post IDs.
     * @param array $shared_post_data Associative array containing the post data.
     */
    do_action('bulk_edit_posts', $updated, $shared_post_data);
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 6.4

/**
 * Processes the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|null $post_data Optional. The array of post data to process.
 *                              Defaults to the `$_POST` superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_ids = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_ids as $post_id) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_id));
        if (!isset($post_type_object) || isset($children) && in_array($post_id, $children, true) || !current_user_can('edit_post', $post_id)) {
            $skipped[] = $post_id;
            continue;
        }
        if (wp_check_post_lock($post_id)) {
            $locked[] = $post_id;
            continue;
        }
        $post = get_post($post_id);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (!$taxonomy_obj->show_in_quick_edit) {
                continue;
            }
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_id);
            if (isset($post_data['indeterminate_post_category']) && is_array($post_data['indeterminate_post_category'])) {
                $indeterminate_post_category = $post_data['indeterminate_post_category'];
            } else {
                $indeterminate_post_category = array();
            }
            $indeterminate_cats = array_intersect($cats, $indeterminate_post_category);
            $determinate_cats = array_diff($new_cats, $indeterminate_post_category);
            $post_data['post_category'] = array_unique(array_merge($indeterminate_cats, $determinate_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_id;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_id;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_id, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        // Reset post date of scheduled post to be published.
        if (in_array($post->post_status, array('future', 'draft'), true) && 'publish' === $post_data['post_status']) {
            $post_data['post_date'] = current_time('mysql');
            $post_data['post_date_gmt'] = '';
        }
        $post_id = wp_update_post($post_data);
        update_post_meta($post_id, '_edit_last', get_current_user_id());
        $updated[] = $post_id;
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_id);
            } else {
                unstick_post($post_id);
            }
        }
    }
    /**
     * Fires after processing the post data for bulk edit.
     *
     * @since 6.3.0
     *
     * @param int[] $updated          An array of updated post IDs.
     * @param array $shared_post_data Associative array containing the post data.
     */
    do_action('bulk_edit_posts', $updated, $shared_post_data);
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 6.3

/**
 * Processes the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|null $post_data Optional. The array of post data to process.
 *                              Defaults to the `$_POST` superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_ids = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_ids as $post_id) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_id));
        if (!isset($post_type_object) || isset($children) && in_array($post_id, $children, true) || !current_user_can('edit_post', $post_id)) {
            $skipped[] = $post_id;
            continue;
        }
        if (wp_check_post_lock($post_id)) {
            $locked[] = $post_id;
            continue;
        }
        $post = get_post($post_id);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (!$taxonomy_obj->show_in_quick_edit) {
                continue;
            }
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_id);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_id;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_id;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_id, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        // Reset post date of scheduled post to be published.
        if (in_array($post->post_status, array('future', 'draft'), true) && 'publish' === $post_data['post_status']) {
            $post_data['post_date'] = current_time('mysql');
            $post_data['post_date_gmt'] = '';
        }
        $post_id = wp_update_post($post_data);
        update_post_meta($post_id, '_edit_last', get_current_user_id());
        $updated[] = $post_id;
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_id);
            } else {
                unstick_post($post_id);
            }
        }
    }
    /**
     * Fires after processing the post data for bulk edit.
     *
     * @since 6.3.0
     *
     * @param int[] $updated          An array of updated post IDs.
     * @param array $shared_post_data Associative array containing the post data.
     */
    do_action('bulk_edit_posts', $updated, $shared_post_data);
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 6.2

/**
 * Processes the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|null $post_data Optional. The array of post data to process.
 *                              Defaults to the `$_POST` superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_ids = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_ids as $post_id) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_id));
        if (!isset($post_type_object) || isset($children) && in_array($post_id, $children, true) || !current_user_can('edit_post', $post_id)) {
            $skipped[] = $post_id;
            continue;
        }
        if (wp_check_post_lock($post_id)) {
            $locked[] = $post_id;
            continue;
        }
        $post = get_post($post_id);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (!$taxonomy_obj->show_in_quick_edit) {
                continue;
            }
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_id, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_id);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_id;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_id;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_id, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        $post_id = wp_update_post($post_data);
        update_post_meta($post_id, '_edit_last', get_current_user_id());
        $updated[] = $post_id;
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_id);
            } else {
                unstick_post($post_id);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 6.1

/**
 * Processes the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|null $post_data Optional. The array of post data to process.
 *                              Defaults to the `$_POST` superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children, true) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (!$taxonomy_obj->show_in_quick_edit) {
                continue;
            }
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        $post_id = wp_update_post($post_data);
        update_post_meta($post_id, '_edit_last', get_current_user_id());
        $updated[] = $post_id;
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.9

/**
 * Processes the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|null $post_data Optional. The array of post data to process.
 *                              Defaults to the `$_POST` superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children, true) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        $post_id = wp_update_post($post_data);
        update_post_meta($post_id, '_edit_last', get_current_user_id());
        $updated[] = $post_id;
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.5

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' === $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' === $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' === $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ((int) $page->ID === $parent) {
                    $parent = (int) $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children, true) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names, true)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' === $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && (int) $post_data['post_parent']) {
        $parent = (int) $post_data['post_parent'];
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = array();
    $skipped = array();
    $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.1

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
        // Prevent wp_insert_post() from overwriting post format with the old data.
        unset($post_data['tax_input']['post_format']);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 0.1

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.0

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 9.9

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 9.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .20

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 9.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .10

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.9

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
            unset($post_data['tax_input']['post_format']);
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 8.8

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 8.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .10

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 6.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .20

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 6.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .13

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.6

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('Sorry, you are not allowed to edit pages.'));
        } else {
            wp_die(__('Sorry, you are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .20

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 5.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .16

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .20

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .17

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 3.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 3.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .20

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 3.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .18

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 4.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @global wpdb $wpdb
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 2.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 2.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .22

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 1.5

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .40

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 1.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 1.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .25

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 0.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 0.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .25

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 8.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 8.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .28

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .20

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 8.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    foreach ($post_IDs as $post_ID) {
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $translated_post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($translated_post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($translated_post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .10

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 3.8

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    foreach ($post_IDs as $post_ID) {
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        $post_data['ID'] = $post_ID;
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 7.5

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .40

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 7.4

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .30

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 7.3

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .28

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_ID'] = $post_ID;
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $post_data = _wp_get_allowed_postdata($post_data);
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($shared_post_data['post_format'])) {
            set_post_format($post_ID, $shared_post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .20

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 7.2

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    foreach ($post_IDs as $post_ID) {
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $translated_post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($translated_post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($translated_post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: .10

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    if (!empty($post_data['post_status'])) {
        $post_data['post_status'] = sanitize_key($post_data['post_status']);
        if ('inherit' == $post_data['post_status']) {
            unset($post_data['post_status']);
        }
    }
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    $shared_post_data = $post_data;
    foreach ($post_IDs as $post_ID) {
        // Start with fresh post data with each iteration.
        $post_data = $shared_post_data;
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_type'] = $post->post_type;
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        foreach (array('comment_status', 'ping_status', 'post_author') as $field) {
            if (!isset($post_data[$field])) {
                $post_data[$field] = $post->{$field};
            }
        }
        $post_data['ID'] = $post_ID;
        $post_data['post_ID'] = $post_ID;
        $post_data = _wp_translate_postdata(true, $post_data);
        if (is_wp_error($post_data)) {
            $skipped[] = $post_ID;
            continue;
        }
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}

WordPress Version: 3.7

/**
 * Process the post data for the bulk editing of posts.
 *
 * Updates all bulk edited posts/pages, adding (but not removing) tags and
 * categories. Skips pages when they would be their own parent or child.
 *
 * @since 2.7.0
 *
 * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
 * @return array
 */
function bulk_edit_posts($post_data = null)
{
    global $wpdb;
    if (empty($post_data)) {
        $post_data =& $_POST;
    }
    if (isset($post_data['post_type'])) {
        $ptype = get_post_type_object($post_data['post_type']);
    } else {
        $ptype = get_post_type_object('post');
    }
    if (!current_user_can($ptype->cap->edit_posts)) {
        if ('page' == $ptype->name) {
            wp_die(__('You are not allowed to edit pages.'));
        } else {
            wp_die(__('You are not allowed to edit posts.'));
        }
    }
    if (-1 == $post_data['_status']) {
        $post_data['post_status'] = null;
        unset($post_data['post_status']);
    } else {
        $post_data['post_status'] = $post_data['_status'];
    }
    unset($post_data['_status']);
    $post_IDs = array_map('intval', (array) $post_data['post']);
    $reset = array('post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky', 'post_format');
    foreach ($reset as $field) {
        if (isset($post_data[$field]) && ('' == $post_data[$field] || -1 == $post_data[$field])) {
            unset($post_data[$field]);
        }
    }
    if (isset($post_data['post_category'])) {
        if (is_array($post_data['post_category']) && !empty($post_data['post_category'])) {
            $new_cats = array_map('absint', $post_data['post_category']);
        } else {
            unset($post_data['post_category']);
        }
    }
    $tax_input = array();
    if (isset($post_data['tax_input'])) {
        foreach ($post_data['tax_input'] as $tax_name => $terms) {
            if (empty($terms)) {
                continue;
            }
            if (is_taxonomy_hierarchical($tax_name)) {
                $tax_input[$tax_name] = array_map('absint', $terms);
            } else {
                $comma = _x(',', 'tag delimiter');
                if (',' !== $comma) {
                    $terms = str_replace($comma, ',', $terms);
                }
                $tax_input[$tax_name] = explode(',', trim($terms, " \n\t\r\x00\v,"));
            }
        }
    }
    if (isset($post_data['post_parent']) && $parent = (int) $post_data['post_parent']) {
        $pages = $wpdb->get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'");
        $children = array();
        for ($i = 0; $i < 50 && $parent > 0; $i++) {
            $children[] = $parent;
            foreach ($pages as $page) {
                if ($page->ID == $parent) {
                    $parent = $page->post_parent;
                    break;
                }
            }
        }
    }
    $updated = $skipped = $locked = array();
    foreach ($post_IDs as $post_ID) {
        $post_type_object = get_post_type_object(get_post_type($post_ID));
        if (!isset($post_type_object) || isset($children) && in_array($post_ID, $children) || !current_user_can('edit_post', $post_ID)) {
            $skipped[] = $post_ID;
            continue;
        }
        if (wp_check_post_lock($post_ID)) {
            $locked[] = $post_ID;
            continue;
        }
        $post = get_post($post_ID);
        $tax_names = get_object_taxonomies($post);
        foreach ($tax_names as $tax_name) {
            $taxonomy_obj = get_taxonomy($tax_name);
            if (isset($tax_input[$tax_name]) && current_user_can($taxonomy_obj->cap->assign_terms)) {
                $new_terms = $tax_input[$tax_name];
            } else {
                $new_terms = array();
            }
            if ($taxonomy_obj->hierarchical) {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'ids'));
            } else {
                $current_terms = (array) wp_get_object_terms($post_ID, $tax_name, array('fields' => 'names'));
            }
            $post_data['tax_input'][$tax_name] = array_merge($current_terms, $new_terms);
        }
        if (isset($new_cats) && in_array('category', $tax_names)) {
            $cats = (array) wp_get_post_categories($post_ID);
            $post_data['post_category'] = array_unique(array_merge($cats, $new_cats));
            unset($post_data['tax_input']['category']);
        }
        $post_data['post_mime_type'] = $post->post_mime_type;
        $post_data['guid'] = $post->guid;
        $post_data['ID'] = $post_ID;
        $updated[] = wp_update_post($post_data);
        if (isset($post_data['sticky']) && current_user_can($ptype->cap->edit_others_posts)) {
            if ('sticky' == $post_data['sticky']) {
                stick_post($post_ID);
            } else {
                unstick_post($post_ID);
            }
        }
        if (isset($post_data['post_format'])) {
            set_post_format($post_ID, $post_data['post_format']);
        }
    }
    return array('updated' => $updated, 'skipped' => $skipped, 'locked' => $locked);
}