vendor/pimcore/pimcore/bundles/EcommerceFrameworkBundle/Tracking/TrackingItemBuilder.php line 72

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\EcommerceFrameworkBundle\Tracking;
  15. use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\CartInterface;
  16. use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\CartItemInterface;
  17. use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\CartPriceModificator\ShippingInterface;
  18. use Pimcore\Bundle\EcommerceFrameworkBundle\Model\AbstractOrder;
  19. use Pimcore\Bundle\EcommerceFrameworkBundle\Model\AbstractOrderItem;
  20. use Pimcore\Bundle\EcommerceFrameworkBundle\Model\CheckoutableInterface;
  21. use Pimcore\Bundle\EcommerceFrameworkBundle\Model\ProductInterface;
  22. use Pimcore\Bundle\EcommerceFrameworkBundle\Type\Decimal;
  23. use Pimcore\Model\DataObject\AbstractObject;
  24. use Pimcore\Model\DataObject\Concrete;
  25. /**
  26.  * Takes an object (e.g. a product, an order) and transforms it into a
  27.  * normalized tracking object (e.g. a ProductAction or a Transaction).
  28.  */
  29. class TrackingItemBuilder implements TrackingItemBuilderInterface
  30. {
  31.     /**
  32.      * Build a product impression object
  33.      *
  34.      * @param ProductInterface&Concrete $product
  35.      * @param string $list
  36.      *
  37.      * @return ProductImpression
  38.      */
  39.     public function buildProductImpressionItem(ProductInterface $productstring $list 'default')
  40.     {
  41.         $item = new ProductImpression();
  42.         $this->initProductAttributes($item$product);
  43.         $item
  44.             ->setId($product->getId())
  45.             ->setName($this->normalizeName($product->getOSName()))
  46.             ->setCategories($this->getProductCategories($product))
  47.             ->setList($list)
  48.         ;
  49.         // set price if product is ready to check out
  50.         if ($product instanceof CheckoutableInterface) {
  51.             $item->setPrice($product->getOSPrice()->getAmount()->asNumeric());
  52.         }
  53.         return $item;
  54.     }
  55.     /**
  56.      * Build a product view object
  57.      *
  58.      * @param ProductInterface $product
  59.      *
  60.      * @return ProductAction
  61.      */
  62.     public function buildProductViewItem(ProductInterface $product)
  63.     {
  64.         return $this->buildProductActionItem($product);
  65.     }
  66.     /**
  67.      * Init common product action attributes and add additional application-specific product action attributes.
  68.      *
  69.      * @param AbstractProductData $item the tracking item that is going to be serialized later on.
  70.      * @param ProductInterface $product
  71.      */
  72.     protected function initProductAttributes(AbstractProductData $itemProductInterface $product)
  73.     {
  74.         $item
  75.             ->setId($product->getOSProductNumber())
  76.             ->setName($this->normalizeName($product->getOSName()))
  77.             ->setCategories($this->getProductCategories($product))
  78.             ->setBrand($this->getProductBrand($product))
  79.         ;
  80.         //
  81.         //Add additional data to tracking items of type "product".
  82.         //Example: $item->addAdditionalAttribute("ean", "test-EAN");
  83.         //
  84.     }
  85.     /**
  86.      * Build a product action item
  87.      *
  88.      * @param ProductInterface $product
  89.      * @param int $quantity
  90.      *
  91.      * @return ProductAction
  92.      */
  93.     public function buildProductActionItem(ProductInterface $product$quantity 1)
  94.     {
  95.         $item = new ProductAction();
  96.         $item->setQuantity($quantity);
  97.         $this->initProductAttributes($item$product);
  98.         // set price if product is ready to check out
  99.         if ($product instanceof CheckoutableInterface) {
  100.             $item->setPrice($product->getOSPrice()->getAmount()->asNumeric());
  101.         }
  102.         return $item;
  103.     }
  104.     /**
  105.      * Build a checkout transaction object
  106.      *
  107.      * @param AbstractOrder $order
  108.      *
  109.      * @return Transaction
  110.      */
  111.     public function buildCheckoutTransaction(AbstractOrder $order)
  112.     {
  113.         $transaction = new Transaction();
  114.         $transaction
  115.             ->setId($order->getOrdernumber())
  116.             ->setTotal(Decimal::create($order->getTotalPrice())->asNumeric())
  117.             ->setSubTotal(Decimal::create($order->getSubTotalPrice())->asNumeric())
  118.             ->setShipping($this->getOrderShipping($order))
  119.             ->setTax($this->getOrderTax($order));
  120.         return $transaction;
  121.     }
  122.     /**
  123.      * Build checkout items
  124.      *
  125.      * @param AbstractOrder $order
  126.      *
  127.      * @return ProductAction[]
  128.      */
  129.     public function buildCheckoutItems(AbstractOrder $order)
  130.     {
  131.         $items = [];
  132.         if (!$order->getItems()) {
  133.             return $items;
  134.         }
  135.         foreach ($order->getItems() as $orderItem) {
  136.             $items[] = $this->buildCheckoutItem($order$orderItem);
  137.         }
  138.         return $items;
  139.     }
  140.     /**
  141.      * Build checkout items
  142.      *
  143.      * @param CartInterface $cart
  144.      *
  145.      * @return ProductAction[]
  146.      */
  147.     public function buildCheckoutItemsByCart(CartInterface $cart)
  148.     {
  149.         $items = [];
  150.         if (!$cart->getItems()) {
  151.             return $items;
  152.         }
  153.         foreach ($cart->getItems() as $cartItem) {
  154.             /** @var ProductInterface|null $product */
  155.             $product $cartItem->getProduct();
  156.             if (!$product) {
  157.                 continue;
  158.             }
  159.             $items[] = $this->buildCheckoutItemByCartItem($cartItem);
  160.         }
  161.         return $items;
  162.     }
  163.     /**
  164.      * Build a checkout item object
  165.      *
  166.      * @param AbstractOrder $order
  167.      * @param AbstractOrderItem $orderItem
  168.      *
  169.      * @return ProductAction
  170.      */
  171.     public function buildCheckoutItem(AbstractOrder $orderAbstractOrderItem $orderItem)
  172.     {
  173.         /** @var ProductInterface $product */
  174.         $product $orderItem->getProduct();
  175.         $item = new ProductAction();
  176.         $item
  177.             ->setTransactionId($order->getOrdernumber())
  178.             ->setPrice(Decimal::create($orderItem->getTotalPrice())->div($orderItem->getAmount())->asNumeric())
  179.             ->setQuantity($orderItem->getAmount());
  180.         $this->initProductAttributes($item$product);
  181.         return $item;
  182.     }
  183.     /**
  184.      * Build a checkout item object by cart Item
  185.      *
  186.      * @param CartItemInterface $cartItem
  187.      *
  188.      * @return ProductAction
  189.      */
  190.     public function buildCheckoutItemByCartItem(CartItemInterface $cartItem)
  191.     {
  192.         /** @var ProductInterface|AbstractObject $product */
  193.         $product $cartItem->getProduct();
  194.         $item = new ProductAction();
  195.         $item->setPrice($cartItem->getTotalPrice()->getAmount()->div($cartItem->getCount())->asNumeric())
  196.             ->setQuantity($cartItem->getCount());
  197.         $this->initProductAttributes($item$product);
  198.         return $item;
  199.     }
  200.     /**
  201.      * Get a product's categories
  202.      *
  203.      * @param ProductInterface $product
  204.      * @param bool $first
  205.      *
  206.      * @return array|string
  207.      */
  208.     protected function getProductCategories(ProductInterface $product$first false)
  209.     {
  210.         $categories = [];
  211.         if (method_exists($product'getCategories')) {
  212.             if ($product->getCategories()) {
  213.                 foreach ($product->getCategories() as $category) {
  214.                     if ($category && method_exists($category'getName')) {
  215.                         $categories[] = $category->getName();
  216.                     }
  217.                 }
  218.             }
  219.         }
  220.         if (count($categories) > && $first) {
  221.             return $categories[0];
  222.         }
  223.         return $categories;
  224.     }
  225.     /**
  226.      * Get a product's brand
  227.      *
  228.      * @param ProductInterface $product
  229.      *
  230.      * @return null|string
  231.      */
  232.     protected function getProductBrand(ProductInterface $product)
  233.     {
  234.         $brandName null;
  235.         if (method_exists($product'getBrand')) {
  236.             if ($brand $product->getBrand()) {
  237.                 if (method_exists($brand'getName')) {
  238.                     $brandName $brand->getName();
  239.                 }
  240.             }
  241.         }
  242.         return $brandName;
  243.     }
  244.     /**
  245.      * Get order shipping
  246.      *
  247.      * @param AbstractOrder $order
  248.      *
  249.      * @return float
  250.      */
  251.     protected function getOrderShipping(AbstractOrder $order)
  252.     {
  253.         $shipping Decimal::zero();
  254.         // calculate shipping
  255.         $modifications $order->getPriceModifications();
  256.         if ($modifications) {
  257.             foreach ($modifications as $modification) {
  258.                 if ($modification instanceof ShippingInterface) {
  259.                     $shipping $shipping->add($modification->getCharge());
  260.                 }
  261.             }
  262.         }
  263.         return $shipping->asNumeric();
  264.     }
  265.     /**
  266.      * Get order tax
  267.      *
  268.      * @param AbstractOrder $order
  269.      *
  270.      * @return float
  271.      */
  272.     protected function getOrderTax(AbstractOrder $order)
  273.     {
  274.         $tax Decimal::zero();
  275.         foreach ($order->getTaxInfo() as $taxInfo) {
  276.             $tax $tax->add(Decimal::create($taxInfo[2]));
  277.         }
  278.         return $tax->asNumeric();
  279.     }
  280.     /**
  281.      * Normalize name for tracking JS
  282.      *
  283.      * @param string $name
  284.      *
  285.      * @return string
  286.      */
  287.     protected function normalizeName($name)
  288.     {
  289.         return str_replace(["\n"], [' '], $name);
  290.     }
  291. }