Last active
June 6, 2018 19:41
-
-
Save richardbuff/2962942da5266795faac1eda2d48d792 to your computer and use it in GitHub Desktop.
WP-CLI - Set all parent / ancestor categories for a WooCommerce product - WP-CLI custom command
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// If a child category for WooCommerce Product is set, but the parent/grandparent/etc category is not set, | |
// running this will also set all the ancestor categories (parent, grandparent, etc...) | |
if ( defined('WP_CLI') && WP_CLI ) { //Check to make sure WP_CLI is running. This way our code isn't loaded on normal site visits. | |
/** | |
* Class EA_Set_All_Ancestor_Cats_For_A_Product | |
*/ | |
class EA_Set_All_Ancestor_Cats_For_A_Product extends WP_CLI_Command { | |
public $step = 1; | |
public $per_step = 100; | |
public $post_count = 0; | |
public $max_num_pages = 0; | |
private $product_category_id = 0; | |
private $complete = false; | |
private $wc_product_taxonomy_slug = "product_cat"; | |
public function __invoke( $args, $assoc_args ) { | |
list( $product_cat_id ) = $args; | |
$this->product_category_id = intval( $product_cat_id ); // <-- convert to integer so that term_exists works later as it needs an integer as input | |
// Value Checking - Verify the number is integer and greater than 0 | |
if( false == filter_var( $this->product_category_id, FILTER_VALIDATE_INT ) || $this->product_category_id < 1 ) { | |
WP_CLI::error( 'You must specify a positive integer greater than zero.' ); | |
return; | |
} | |
// Value Checking - Verify this is a valid term in the product_cat taxonomy | |
if( false == term_exists( $this->product_category_id, $this->wc_product_taxonomy_slug) ){ | |
// invalid id so list the current root cat ids at the command line to make it easy on the user | |
WP_CLI::runcommand( 'term list product_cat --parent=0 --fields=id,name,slug --format=table' ); | |
WP_CLI::error( 'A valid product category ID was not provided. Try again using one of the above product category/term IDs.' ); | |
return; | |
} | |
// Count all posts that are using the passed product category ID | |
$args = array( | |
'posts_per_page' => -1, | |
'post_type' => 'product', | |
'fields' => 'ids', | |
'post_status' => 'any', // <-- we need to get the 'draft' ones too | |
'tax_query' => array( | |
array( | |
'taxonomy' => $this->wc_product_taxonomy_slug, | |
'field' => 'term_id', // Possible values are 'term_id', 'name', 'slug' or term_taxonomy_id'. Default value is 'term_id'. | |
'terms' => $this->product_category_id, | |
'include_children' => true // MUST BE A BOOLEAN NOT A STRING - switch this to false when you want to test how many are really there vs should be there | |
) | |
), | |
// 'no_found_rows' => true, | |
// 'update_post_term_cache' => false | |
); | |
$post_ids = new WP_Query( $args ); | |
$this->post_count = count( $post_ids->posts ); | |
// always round up. | |
// 80 total posts / 100 posts per step = .8 -> round this up to one page | |
// 120 total posts / 100 posts per step = 1.2 -> round this up to two pages | |
$this->max_num_pages = ceil( $this->post_count / $this->per_step ); | |
wp_reset_postdata(); | |
WP_CLI::line( 'Found ' . $this->post_count . ' posts' ); | |
// WP_CLI::error('Wrapping up early for debugging reasons.'); | |
while( false === $this->complete ){ | |
$this->process_step(); | |
} // end while | |
} // end function | |
private function process_step(){ | |
// check to see if we've exceeded the pages | |
if( $this->max_num_pages < $this->step ){ | |
$this->complete = true; | |
WP_CLI::line( 'We have exceeded the number of pages. Ending.' ); | |
return; | |
} // end if | |
$args = array( | |
'posts_per_page' => $this->per_step, | |
'paged' => $this->step, | |
'post_type' => 'product', | |
'no_found_rows' => true, | |
'update_post_term_cache' => false, | |
'post_status' => 'any', // <-- we need to get the 'draft' ones too | |
'tax_query' => array( | |
array( | |
'taxonomy' => $this->wc_product_taxonomy_slug, | |
'field' => 'term_id', // Possible values are 'term_id', 'name', 'slug' or term_taxonomy_id'. Default value is 'term_id'. | |
'terms' => $this->product_category_id, | |
) | |
), | |
); | |
$my_query = new WP_Query( $args ); | |
if( $my_query->have_posts() ): | |
while ( $my_query->have_posts() ) : $my_query->the_post(); | |
WP_CLI::line(); // blank line for readability in terminal | |
global $post; | |
$terms = wp_get_object_terms( $post->ID, $this->wc_product_taxonomy_slug ); | |
WP_CLI::line( $my_query->current_post . ' - Post ID: ' . $post->ID . ' || Post Title: ' . get_the_title($post->ID) . ' || Currently has these terms: ' . join( ', ', wp_list_pluck( $terms, 'name' ) ) ); | |
foreach ( $terms as $term ) { | |
// Note this isn't super efficient probably. We could check to make sure the term | |
// ancestors weren't already asigned to the post but the overhead should matter | |
// too much running this via WP-CLI and only running it on thousands of products | |
// and not 10s of thousands | |
$ancestor_terms = get_ancestors( $term->term_id, $this->wc_product_taxonomy_slug ); | |
if ( ! empty( $ancestor_terms ) ) { | |
wp_set_object_terms( $post->ID, $ancestor_terms, $this->wc_product_taxonomy_slug, true ); | |
WP_CLI::line( 'Term name: ' . $term->name . ' || Term ID: ' . $term->term_id . ' > Ancestors added were: ' . join( ', ', $ancestor_terms ) ); | |
} else { | |
WP_CLI::line( 'Term name: ' . $term->name . ' || Term ID: ' . $term->term_id . ' > Ancestors array was empty, must be a top level term' ); | |
} // end if | |
} // end foreach | |
// Leave this off if dealing with thousands of posts | |
// WP_CLI::line( 'Updated post with ID ' . get_the_ID() ); | |
endwhile; | |
// increment our step | |
WP_CLI::line( 'Completed Step #' . $this->step); | |
$this->step++; | |
else: | |
WP_CLI::line( 'ERROR! Query returned no posts!' ); | |
endif; | |
wp_reset_postdata(); | |
} // end function | |
} // end class | |
WP_CLI::add_command( 'setancestorcategoriesforproducts', 'EA_Set_All_Ancestor_Cats_For_A_Product' ); | |
}// end if |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment