These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Eliurkis\Crud; |
||
4 | |||
5 | use DB; |
||
6 | use Illuminate\Http\Request; |
||
7 | use App\Http\Controllers\Controller; |
||
8 | use Illuminate\Database\QueryException; |
||
9 | use Illuminate\Database\Eloquent\Builder; |
||
10 | |||
11 | class CrudController extends Controller |
||
12 | { |
||
13 | protected $route; |
||
14 | protected $entity; |
||
15 | protected $entityInstance = null; |
||
16 | protected $fields = []; |
||
17 | protected $columns = []; |
||
18 | protected $buttons = [ |
||
19 | 'create', |
||
20 | 'edit', |
||
21 | 'delete', |
||
22 | ]; |
||
23 | protected $paginate = null; |
||
24 | protected $searchable = []; |
||
25 | protected $filters = []; |
||
26 | protected $queryFilters = []; |
||
27 | protected $orderBy = []; |
||
28 | protected $orderByRaw = null; |
||
29 | protected $filterRequire = []; |
||
30 | protected $textsGeneral = [ |
||
31 | 'list_title' => 'Contents', |
||
32 | 'create_title' => '', |
||
33 | 'edit_title' => '', |
||
34 | ]; |
||
35 | protected $texts = []; |
||
36 | protected $htmlFilters = []; |
||
37 | protected $action = null; |
||
38 | protected $formColsClasses = [ |
||
39 | 'col-md-10 col-md-offset-1', |
||
40 | 'col-md-2', |
||
41 | 'col-md-10', |
||
42 | ]; |
||
43 | protected $links = []; |
||
44 | |||
45 | public function __construct($entity, $config = []) |
||
46 | { |
||
47 | $this->entity = $entity; |
||
48 | |||
49 | $config = count($config) ? $config : config('crud.'.$this->route); |
||
50 | |||
51 | if (is_array($config)) { |
||
52 | foreach ($config as $key => $value) { |
||
53 | $this->$key = $value; |
||
54 | } |
||
55 | } |
||
56 | } |
||
57 | |||
58 | public function index(Request $request) |
||
59 | { |
||
60 | $entity = $this->entity; |
||
61 | |||
62 | // Relation Fields |
||
63 | if ($belongToFields = $this->getBelongToFields()) { |
||
64 | $entity = $this->entity->with($belongToFields); |
||
65 | } |
||
66 | |||
67 | // Filters |
||
68 | $entity = $this->filters($entity, $request); |
||
69 | |||
70 | // Search |
||
71 | $entity = $this->search($entity, $request); |
||
72 | |||
73 | // Order By |
||
74 | if ($this->orderBy) { |
||
0 ignored issues
–
show
|
|||
75 | foreach ($this->orderBy as $column => $direction) { |
||
76 | $entity = $entity->orderBy($column, $direction); |
||
77 | } |
||
78 | } |
||
79 | |||
80 | if ($this->orderByRaw) { |
||
81 | $entity = $entity->orderByRaw($this->orderByRaw); |
||
82 | } |
||
83 | |||
84 | // Pagination |
||
85 | $rows = $this->paginate > 0 ? $this->paginate($entity, $request) : $entity->get(); |
||
86 | |||
87 | // HTML Filters |
||
88 | $this->htmlFilters(); |
||
89 | |||
90 | return view('crud::list', compact('rows')) |
||
91 | ->with('fields', $this->fields) |
||
92 | ->with('columns', $this->columns) |
||
93 | ->with('searchable', $this->searchable) |
||
94 | ->with('buttons', $this->buttons) |
||
95 | ->with('paginate', $this->paginate) |
||
96 | ->with('t', $this->texts) |
||
97 | ->with('htmlFilters', $this->htmlFilters) |
||
98 | ->with('links', $this->prepareLinks()) |
||
99 | ->with('request', $request) |
||
100 | ->with('route', $this->route); |
||
101 | } |
||
102 | |||
103 | public function create() |
||
104 | { |
||
105 | $this->prepareFields(); |
||
106 | |||
107 | return view('crud::create') |
||
108 | ->with('type', 'create') |
||
109 | ->with('route', $this->route) |
||
110 | ->with('t', $this->texts) |
||
111 | ->with('formColsClasses', $this->formColsClasses) |
||
112 | ->with('links', $this->prepareLinks()) |
||
113 | ->with('fields', $this->fields); |
||
114 | } |
||
115 | |||
116 | public function store(Request $request) |
||
117 | { |
||
118 | $this->validateRequest($request); |
||
119 | |||
120 | DB::beginTransaction(); |
||
121 | |||
122 | try { |
||
123 | $row = $this->entity->create(array_merge($request->all(), $this->queryFilters)); |
||
124 | $this->updateForeignRelations($row, $request); |
||
125 | } catch (QueryException $e) { |
||
126 | return redirect() |
||
127 | ->back() |
||
128 | ->with('error', 'Ha ocurrido un error, intente nuevamente'); |
||
129 | } |
||
130 | |||
131 | DB::commit(); |
||
132 | |||
133 | return redirect() |
||
134 | ->route($this->route.'.index') |
||
135 | ->with('success', isset($this->textsGeneral['save_action']) |
||
136 | ? $this->textsGeneral['save_action'] |
||
137 | : trans('eliurkis::crud.save_action')); |
||
138 | } |
||
139 | |||
140 | public function edit($id) |
||
141 | { |
||
142 | if (! $this->entityInstance) { |
||
143 | $this->entityInstance = $this->entity->findOrFail($id); |
||
144 | } |
||
145 | |||
146 | $this->prepareFields(); |
||
147 | |||
148 | return view('crud::create') |
||
149 | ->with('type', 'edit') |
||
150 | ->with('route', $this->route) |
||
151 | ->with('t', $this->texts) |
||
152 | ->with('fields', $this->fields) |
||
153 | ->with('formColsClasses', $this->formColsClasses) |
||
154 | ->with('links', $this->prepareLinks()) |
||
155 | ->with('data', $this->entityInstance); |
||
156 | } |
||
157 | |||
158 | public function update(Request $request, $id) |
||
159 | { |
||
160 | $this->validateRequest($request); |
||
161 | |||
162 | DB::beginTransaction(); |
||
163 | |||
164 | try { |
||
165 | $row = $this->entity->findOrFail($id); |
||
166 | $row->update( |
||
167 | array_merge( |
||
168 | $request->all(), |
||
169 | $this->queryFilters |
||
170 | ) |
||
171 | ); |
||
172 | $this->updateForeignRelations($row, $request); |
||
173 | } catch (QueryException $e) { |
||
174 | return redirect() |
||
175 | ->back() |
||
176 | ->with('error', 'Ha ocurrido un error, intente nuevamente'); |
||
177 | } |
||
178 | |||
179 | DB::commit(); |
||
180 | |||
181 | return redirect() |
||
182 | ->route($this->route.'.index', $this->getParamsFilters($row)) |
||
183 | ->with('success', isset($this->textsGeneral['save_action']) |
||
184 | ? $this->textsGeneral['save_action'] |
||
185 | : trans('eliurkis::crud.save_action')); |
||
186 | } |
||
187 | |||
188 | public function destroy($id) |
||
189 | { |
||
190 | $this->entity->destroy($id); |
||
191 | |||
192 | return redirect() |
||
193 | ->route($this->route.'.index') |
||
194 | ->with('success', isset($this->textsGeneral['delete_action']) |
||
195 | ? $this->textsGeneral['delete_action'] |
||
196 | : trans('eliurkis::crud.delete_action')); |
||
197 | } |
||
198 | |||
199 | /* Private Actions */ |
||
200 | |||
201 | /** |
||
202 | * @param $entity |
||
203 | * @param Request $request |
||
204 | * |
||
205 | * @return mixed |
||
206 | */ |
||
207 | protected function filters($entity, $request) |
||
208 | { |
||
209 | if ($request->query('filter')) { |
||
210 | $filters = is_array($request->query('filter')) ? $request->query('filter') : []; |
||
211 | foreach ($filters as $field => $value) { |
||
212 | $entity = $entity->where($field, $value); |
||
213 | } |
||
214 | } |
||
215 | |||
216 | if (count($this->queryFilters)) { |
||
217 | foreach ($this->queryFilters as $field => $value) { |
||
218 | if (is_array($value)) { |
||
219 | $entity = $entity->whereIn($field, $value); |
||
220 | } else { |
||
221 | $entity = $entity->where($field, $value); |
||
222 | } |
||
223 | } |
||
224 | } |
||
225 | |||
226 | return $entity; |
||
227 | } |
||
228 | |||
229 | protected function htmlFilters() |
||
230 | { |
||
231 | $this->htmlFilters = []; |
||
232 | if (count($this->filters)) { |
||
233 | foreach ($this->filters as $filter) { |
||
234 | // Build params |
||
235 | $urlParams = \Input::query(); |
||
236 | |||
237 | // Default Value |
||
238 | $this->fields[$filter]['config']['default_value'] = isset($urlParams['filter'][$filter]) |
||
239 | ? $urlParams['filter'][$filter] |
||
240 | : null; |
||
241 | |||
242 | // Create URL |
||
243 | if (isset($urlParams['filter'][$filter])) { |
||
244 | unset($urlParams['filter'][$filter]); |
||
245 | } |
||
246 | $this->fields[$filter]['attributes']['data-filter-url'] = route($this->route.'.index', $urlParams) |
||
247 | .(count($urlParams) ? '&' : '?'); |
||
248 | |||
249 | // Create array |
||
250 | $this->action = 'list'; |
||
251 | $this->htmlFilters[$filter] = $this->prepareField($filter); |
||
252 | } |
||
253 | } |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * @param $entity |
||
258 | * @param Request $request |
||
259 | * |
||
260 | * @return mixed |
||
261 | */ |
||
262 | protected function paginate($entity, $request) |
||
263 | { |
||
264 | $rows = $entity->paginate($this->paginate); |
||
265 | |||
266 | if ($request->get('q') != '') { |
||
267 | $rows->appends(['q' => $request->get('q')]); |
||
268 | } |
||
269 | |||
270 | if ($request->get('filter')) { |
||
271 | foreach ($request->get('filter') as $field => $value) { |
||
272 | $rows->appends(['filter['.$field.']' => $value]); |
||
273 | } |
||
274 | } |
||
275 | |||
276 | return $rows; |
||
277 | } |
||
278 | |||
279 | /** |
||
280 | * @param $entity |
||
281 | * @param Request $request |
||
282 | * |
||
283 | * @return mixed |
||
284 | */ |
||
285 | protected function search($entity, $request) |
||
286 | { |
||
287 | if ($request->get('q') != '') { |
||
288 | $searchableCols = isset($this->searchable['columns']) ? $this->searchable['columns'] : $this->searchable; |
||
289 | |||
290 | $entity = $entity->where(function (Builder $query) use ($request, $searchableCols) { |
||
291 | foreach ($searchableCols as $field) { |
||
292 | $query->orWhere($field, 'like', '%'.$request->get('q').'%'); |
||
293 | } |
||
294 | }); |
||
295 | |||
296 | if (isset($this->searchable['joins'])) { |
||
297 | foreach ($this->searchable['joins'] as $table => $joinFields) { |
||
298 | $entity = $entity->join($table, $joinFields[0], '=', $joinFields[1]); |
||
299 | } |
||
300 | } |
||
301 | } |
||
302 | |||
303 | return $entity; |
||
304 | } |
||
305 | |||
306 | protected function getForeignRelationsFields() |
||
307 | { |
||
308 | $foreignRelations = []; |
||
309 | foreach ($this->fields as $field => $options) { |
||
310 | if ($options['type'] === 'foreign') { |
||
311 | $foreignRelations[] = $field; |
||
312 | } |
||
313 | } |
||
314 | |||
315 | return $foreignRelations; |
||
316 | } |
||
317 | |||
318 | protected function getBelongToFields() |
||
319 | { |
||
320 | $fields = []; |
||
321 | foreach ($this->fields as $field => $options) { |
||
322 | if ($options['type'] === 'select' && isset($options['config']['rel'])) { |
||
323 | $fields[] = $options['config']['rel']; |
||
324 | } |
||
325 | } |
||
326 | |||
327 | return $fields; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @param object $row |
||
332 | * @param Request $request |
||
333 | */ |
||
334 | protected function updateForeignRelations($row, $request) |
||
335 | { |
||
336 | $foreignRelations = $this->getForeignRelationsFields(); |
||
337 | |||
338 | foreach ($foreignRelations as $foreignRelation) { |
||
339 | $values = $request->get($foreignRelation); |
||
340 | $row->$foreignRelation()->sync((array) $values); |
||
341 | } |
||
342 | } |
||
343 | |||
344 | protected function getParamsFilters($row) |
||
345 | { |
||
346 | $params = []; |
||
347 | |||
348 | if (count($this->filterRequire)) { |
||
349 | $params['filter'] = []; |
||
350 | |||
351 | foreach ($this->filterRequire as $field) { |
||
352 | $params['filter'][$field] = $row->$field; |
||
353 | } |
||
354 | } |
||
355 | |||
356 | return $params; |
||
357 | } |
||
358 | |||
359 | protected function prepareLinks() |
||
360 | { |
||
361 | $links = ['index', 'create', 'store']; |
||
362 | |||
363 | foreach ($links as $link) { |
||
364 | if (! isset($this->links[$link])) { |
||
365 | $this->links[$link] = route($this->route.'.'.$link); |
||
366 | } |
||
367 | } |
||
368 | |||
369 | return $this->links; |
||
370 | } |
||
371 | |||
372 | /** |
||
373 | * @param Request $request |
||
374 | */ |
||
375 | protected function validateRequest($request) |
||
376 | { |
||
377 | $validations = [ |
||
378 | 'rules' => [], |
||
379 | 'messages' => [], |
||
380 | 'customAttributes' => [], |
||
381 | ]; |
||
382 | |||
383 | foreach ($this->fields as $field => $options) { |
||
384 | if (isset($options['validation'])) { |
||
385 | $validations['rules'][$field] = $options['validation']; |
||
386 | $validations['customAttributes'][$field] = $options['label']; |
||
387 | } |
||
388 | } |
||
389 | |||
390 | if ($validations['rules']) { |
||
391 | $this->validate( |
||
392 | $request, |
||
393 | $validations['rules'], |
||
394 | $validations['messages'], |
||
395 | $validations['customAttributes'] |
||
396 | ); |
||
397 | } |
||
398 | } |
||
399 | |||
400 | protected function prepareRelationalFields($name) |
||
401 | { |
||
402 | // Default values |
||
403 | $config = isset($this->fields[$name]['config']) ? $this->fields[$name]['config'] : []; |
||
404 | $config['options'] = isset($config['options']) ? $config['options'] : []; |
||
405 | $config['cols'] = isset($config['cols']) ? $config['cols'] : 1; |
||
406 | |||
407 | // Get foreign values |
||
408 | if (! count($config['options']) && isset($config['entity'])) { |
||
409 | $config['options'] = $config['entity']::get() |
||
410 | ->lists($config['field_value'], $config['field_key']) |
||
411 | ->toArray(); |
||
412 | } |
||
413 | |||
414 | // No selection for filters |
||
415 | if ($this->action == 'list' && isset($config['filter_no_selection'])) { |
||
416 | $config['options'] = array_merge([ |
||
417 | '-1' => $config['filter_no_selection'], |
||
418 | ], $config['options']); |
||
419 | } |
||
420 | |||
421 | $this->fields[$name]['config'] = $config; |
||
422 | |||
423 | return $this->fields[$name]; |
||
424 | } |
||
425 | |||
426 | protected function prepareFields() |
||
427 | { |
||
428 | if ($this->entityInstance) { |
||
429 | \Form::model($this->entityInstance); |
||
430 | } |
||
431 | |||
432 | foreach ($this->fields as $name => $properties) { |
||
433 | $this->fields[$name]['html'] = $this->prepareField($name, $properties); |
||
434 | } |
||
435 | } |
||
436 | |||
437 | protected function prepareField($name, $properties = []) |
||
438 | { |
||
439 | // Init |
||
440 | if (! $properties) { |
||
0 ignored issues
–
show
The expression
$properties of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
441 | $properties = $this->fields[$name]; |
||
442 | } |
||
443 | |||
444 | $this->fields[$name]['config'] = isset($properties['config']) ? $properties['config'] : []; |
||
445 | $this->fields[$name]['attributes'] = isset($properties['attributes']) ? $properties['attributes'] : []; |
||
446 | $this->fields[$name]['attributes']['class'] = 'form-control'; |
||
447 | $this->fields[$name]['html'] = null; |
||
448 | |||
449 | $config = $this->fields[$name]['config']; |
||
450 | |||
451 | $value = $this->entityInstance |
||
452 | ? $this->entityInstance->$name |
||
453 | : (isset($config['default_value']) ? $config['default_value'] : null); |
||
454 | |||
455 | // Define field type class namespace |
||
456 | $className = '\Eliurkis\Crud\FieldTypes\\'.ucfirst($properties['type']); |
||
457 | if (! class_exists($className)) { |
||
458 | return; |
||
459 | } |
||
460 | |||
461 | if ($properties['type'] == 'foreign' || $properties['type'] == 'select') { |
||
462 | $properties = $this->prepareRelationalFields($name); |
||
463 | |||
464 | if ($properties['type'] == 'foreign' && $this->entityInstance) { |
||
465 | $value = $this->entityInstance->{$config['rel']}->lists('id')->toArray(); |
||
466 | } |
||
467 | |||
468 | if ($properties['type'] == 'select') { |
||
469 | $properties['attributes']['class'] = 'form-control chosen-select-width'; |
||
470 | } |
||
471 | |||
472 | return $className::prepare( |
||
473 | $name, |
||
474 | $properties['config']['options'], |
||
475 | $value, |
||
476 | $properties |
||
477 | ); |
||
478 | } |
||
479 | |||
480 | return $className::prepare( |
||
481 | $name, |
||
482 | $value, |
||
483 | $this->fields[$name] |
||
484 | ); |
||
485 | } |
||
486 | } |
||
487 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.