Extension.php 7.0 KB

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