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