Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace App\Service\Cart;
- use App\Entity\CartItem;
- use App\DTO\CartTreeNode;
- use App\Entity\Category;
- use App\Service\Utils\CategoryUtils;
- /**
- * Class CartTreeBuilder.
- */
- class CartTreeBuilder
- {
- /**
- * @var array|CartItem[]
- */
- private $cartItems = [];
- /**
- * @var array|Category[]
- */
- private $categories = [];
- /**
- * @var array|CartTreeNode[]
- */
- private $tree = [];
- /**
- * CartTreeBuilder constructor.
- *
- * @param CategoryUtils $categoryUtils
- */
- public function __construct(CategoryUtils $categoryUtils)
- {
- $this->categories = $categoryUtils->getAllCategories();
- }
- /**
- * @param array $cartItems
- *
- * @return array|CartTreeNode[]
- */
- public function build(array $cartItems): array
- {
- $this->cartItems = $cartItems;
- $this->buildRootNodes();
- foreach ($this->tree as $rootNode) {
- $this->buildBranch($this->fillRootNodeWithCartItems($rootNode));
- if (0 === $rootNode->getCartItemsCount()) {
- unset($this->tree[array_search($rootNode, $this->tree)]);
- }
- }
- $result = $this->tree;
- $this->clearProperties();
- return $result;
- }
- private function buildRootNodes(): void
- {
- foreach ($this->categories as $category) {
- if (is_null($category->getParent())) {
- $node = new CartTreeNode();
- $node->setParent(null);
- $node->setCategory($category);
- $this->tree[] = $node;
- }
- }
- }
- /**
- * @param CartTreeNode $rootNode
- *
- * @return CartTreeNode
- */
- private function fillRootNodeWithCartItems(CartTreeNode $rootNode): CartTreeNode
- {
- foreach ($this->cartItems as $cartItem) {
- if ($cartItem->getItem()->getCategory() === $rootNode->getCategory()) {
- $remainsCount = $this->getRemainsCountByCartItem($cartItem);
- $rootNode->addCartItem($cartItem);
- $rootNode->setTotalPrice($rootNode->getTotalPrice() + $cartItem->getItem()->getPrice() * $remainsCount);
- $rootNode->setCartItemsCount($rootNode->getCartItemsCount() + $remainsCount);
- unset($this->cartItems[array_search($cartItem, $this->cartItems)]);
- }
- }
- return $rootNode;
- }
- /**
- * @param CartTreeNode $rootNode
- */
- private function buildBranch(CartTreeNode $rootNode): void
- {
- foreach ($this->categories as $category) {
- foreach ($this->cartItems as $cartItem) {
- if ($cartItem->getItem()->getCategory() === $category) {
- $currentNode = $this->getChildNode($rootNode, $category, $cartItem);
- $remainsCount = $this->getRemainsCountByCartItem($cartItem);
- $currentNode->addCartItem($cartItem);
- $currentNode->setTotalPrice($currentNode->getTotalPrice() + $cartItem->getItem()->getPrice() * $remainsCount);
- $currentNode->setCartItemsCount($currentNode->getCartItemsCount() + $remainsCount);
- unset($this->cartItems[array_search($cartItem, $this->cartItems)]);
- $rootNode->setTotalPrice($rootNode->getTotalPrice() + $currentNode->getTotalPrice());
- $rootNode->setCartItemsCount($rootNode->getCartItemsCount() + $remainsCount);
- }
- }
- }
- }
- /**
- * Возвращает существующую ноду-потомок или создает ее.
- *
- * @param CartTreeNode $cartTreeNode
- * @param Category $category
- * @param CartItem $cartItem
- *
- * @return CartTreeNode
- */
- private function getChildNode(CartTreeNode $cartTreeNode, Category $category, CartItem $cartItem): CartTreeNode
- {
- foreach ($cartTreeNode->getChildren() as $children) {
- if ($children->getCategory() === $category && $cartItem->getItem()->getCategory() === $category) {
- return $children;
- }
- }
- $childNode = new CartTreeNode();
- $childNode->setCategory($category);
- $childNode->setParent($cartTreeNode);
- $cartTreeNode->addChild($childNode);
- return $childNode;
- }
- /**
- * @param CartItem $cartItem
- *
- * @return int
- */
- private function getRemainsCountByCartItem(CartItem $cartItem): int
- {
- $count = 0;
- foreach ($cartItem->getCartItemRemains() as $remain) {
- $count += $remain->getCount();
- }
- return $count;
- }
- private function clearProperties(): void
- {
- $this->tree = [];
- $this->cartItems = [];
- $this->categories = [];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement