diff --git a/ViewModel/DataLayer.php b/ViewModel/DataLayer.php new file mode 100644 index 0000000..8dcf6f5 --- /dev/null +++ b/ViewModel/DataLayer.php @@ -0,0 +1,149 @@ +taxHelper = $taxHelper; + $this->checkoutSession = $checkoutSession; + $this->request = $request; + $this->registry = $registry; + $this->helper = $helper; + } + + public function getSiteId() + { + return $this->helper->getSiteId(); + } + + public function getData() + { + if (!($siteId = $this->getSiteId())) { + return json_encode([]); + } + + /** + * The logic is functionally-equivalent to the _toHtml() function of the custom Salesfire block class herein. + * Additional comments have been added to highlight specifically where customisations have been made. + * @see SalesfireScript::_toHtml() + */ + + $formatter = new SalesfireFormatter($siteId); + $formatter->addPlatform('magento2'); + + if ($this->request->getFullActionName() == 'checkout_onepage_success' + && $order = $this->checkoutSession->getLastRealOrder() // customisation: use checkout session directly rather than class-level helper function + ) { + $transaction = new SalesfireTransactionType([ + 'id' => $order->getIncrementId(), + 'shipping' => round((float)$order->getShippingAmount(), 2), // customisation: float type casting + 'currency' => $order->getOrderCurrencyCode(), + 'coupon' => $order->getCouponCode(), + ]); + + foreach ($order->getAllVisibleItems() as $product) { + $variant = ''; + $options = $product->getProductOptions(); + $parent_product_id = $product_id = $product->getProductId(); + + if ($product->getHasChildren()) { + foreach ($product->getChildrenItems() as $child) { + $product_id = $child->getProductId(); + } + } + + if (!empty($options) && !empty($options['attribute_info'])) { + $variant = implode(', ', array_map(function ($item) { + return $item['label'].': '.$item['value']; + }, $options['attribute_info'])); + } + + $quantity = $product->getQtyOrdered() ?? 1; + $pricing = $this->calculateItemPriceAndTax($product, $quantity); + + $transaction->addProduct(new SalesfireProductType([ + 'sku' => $product_id, + 'parent_sku' => $parent_product_id, + 'name' => $product->getName(), + 'price' => round((float)$pricing['price'], 2), // customisation: float type casting + 'tax' => round((float)$pricing['tax'], 2), // customisation: float type casting + 'quantity' => round((float)$quantity, 2), // customisation: float type casting + 'variant' => $variant, + ])); + } + + $formatter->addTransaction($transaction); + } + + if ($product = $this->registry->registry('product')) { // customisation: use registry directly rather than class-level helper function + // Calculate product tax + $price = round((float)$this->taxHelper->getTaxPrice($product, $product->getFinalPrice(), false), 2); // customisation: float type casting + $tax = round((float)$this->taxHelper->getTaxPrice($product, $product->getFinalPrice(), true), 2) - $price; // customisation: float type casting + + $formatter->addProductView(new SalesfireProductType([ + 'sku' => $product->getId(), + 'parent_sku' => $product->getId(), + 'name' => $product->getName(), + 'price' => $price, + 'tax' => $tax, + ])); + } + + // customisation: return only the JSON as the template is responsible for pushing the data to the sfDataLayer + return $formatter->toJson(); + } + + /** + * This function has been copied as-is from the custom Salesfire block class, save for the function visibility which + * has been set to public rather than private for improved extensibility. + */ + public function calculateItemPriceAndTax($product, $quantity) + { + // Row totals represent all items in the order line (e.g., if qty=4, this is the total for all 4) + $rowTotal = $product->getRowTotal() ?: 0; + $rowTax = $product->getTaxAmount() ?: 0; + + if ($quantity <= 0) { + return ['price' => 0, 'tax' => 0]; + } + + return [ + 'price' => $rowTotal / $quantity, + 'tax' => $rowTax / $quantity, + ]; + } +} diff --git a/view/frontend/layout/hyva_default.xml b/view/frontend/layout/hyva_default.xml new file mode 100644 index 0000000..d113f80 --- /dev/null +++ b/view/frontend/layout/hyva_default.xml @@ -0,0 +1,23 @@ + + + + + + + + + https://cdn.salesfire.co.uk/code/ + false + true + + + + + diff --git a/view/frontend/templates/sf-cdn.phtml b/view/frontend/templates/sf-cdn.phtml new file mode 100644 index 0000000..3f86fc5 --- /dev/null +++ b/view/frontend/templates/sf-cdn.phtml @@ -0,0 +1,32 @@ +getData('url'))) { + return; +} + +/** @var ViewModelRegistry $viewModels */ +/** @var DataLayer $dataLayer */ +$dataLayer = $viewModels->require(DataLayer::class); +$siteId = $dataLayer->getSiteId(); + +if (!$siteId) { + return; +} + +$url .= $siteId . '.js'; +?> + +registerInlineScript(); ?> diff --git a/view/frontend/templates/sf-datalayer.phtml b/view/frontend/templates/sf-datalayer.phtml new file mode 100644 index 0000000..4c4a0a1 --- /dev/null +++ b/view/frontend/templates/sf-datalayer.phtml @@ -0,0 +1,30 @@ +require(DataLayer::class); +$data = $dataLayer->getData(); + +if (!$data) { + return; +} +?> + +registerInlineScript(); ?> diff --git a/view/frontend/templates/sfgetid.phtml b/view/frontend/templates/sfgetid.phtml new file mode 100644 index 0000000..e008cb7 --- /dev/null +++ b/view/frontend/templates/sfgetid.phtml @@ -0,0 +1,42 @@ + + +registerInlineScript(); ?>