Search code examples
wordpressbashpipechainingwp-cli

WP-CLI: Command chaining for deleting orders - Too many positional arguments error


While cloning & translating a WordPress site, I wanted to use WP-CLI to delete all orders like this: wp wc shop_order delete $(wp wc shop_order list --user=4 --field=id) --user=4. Unfortunately, I get errors Too many positional arguments.

Complete example:

wp wc shop_order delete $(wp wc shop_order list --user=4 --field=id) --user=4


Error: Too many positional arguments: 63537 63536 63534 63533 63532 63531 63527 63525
63524 63522 63521 63515 63507 63504 63503 63502 63501 63500 63499 63497 63496 63495 63494 
63493 63492 63491 63483 63482 63479 63430 63429 63428 63427 63425 63423 63422 63421 63420 
63415 63414 63412 63411 63410 63408 63407 63406 63405 63404 63403 63402 63401 63400 63399 
63398 63397 63396 63395 63394 63393 63391 63390 63389 63388 63386 63385 63384 63382 63381 
63375 63373 63372 63371 63370 63369 63368 63365 63364 63363 63362 63361 63360 63358 63357 
63356 63355 63354 63352 63350 63349 63348 63347 63346 63344 63343 63342 63339 63337 63336 
63335

Additional information:

  • The same syntaxis does work to delete users: wp user delete $(wp user list --role="customer" --field=ID) --yes. I don't understand why it doesn't work for deleting orders
  • Using xargs didn't seem to work either (I'm new to xargs): wp wc shop_order list --user=4 --field=id | xargs -t wp wc shop_order delete --user=4

Any help is appreciated - Thanks already! Jeroen


Solution

  • I found it: With xargs, using the -n1 switch to take max. 1 argument at a time:

    wp wc shop_order list --user=4 --field=id | xargs -n1 wp wc shop_order delete --user=4
    

    The output looked like this (maybe handy for debugging):

    Success: Trashed shop_order 63333
    
    Success: Trashed shop_order 63332
    
    Success: Trashed shop_order 63331
    

    Notes:

    • This command only moves orders to trash. To actually delete them, use the boolean flag --force
    • wp wc shop_order list returns max. 100 orders. You can lower this with the flag --per_page, but you can't raise it. I'm sure this can be alluviated with some elegant conditional looping, but I just want to delete some 6,700 orders, so a loop with a fixed number will do.

    End result:

    for i in {1..70}
    do
        wp wc shop_order list --user=4 --field=id | xargs -n1 wp wc shop_order delete --user=4 --force=1
    done
    

    Example of the output (note that it now states Deleted in stead of Trashed):

    Success: Deleted shop_order 62886.
    
    Success: Deleted shop_order 62885.
    
    Success: Deleted shop_order 62884.
    

    I'm still puzzled though, why the original code worked for deleting users, but not for orders.

    Something about performance: The code above takes about 5s/order. So (in my case) deleting 67,000 orders, takes about 9,5 hours