'adnvg-settings', 'adnvg_synced' => $count, ), admin_url( 'admin.php' ) ) ); exit; } public static function sync_all() { $product_ids = wc_get_products( array( 'type' => 'variable', 'limit' => -1, 'return' => 'ids', ) ); foreach ( $product_ids as $product_id ) { self::sync_product( $product_id ); } /** * Premium hook: background-sync module listens here to log * completion, update its sync-queue dashboard, etc. */ do_action( 'adnvg_after_bulk_sync', $product_ids ); return count( $product_ids ); } public function maybe_sync_single_product( $product_id ) { $product = wc_get_product( $product_id ); if ( $product && $product->is_type( 'variable' ) ) { self::sync_product( $product_id ); } } /** * Core sync logic for a single variable product: copies category/tag * terms onto variations, and flags one "representative" variation per * primary-attribute group. */ public static function sync_product( $product_id ) { $options = ADNVG_Options::get_all(); $primary_attribute = $options['primary_attribute']; $product = wc_get_product( $product_id ); if ( ! $product || ! $product->is_type( 'variable' ) ) { return; } $taxonomies_to_copy = array( 'product_cat', 'product_tag' ); $variation_ids = $product->get_children(); foreach ( $taxonomies_to_copy as $taxonomy ) { $terms = wp_get_object_terms( $product_id, $taxonomy, array( 'fields' => 'ids' ) ); if ( ! is_wp_error( $terms ) ) { foreach ( $variation_ids as $variation_id ) { wp_set_object_terms( $variation_id, $terms, $taxonomy ); } } } $groups = array(); foreach ( $variation_ids as $variation_id ) { $variation = wc_get_product( $variation_id ); if ( ! $variation ) { continue; } $attributes = $variation->get_variation_attributes(); $key = 'attribute_' . $primary_attribute; $value = isset( $attributes[ $key ] ) ? $attributes[ $key ] : ''; $groups[ $value ][] = $variation; update_post_meta( $variation_id, '_adnvg_representative', 0 ); update_post_meta( $variation_id, '_adnvg_group_value', $value ); } foreach ( $groups as $value => $variations ) { $representative = null; foreach ( $variations as $variation ) { if ( $variation->is_in_stock() ) { $representative = $variation; break; } } if ( ! $representative ) { $representative = $variations[0]; } update_post_meta( $representative->get_id(), '_adnvg_representative', 1 ); } update_post_meta( $product_id, '_adnvg_hidden_parent', $options['hide_parent'] === 'yes' ? 1 : 0 ); /** * Premium hook: analytics module can listen here to refresh * cached stats for this product. */ do_action( 'adnvg_after_sync_product', $product_id ); } }