update_meta_data( self::META_VISITOR, $id ); $order->save_meta_data(); } /** * The visitor id kept on an order, or null. * * @param WC_Order $order The order. */ public static function visitorId( WC_Order $order ): ?string { $id = (string) $order->get_meta( self::META_VISITOR ); return 1 === preg_match( '/^[0-9a-f]{16}$/', $id ) ? $id : null; } /** * `analytics` for an order snapshot (contract 1.3). * * @param WC_Order $order The order. * * @return array{visitor_id: string}|null */ public static function analytics( WC_Order $order ): ?array { $id = self::visitorId( $order ); return null === $id ? null : [ 'visitor_id' => $id ]; } /** * Is the order in one of the store's sale statuses? * * @param WC_Order $order The order. */ public static function isSale( WC_Order $order ): bool { return in_array( $order->get_status(), Stats::saleStatuses(), true ); } /** * The order's items and totals, in rials where the currency converts. * * Each item goes under its parent product id, not its SKU: SKUs are optional * in WooCommerce and the dashboard knows products by id (DATA-MODEL §4-29). * * @param WC_Order $order The order. * * @return array{id: string, items: list, total: float, subtotal: float, tax: float, shipping: float, discount: float} */ public static function ecommerce( WC_Order $order ): array { $currency = $order->get_currency(); $items = []; foreach ( $order->get_items() as $item ) { if ( ! $item instanceof WC_Order_Item_Product ) { continue; } $quantity = max( 1, (int) $item->get_quantity() ); $items[] = [ (string) $item->get_product_id(), $item->get_name(), '', Parse::money( (float) $item->get_subtotal() / $quantity, $currency ), $quantity, ]; } $discount = (float) $order->get_discount_total(); return [ 'id' => (string) $order->get_id(), 'items' => $items, 'total' => Parse::money( $order->get_total(), $currency ), 'subtotal' => Parse::money( (float) $order->get_subtotal() - $discount, $currency ), 'tax' => Parse::money( $order->get_total_tax(), $currency ), 'shipping' => Parse::money( $order->get_shipping_total(), $currency ), 'discount' => Parse::money( $discount, $currency ), ]; } }