'product', 'post_status' => 'any', 'posts_per_page' => -1, 'fields' => 'ids' ) ); $args = array( 'post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => $limit, 'fields' => 'ids' ); $products = get_posts( $args ); // Also check with WooCommerce function for comparison $wc_products = wc_get_products( array( 'status' => 'publish', 'limit' => $limit, 'return' => 'ids' ) ); // Check if WooCommerce is active and functional if ( ! function_exists( 'wc_get_products' ) ) {} // Test with a simple product count $product_count = wp_count_posts( 'product' ); return $products; } /** * Get complete product data for Ovena API */ public function get_product_feed_data( $product_id ) { $product = wc_get_product( $product_id ); if ( ! $product ) { return false; } // Send raw WooCommerce data - let Ovena API handle processing $data = array( 'source' => 'woocommerce', 'product_id' => $product_id, 'product_data' => $this->get_raw_product_data( $product ) ); return $data; } /** * Get raw WooCommerce product data */ private function get_raw_product_data( $product ) { if ( ! $product ) { return null; } // Extract comprehensive WooCommerce data - let Ovena API handle all processing $data = array( // Basic product info 'id' => $product->get_id(), 'name' => $product->get_name(), 'slug' => $product->get_slug(), 'permalink' => $product->get_permalink(), 'type' => $product->get_type(), 'status' => $product->get_status(), 'featured' => $product->is_featured(), 'catalog_visibility' => $product->get_catalog_visibility(), 'description' => $product->get_description(), 'short_description' => $product->get_short_description(), 'sku' => $product->get_sku(), // Pricing 'price' => $product->get_price(), 'regular_price' => $product->get_regular_price(), 'sale_price' => $product->get_sale_price(), 'currency' => get_woocommerce_currency(), 'currency_symbol' => get_woocommerce_currency_symbol(), 'date_on_sale_from' => $product->get_date_on_sale_from() ? $product->get_date_on_sale_from()->format('c') : null, 'date_on_sale_to' => $product->get_date_on_sale_to() ? $product->get_date_on_sale_to()->format('c') : null, 'price_html' => $product->get_price_html(), // Inventory 'manage_stock' => $product->get_manage_stock(), 'stock_quantity' => $product->get_stock_quantity(), 'stock_status' => $product->get_stock_status(), 'backorders' => $product->get_backorders(), 'sold_individually' => $product->get_sold_individually(), 'low_stock_amount' => $product->get_low_stock_amount(), // Physical properties 'weight' => $product->get_weight(), 'length' => $product->get_length(), 'width' => $product->get_width(), 'height' => $product->get_height(), 'dimensions' => array( 'length' => $product->get_length(), 'width' => $product->get_width(), 'height' => $product->get_height(), ), // Media - Include full image URLs 'image_id' => $product->get_image_id(), 'image_url' => $this->get_image_url( $product->get_image_id() ), 'gallery_image_ids' => $product->get_gallery_image_ids(), 'gallery_image_urls' => $this->get_gallery_image_urls( $product->get_gallery_image_ids() ), // Attributes & Categories with full details 'attributes' => $this->get_product_attributes( $product ), 'categories' => $this->get_product_categories( $product ), 'tags' => $this->get_product_tags( $product ), // Reviews and ratings 'review_count' => $product->get_review_count(), 'average_rating' => $product->get_average_rating(), 'rating_count' => $product->get_rating_count(), // Shipping 'shipping_class' => $product->get_shipping_class(), 'shipping_class_id' => $product->get_shipping_class_id(), 'virtual' => $product->is_virtual(), 'downloadable' => $product->is_downloadable(), // Tax 'tax_status' => $product->get_tax_status(), 'tax_class' => $product->get_tax_class(), // Additional product data 'total_sales' => $product->get_total_sales(), 'cross_sell_ids' => $product->get_cross_sell_ids(), 'upsell_ids' => $product->get_upsell_ids(), 'parent_id' => $product->get_parent_id(), 'menu_order' => $product->get_menu_order(), // Variant grouping 'item_group_id' => $this->get_item_group_id( $product ), // Meta data 'meta_data' => $this->get_product_meta( $product ), // Timestamps 'created_date' => $product->get_date_created() ? $product->get_date_created()->format('c') : null, 'modified_date' => $product->get_date_modified() ? $product->get_date_modified()->format('c') : null, // Site context 'site_url' => home_url(), 'woocommerce_version' => WC()->version, 'wordpress_version' => get_bloginfo( 'version' ), ); return $data; } /** * Get product attributes in simple format */ private function get_product_attributes( $product ) { $attributes = array(); foreach ( $product->get_attributes() as $attribute ) { $attributes[] = array( 'name' => wc_attribute_label( $attribute->get_name() ), 'value' => $product->get_attribute( $attribute->get_name() ) ); } return $attributes; } /** * Get product categories */ private function get_product_categories( $product ) { $categories = wp_get_post_terms( $product->get_id(), 'product_cat' ); if ( is_wp_error( $categories ) ) { return array(); } $category_data = array(); foreach ( $categories as $category ) { $category_data[] = array( 'id' => $category->term_id, 'name' => $category->name, 'slug' => $category->slug ); } return $category_data; } /** * Get product tags */ private function get_product_tags( $product ) { $tags = wp_get_post_terms( $product->get_id(), 'product_tag' ); if ( is_wp_error( $tags ) ) { return array(); } $tag_data = array(); foreach ( $tags as $tag ) { $tag_data[] = array( 'id' => $tag->term_id, 'name' => $tag->name, 'slug' => $tag->slug ); } return $tag_data; } /** * Get essential product meta data */ private function get_product_meta( $product ) { $meta_data = array(); foreach ( $product->get_meta_data() as $meta ) { $data = $meta->get_data(); // Only include non-private meta keys if ( ! str_starts_with( $data['key'], '_' ) ) { $meta_data[ $data['key'] ] = $data['value']; } } return $meta_data; } /** * Get image URL from image ID */ private function get_image_url( $image_id ) { if ( ! $image_id ) { return null; } $image_url = wp_get_attachment_image_url( $image_id, 'full' ); return $image_url ? $image_url : null; } /** * Get gallery image URLs from gallery image IDs */ private function get_gallery_image_urls( $gallery_image_ids ) { if ( ! $gallery_image_ids || ! is_array( $gallery_image_ids ) ) { return array(); } $urls = array(); foreach ( $gallery_image_ids as $image_id ) { $url = $this->get_image_url( $image_id ); if ( $url ) { $urls[] = $url; } } return $urls; } /** * Get item group ID for product variants * * Required by OpenAI Commerce Feed spec when product has variants. * Groups related products (e.g., same shirt in different colors/sizes). * * @param WC_Product $product Product object * @return string|null Item group ID or null if not a variant */ private function get_item_group_id( $product ) { if ( ! $product ) { return null; } $product_type = $product->get_type(); // For product variations (child products), use parent's identifier if ( $product_type === 'variation' ) { $parent_id = $product->get_parent_id(); if ( ! $parent_id ) { return null; } $parent_product = wc_get_product( $parent_id ); if ( ! $parent_product ) { return null; } // Prefer parent SKU for stability, fallback to parent ID $parent_sku = $parent_product->get_sku(); if ( $parent_sku ) { // Ensure max 70 chars as per OpenAI spec return substr( $parent_sku, 0, 70 ); } // Fallback to parent ID with prefix return 'GROUP_' . $parent_id; } // For variable products (parent products), use own identifier if ( $product_type === 'variable' ) { $sku = $product->get_sku(); if ( $sku ) { // Ensure max 70 chars as per OpenAI spec return substr( $sku, 0, 70 ); } // Fallback to product ID with prefix return 'GROUP_' . $product->get_id(); } // For grouped products, each product in the group might reference the group if ( $product_type === 'grouped' ) { $sku = $product->get_sku(); if ( $sku ) { return substr( $sku, 0, 70 ); } return 'GROUP_' . $product->get_id(); } // For simple products, no grouping needed (return null) // Simple products don't have variants return null; } }