You may find at some point that it could be very helpful to pass some data in the form of an array or object as an associated argument into a custom WP CLI command. At least, that is the situation I found myself in recently.
To give an example, here’s a demonstration of a CLI function that takes a JSON string as an associated argument, then loops through two lots of data (the JSON data as an array, and another additional array representing product bundle sizes in this case) and uses that data in order to run another WP CLI command on each iteration.
public function bulk_add_items( array $args, array $assoc_args ): void {
if ( ! isset( $assoc_args['product-add-array'] ) ) {
WP_CLI::error( "Please specify --product-add-array in JSON format, eg. --product-add-array='{ "firstitem": [ { "item_no": 2705, "item_label": "my_item_label", "item_price": 32 } ] }'" );
}
$array_of_items = WP_CLI\Utils\parse_shell_arrays($assoc_args, array('product-add-array'));
$bundle_sizes = array(5, 10, 15);
foreach( $array_of_items['product-add-array'] as $item ) {
$item = $item[0];
foreach( $bundle_sizes as $bundle_size ) {
$bundle_price_per_unit = $bundle_size * $item['item_price'];
$new_assoc_args = array(
'item_no' => $item['item_no'],
'item_label' => $item['item_label'],
'item_price' => $bundle_price_per_unit,
'quantity' => $bundle_size,
);
WP_CLI::run_command( 'my-add-command', $new_assoc_args );
}
}
}
This does not cover any CLI command creation best practices of course, for that refer to the WP CLI guides themselves (for example, documentation standards).
Helper functions
There are some in-built commands to help work with the JSON as well, one of which was used in the above example.
is_json
This is a helper function for the above parsing, that detects whether a given string is valid JSON.
The following will return true if the string provided with the ‘product-add-array’ flag is JSON:
print_r(WP_CLI\Utils\is_json($assoc_args['product-add-array']));
parse_shell_arrays
This takes an existing $assoc_args array, and parses possible shell arguments for all keys that are provided in $array_arguments.
So, given this CLI command: wp demo-package bulk_add_products null --product-add-array='{ "product1": [ { "productno": 123, "external_price_id": "product_one_demo", "price_per_unit": 32, "currency": "USD" } ] }', if we then print out the result with the following:
print_r(WP_CLI\Utils\parse_shell_arrays($assoc_args, array('product-add-array')));
The printed result looks like this:
Array
(
[product-add-array] => Array
(
[product1] => Array
(
[0] => Array
(
[product_no] => 123
[external_price_id] => product_one_demo
[price_per_unit] => 32
[currency] => USD
)
)
)
)
However if we print the result with json_decode:
print_r(json_decode($assoc_args['product-add-array']));
The printed result of this looks like the following:
stdClass Object
(
[product1] => Array
(
[0] => stdClass Object
(
[product_no] => 123
[external_price_id] => product_one_demo
[price_per_unit] => 32
[currency] => USD
)
)
)
Quick summary
In short, it can be useful to know how you can pass data via a WP CLI command as a JSON string, and there may be valid use-cases. However if the reason you’re doing so is to do something such as generate multiple WP CLI commands with the data, in many cases creating another helper function to iterate through and manipulate the data and then run the WP CLI commands would likely be a much cleaner approach.
Leave a Reply