1

In a plugin I'm developing, I need to add the ability to bulk edit some meta fields in a custom post named "lot". I want to use the new bulk_edit_posts hook added in WP 6.3. This is the code I came up with:

function my_show_bulk_edit_lot_metabox( $column_name ) {
    static $print_nonce = true;
    if ( $print_nonce ) {
        $print_nonce = false;
        wp_nonce_field( plugin_basename( __FILE__ ), 'lot_edit_nonce' );
    }

    switch ( $column_name ) {
        case 'price':
            ?>
        <fieldset class="inline-edit-col-right inline-edit-lot">
            <div class="inline-edit-col column-<?php echo esc_attr( $column_name ); ?>">
                <label class="inline-edit-group">
                    <span class="title"><?php _e( 'Price' ); ?></span>
                    <input type="text" name="price" />
                </label>
            </div>
        </fieldset>
            <?php
            break;
        case 'auction':
            $auctions = get_posts(
                array(
                    'post_type'        => 'auction',
                    'post_status'      => 'any',
                    'numberposts'      => -1,
                    'suppress_filters' => 0,
                )
            );
            ?>
        <fieldset class="inline-edit-col-right inline-edit-lot">
            <div class="inline-edit-col column-<?php echo esc_attr( $column_name ); ?>">
                <label class="inline-edit-group">
                    <span class="title"><?php _e( 'Auction' ); ?></span>
                    <select name="auction_id" id="auction_id">
                        <option value="0"><?php _e( '&mdash; No Change &mdash;' ); ?></option>
                        <?php
                        foreach ( $auctions as $auction ) {
                            $title = $auction->post_title;
                            if ( empty( $title ) ) {
                                $title = __( '(no title)' );
                            }
                            $title = esc_html( $title );
                            echo '<option value="' . esc_attr( $auction->ID ) . '">' . $title . '</option>';
                        }
                        ?>
                    </select>
                </label>
            </div>
        </fieldset>
            <?php
            break;
    }
}
add_action( 'bulk_edit_custom_box', 'my_show_bulk_edit_lot_metabox', 10, 2 );

function my_save_bulk_edit_lot( $updated, $shared_post_data ) {
    if ( wp_verify_nonce( wp_unslash( $shared_post_data['lot_edit_nonce'] ), plugin_basename( __FILE__ ) ) && 'lot' === $shared_post_data['post_type'] ) {
        foreach ( $updated as $post_id ) {
            if ( ! empty( $shared_post_data['auction_id'] ) ) {
                update_post_meta( $post_id, 'auction_id', wp_unslash( $shared_post_data['auction_id'] ) );
            }
            if ( ! empty( $shared_post_data['price'] ) ) {
                update_post_meta( $post_id, 'price', wp_unslash( $shared_post_data['price'] ) );
            }
        }
    }
}
add_action( 'bulk_edit_posts', 'my_save_bulk_edit_lot', 10, 2 );

Everything is working as expected if I remove the nonce check. This is the content of the $shared_post_data var inside the my_save_bulk_edit_lot() function:

Array
(
    [s] => 
    [post_type] => lot
    [_wpnonce] => ea9131e013
    [_wp_http_referer] => /wp-admin/edit.php?post_type=lot
    [action] => edit
    [m] => 0
    [filter_by_auction] => 
    [paged] => 1
    [auction_id] => 0
    [price] => 100€
    [autodescription-bulk] => Array
        (
            [noindex] => nochange
            [nofollow] => nochange
            [noarchive] => nochange
        )

    [bulk_edit] => Update
    [post_view] => list
    [screen] => edit-lot
    [post] => Array
        (
            [0] => 7176
            [1] => 7174
        )

    [action2] => edit
)

As you can see there's no trace of the lot_edit_nonce nonce value I print in the my_show_bulk_edit_lot_metabox() function. There's a _wpnonce value, though. Do I need to check for this nonce instead? If so, how?

1 Answer 1

1

In order for the nonce verification to work, I needed to replace this:

wp_verify_nonce( wp_unslash( $shared_post_data['lot_edit_nonce'] ), plugin_basename( __FILE__ ) )

with this:

wp_verify_nonce( wp_unslash( $shared_post_data['_wpnonce'] ), 'bulk-posts' )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.