FamilyTree.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. /**
  3. * Author: lf
  4. * Blog: https://blog.feehi.com
  5. * Email: job@feehi.com
  6. * Created at: 2020-02-29 21:13
  7. */
  8. namespace common\libs;
  9. use yii\helpers\ArrayHelper;
  10. trait FamilyTree
  11. {
  12. abstract public function getItems();
  13. public function getIdSign()
  14. {
  15. return "id";
  16. }
  17. public function getParentSign()
  18. {
  19. return "parent_id";
  20. }
  21. public function getLevelSign()
  22. {
  23. return "level";
  24. }
  25. /**
  26. * 获取某节点的所有子节点
  27. *
  28. * @param $id
  29. * @return array
  30. */
  31. public function getSons($id)
  32. {
  33. $items = $this->getItems();
  34. $sons = [];
  35. foreach ($items as $key => $value) {
  36. if ($value[$this->getParentSign()] == $id) {
  37. $sons[] = $value;
  38. }
  39. }
  40. return $sons;
  41. }
  42. /**
  43. * 获取某节点的所有子孙节点
  44. *
  45. * @param $id
  46. * @param int $level
  47. * @return array
  48. */
  49. public function getDescendants($id, $level = 1)
  50. {
  51. $nodes = [];
  52. $items = $this->getItems();
  53. foreach ($items as $key => $value) {
  54. if ($value[$this->getParentSign()] == $id) {
  55. $value[$this->getLevelSign()] = $level;
  56. $nodes[] = $value;
  57. $nodes = array_merge($nodes, $this->getDescendants($value[$this->getIdSign()], $level + 1));
  58. }
  59. }
  60. return $nodes;
  61. }
  62. /**
  63. * 获取某节点的所有父节点
  64. *
  65. * @param $id
  66. * @return array
  67. */
  68. public function getParents($id)
  69. {
  70. $nodes = [];
  71. $items = $this->getItems();
  72. $items = ArrayHelper::index($items, $this->getIdSign());
  73. foreach ($items as $key => $value) {
  74. if ($items[$id][$this->getParentSign()] == $value[$this->getIdSign()]) {
  75. $nodes[] = $value;
  76. }
  77. }
  78. return $nodes;
  79. }
  80. /**
  81. * 递归获取祖先节点
  82. *
  83. * @param $id
  84. * @return array
  85. */
  86. public function getAncestors($id)
  87. {
  88. $nodes = [];
  89. $items = $this->getItems();
  90. foreach ($items as $key => $value) {
  91. if ($value[$this->getIdSign()] == $id) {
  92. $nodes[] = $value;
  93. if ($value[$this->getParentSign()] != 0) {
  94. $nodes = array_merge($nodes, $this->getAncestors($value[$this->getParentSign()]));
  95. }
  96. }
  97. }
  98. return $nodes;
  99. }
  100. }