1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Sco\Admin\Component; |
4
|
|
|
|
5
|
|
|
use Illuminate\Foundation\Application; |
6
|
|
|
use Illuminate\Http\Request; |
7
|
|
|
use Sco\Admin\Component\Concerns\HasEvents; |
8
|
|
|
use Sco\Admin\Component\Concerns\HasNavigation; |
9
|
|
|
use Sco\Admin\Contracts\ComponentInterface; |
10
|
|
|
use Sco\Admin\Contracts\Form\FormInterface; |
11
|
|
|
use Sco\Admin\Contracts\RepositoryInterface; |
12
|
|
|
use Sco\Admin\Contracts\View\ViewInterface; |
13
|
|
|
use Sco\Admin\Contracts\WithNavigation; |
14
|
|
|
use Sco\Admin\Exceptions\BadMethodCallException; |
15
|
|
|
use Sco\Admin\Exceptions\InvalidArgumentException; |
16
|
|
|
|
17
|
|
|
abstract class Component implements |
18
|
|
|
ComponentInterface, |
19
|
|
|
WithNavigation |
20
|
|
|
{ |
21
|
|
|
use HasEvents, |
22
|
|
|
HasNavigation; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var |
26
|
|
|
*/ |
27
|
|
|
protected $name; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var \Illuminate\Foundation\Application |
31
|
|
|
*/ |
32
|
|
|
protected $app; |
33
|
|
|
|
34
|
|
|
protected $title; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var mixed|\Sco\Admin\Contracts\RepositoryInterface |
38
|
|
|
*/ |
39
|
|
|
protected $repository; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var \Illuminate\Database\Eloquent\Model |
43
|
|
|
*/ |
44
|
|
|
protected $model; |
45
|
|
|
|
46
|
|
|
protected static $booted = []; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @var \Illuminate\Contracts\Events\Dispatcher |
50
|
|
|
*/ |
51
|
|
|
protected static $dispatcher; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var string |
55
|
|
|
*/ |
56
|
|
|
protected $permissionObserver; |
57
|
|
|
|
58
|
|
|
protected $permissions; |
59
|
|
|
|
60
|
|
|
protected $permissionMethods = [ |
61
|
|
|
'view', 'create', 'edit', |
62
|
|
|
'delete', 'destroy', 'restore', |
63
|
|
|
]; |
64
|
|
|
|
65
|
|
|
public function __construct(Application $app, $modelClass) |
66
|
|
|
{ |
67
|
|
|
$this->app = $app; |
68
|
|
|
|
69
|
|
|
$this->repository = $this->app->make(RepositoryInterface::class); |
70
|
|
|
$this->repository->setClass($modelClass); |
71
|
|
|
|
72
|
|
|
$this->model = $this->repository->getModel(); |
73
|
|
|
if (!$this->name) { |
74
|
|
|
$this->setDefaultName(); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$this->registerObserver($this->permissionObserver); |
78
|
|
|
|
79
|
|
|
$this->bootIfNotBooted(); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
protected function setDefaultName() |
83
|
|
|
{ |
84
|
|
|
$this->name = $this->getModelClassName(); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
protected function getModelClassName() |
88
|
|
|
{ |
89
|
|
|
return snake_case(str_plural(class_basename(get_class($this->getModel())))); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
public function getName() |
93
|
|
|
{ |
94
|
|
|
return $this->name; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
public function getTitle() |
98
|
|
|
{ |
99
|
|
|
return $this->title; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
public function getModel() |
103
|
|
|
{ |
104
|
|
|
return $this->model; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
public function getRepository() |
108
|
|
|
{ |
109
|
|
|
return $this->repository; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* {@inheritdoc} |
114
|
|
|
*/ |
115
|
|
|
public function getConfigs() |
116
|
|
|
{ |
117
|
|
|
return collect([ |
118
|
|
|
'primaryKey' => $this->getModel()->getKeyName(), |
119
|
|
|
'title' => $this->getTitle(), |
120
|
|
|
'permissions' => $this->getPermissions(), |
121
|
|
|
'view' => $this->fireView(), |
122
|
|
|
//'elements' => $this->getElements()->values(), |
|
|
|
|
123
|
|
|
]); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* {@inheritdoc} |
128
|
|
|
*/ |
129
|
|
|
public function fireView() |
130
|
|
|
{ |
131
|
|
|
if (!method_exists($this, 'callView')) { |
132
|
|
|
throw new BadMethodCallException('Not Found Method "callView"'); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
$view = $this->app->call([$this, 'callView']); |
136
|
|
|
|
137
|
|
|
if (!$view instanceof ViewInterface) { |
138
|
|
|
throw new InvalidArgumentException('callView must be instanced of Sco\Admin\Contracts\View\ViewInterface'); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
return $view; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
public function get() |
145
|
|
|
{ |
146
|
|
|
$view = $this->fireView(); |
147
|
|
|
|
148
|
|
|
$this->getRepository(); |
|
|
|
|
149
|
|
|
|
150
|
|
|
$view->setRepository($this->getRepository()); |
151
|
|
|
|
152
|
|
|
return $view->get(); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* {@inheritdoc} |
157
|
|
|
*/ |
158
|
|
|
public function fireCreate() |
159
|
|
|
{ |
160
|
|
|
if (!method_exists($this, 'callCreate')) { |
161
|
|
|
return; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
$form = $this->app->call([$this, 'callCreate']); |
165
|
|
|
if (!$form instanceof FormInterface) { |
166
|
|
|
throw new InvalidArgumentException('callCreate must be instanced of Sco\Admin\Contracts\Form\FormInterface'); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
$form->setModel($this->getModel()); |
170
|
|
|
|
171
|
|
|
return $form; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* {@inheritdoc} |
176
|
|
|
*/ |
177
|
|
|
public function store() |
178
|
|
|
{ |
179
|
|
|
$form = $this->fireCreate(); |
180
|
|
|
|
181
|
|
|
$form->validate()->save(); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* {@inheritdoc} |
186
|
|
|
*/ |
187
|
|
|
public function fireEdit($id) |
188
|
|
|
{ |
189
|
|
|
if (!method_exists($this, 'callEdit')) { |
190
|
|
|
return; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
$form = $this->app->call([$this, 'callEdit'], ['id' => $id]); |
194
|
|
|
|
195
|
|
|
if (!$form instanceof ViewInterface) { |
196
|
|
|
throw new InvalidArgumentException('callEdit must be instanced of Sco\Admin\Contracts\View\ViewInterface'); |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
$model = $this->getRepository()->findOrFail($id); |
200
|
|
|
|
201
|
|
|
$form->setModel($model); |
|
|
|
|
202
|
|
|
|
203
|
|
|
return $form; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* {@inheritdoc} |
208
|
|
|
*/ |
209
|
|
|
public function update($id) |
210
|
|
|
{ |
211
|
|
|
$form = $this->fireEdit($id); |
212
|
|
|
$form->validate()->save(); |
|
|
|
|
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
public function delete($id) |
216
|
|
|
{ |
217
|
|
|
$this->getRepository()->findOrFail($id)->delete(); |
218
|
|
|
return true; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
public function forceDelete($id) |
222
|
|
|
{ |
223
|
|
|
$this->getRepository()->forceDelete($id); |
224
|
|
|
return true; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
public function restore($id) |
228
|
|
|
{ |
229
|
|
|
$this->getRepository()->restore($id); |
230
|
|
|
return true; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
protected function bootIfNotBooted() |
234
|
|
|
{ |
235
|
|
|
if (!isset(static::$booted[static::class])) { |
236
|
|
|
static::$booted[static::class] = true; |
237
|
|
|
|
238
|
|
|
$this->fireEvent('booting', false); |
239
|
|
|
|
240
|
|
|
$this->boot(); |
|
|
|
|
241
|
|
|
|
242
|
|
|
$this->fireEvent('booted', false); |
243
|
|
|
} |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
public function boot() |
247
|
|
|
{ |
248
|
|
|
return true; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
public function isView() |
252
|
|
|
{ |
253
|
|
|
return method_exists($this, 'callView') && $this->can('view'); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
public function isCreate() |
257
|
|
|
{ |
258
|
|
|
return method_exists($this, 'callCreate') && $this->can('create'); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
public function isEdit() |
262
|
|
|
{ |
263
|
|
|
return method_exists($this, 'callEdit') && $this->can('edit'); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
public function isDelete() |
267
|
|
|
{ |
268
|
|
|
return $this->can('delete'); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
public function isDestroy() |
272
|
|
|
{ |
273
|
|
|
return $this->isRestorableModel() && $this->can('destroy'); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
public function isRestore() |
277
|
|
|
{ |
278
|
|
|
return $this->isRestorableModel() && $this->can('restore'); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
protected function isRestorableModel() |
282
|
|
|
{ |
283
|
|
|
return $this->getRepository()->isRestorable(); |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
public function registerObserver($class = null) |
287
|
|
|
{ |
288
|
|
|
if (!$class) { |
289
|
|
|
return; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
$className = is_string($class) ? $class : get_class($class); |
293
|
|
|
|
294
|
|
|
foreach ($this->permissionMethods as $method) { |
295
|
|
|
if (method_exists($class, $method)) { |
296
|
|
|
$this->registerPermission( |
297
|
|
|
$method, |
298
|
|
|
[$this->app->make($className), $method] |
299
|
|
|
); |
300
|
|
|
} |
301
|
|
|
} |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
public function registerPermission($permission, $callback) |
305
|
|
|
{ |
306
|
|
|
$this->permissions[$permission] = $callback; |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
public function can($permission) |
310
|
|
|
{ |
311
|
|
|
if (is_callable($this->permissions[$permission])) { |
312
|
|
|
return call_user_func_array($this->permissions[$permission], [$this]); |
313
|
|
|
} |
314
|
|
|
return $this->permissions[$permission] ? true : false; |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
public function getPermissions() |
318
|
|
|
{ |
319
|
|
|
$data = collect(); |
320
|
|
|
foreach ($this->permissionMethods as $perm) { |
321
|
|
|
$method = 'is' . ucfirst($perm); |
322
|
|
|
if (!method_exists($this, $method)) { |
323
|
|
|
$method = 'can'; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
$data->put($perm, $this->{$method}($perm)); |
327
|
|
|
} |
328
|
|
|
return $data; |
329
|
|
|
} |
330
|
|
|
} |
331
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.