the one wire vocabulary all three store * snippets send (in_stock / out_of_stock / backorder). * * @param mixed $status 'instock' | 'outofstock' | 'onbackorder' | other * @return string|null */ public static function stock_status($status) { switch ($status) { case 'instock': return 'in_stock'; case 'outofstock': return 'out_of_stock'; case 'onbackorder': return 'backorder'; default: return null; } } /** * Build the add_to_cart wire event. Property names are the ones the * snippet already sent (productId, quantity) plus variantId, price, * currency, name, sku and stock. * * @param array $a product_id, variation_id, quantity, price, currency, name, sku, in_stock, stock_status, event_id * @return array|null null when there is no product id */ public static function add_to_cart_event(array $a) { $product_id = isset($a['product_id']) ? (int) $a['product_id'] : 0; if ($product_id <= 0) { return null; } $variation_id = isset($a['variation_id']) ? (int) $a['variation_id'] : 0; $quantity = isset($a['quantity']) ? (float) $a['quantity'] : 1; if ($quantity <= 0) { $quantity = 1; } // Whole quantities as ints (2, not 2.0) - decimal quantities exist with // some plugins and are kept as they are. if ($quantity == (int) $quantity) { $quantity = (int) $quantity; } $data = array( 'productId' => (string) $product_id, 'variantId' => $variation_id > 0 ? (string) $variation_id : null, 'quantity' => $quantity, 'price' => isset($a['price']) && $a['price'] !== '' ? (float) $a['price'] : null, 'currency' => !empty($a['currency']) ? (string) $a['currency'] : null, 'name' => isset($a['name']) ? (string) $a['name'] : null, 'sku' => isset($a['sku']) && $a['sku'] !== '' ? (string) $a['sku'] : null, 'inStock' => isset($a['in_stock']) ? (bool) $a['in_stock'] : null, 'stockStatus' => self::stock_status(isset($a['stock_status']) ? $a['stock_status'] : null), ); return array( 'eventId' => (string) $a['event_id'], 'eventType' => 'add_to_cart', 'data' => array_filter($data, function ($v) { return $v !== null; }), ); } /** * Append an event, ignoring a repeat of an id already queued and keeping * only the newest MAX_QUEUED. * * @param mixed $queue whatever the session held (non-arrays reset it) * @param array|null $event * @return array */ public static function enqueue($queue, $event) { $queue = self::clean($queue); if (!is_array($event) || empty($event['eventId']) || empty($event['eventType'])) { return $queue; } foreach ($queue as $queued) { if ($queued['eventId'] === $event['eventId']) { return $queue; } } $queue[] = $event; if (count($queue) > self::MAX_QUEUED) { $queue = array_slice($queue, -self::MAX_QUEUED); } return $queue; } /** * Only well-formed events survive a round trip through the session. * * @param mixed $queue * @return array */ public static function clean($queue) { if (!is_array($queue)) { return array(); } $out = array(); foreach ($queue as $e) { if (is_array($e) && !empty($e['eventId']) && is_string($e['eventId']) && !empty($e['eventType']) && is_string($e['eventType'])) { $out[] = array( 'eventId' => $e['eventId'], 'eventType' => $e['eventType'], 'data' => isset($e['data']) && is_array($e['data']) ? $e['data'] : array(), ); } } return array_values($out); } /** * Category page payload (wire event collection_viewed -> Product List Viewed). * * @return array|null */ public static function category_payload($term_id, $name, $url) { $term_id = (int) $term_id; if ($term_id <= 0) { return null; } return array( 'categoryId' => (string) $term_id, 'categoryName' => (string) $name, 'url' => (string) $url, ); } }