WC_Product_Variation_Data_Store_CPT::update
Updates an existing product.
Method of the class: WC_Product_Variation_Data_Store_CPT{}
Hooks from the method
Returns
null. Nothing (null).
Usage
$WC_Product_Variation_Data_Store_CPT = new WC_Product_Variation_Data_Store_CPT(); $WC_Product_Variation_Data_Store_CPT->update( $product );
- $product(WC_Product_Variation) (required) (passed by reference — &)
- Product object.
Changelog
| Since 3.0.0 | Introduced. |
WC_Product_Variation_Data_Store_CPT::update() WC Product Variation Data Store CPT::update code WC 10.5.0
public function update( &$product ) {
$product->save_meta_data();
if ( ! $product->get_date_created() ) {
$product->set_date_created( time() );
}
$new_title = $this->generate_product_title( $product );
if ( $product->get_name( 'edit' ) !== $new_title ) {
$product->set_name( $new_title );
}
// The post parent is not a valid variable product so we should prevent this.
if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) {
$product->set_parent_id( 0 );
}
$changes = $product->get_changes();
// Always recompute and sync the attribute summary as a safety net.
// This ensures it's up-to-date not just for direct attribute changes (e.g., via $changes['attributes']),
// but also for indirect desyncs, like when a global term (e.g., 'Blue' -> 'Blue2') is updated elsewhere.
// We ideally handle those at the source (e.g., global term update hooks), but this provides a fallback.
$new_attribute_summary = $this->generate_attribute_summary( $product );
// Compare the fresh attribute summary with the stored summary and update if out of sync.
if ( $new_attribute_summary !== $product->get_attribute_summary() ) {
$product->set_attribute_summary( $new_attribute_summary );
// If attributes weren't explicitly changed in this update, flag it to ensure the product is saved.
// This acts as a "just-in-case" trigger for indirect desyncs.
if ( ! isset( $changes['attributes'] ) ) {
$changes['attributes'] = true;
}
}
// Only update the post when the post data changes.
if ( array_intersect( array( 'name', 'parent_id', 'status', 'menu_order', 'date_created', 'date_modified', 'attributes' ), array_keys( $changes ) ) ) {
$post_data = array(
'post_title' => $product->get_name( 'edit' ),
'post_excerpt' => $product->get_attribute_summary( 'edit' ),
'post_parent' => $product->get_parent_id( 'edit' ),
'comment_status' => 'closed',
'post_status' => $product->get_status( 'edit' ) ? $product->get_status( 'edit' ) : ProductStatus::PUBLISH,
'menu_order' => $product->get_menu_order( 'edit' ),
'post_date' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ),
'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ),
'post_modified' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getOffsetTimestamp() ) : current_time( 'mysql' ),
'post_modified_gmt' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getTimestamp() ) : current_time( 'mysql', 1 ),
'post_type' => 'product_variation',
'post_name' => $product->get_slug( 'edit' ),
);
/**
* When updating this object, to prevent infinite loops, use $wpdb
* to update data, since wp_update_post spawns more calls to the
* save_post action.
*
* This ensures hooks are fired by either WP itself (admin screen save),
* or an update purely from CRUD.
*/
if ( doing_action( 'save_post' ) ) {
$GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $product->get_id() ) );
clean_post_cache( $product->get_id() );
} else {
wp_update_post( array_merge( array( 'ID' => $product->get_id() ), $post_data ) );
}
$product->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook.
} else { // Only update post modified time to record this save event.
$GLOBALS['wpdb']->update(
$GLOBALS['wpdb']->posts,
array(
'post_modified' => current_time( 'mysql' ),
'post_modified_gmt' => current_time( 'mysql', 1 ),
),
array(
'ID' => $product->get_id(),
)
);
clean_post_cache( $product->get_id() );
}
$this->update_post_meta( $product );
$this->update_terms( $product );
$this->update_visibility( $product, true );
$this->update_attributes( $product );
$this->handle_updated_props( $product );
$product->apply_changes();
$this->update_version_and_type( $product );
$this->clear_caches( $product );
do_action( 'woocommerce_update_product_variation', $product->get_id(), $product );
}