Просмотр файла app/Traits/CategoryTreeTrait.php

Размер файла: 2.36Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Traits;
  6.  
  7. use Illuminate\Database\Eloquent\Collection;
  8. use Illuminate\Database\Eloquent\Model;
  9.  
  10. trait CategoryTreeTrait
  11. {
  12. /**
  13. * Get parents
  14. *
  15. * @return Collection
  16. */
  17. public function getParents(): Collection
  18. {
  19. $flat = $this->buildParentCategoriesFlat($this);
  20.  
  21. return Collection::make($flat);
  22. }
  23.  
  24. /**
  25. * Get children
  26. *
  27. * @return Collection
  28. */
  29. public function getChildren(): Collection
  30. {
  31. $categories = $this::query()
  32. ->orderBy('sort')
  33. ->get();
  34.  
  35. $tree = $this->buildAllCategoriesTree($categories);
  36. $flat = $this->buildAllCategoriesFlat($tree);
  37.  
  38. return Collection::make($flat);
  39. }
  40.  
  41. /**
  42. * Build parent categories flat
  43. *
  44. * @param Model $category
  45. * @param array $tree
  46. *
  47. * @return array
  48. */
  49. private function buildParentCategoriesFlat(Model $category, array &$tree = []): array
  50. {
  51. if ($category->parent->id) {
  52. $this->buildParentCategoriesFlat($category->parent, $tree);
  53. }
  54.  
  55. $tree[] = $category;
  56.  
  57. return $tree;
  58. }
  59.  
  60. /**
  61. * Build all categories tree
  62. *
  63. * @param Collection $categories
  64. * @param int $parentId
  65. * @param int $depth
  66. *
  67. * @return array
  68. */
  69. private function buildAllCategoriesTree(Collection $categories, int $parentId = 0, int $depth = 0): array
  70. {
  71. $tree = [];
  72.  
  73. foreach ($categories as $category) {
  74. if ($category->parent_id === $parentId) {
  75. $child = $this->buildAllCategoriesTree($categories, $category->id, $depth + 1);
  76.  
  77. $category->depth = $depth;
  78.  
  79. if ($child) {
  80. $category->child = $child;
  81. }
  82.  
  83. $tree[] = $category;
  84. }
  85. }
  86.  
  87. return $tree;
  88. }
  89.  
  90. /**
  91. * Build all categories flat
  92. *
  93. * @param array $categories
  94. * @param array $flat
  95. *
  96. * @return array
  97. */
  98. private function buildAllCategoriesFlat(array $categories, array &$flat = []): array
  99. {
  100. foreach ($categories as $category) {
  101. $flat[] = $category;
  102.  
  103. if (isset($category->child)) {
  104. $this->buildAllCategoriesFlat($category->child, $flat);
  105. }
  106. }
  107.  
  108. return $flat;
  109. }
  110. }