admin管理员组

文章数量:1122832

I am using this function which works great in case anyone wants to bulk update custom fields for custom post types (just change parameters as necessary).

 $args=array(
  'posts_per_page' => -1,
  'post_type' => 'mycptype'
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
  while ( $the_query->have_posts() ) : $the_query->the_post();
    $testa = get_field('br_type');
    $testb = get_field('br_category');
    if ($testa === 'Apples') {
    update_field('br_featured', '0', get_the_ID());
    }
  endwhile;
  wp_reset_postdata();
endif;

How to use:

  1. Insert the code inside your functions.php and refresh your website ONCE
  2. Then don't forget to delete the code.

The problem I am having is that even if the function works as expected and updates the value of the custom field, I need to go inside each custom post type and click on the button "Update" for the changes to take effect.

This is because the ACF field has been registered after the custom post types were published.

Is there a workaround for not going inside each post and click update?

I am using this function which works great in case anyone wants to bulk update custom fields for custom post types (just change parameters as necessary).

 $args=array(
  'posts_per_page' => -1,
  'post_type' => 'mycptype'
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
  while ( $the_query->have_posts() ) : $the_query->the_post();
    $testa = get_field('br_type');
    $testb = get_field('br_category');
    if ($testa === 'Apples') {
    update_field('br_featured', '0', get_the_ID());
    }
  endwhile;
  wp_reset_postdata();
endif;

How to use:

  1. Insert the code inside your functions.php and refresh your website ONCE
  2. Then don't forget to delete the code.

The problem I am having is that even if the function works as expected and updates the value of the custom field, I need to go inside each custom post type and click on the button "Update" for the changes to take effect.

This is because the ACF field has been registered after the custom post types were published.

Is there a workaround for not going inside each post and click update?

Share Improve this question asked Feb 5, 2021 at 20:07 JoaMikaJoaMika 6986 gold badges27 silver badges58 bronze badges 1
  • 1 Instead of update_field use update_post_meta – Buttered_Toast Commented May 29, 2022 at 13:16
Add a comment  | 

3 Answers 3

Reset to default 1

Why not save yourself a whole lot of hassle and add a handy admin menu item "Bulk Update" that you can just click whenever you need it.

This method (using hooks) also ensures that WordPress (as well as ACF and your custom post types) are safely loaded and ready to go.

/**
 * Register "Bulk Update" menu item under the "mycptype" admin menu.
 *
 * Menu item links directly to admin-post.php?action=mycptype_bulk_update
 *
 * ...which is handled by {@see wpse_382892_bulk_update()}
 *
 * @see https://developer.wordpress.org/reference/functions/add_submenu_page/
 */
function wpse_382892_menu_item() {
    add_submenu_page(
        'edit.php?post_type=mycptype',
        'Bulk Update',
        'Bulk Update',
        'edit_others_posts',
        // https://developer.wordpress.org/reference/files/wp-admin/admin-post.php/
        admin_url( 'admin-post.php?action=mycptype_bulk_update' ),
    );
}

add_action( 'admin_menu', 'wpse_382892_menu_item' );

/**
 * Handle the bulk update request.
 *
 * @see wpse_382892_menu_item()
 */
function wpse_382892_bulk_update() {
    if ( ! current_user_can( 'edit_others_posts' ) ) {
        wp_die( 'You do not have permission to do this.' );
    }

    $args = array(
        'posts_per_page' => -1,
        'post_type' => 'post',
    );

    $the_query = new WP_Query( $args );

    while ( $the_query->have_posts() ) {
        $the_query->the_post();

        $testa = get_field('br_type');
        $testb = get_field('br_category');

        if ($testa === 'Apples') {
            update_field('br_featured', '0', get_the_ID());
        }
    }

    wp_die( 'Bulk update completed!', 'Bulk Update', [
        'back_link' => true,
    ]);
}

// This custom action is fired in wp-admin/admin-post.php
add_action( 'admin_post_mycptype_bulk_update', 'wpse_382892_bulk_update' );

Note that you don't actually need the menu item for the second function to still be usuable - you can trigger the action manually just by loading the action URL in your browser:

https://example.com/wp-admin/admin-post.php?action=mycptype_bulk_update

When you access get_field() from functions.php it will load before ACF has initialized. You can solve it by wrapping the code inside acf/init hook. Update the code as follows.

Hope it helps @JoaMika

add_action('acf/init', 'custom_code');

function custom_code() {
    $args = array(
        'posts_per_page' => -1,
        'post_type' => 'mycptype'
    );
    $the_query = new WP_Query($args);
    if ($the_query->have_posts()) :
        while ($the_query->have_posts()) : $the_query->the_post();
            $testa = get_field('br_type');
            $testb = get_field('br_category');
            if ($testa === 'Apples') {
                update_field('br_featured', '0', get_the_ID());
            }
        endwhile;
        wp_reset_postdata();
    endif;
}

In addition to TheDeadMedic's answer you can create a reusable task with Bulk Task Editor (BTE) to add more flexibility with filters.

Register your task

add_action( 'rewbe_post_type_actions', function($actions,$post_type){

     if( $post_type == 'your-custom-post-type' ){

          $actions[] = array(

               'label'  => 'Name of your task',
               'id'     => 'bulk_task_name',
               'fields' => array(
                    array(
                         'name' => 'var_1',
                         'type' => 'text',
                    ),
               ),
          );
     }
     
     return $actions;
     
},10,2);

Add a callback

add_action('rewbe_do_post_{bulk_task_name}',function($post,$args){
     
     if( !empty($args['var_1']) ){
          
          $var_1 = sanitize_title($args['var_1']);

          // your logic here

          $testa = get_field('br_type',$post->ID);

          if ( $testa === $var_1 ) {

              update_field('br_featured', '0', $post->ID );
          }
     }
     
     return $post;
     
},10,2);

Execute the Task

Navigate to the “Tasks” menu in the WordPress admin sidebar.

Click “Add New” to create a new post task, select the post type and give it a descriptive name for easy identification.

If needed, use the filtering options to narrow down the list of posts.

From the dropdown menu, select the task “Name of your task” registered earlier.

Adjust the number of items processed at a time based on your server’s capacity.

Click “Publish” or “Update” to start the process.

Resources

How to implement a custom post task with BTE using hooks?

本文标签: Bulk Update Custom Fields for Custom Post Types