Admin.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. namespace App\Http\Middleware\Prepare;
  3. use Closure;
  4. use Illuminate\Support\Facades\View;
  5. use Spatie\Menu\Laravel\Facades\Menu;
  6. use Spatie\Menu\Laravel\Link;
  7. use Spatie\Menu\Laravel\Html;
  8. use Exception;
  9. class Admin
  10. {
  11. /**
  12. * Handle an incoming request.
  13. *
  14. * @param \Illuminate\Http\Request $request
  15. * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
  16. * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
  17. */
  18. public function handle($request, Closure $next)
  19. {
  20. $menus = config('menus');
  21. // 관리자 메뉴 설정
  22. $routers = $this->routers($menus);
  23. // 현재 메뉴 위치 조회
  24. $menus = $this->buildMenu($menus, $routers);
  25. View::share('menus', $menus);
  26. unset($menus, $routers, $menus);
  27. return $next($request);
  28. }
  29. /**
  30. * 관리자 메뉴 배열화
  31. */
  32. private function routers(array $menus, $arr = [], $parent = null)
  33. {
  34. foreach ($menus as $controller => $row) {
  35. $info = (key($row) == '/' ? current($row) : $row);
  36. if ($parent) {
  37. $segment = [
  38. ADMIN_PATH,
  39. $parent,
  40. $controller
  41. ];
  42. } else {
  43. $segment = [
  44. ADMIN_PATH,
  45. $controller
  46. ];
  47. }
  48. $arr[$info[1]] = join(DIRECTORY_SEPARATOR, $segment);
  49. if (isset($info[5]) && $info[5]) {
  50. $arr = $this->routers($info[5], $arr, $controller);
  51. }
  52. }
  53. return $arr;
  54. }
  55. /**
  56. * 관리자 메뉴 생성
  57. */
  58. private function buildMenu(array $menus, array $routers): \Spatie\Menu\Menu|callable
  59. {
  60. $menu = Menu::new();
  61. $segments = request()->segments();
  62. foreach ($menus as $row) {
  63. $info = (key($row) == '/' ? current($row) : $row);
  64. $router = (array_key_exists($info[1], $routers) ? $routers[$info[1]] : "");
  65. try {
  66. $link = Link::to(url($router), (
  67. ($info[3] ? Html::raw(sprintf('<i class="%s"></i>', $info[3]))->render() : '') .
  68. Html::raw(sprintf('<span class="ps-2">%s</span>', $info[2]))->render()
  69. ))->addClass('nav-link')->setActive(function () use ($router, $routers, $segments) {
  70. $d1 = array_filter($segments);
  71. $d2 = array_filter(explode(DIRECTORY_SEPARATOR, $router));
  72. $c = count(array_diff($d1, $d2));
  73. $e = join(DIRECTORY_SEPARATOR, $d1);
  74. if (in_array($e, $routers)) {
  75. if ($c == 0 && ($router == $e)) {
  76. return true;
  77. }
  78. } else if (count($d1) == count($d2)) {
  79. if ($c == 1) {
  80. array_splice($d2, -1, 1);
  81. return request()->is(join(DIRECTORY_SEPARATOR, $d2) . '/*');
  82. }
  83. }
  84. return false;
  85. });
  86. if (isset($info[5]) && $info[5]) {
  87. $id = ('menu_' . $info[1]);
  88. $menu->submenu(
  89. // 상위 메뉴
  90. $link->setAttributes([
  91. 'data-bs-target' => ('#' . $id),
  92. 'data-bs-toggle' => 'collapse',
  93. 'role' => 'button',
  94. 'aria-expanded' => 'false',
  95. 'aria-controls' => $id
  96. ])->setActive(function () use ($router) {
  97. return request()->is($router . '/*');
  98. }),
  99. // 하위 메뉴
  100. Menu::new()
  101. ->withoutWrapperTag()
  102. ->withoutParentTag()
  103. ->html(
  104. sprintf('<div id="%s" class="collapse">%s</div>', $id, $this->buildMenu($info[5], $routers))
  105. )
  106. );
  107. } else {
  108. $menu->add(
  109. $link
  110. );
  111. }
  112. unset($info, $router, $link);
  113. } catch (Exception) {
  114. exit('관리자 메뉴 설정 값이 잘못되었습니다.');
  115. }
  116. }
  117. unset($menus, $routers, $segments);
  118. return $menu->addClass('nav flex-column');
  119. }
  120. }