Advertisement
Guest User

Untitled

a guest
Nov 12th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.90 KB | None | 0 0
  1. <?php
  2.  
  3. namespace App\Service\Cart;
  4.  
  5. use App\Entity\CartItem;
  6. use App\DTO\CartTreeNode;
  7. use App\Entity\Category;
  8. use App\Service\Utils\CategoryUtils;
  9.  
  10. /**
  11.  * Class CartTreeBuilder.
  12.  */
  13. class CartTreeBuilder
  14. {
  15.     /**
  16.      * @var array|CartItem[]
  17.      */
  18.     private $cartItems = [];
  19.  
  20.     /**
  21.      * @var array|Category[]
  22.      */
  23.     private $categories = [];
  24.  
  25.     /**
  26.      * @var array|CartTreeNode[]
  27.      */
  28.     private $tree = [];
  29.  
  30.     /**
  31.      * CartTreeBuilder constructor.
  32.      *
  33.      * @param CategoryUtils $categoryUtils
  34.      */
  35.     public function __construct(CategoryUtils $categoryUtils)
  36.     {
  37.         $this->categories = $categoryUtils->getAllCategories();
  38.     }
  39.  
  40.     /**
  41.      * @param array $cartItems
  42.      *
  43.      * @return array|CartTreeNode[]
  44.      */
  45.     public function build(array $cartItems): array
  46.     {
  47.         $this->cartItems = $cartItems;
  48.  
  49.         $this->buildRootNodes();
  50.  
  51.         foreach ($this->tree as $rootNode) {
  52.             $this->buildBranch($this->fillRootNodeWithCartItems($rootNode));
  53.  
  54.             if (0 === $rootNode->getCartItemsCount()) {
  55.                 unset($this->tree[array_search($rootNode, $this->tree)]);
  56.             }
  57.         }
  58.  
  59.         $result = $this->tree;
  60.  
  61.         $this->clearProperties();
  62.  
  63.         return $result;
  64.     }
  65.  
  66.     private function buildRootNodes(): void
  67.     {
  68.         foreach ($this->categories as $category) {
  69.             if (is_null($category->getParent())) {
  70.                 $node = new CartTreeNode();
  71.                 $node->setParent(null);
  72.                 $node->setCategory($category);
  73.  
  74.                 $this->tree[] = $node;
  75.             }
  76.         }
  77.     }
  78.  
  79.     /**
  80.      * @param CartTreeNode $rootNode
  81.      *
  82.      * @return CartTreeNode
  83.      */
  84.     private function fillRootNodeWithCartItems(CartTreeNode $rootNode): CartTreeNode
  85.     {
  86.         foreach ($this->cartItems as $cartItem) {
  87.             if ($cartItem->getItem()->getCategory() === $rootNode->getCategory()) {
  88.                 $remainsCount = $this->getRemainsCountByCartItem($cartItem);
  89.  
  90.                 $rootNode->addCartItem($cartItem);
  91.                 $rootNode->setTotalPrice($rootNode->getTotalPrice() + $cartItem->getItem()->getPrice() * $remainsCount);
  92.                 $rootNode->setCartItemsCount($rootNode->getCartItemsCount() + $remainsCount);
  93.  
  94.                 unset($this->cartItems[array_search($cartItem, $this->cartItems)]);
  95.             }
  96.         }
  97.  
  98.         return $rootNode;
  99.     }
  100.  
  101.     /**
  102.      * @param CartTreeNode $rootNode
  103.      */
  104.     private function buildBranch(CartTreeNode $rootNode): void
  105.     {
  106.         foreach ($this->categories as $category) {
  107.             foreach ($this->cartItems as $cartItem) {
  108.                 if ($cartItem->getItem()->getCategory() === $category) {
  109.                     $currentNode = $this->getChildNode($rootNode, $category, $cartItem);
  110.                     $remainsCount = $this->getRemainsCountByCartItem($cartItem);
  111.  
  112.                     $currentNode->addCartItem($cartItem);
  113.                     $currentNode->setTotalPrice($currentNode->getTotalPrice() + $cartItem->getItem()->getPrice() * $remainsCount);
  114.                     $currentNode->setCartItemsCount($currentNode->getCartItemsCount() + $remainsCount);
  115.  
  116.                     unset($this->cartItems[array_search($cartItem, $this->cartItems)]);
  117.  
  118.                     $rootNode->setTotalPrice($rootNode->getTotalPrice() + $currentNode->getTotalPrice());
  119.                     $rootNode->setCartItemsCount($rootNode->getCartItemsCount() + $remainsCount);
  120.                 }
  121.             }
  122.         }
  123.     }
  124.  
  125.     /**
  126.      * Возвращает существующую ноду-потомок или создает ее.
  127.      *
  128.      * @param CartTreeNode $cartTreeNode
  129.      * @param Category     $category
  130.      * @param CartItem     $cartItem
  131.      *
  132.      * @return CartTreeNode
  133.      */
  134.     private function getChildNode(CartTreeNode $cartTreeNode, Category $category, CartItem $cartItem): CartTreeNode
  135.     {
  136.         foreach ($cartTreeNode->getChildren() as $children) {
  137.             if ($children->getCategory() === $category && $cartItem->getItem()->getCategory() === $category) {
  138.                 return $children;
  139.             }
  140.         }
  141.  
  142.         $childNode = new CartTreeNode();
  143.         $childNode->setCategory($category);
  144.         $childNode->setParent($cartTreeNode);
  145.  
  146.         $cartTreeNode->addChild($childNode);
  147.  
  148.         return $childNode;
  149.     }
  150.  
  151.     /**
  152.      * @param CartItem $cartItem
  153.      *
  154.      * @return int
  155.      */
  156.     private function getRemainsCountByCartItem(CartItem $cartItem): int
  157.     {
  158.         $count = 0;
  159.  
  160.         foreach ($cartItem->getCartItemRemains() as $remain) {
  161.             $count += $remain->getCount();
  162.         }
  163.  
  164.         return $count;
  165.     }
  166.  
  167.     private function clearProperties(): void
  168.     {
  169.         $this->tree = [];
  170.         $this->cartItems = [];
  171.         $this->categories = [];
  172.     }
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement