Extension.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <?php
  2. namespace Dcat\Admin;
  3. use Illuminate\Support\Arr;
  4. use Illuminate\Support\Facades\Route;
  5. use Illuminate\Support\Facades\Validator;
  6. use Illuminate\Support\Str;
  7. use Illuminate\Console\Command;
  8. abstract class Extension
  9. {
  10. const NAME = null;
  11. /**
  12. * @var string
  13. */
  14. protected $serviceProvider;
  15. /**
  16. * @var array
  17. */
  18. protected $css = [];
  19. /**
  20. * @var array
  21. */
  22. protected $js = [];
  23. /**
  24. * @var string
  25. */
  26. protected $assets = '';
  27. /**
  28. * @var string
  29. */
  30. protected $views = '';
  31. /**
  32. * @var string
  33. */
  34. protected $lang = '';
  35. /**
  36. * @var string
  37. */
  38. protected $migrations = '';
  39. /**
  40. * @var string
  41. */
  42. protected $composerJson = '';
  43. /**
  44. * @var array
  45. */
  46. protected $menu = [];
  47. /**
  48. * @var array
  49. */
  50. protected $permission = [];
  51. /**
  52. * The menu validation rules.
  53. *
  54. * @var array
  55. */
  56. protected $menuValidationRules = [
  57. 'title' => 'required',
  58. 'path' => 'required',
  59. 'icon' => 'required',
  60. ];
  61. /**
  62. * The permission validation rules.
  63. *
  64. * @var array
  65. */
  66. protected $permissionValidationRules = [
  67. 'name' => 'required',
  68. 'slug' => 'required',
  69. 'path' => 'required',
  70. ];
  71. /**
  72. * @return string
  73. */
  74. public function getName()
  75. {
  76. return static::NAME;
  77. }
  78. /**
  79. * @return string
  80. */
  81. public function composerJson()
  82. {
  83. return $this->composerJson;
  84. }
  85. /**
  86. * @return string
  87. */
  88. public function serviceProvider()
  89. {
  90. return $this->serviceProvider;
  91. }
  92. /**
  93. * Get the path of assets files.
  94. *
  95. * @return string
  96. */
  97. public function assets()
  98. {
  99. return $this->assets;
  100. }
  101. /**
  102. * Get the paths of css files.
  103. *
  104. * @return array
  105. */
  106. public function css()
  107. {
  108. return $this->css;
  109. }
  110. /**
  111. * Get the paths of js files.
  112. *
  113. * @return array
  114. */
  115. public function js()
  116. {
  117. return $this->js;
  118. }
  119. /**
  120. * Get the path of view files.
  121. *
  122. * @return string
  123. */
  124. public function views()
  125. {
  126. return $this->views;
  127. }
  128. /**
  129. * Get the path of migration files.
  130. *
  131. * @return string
  132. */
  133. public function migrations()
  134. {
  135. return $this->migrations;
  136. }
  137. /**
  138. * @return array
  139. */
  140. public function menu()
  141. {
  142. return $this->menu;
  143. }
  144. /**
  145. * @return array
  146. */
  147. public function permission()
  148. {
  149. return $this->permission;
  150. }
  151. /**
  152. * @return string
  153. */
  154. public function lang()
  155. {
  156. return $this->lang;
  157. }
  158. /**
  159. * Whether the extension is enabled.
  160. *
  161. * @return bool
  162. */
  163. final public static function enabled()
  164. {
  165. return config('admin-extensions.'.static::NAME.'.enable') ? true : false;
  166. }
  167. /**
  168. * Whether the extension is disabled.
  169. *
  170. * @return bool
  171. */
  172. final public static function disabled()
  173. {
  174. return !static::enabled();
  175. }
  176. /**
  177. * Get config set in config/admin.php.
  178. *
  179. * @param string $key
  180. * @param null $default
  181. *
  182. * @return \Illuminate\Config\Repository|mixed
  183. */
  184. final public function config($key = null, $default = null)
  185. {
  186. if (is_null($key)) {
  187. $key = sprintf('admin.extensions.%s', static::NAME);
  188. } else {
  189. $key = sprintf('admin.extensions.%s.%s', static::NAME, $key);
  190. }
  191. return config($key, $default);
  192. }
  193. /**
  194. * Import menu item and permission to dcat-admin.
  195. */
  196. public function import(Command $command)
  197. {
  198. if ($menu = $this->menu()) {
  199. if ($this->validateMenu($menu)) {
  200. extract($menu);
  201. if ($this->checkMenuExist($path)) {
  202. $command->warn("Menu [$path] already exists!");
  203. } else {
  204. $this->createMenu($title, $path, $icon);
  205. $command->info("Import extension menu succeeded!");
  206. }
  207. }
  208. }
  209. if ($permission = $this->permission()) {
  210. if ($this->validatePermission($permission)) {
  211. extract($permission);
  212. if ($this->checkPermissionExist($slug)) {
  213. $command->warn("Permission [$slug] already exists!");
  214. } else {
  215. $this->createPermission($name, $slug, $path);
  216. $command->info("Import extension permission succeeded!");
  217. }
  218. }
  219. }
  220. }
  221. /**
  222. * Uninstall the extension.
  223. *
  224. * @param Command $command
  225. */
  226. public function uninstall(Command $command)
  227. {
  228. }
  229. /**
  230. * Validate menu fields.
  231. *
  232. * @param array $menu
  233. *
  234. * @throws \Exception
  235. *
  236. * @return bool
  237. */
  238. public function validateMenu(array $menu)
  239. {
  240. /** @var \Illuminate\Validation\Validator $validator */
  241. $validator = Validator::make($menu, $this->menuValidationRules);
  242. if ($validator->passes()) {
  243. return true;
  244. }
  245. $message = "Invalid menu:\r\n".implode("\r\n", Arr::flatten($validator->errors()->messages()));
  246. throw new \Exception($message);
  247. }
  248. /**
  249. * @param $path
  250. * @return bool
  251. */
  252. protected function checkMenuExist($path)
  253. {
  254. $menuModel = config('admin.database.menu_model');
  255. /* @var \Illuminate\Database\Eloquent\Builder $query */
  256. $query = $menuModel::query();
  257. $result = $query->where('uri', $path)
  258. ->get()
  259. ->first();
  260. return $result ? true : false;
  261. }
  262. /**
  263. * Validate permission fields.
  264. *
  265. * @param array $permission
  266. *
  267. * @throws \Exception
  268. *
  269. * @return bool
  270. */
  271. public function validatePermission(array $permission)
  272. {
  273. /** @var \Illuminate\Validation\Validator $validator */
  274. $validator = Validator::make($permission, $this->permissionValidationRules);
  275. if ($validator->passes()) {
  276. return true;
  277. }
  278. $message = "Invalid permission:\r\n".implode("\r\n", Arr::flatten($validator->errors()->messages()));
  279. throw new \Exception($message);
  280. }
  281. /**
  282. * Create a item in dcat-admin left side menu.
  283. *
  284. * @param string $title
  285. * @param string $uri
  286. * @param string $icon
  287. * @param int $parentId
  288. */
  289. protected function createMenu($title, $uri, $icon = 'fa-bars', $parentId = 0)
  290. {
  291. $menuModel = config('admin.database.menu_model');
  292. $lastOrder = $menuModel::max('order');
  293. $menuModel::create([
  294. 'parent_id' => $parentId,
  295. 'order' => $lastOrder + 1,
  296. 'title' => $title,
  297. 'icon' => $icon,
  298. 'uri' => $uri,
  299. ]);
  300. }
  301. /**
  302. * @param $slug
  303. * @return bool
  304. */
  305. protected function checkPermissionExist($slug)
  306. {
  307. $permissionModel = config('admin.database.permissions_model');
  308. /* @var \Illuminate\Database\Eloquent\Builder $query */
  309. $query = $permissionModel::query();
  310. $result = $query->where('slug', $slug)
  311. ->get()
  312. ->first();
  313. return $result ? true : false;
  314. }
  315. /**
  316. * Create a permission for this extension.
  317. *
  318. * @param $name
  319. * @param $slug
  320. * @param $path
  321. */
  322. protected function createPermission($name, $slug, $path)
  323. {
  324. $permissionModel = config('admin.database.permissions_model');
  325. $permissionModel::create([
  326. 'name' => $name,
  327. 'slug' => $slug,
  328. 'http_path' => '/'.trim($path, '/'),
  329. ]);
  330. }
  331. /**
  332. * Set routes for this extension.
  333. *
  334. * @param $callback
  335. */
  336. public function routes($callback)
  337. {
  338. $attributes = array_merge(
  339. [
  340. 'prefix' => config('admin.route.prefix'),
  341. 'middleware' => config('admin.route.middleware'),
  342. ],
  343. $this->config('route', [])
  344. );
  345. Route::group($attributes, $callback);
  346. }
  347. /**
  348. * @return static
  349. */
  350. public static function make()
  351. {
  352. return new static;
  353. }
  354. }