Menu.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. namespace Dcat\Admin\Layout;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Support\Helper;
  5. use Illuminate\Support\Facades\Lang;
  6. class Menu
  7. {
  8. protected static $helperNodes = [
  9. [
  10. 'id' => 1,
  11. 'title' => 'Helpers',
  12. 'icon' => 'fa fa-keyboard-o',
  13. 'uri' => '',
  14. 'parent_id' => 0,
  15. ],
  16. [
  17. 'id' => 2,
  18. 'title' => 'Extensions',
  19. 'icon' => '',
  20. 'uri' => 'auth/extensions',
  21. 'parent_id' => 1,
  22. ],
  23. [
  24. 'id' => 3,
  25. 'title' => 'Scaffold',
  26. 'icon' => '',
  27. 'uri' => 'helpers/scaffold',
  28. 'parent_id' => 1,
  29. ],
  30. [
  31. 'id' => 4,
  32. 'title' => 'Icons',
  33. 'icon' => '',
  34. 'uri' => 'helpers/icons',
  35. 'parent_id' => 1,
  36. ],
  37. ];
  38. protected $view = 'admin::partials.menu';
  39. public function register()
  40. {
  41. if (! admin_has_default_section(Admin::SECTION['LEFT_SIDEBAR_MENU'])) {
  42. admin_inject_default_section(Admin::SECTION['LEFT_SIDEBAR_MENU'], function () {
  43. $menuModel = config('admin.database.menu_model');
  44. return $this->toHtml((new $menuModel())->allNodes()->toArray());
  45. });
  46. }
  47. if (config('app.debug') && config('admin.helpers.enable', true)) {
  48. $this->add(static::$helperNodes, 20);
  49. }
  50. }
  51. /**
  52. * 增加菜单节点.
  53. *
  54. * @param array $nodes
  55. * @param int $priority
  56. * @return void
  57. */
  58. public function add(array $nodes = [], int $priority = 10)
  59. {
  60. admin_inject_section(Admin::SECTION['LEFT_SIDEBAR_MENU_BOTTOM'], function () use (&$nodes) {
  61. return $this->toHtml($nodes);
  62. }, true, $priority);
  63. }
  64. /**
  65. * 转化为HTML.
  66. *
  67. * @param array $nodes
  68. * @return string
  69. *
  70. * @throws \Throwable
  71. */
  72. public function toHtml($nodes)
  73. {
  74. $html = '';
  75. foreach (Helper::buildNestedArray($nodes) as $item) {
  76. $html .= $this->render($item);
  77. }
  78. return $html;
  79. }
  80. /**
  81. * 设置菜单视图.
  82. *
  83. * @param string $view
  84. * @return $this
  85. */
  86. public function view(string $view)
  87. {
  88. $this->view = $view;
  89. return $this;
  90. }
  91. /**
  92. * 渲染视图.
  93. *
  94. * @param array $item
  95. * @return string
  96. */
  97. public function render($item)
  98. {
  99. return view($this->view, ['item' => &$item, 'builder' => $this])->render();
  100. }
  101. /**
  102. * 判断是否选中.
  103. *
  104. * @param array $item
  105. * @param null|string $path
  106. * @return bool
  107. */
  108. public function isActive($item, ?string $path = null)
  109. {
  110. if (empty($path)) {
  111. $path = request()->path();
  112. }
  113. if (empty($item['children'])) {
  114. if (empty($item['uri'])) {
  115. return false;
  116. }
  117. return trim($this->getPath($item['uri']), '/') == $path;
  118. }
  119. foreach ($item['children'] as $v) {
  120. if ($path == trim($this->getPath($v['uri']), '/')) {
  121. return true;
  122. }
  123. if (! empty($v['children'])) {
  124. if ($this->isActive($v, $path)) {
  125. return true;
  126. }
  127. }
  128. }
  129. return false;
  130. }
  131. /**
  132. * 判断节点是否可见.
  133. *
  134. * @param array $item
  135. * @return bool
  136. */
  137. public function visible($item)
  138. {
  139. if (
  140. ! $this->checkPermission($item)
  141. || ! $this->checkExtension($item)
  142. || ! $this->userCanSeeMenu($item)
  143. ) {
  144. return false;
  145. }
  146. $show = $item['show'] ?? null;
  147. if ($show !== null && ! $show) {
  148. return false;
  149. }
  150. return true;
  151. }
  152. /**
  153. * 判断扩展是否启用.
  154. *
  155. * @param $item
  156. * @return bool
  157. */
  158. protected function checkExtension($item)
  159. {
  160. $extension = $item['extension'] ?? null;
  161. if (! $extension) {
  162. return true;
  163. }
  164. if (! $extension = Admin::extension($extension)) {
  165. return false;
  166. }
  167. return $extension->enabled();
  168. }
  169. /**
  170. * 判断用户.
  171. *
  172. * @param array|\Dcat\Admin\Models\Menu $item
  173. * @return bool
  174. */
  175. protected function userCanSeeMenu($item)
  176. {
  177. $user = Admin::user();
  178. if (! $user || ! method_exists($user, 'canSeeMenu')) {
  179. return true;
  180. }
  181. return $user->canSeeMenu($item);
  182. }
  183. /**
  184. * 判断权限.
  185. *
  186. * @param $item
  187. * @return bool
  188. */
  189. protected function checkPermission($item)
  190. {
  191. $permissionIds = $item['permission_id'] ?? null;
  192. $roles = array_column(Helper::array($item['roles'] ?? []), 'slug');
  193. $permissions = array_column(Helper::array($item['permissions'] ?? []), 'slug');
  194. if (! $permissionIds && ! $roles && ! $permissions) {
  195. return true;
  196. }
  197. $user = Admin::user();
  198. if (! $user || $user->visible($roles)) {
  199. return true;
  200. }
  201. foreach (array_merge(Helper::array($permissionIds), $permissions) as $permission) {
  202. if ($user->can($permission)) {
  203. return true;
  204. }
  205. }
  206. return false;
  207. }
  208. /**
  209. * @param string $text
  210. * @return string
  211. */
  212. public function translate($text)
  213. {
  214. $titleTranslation = 'menu.titles.'.trim(str_replace(' ', '_', strtolower($text)));
  215. if (Lang::has($titleTranslation)) {
  216. return __($titleTranslation);
  217. }
  218. return $text;
  219. }
  220. /**
  221. * @param string $uri
  222. * @return string
  223. */
  224. public function getPath($uri)
  225. {
  226. return $uri
  227. ? (url()->isValidUrl($uri) ? $uri : admin_base_path($uri))
  228. : $uri;
  229. }
  230. /**
  231. * @param string $uri
  232. * @return string
  233. */
  234. public function getUrl($uri)
  235. {
  236. return $uri ? admin_url($uri) : $uri;
  237. }
  238. }