eliurkis /
crud
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
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 App\Http\Controllers\Controller; |
||
| 6 | use DB; |
||
| 7 | use Illuminate\Database\Eloquent\Builder; |
||
| 8 | use Illuminate\Database\Eloquent\ModelNotFoundException; |
||
| 9 | use Illuminate\Database\QueryException; |
||
| 10 | use Illuminate\Http\Request; |
||
| 11 | use Illuminate\Support\Carbon; |
||
| 12 | use Illuminate\Support\Facades\Route; |
||
| 13 | |||
| 14 | class CrudController extends Controller |
||
| 15 | { |
||
| 16 | protected $route; |
||
| 17 | protected $entity; |
||
| 18 | protected $entityInstance = null; |
||
| 19 | protected $fields = []; |
||
| 20 | protected $columns = []; |
||
| 21 | protected $buttons = [ |
||
| 22 | 'show', |
||
| 23 | 'create', |
||
| 24 | 'edit', |
||
| 25 | 'delete', |
||
| 26 | ]; |
||
| 27 | protected $paginate = null; |
||
| 28 | protected $searchable = []; |
||
| 29 | protected $filters = []; |
||
| 30 | protected $queryFilters = []; |
||
| 31 | protected $orderBy = []; |
||
| 32 | protected $orderByRaw = null; |
||
| 33 | protected $filterRequire = []; |
||
| 34 | protected $textsGeneral = [ |
||
| 35 | 'list_title' => 'Contents', |
||
| 36 | 'create_title' => '', |
||
| 37 | 'edit_title' => '', |
||
| 38 | ]; |
||
| 39 | protected $texts = []; |
||
| 40 | protected $htmlFilters = []; |
||
| 41 | protected $action = null; |
||
| 42 | protected $formColsClasses = [ |
||
| 43 | 'col-md-10 col-md-offset-1', |
||
| 44 | 'col-md-2', |
||
| 45 | 'col-md-10', |
||
| 46 | ]; |
||
| 47 | protected $formCols = [ |
||
| 48 | 'show' => 2, |
||
| 49 | 'create' => 2, |
||
| 50 | 'edit' => 2, |
||
| 51 | ]; |
||
| 52 | protected $links = []; |
||
| 53 | protected $listDisplay = [ |
||
| 54 | 'action-buttons' => true, |
||
| 55 | ]; |
||
| 56 | protected $actions = []; |
||
| 57 | |||
| 58 | public function __construct($entity, $config = []) |
||
| 59 | { |
||
| 60 | $this->entity = $entity; |
||
| 61 | |||
| 62 | $config = count($config) ? $config : config('crud.'.$this->route); |
||
| 63 | |||
| 64 | if (is_array($config)) { |
||
| 65 | foreach ($config as $key => $value) { |
||
| 66 | $this->$key = $value; |
||
| 67 | } |
||
| 68 | } |
||
| 69 | |||
| 70 | $this->actions = [ |
||
| 71 | 'details' => function ($row, $route) { |
||
| 72 | return '<a href="'.route($route.'.show', $row->{$row->getKeyName()}).'" class="btn-default btn btn-xs"> |
||
| 73 | <i class="fas fa-eye"></i> |
||
| 74 | </a>'; |
||
| 75 | }, |
||
| 76 | 'edit' => function ($row, $route) { |
||
| 77 | return '<a href="'.route($route.'.edit', $row->{$row->getKeyName()}).'" class="btn-primary btn btn-xs edit_element"> |
||
| 78 | <i class="far fa-edit"></i> |
||
| 79 | </a>'; |
||
| 80 | }, |
||
| 81 | 'delete' => function ($row, $route) { |
||
| 82 | return '<a href="'.route($route.'.destroy', $row->{$row->getKeyName()}).'" |
||
| 83 | class="btn-danger btn btn-xs delete_element" |
||
| 84 | onclick="return confirm(\''.trans('eliurkis::crud.confirmation_delete').'\');"> |
||
| 85 | <i class="far fa-trash-alt"></i> |
||
| 86 | </a>'; |
||
| 87 | }, |
||
| 88 | ]; |
||
| 89 | } |
||
| 90 | |||
| 91 | public function index(Request $request) |
||
| 92 | { |
||
| 93 | // If DataTable is activated |
||
| 94 | if (isset($this->dataTableActivated)) { |
||
| 95 | return $this->indexDataTable($request); |
||
| 96 | } |
||
| 97 | |||
| 98 | $entity = $this->entity; |
||
| 99 | |||
| 100 | // Relation Fields |
||
| 101 | if ($belongToFields = $this->getBelongToFields()) { |
||
| 102 | $entity = $this->entity->with($belongToFields); |
||
| 103 | } |
||
| 104 | |||
| 105 | // Filters |
||
| 106 | $entity = $this->filters($entity, $request); |
||
| 107 | |||
| 108 | // Search |
||
| 109 | $entity = $this->search($entity, $request); |
||
| 110 | |||
| 111 | // Order By |
||
| 112 | if (!empty($this->orderBy)) { |
||
| 113 | foreach ($this->orderBy as $column => $direction) { |
||
| 114 | $entity = $entity->orderBy($column, $direction); |
||
| 115 | } |
||
| 116 | } |
||
| 117 | |||
| 118 | if ($this->orderByRaw) { |
||
| 119 | $entity = $entity->orderByRaw($this->orderByRaw); |
||
| 120 | } |
||
| 121 | |||
| 122 | // Pagination |
||
| 123 | $rows = $this->paginate > 0 ? $this->paginate($entity, $request) : $entity->get(); |
||
| 124 | |||
| 125 | // Sort By Rows |
||
| 126 | if (!empty($this->sortBy)) { |
||
| 127 | foreach ($this->sortBy as $column => $direction) { |
||
| 128 | $rows = strtolower($direction) == 'desc' |
||
| 129 | ? $rows->sortByDesc($column) |
||
| 130 | : $rows->sortBy($column); |
||
| 131 | } |
||
| 132 | } |
||
| 133 | |||
| 134 | // HTML Filters |
||
| 135 | $this->htmlFilters(); |
||
| 136 | |||
| 137 | return view('crud::list', compact('rows')) |
||
| 138 | ->with('fields', $this->fields) |
||
| 139 | ->with('columns', $this->columns) |
||
| 140 | ->with('searchable', $this->searchable) |
||
| 141 | ->with('buttons', $this->buttons) |
||
| 142 | ->with('paginate', $this->paginate) |
||
| 143 | ->with('t', $this->texts) |
||
| 144 | ->with('htmlFilters', $this->htmlFilters) |
||
| 145 | ->with('listDisplay', $this->listDisplay) |
||
| 146 | ->with('links', $this->prepareLinks()) |
||
| 147 | ->with('request', $request) |
||
| 148 | ->with('actions', $this->actions) |
||
| 149 | ->with('route', $this->route); |
||
| 150 | } |
||
| 151 | |||
| 152 | View Code Duplication | public function show($id) |
|
|
0 ignored issues
–
show
|
|||
| 153 | { |
||
| 154 | if (!$this->entityInstance) { |
||
| 155 | $this->entityInstance = $this->entity->findOrFail($id); |
||
| 156 | } |
||
| 157 | |||
| 158 | $this->prepareFields(); |
||
| 159 | |||
| 160 | return view('crud::show') |
||
| 161 | ->with('type', 'show') |
||
| 162 | ->with('route', $this->route) |
||
| 163 | ->with('t', $this->texts) |
||
| 164 | ->with('formColsClasses', $this->formColsClasses) |
||
| 165 | ->with('colsNumber', $this->formCols['show']) |
||
| 166 | ->with('fieldsGroup', collect($this->fields)->split($this->formCols['show'])) |
||
| 167 | ->with('fields', $this->fields) |
||
| 168 | ->with('data', $this->entityInstance); |
||
| 169 | } |
||
| 170 | |||
| 171 | public function create() |
||
| 172 | { |
||
| 173 | $this->prepareFields(); |
||
| 174 | |||
| 175 | return view('crud::create') |
||
| 176 | ->with('type', 'create') |
||
| 177 | ->with('route', $this->route) |
||
| 178 | ->with('t', $this->texts) |
||
| 179 | ->with('formColsClasses', $this->formColsClasses) |
||
| 180 | ->with('links', $this->prepareLinks()) |
||
| 181 | ->with('colsNumber', $this->formCols['create']) |
||
| 182 | ->with('fieldsGroup', collect($this->fields)->split($this->formCols['create'])) |
||
| 183 | ->with('fields', $this->fields); |
||
| 184 | } |
||
| 185 | |||
| 186 | protected function manageFiles($row, $request) |
||
| 187 | { |
||
| 188 | $mediaFiles = []; |
||
| 189 | |||
| 190 | foreach ($this->fields as $fieldName => $field) { |
||
| 191 | if (substr($field['type'], 0, 4) === 'file' && $request->file($fieldName)) { |
||
| 192 | $customProperties = ['route' => $this->route, 'field' => $fieldName]; |
||
| 193 | if (isset($field['storage_path'])) { |
||
| 194 | $customProperties['storage_path'] = $field['storage_path']; |
||
| 195 | } |
||
| 196 | $mediaFiles[] = $row->addMedia($request->file($fieldName)) |
||
| 197 | ->withCustomProperties($customProperties) |
||
| 198 | ->toMediaCollection($fieldName); |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | return $mediaFiles; |
||
| 203 | } |
||
| 204 | |||
| 205 | public function store(Request $request) |
||
| 206 | { |
||
| 207 | $this->validateRequest($request, 'store'); |
||
| 208 | |||
| 209 | DB::beginTransaction(); |
||
| 210 | |||
| 211 | try { |
||
| 212 | $row = $this->entity->create(array_merge($request->all(), $this->queryFilters)); |
||
| 213 | $this->updateForeignRelations($row, $request); |
||
| 214 | $mediaFiles = $this->manageFiles($row, $request); |
||
| 215 | } catch (QueryException $e) { |
||
| 216 | \Log::error($e); |
||
| 217 | if (config('app.debug')) { |
||
| 218 | throw new \Exception($e); |
||
| 219 | } |
||
| 220 | |||
| 221 | return redirect() |
||
| 222 | ->back() |
||
| 223 | ->with('error', 'Ha ocurrido un error, intente nuevamente'); |
||
| 224 | } |
||
| 225 | |||
| 226 | DB::commit(); |
||
| 227 | |||
| 228 | event($this->route.'.store', [$row, $mediaFiles]); |
||
| 229 | |||
| 230 | return redirect() |
||
| 231 | ->route($this->route.'.index') |
||
| 232 | ->with('success', isset($this->textsGeneral['save_action']) |
||
| 233 | ? $this->textsGeneral['save_action'] |
||
| 234 | : trans('eliurkis::crud.save_action')); |
||
| 235 | } |
||
| 236 | |||
| 237 | View Code Duplication | public function edit($id) |
|
| 238 | { |
||
| 239 | if (!$this->entityInstance) { |
||
| 240 | $this->entityInstance = $this->entity->findOrFail($id); |
||
| 241 | } |
||
| 242 | |||
| 243 | $this->prepareFields(); |
||
| 244 | |||
| 245 | return view('crud::create') |
||
| 246 | ->with('type', 'edit') |
||
| 247 | ->with('route', $this->route) |
||
| 248 | ->with('t', $this->texts) |
||
| 249 | ->with('formColsClasses', $this->formColsClasses) |
||
| 250 | ->with('links', $this->prepareLinks()) |
||
| 251 | ->with('colsNumber', $this->formCols['edit']) |
||
| 252 | ->with('fieldsGroup', collect($this->fields)->split($this->formCols['edit'])) |
||
| 253 | ->with('fields', $this->fields) |
||
| 254 | ->with('data', $this->entityInstance); |
||
| 255 | } |
||
| 256 | |||
| 257 | public function update(Request $request, $id) |
||
| 258 | { |
||
| 259 | $this->validateRequest($request, 'update'); |
||
| 260 | |||
| 261 | DB::beginTransaction(); |
||
| 262 | |||
| 263 | try { |
||
| 264 | $row = $this->entity->findOrFail($id); |
||
| 265 | $row->update( |
||
| 266 | array_merge( |
||
| 267 | $request->all(), |
||
| 268 | $this->queryFilters |
||
| 269 | ) |
||
| 270 | ); |
||
| 271 | $this->updateForeignRelations($row, $request); |
||
| 272 | $mediaFiles = $this->manageFiles($row, $request); |
||
| 273 | } catch (QueryException $e) { |
||
| 274 | \Log::error($e); |
||
| 275 | if (config('app.debug')) { |
||
| 276 | throw new \Exception($e); |
||
| 277 | } |
||
| 278 | |||
| 279 | return redirect() |
||
| 280 | ->back() |
||
| 281 | ->with('error', 'Ha ocurrido un error, intente nuevamente'); |
||
| 282 | } |
||
| 283 | |||
| 284 | DB::commit(); |
||
| 285 | |||
| 286 | event($this->route.'.update', [$row, $mediaFiles]); |
||
| 287 | |||
| 288 | return redirect() |
||
| 289 | ->route($this->route.'.index', $this->getParamsFilters($row)) |
||
| 290 | ->with('success', isset($this->textsGeneral['save_action']) |
||
| 291 | ? $this->textsGeneral['save_action'] |
||
| 292 | : trans('eliurkis::crud.save_action')); |
||
| 293 | } |
||
| 294 | |||
| 295 | public function destroy($id) |
||
| 296 | { |
||
| 297 | try { |
||
| 298 | $row = $this->entity->findOrFail($id); |
||
| 299 | $row->delete(); |
||
| 300 | |||
| 301 | event($this->route.'.destroy', [$row]); |
||
| 302 | } catch (ModelNotFoundException $e) { |
||
| 303 | return redirect() |
||
| 304 | ->route($this->route.'.index') |
||
| 305 | ->with('error', __('The element that you are trying to delete does not exist')); |
||
| 306 | } catch (\Exception $e) { |
||
| 307 | \Log::error($e); |
||
| 308 | if (config('app.debug')) { |
||
| 309 | throw new \Exception($e); |
||
| 310 | } |
||
| 311 | |||
| 312 | return redirect() |
||
| 313 | ->route($this->route.'.index') |
||
| 314 | ->with('error', __('An error occurred, try again')); |
||
| 315 | } |
||
| 316 | |||
| 317 | return redirect() |
||
| 318 | ->route($this->route.'.index') |
||
| 319 | ->with('success', isset($this->textsGeneral['delete_action']) |
||
| 320 | ? $this->textsGeneral['delete_action'] |
||
| 321 | : trans('eliurkis::crud.delete_action')); |
||
| 322 | } |
||
| 323 | |||
| 324 | public function download($id, $fieldName) |
||
| 325 | { |
||
| 326 | if (!$this->entityInstance) { |
||
| 327 | $this->entityInstance = $this->entity->findOrFail($id); |
||
| 328 | } |
||
| 329 | |||
| 330 | $media = $this->entityInstance->getMedia($fieldName)->last(); |
||
| 331 | |||
| 332 | if ($media && $media->disk === 's3') { |
||
| 333 | $tempImage = tempnam(sys_get_temp_dir(), $media->file_name); |
||
| 334 | copy($media->getTemporaryUrl(\Carbon::now()->addMinutes(5)), $tempImage); |
||
| 335 | |||
| 336 | return response()->file($tempImage, ['Content-Type' => $media->mime_type]); |
||
| 337 | } |
||
| 338 | |||
| 339 | return $media; |
||
| 340 | } |
||
| 341 | |||
| 342 | /* Private Actions */ |
||
| 343 | |||
| 344 | /** |
||
| 345 | * @param $entity |
||
| 346 | * @param Request $request |
||
| 347 | * |
||
| 348 | * @return mixed |
||
| 349 | */ |
||
| 350 | protected function filters($entity, $request) |
||
| 351 | { |
||
| 352 | if ($request->query('filter')) { |
||
| 353 | $filters = is_array($request->query('filter')) ? $request->query('filter') : []; |
||
| 354 | foreach ($filters as $field => $value) { |
||
| 355 | $entity = $entity->where($field, $value); |
||
| 356 | } |
||
| 357 | } |
||
| 358 | |||
| 359 | if (count($this->queryFilters)) { |
||
| 360 | foreach ($this->queryFilters as $field => $value) { |
||
| 361 | if (is_array($value)) { |
||
| 362 | $entity = $entity->whereIn($field, $value); |
||
| 363 | } else { |
||
| 364 | $entity = $entity->where($field, $value); |
||
| 365 | } |
||
| 366 | } |
||
| 367 | } |
||
| 368 | |||
| 369 | return $entity; |
||
| 370 | } |
||
| 371 | |||
| 372 | protected function htmlFilters() |
||
| 373 | { |
||
| 374 | $this->htmlFilters = []; |
||
| 375 | if (count($this->filters)) { |
||
| 376 | foreach ($this->filters as $filter) { |
||
| 377 | // Build params |
||
| 378 | $urlParams = \Input::query(); |
||
| 379 | |||
| 380 | // Default Value |
||
| 381 | $this->fields[$filter]['config']['default_value'] = isset($urlParams['filter'][$filter]) |
||
| 382 | ? $urlParams['filter'][$filter] |
||
| 383 | : null; |
||
| 384 | |||
| 385 | // Create URL |
||
| 386 | if (isset($urlParams['filter'][$filter])) { |
||
| 387 | unset($urlParams['filter'][$filter]); |
||
| 388 | } |
||
| 389 | $this->fields[$filter]['attributes']['data-filter-url'] = route($this->route.'.index', $urlParams) |
||
| 390 | .(count($urlParams) ? '&' : '?'); |
||
| 391 | |||
| 392 | // Create array |
||
| 393 | $this->action = 'list'; |
||
| 394 | $this->htmlFilters[$filter] = $this->prepareField($filter); |
||
| 395 | } |
||
| 396 | } |
||
| 397 | } |
||
| 398 | |||
| 399 | /** |
||
| 400 | * @param $entity |
||
| 401 | * @param Request $request |
||
| 402 | * |
||
| 403 | * @return mixed |
||
| 404 | */ |
||
| 405 | protected function paginate($entity, $request) |
||
| 406 | { |
||
| 407 | $rows = $entity->paginate($this->paginate); |
||
| 408 | |||
| 409 | if ($request->get('q') != '') { |
||
| 410 | $rows->appends(['q' => $request->get('q')]); |
||
| 411 | } |
||
| 412 | |||
| 413 | if ($request->get('filter')) { |
||
| 414 | foreach ($request->get('filter') as $field => $value) { |
||
| 415 | $rows->appends(['filter['.$field.']' => $value]); |
||
| 416 | } |
||
| 417 | } |
||
| 418 | |||
| 419 | return $rows; |
||
| 420 | } |
||
| 421 | |||
| 422 | /** |
||
| 423 | * @param $entity |
||
| 424 | * @param Request $request |
||
| 425 | * |
||
| 426 | * @return mixed |
||
| 427 | */ |
||
| 428 | protected function search($entity, $request) |
||
| 429 | { |
||
| 430 | if ($request->get('q') != '') { |
||
| 431 | $searchableCols = isset($this->searchable['columns']) ? $this->searchable['columns'] : $this->searchable; |
||
| 432 | |||
| 433 | $entity = $entity->where(function (Builder $query) use ($request, $searchableCols) { |
||
| 434 | foreach ($searchableCols as $field) { |
||
| 435 | $query->orWhere($field, 'like', '%'.$request->get('q').'%'); |
||
| 436 | } |
||
| 437 | }); |
||
| 438 | |||
| 439 | if (isset($this->searchable['joins'])) { |
||
| 440 | foreach ($this->searchable['joins'] as $table => $joinFields) { |
||
| 441 | $entity = $entity->join($table, $joinFields[0], '=', $joinFields[1]); |
||
| 442 | } |
||
| 443 | } |
||
| 444 | } |
||
| 445 | |||
| 446 | return $entity; |
||
| 447 | } |
||
| 448 | |||
| 449 | protected function getForeignRelationsFields() |
||
| 450 | { |
||
| 451 | $foreignRelations = []; |
||
| 452 | foreach ($this->fields as $field => $options) { |
||
| 453 | if ($options['type'] === 'foreign') { |
||
| 454 | $foreignRelations[] = $field; |
||
| 455 | } |
||
| 456 | } |
||
| 457 | |||
| 458 | return $foreignRelations; |
||
| 459 | } |
||
| 460 | |||
| 461 | protected function getBelongToFields() |
||
| 462 | { |
||
| 463 | $fields = []; |
||
| 464 | foreach ($this->fields as $field => $options) { |
||
| 465 | if ($options['type'] === 'select' && isset($options['config']['rel'])) { |
||
| 466 | $fields[] = $options['config']['rel']; |
||
| 467 | } |
||
| 468 | } |
||
| 469 | |||
| 470 | return $fields; |
||
| 471 | } |
||
| 472 | |||
| 473 | /** |
||
| 474 | * @param object $row |
||
| 475 | * @param Request $request |
||
| 476 | */ |
||
| 477 | protected function updateForeignRelations($row, $request) |
||
| 478 | { |
||
| 479 | $foreignRelations = $this->getForeignRelationsFields(); |
||
| 480 | |||
| 481 | foreach ($foreignRelations as $foreignRelation) { |
||
| 482 | $values = $request->get($foreignRelation); |
||
| 483 | $row->$foreignRelation()->sync((array) $values); |
||
| 484 | } |
||
| 485 | } |
||
| 486 | |||
| 487 | protected function getParamsFilters($row) |
||
| 488 | { |
||
| 489 | $params = []; |
||
| 490 | |||
| 491 | if (count($this->filterRequire)) { |
||
| 492 | $params['filter'] = []; |
||
| 493 | |||
| 494 | foreach ($this->filterRequire as $field) { |
||
| 495 | $params['filter'][$field] = $row->$field; |
||
| 496 | } |
||
| 497 | } |
||
| 498 | |||
| 499 | return $params; |
||
| 500 | } |
||
| 501 | |||
| 502 | protected function prepareLinks() |
||
| 503 | { |
||
| 504 | $links = ['index', 'create', 'store']; |
||
| 505 | |||
| 506 | foreach ($links as $link) { |
||
| 507 | if (!isset($this->links[$link]) && Route::has($this->route.'.'.$link)) { |
||
| 508 | $this->links[$link] = route($this->route.'.'.$link); |
||
| 509 | } |
||
| 510 | } |
||
| 511 | |||
| 512 | return $this->links; |
||
| 513 | } |
||
| 514 | |||
| 515 | /** |
||
| 516 | * @param Request $request |
||
| 517 | * @param $type |
||
| 518 | */ |
||
| 519 | protected function validateRequest($request, $type) |
||
| 520 | { |
||
| 521 | $validations = [ |
||
| 522 | 'rules' => [], |
||
| 523 | 'messages' => [], |
||
| 524 | 'customAttributes' => [], |
||
| 525 | ]; |
||
| 526 | |||
| 527 | foreach ($this->fields as $field => $options) { |
||
| 528 | $validation = null; |
||
| 529 | if (isset($options['validation'][$type])) { |
||
| 530 | $validation = $options['validation'][$type]; |
||
| 531 | } elseif (isset($options['validation']) && is_string($options['validation'])) { |
||
| 532 | $validation = $options['validation']; |
||
| 533 | } |
||
| 534 | |||
| 535 | if ($validation != '') { |
||
| 536 | $validations['rules'][$field] = $validation; |
||
| 537 | $validations['customAttributes'][$field] = $options['label']; |
||
| 538 | } |
||
| 539 | } |
||
| 540 | |||
| 541 | if ($validations['rules']) { |
||
| 542 | $this->validate( |
||
| 543 | $request, |
||
| 544 | $validations['rules'], |
||
| 545 | $validations['messages'], |
||
| 546 | $validations['customAttributes'] |
||
| 547 | ); |
||
| 548 | } |
||
| 549 | } |
||
| 550 | |||
| 551 | protected function prepareRelationalFields($name) |
||
| 552 | { |
||
| 553 | // Default values |
||
| 554 | $config = isset($this->fields[$name]['config']) ? $this->fields[$name]['config'] : []; |
||
| 555 | $config['options'] = isset($config['options']) ? $config['options'] : []; |
||
| 556 | $config['cols'] = isset($config['cols']) ? $config['cols'] : 1; |
||
| 557 | |||
| 558 | // Get foreign values |
||
| 559 | if (!count($config['options']) && isset($config['entity'])) { |
||
| 560 | $config['options'] = $config['entity']::get() |
||
| 561 | ->pluck($config['field_value'], $config['field_key']) |
||
| 562 | ->toArray(); |
||
| 563 | } |
||
| 564 | |||
| 565 | // No selection for filters |
||
| 566 | if ($this->action == 'list' && isset($config['filter_no_selection'])) { |
||
| 567 | $config['options'] = array_merge([ |
||
| 568 | '-1' => $config['filter_no_selection'], |
||
| 569 | ], $config['options']); |
||
| 570 | } |
||
| 571 | |||
| 572 | if (isset($config['pre_options'])) { |
||
| 573 | $config['options'] = $config['pre_options'] + $config['options']; |
||
| 574 | } |
||
| 575 | |||
| 576 | $this->fields[$name]['config'] = $config; |
||
| 577 | |||
| 578 | return $this->fields[$name]; |
||
| 579 | } |
||
| 580 | |||
| 581 | protected function prepareFields() |
||
| 582 | { |
||
| 583 | if ($this->entityInstance) { |
||
| 584 | \Form::model($this->entityInstance); |
||
| 585 | } |
||
| 586 | |||
| 587 | foreach ($this->fields as $name => $properties) { |
||
| 588 | $this->fields[$name]['html'] = $this->prepareField($name, $properties); |
||
| 589 | $this->fields[$name]['value'] = $this->entityInstance->$name ?? null; |
||
| 590 | $this->fields[$name]['value_text'] = $this->prepareFieldShow($name, $properties); |
||
| 591 | } |
||
| 592 | |||
| 593 | return $this->fields; |
||
| 594 | } |
||
| 595 | |||
| 596 | protected function prepareFieldShow($name, $properties = []) |
||
| 597 | { |
||
| 598 | // Init |
||
| 599 | if (empty($properties)) { |
||
| 600 | $properties = $this->fields[$name]; |
||
| 601 | } |
||
| 602 | |||
| 603 | $this->fields[$name]['config'] = isset($properties['config']) ? $properties['config'] : []; |
||
| 604 | $this->fields[$name]['attributes'] = isset($properties['attributes']) ? $properties['attributes'] : []; |
||
| 605 | $config = $this->fields[$name]['config']; |
||
| 606 | |||
| 607 | $value = $this->entityInstance |
||
| 608 | ? ($this->entityInstance->$name ?? null) |
||
| 609 | : (isset($config['default_value']) ? $config['default_value'] : null); |
||
| 610 | |||
| 611 | if ($this->entityInstance) { |
||
| 612 | if (($properties['type'] === 'date' || $properties['type'] === 'datetime') && |
||
| 613 | $this->entityInstance->$name != '') { |
||
| 614 | $fieldValue = $this->entityInstance->$name; |
||
| 615 | |||
| 616 | if (!is_object($fieldValue)) { |
||
| 617 | $fieldValue = Carbon::parse($this->entityInstance->$name); |
||
| 618 | } |
||
| 619 | |||
| 620 | $value = $fieldValue->diff(Carbon::now())->format('%y') != date('Y') |
||
| 621 | ? $fieldValue->format($properties['type'] === 'date' ? 'm/d/Y' : 'm/d/Y h:ia') |
||
| 622 | : null; |
||
| 623 | } |
||
| 624 | |||
| 625 | if (substr($properties['type'], 0, 4) === 'file' && $this->entityInstance->getMedia($name)->last()) { |
||
| 626 | $value = '<a href="'.route($this->route.'.download', [$this->entityInstance->id, $name]). |
||
| 627 | '" target="_blank">'.( |
||
| 628 | isset($this->fields[$name]['link_name']) |
||
| 629 | ? $this->fields[$name]['link_name'] |
||
| 630 | : 'download' |
||
| 631 | ).'</a>'; |
||
| 632 | } |
||
| 633 | |||
| 634 | if (isset($config['entity'])) { |
||
| 635 | $value = isset($this->entityInstance->{$config['rel']}->{$config['field_value']}) |
||
| 636 | ? $this->entityInstance->{$config['rel']}->{$config['field_value']} |
||
| 637 | : null; |
||
| 638 | } elseif (isset($config['options']) && count($config['options'])) { |
||
| 639 | $value = $config['options'][$value] ?? null; |
||
| 640 | } |
||
| 641 | } |
||
| 642 | |||
| 643 | return empty($value) ? 'N/A' : $value; |
||
| 644 | } |
||
| 645 | |||
| 646 | protected function prepareField($name, $properties = []) |
||
| 647 | { |
||
| 648 | // Init |
||
| 649 | if (empty($properties)) { |
||
| 650 | $properties = $this->fields[$name]; |
||
| 651 | } |
||
| 652 | |||
| 653 | $this->fields[$name]['config'] = isset($properties['config']) ? $properties['config'] : []; |
||
| 654 | $this->fields[$name]['attributes'] = isset($properties['attributes']) ? $properties['attributes'] : []; |
||
| 655 | $this->fields[$name]['attributes']['class'] = 'form-control'; |
||
| 656 | $this->fields[$name]['html'] = null; |
||
| 657 | |||
| 658 | $config = $this->fields[$name]['config']; |
||
| 659 | |||
| 660 | $value = $this->entityInstance |
||
| 661 | ? isset($properties['value_alias']) |
||
| 662 | ? $this->entityInstance->{$properties['value_alias']} |
||
| 663 | : $this->entityInstance->$name |
||
| 664 | : ($this->fields[$name]['default_value'] ?? null); |
||
| 665 | |||
| 666 | // Define field type class namespace |
||
| 667 | $className = '\Eliurkis\Crud\FieldTypes\\'.studly_case($properties['type']); |
||
| 668 | if (!class_exists($className)) { |
||
| 669 | return; |
||
| 670 | } |
||
| 671 | |||
| 672 | if ($properties['type'] == 'foreign' || $properties['type'] == 'select') { |
||
| 673 | $properties = $this->prepareRelationalFields($name); |
||
| 674 | |||
| 675 | if ($properties['type'] == 'foreign' && $this->entityInstance) { |
||
| 676 | $value = $this->entityInstance->{$config['rel']}->pluck($config['field_key'])->toArray(); |
||
| 677 | } |
||
| 678 | |||
| 679 | if ($properties['type'] == 'select') { |
||
| 680 | $properties['attributes']['class'] = 'form-control chosen-select-width'; |
||
| 681 | } |
||
| 682 | |||
| 683 | return $className::prepare( |
||
| 684 | $name, |
||
| 685 | $properties['config']['options'], |
||
| 686 | $value, |
||
| 687 | $properties |
||
| 688 | ); |
||
| 689 | } |
||
| 690 | |||
| 691 | return $className::prepare( |
||
| 692 | $name, |
||
| 693 | $value, |
||
| 694 | $this->fields[$name] |
||
| 695 | ); |
||
| 696 | } |
||
| 697 | } |
||
| 698 |
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.