1 | <?php |
||
56 | abstract class AbstractTableController |
||
57 | { |
||
58 | use ValidatesRequests; |
||
59 | use NotifyTrait; |
||
60 | use AliasesTrait; |
||
61 | use DeleteHandlerTrait; |
||
62 | use ToolbarHandlerTrait; |
||
63 | use InlineHandlerTrait; |
||
64 | use ForceDeleteHandlerTrait; |
||
65 | use RestoreHandlerTrait; |
||
66 | use UpdateHandlerTrait; |
||
67 | use StoreHandlerTrait; |
||
68 | use ListHandlerTrait; |
||
69 | use EditHandlerTrait; |
||
70 | use CreateHandlerTrait; |
||
71 | use OrderByHandlerTrait; |
||
72 | use PerPageHandlerTrait; |
||
73 | use SortableHandlerTrait; |
||
74 | use SearchRelationHandlerTrait; |
||
75 | use SearchHandlerTrait; |
||
76 | use BreadcrumbsTrait; |
||
77 | use RenderRepeaterItemHandlerTrait; |
||
78 | use HistoryHandlerTrait; |
||
79 | use RevertHandlerTrait; |
||
80 | |||
81 | /** |
||
82 | * Permission group name. |
||
83 | * |
||
84 | * @var string|array |
||
85 | * array( |
||
86 | * 'list' => 'permission:list', |
||
87 | * 'search' => 'permission:search', |
||
88 | * 'create' => 'permission:create', |
||
89 | * 'store' => 'permission:store', |
||
90 | * 'edit' => 'permission:edit', |
||
91 | * 'update' => 'permission:update', |
||
92 | * 'inline' => 'permission:inline', |
||
93 | * 'delete' => 'permission:delete', |
||
94 | * 'restore' => 'permission:restore', |
||
95 | * 'forceDelete' => 'permission:force-delete', |
||
96 | * 'history' => 'permission:history', |
||
97 | * 'revert' => 'permission:revert', |
||
98 | * ) |
||
99 | */ |
||
100 | protected $permissions = ''; |
||
101 | |||
102 | /** |
||
103 | * @var CRUD |
||
104 | */ |
||
105 | protected $crud; |
||
106 | |||
107 | /** |
||
108 | * ID of manipulated model. |
||
109 | * |
||
110 | * @var mixed |
||
111 | */ |
||
112 | protected $idEntity; |
||
113 | |||
114 | 79 | public function __construct() |
|
115 | { |
||
116 | 79 | $this->crud = app(CRUD::class); |
|
117 | 79 | $this->crud()->tableIdentifier(crc32(static::class)); |
|
118 | 79 | $this->crud()->formClass(config('jarboe.crud.form_class')); |
|
119 | 79 | $this->crud()->actions()->set([ |
|
120 | 79 | CreateAction::make(), |
|
121 | 79 | EditAction::make(), |
|
122 | 79 | RestoreAction::make(), |
|
123 | 79 | DeleteAction::make(), |
|
124 | 79 | ForceDeleteAction::make(), |
|
125 | ]); |
||
126 | 79 | $this->breadcrumbs = app(BreadcrumbsInterface::class); |
|
127 | 79 | } |
|
128 | |||
129 | 79 | protected function crud(): CRUD |
|
130 | { |
||
131 | 79 | return $this->crud; |
|
132 | } |
||
133 | |||
134 | /** |
||
135 | * Check if user has permission for the action. |
||
136 | * |
||
137 | * @param $action |
||
138 | * @return bool |
||
139 | */ |
||
140 | 44 | protected function can($action): bool |
|
157 | |||
158 | 27 | public function __call($name, $arguments) |
|
159 | { |
||
160 | /** @var Request $request */ |
||
161 | 27 | $request = RequestFacade::instance(); |
|
162 | |||
163 | 27 | $id = null; |
|
164 | 27 | if (isset($arguments[0])) { |
|
165 | 26 | $id = $arguments[1] ?? $arguments[0]; |
|
166 | } |
||
167 | |||
168 | try { |
||
169 | 27 | switch ($name) { |
|
170 | 27 | case 'list': |
|
171 | 4 | return $this->handleList($request); |
|
172 | 23 | case 'search': |
|
173 | 2 | return $this->handleSearch($request); |
|
174 | 21 | case 'create': |
|
175 | 2 | return $this->handleCreate($request); |
|
176 | 19 | case 'store': |
|
177 | 2 | return $this->handleStore($request); |
|
178 | 17 | case 'edit': |
|
179 | 2 | return $this->handleEdit($request, $id); |
|
180 | 15 | case 'update': |
|
181 | 2 | return $this->handleUpdate($request, $id); |
|
182 | 13 | case 'delete': |
|
183 | 2 | return $this->handleDelete($request, $id); |
|
184 | 11 | case 'restore': |
|
185 | 3 | return $this->handleRestore($request, $id); |
|
186 | 8 | case 'forceDelete': |
|
187 | 2 | return $this->handleForceDelete($request, $id); |
|
188 | 6 | case 'inline': |
|
189 | 2 | return $this->handleInline($request); |
|
190 | 4 | case 'renderRepeaterItem': |
|
191 | $fieldName = $id; |
||
192 | return $this->handleRenderRepeaterItem($request, $fieldName); |
||
193 | 4 | case 'history': |
|
194 | 2 | return $this->handleHistory($request, $id); |
|
195 | 2 | case 'revert': |
|
196 | 1 | return $this->handleRevert($request, $id); |
|
197 | |||
198 | default: |
||
199 | 1 | throw new \RuntimeException('Invalid method ' . $name); |
|
200 | } |
||
201 | 13 | } catch (ValidationException $e) { |
|
202 | 1 | throw $e; |
|
203 | 12 | } catch (UnauthorizedException $e) { |
|
204 | 11 | return $this->createUnauthorizedResponse($request, $e); |
|
205 | 1 | } catch (\Throwable $e) { |
|
206 | 1 | $response = $this->onException($e); |
|
207 | 1 | if (!is_null($response)) { |
|
208 | return $response; |
||
209 | } |
||
210 | |||
211 | // TODO: response objects |
||
212 | 1 | if ($request->isXmlHttpRequest() || $request->wantsJson()) { |
|
213 | return response()->json([ |
||
214 | 'title' => get_class($e), |
||
215 | 'description' => $e->getMessage(), |
||
216 | ], 406); |
||
217 | } |
||
218 | |||
219 | 1 | $this->notifyBigDanger(get_class($e), $e->getMessage(), 0); |
|
220 | |||
221 | /** @var RedirectResponse $redirect */ |
||
222 | 1 | $redirect = redirect()->back(); |
|
223 | 1 | if ($redirect->getTargetUrl() == $request->url()) { |
|
224 | 1 | $redirect->setTargetUrl(admin_url()); |
|
225 | } |
||
226 | |||
227 | 1 | return $redirect->withInput($request->input()); |
|
228 | } |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Event for processing exceptions before forming error response. |
||
233 | * Non-null return value will be processed as response. |
||
234 | * |
||
235 | * @param \Throwable $exception |
||
236 | * |
||
237 | * @return mixed|void |
||
238 | */ |
||
239 | 1 | protected function onException(\Throwable $exception) |
|
243 | |||
244 | /** |
||
245 | * Method for overriding to define basic/common init() settings. |
||
246 | * |
||
247 | * @return void |
||
248 | */ |
||
249 | 51 | protected function beforeInit() |
|
253 | |||
254 | /** |
||
255 | * Bound fields/tools/etc with global data. |
||
256 | */ |
||
257 | 59 | protected function bound() |
|
275 | |||
276 | /** |
||
277 | * Create response for unauthorized request. |
||
278 | * |
||
279 | * @param Request $request |
||
280 | * @param UnauthorizedException $exception |
||
281 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View |
||
282 | */ |
||
283 | 12 | protected function createUnauthorizedResponse(Request $request, UnauthorizedException $exception) |
|
293 | |||
294 | /** |
||
295 | * Get model for current request. |
||
296 | * |
||
297 | * @return string |
||
298 | * @throws \RuntimeException |
||
299 | */ |
||
300 | protected function model() |
||
308 | |||
309 | /** |
||
310 | * @return void |
||
311 | */ |
||
312 | abstract protected function init(); |
||
313 | } |
||
314 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: