Iterate over objects (WP-CLI)
Naar navigatie springen
Naar zoeken springen
There seems to be no obvious way to iterate over a collection of objects, like posts or taxonomy terms. To add insult to injury: WP-CLI commands that return object-IDs, are often limited to returning max. 100 ids at a time.
Hybrid SQL-WP-CLI solution
As of Nov. 2022, this seems a quite good approach. In this example, the ids are collected of the terms of a certain WooCommerce product attribute taxonomy:
i='select term_id from wp_terms join wp_term_taxonomy using (term_id) where taxonomy like "pa_as%"' mapfile -t j < <( wp db query "$i" --skip-column-names ) echo ${j[@]} echo "# of entries: ${#j[@]}" echo ${!j[@]} echo "Entry 5: ${j[5]}"
- It's only two lines of Bash code (the last four lines are debugging)
- It's so simple that I don't even see the point of turning this into a function to be incorporated in some general WP-CLI-Bash library
- All IDs are received at once: No need for iterations. And thanks to SQL, it's already vector-oriented
- Much faster than using a 100% WP-CLI approach
- I tend to extend these kind of mapfile lines with a filter
|grep .
to remove whitespace, likemapfile -t j < <( wp db query "$i" --skip-column-names | grep . )
, but it doesn't seem necessary here --skip-column-names
is a mysql Client option → https://dev.mysql.com/doc/refman/8.0/en/mysql-command-options.html- I feel ok with using SQL for this, rather than going through the WP-CLI interface: Use what works.
100% WP-CLI solution
First example
Example from Oct. 2022 (tourlib-en-taxonomies-pa.sh
» translate_pa_diagram_terms()
):
# # Store all term ids in array "termid" ######################################## # # * All fields: wp --user=4 wc product_attribute_term list 20 # * Only ids: wp --user=4 wc product_attribute_term list 20 --field=id # * Use "grep ." to remove some whitespace # * Max. 100 items are returned at a time. There are 149 items in total, # so just merge the input of 2x this command # taxid=20 # Taxonomy-IDA more extensive example: # mapfile -t j0 < <( wp --user=4 wc product_attribute_term list $taxid --field=id | grep . ) mapfile -t j1 < <( wp --user=4 wc product_attribute_term list $taxid --field=id --offset=100 | grep . ) termid=( "${j0[@]}" "${j1[@]}" ) # echo "Length of array j0: ${#j0[@]}" echo "Length of array j1: ${#j1[@]}" echo "Length of array termid: ${#termid[@]}" echo "Array termid: ${termid[@]}"
Second example
Only max. 100 ids are returned. This example below contains a loop, to make sure that all ids are collected (tourlib-en-taxonomies-pa.sh
» translate_pa_original_xxx_widget_terms)
)
# Assign taxonomy id ######################################## # taxonomy_id=23 # echo "Init:" echo " taxonomy_id: $taxonomy_id" # Store number of terms in term_id_rows ######################################## # # term_id_rows=$(wp --user=4 wc product_attribute_term list $taxonomy_id --format=count | grep .) echo " term_id_rows: $term_id_rows" # Calculate number of iterations ######################################## # number_of_iterations=$(($term_id_rows/100+1)) echo " number_of_iterations: $number_of_iterations" # Unset term_id array ######################################## # # This array will contain all term ids # unset term_id # Collect all term_ids - Loop through all terms ######################################## # i=1 echo "Loop - Collect all term_ids" # for ((i; i<=$number_of_iterations; i++)) do # echo " Iteration $i/$number_of_iterations" # # Store batch of term ids in tmp array j ######################################## # mapfile -t j < <( wp wc product_attribute_term list \ $taxonomy_id \ --user=4 \ --field=id \ --offset=$((($i-1)*100)) | grep . ) # # echo " j: ${j[@]}" # # Append to array term_id ######################################## # term_id=(${term_id[@]} ${j[@]}) echo " Length term_id: ${#term_id[@]}" # done
- Of course, this code can be made more compactly
- If I remember correctly, execution took about half a minute. That became quite annoying, since this code is only 'preparatory': The real action comes after this. When I have to wait for half a minute, every time before I get to debug the real code, that becomes quite tiring.
Same functionality, but more compact:
term_id_rows=$(wp --user=4 wc product_attribute_term list 23 --format=count | grep .) number_of_iterations=$(($term_id_rows/100+1)) i=1 for ((i; i<=$number_of_iterations; i++)) do mapfile -t j < <( wp wc product_attribute_term list \ $taxonomy_id --user=4 --field=id \ --offset=$((($i-1)*100)) | grep . ) term_id=(${term_id[@]} ${j[@]}) done