ldc-portsalaries/app/Http/Controllers/CrudController.php
2021-06-07 18:28:25 +02:00

199 lines
6.1 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Exceptions\CrudException;
use App\Http\Requests\StoreCrudModel;
use App\Http\Requests\UpdateCrudModel;
use App\Http\Resources\CrudResource;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Str;
class CrudController extends Controller
{
/** @var \Illuminate\Database\Eloquent\Model */
protected static $modelClass = null;
// Eloquent callbacks
public function indexQuery(Builder $query): Builder
{
return $query;
}
public function storeModel(Model &$model)
{
}
public function updateModel(Model &$model)
{
}
public function __construct()
{
// AUTH CONTROL TO ROOT POLICY
$this->authorizeResource(static::$modelClass);
$modelClass = static::$modelClass;
if (is_null($modelClass) or !class_exists($modelClass)) {
throw new CrudException(sprintf(
'%s needs the modelClass prop to be a class, %s %s given',
__CLASS__,
gettype($modelClass),
$modelClass
));
}
if (!is_subclass_of(new $modelClass(), Model::class)) {
throw new CrudException(sprintf(
'%s needs the model prop to be a class the extends %s',
__CLASS__,
Model::class
));
}
if (!request()->ajax() and !app()->runningInConsole()) {
self::shareCrudModelsClassesToView();
$this->shareModelClassToView();
$this->shareModelTableToView();
$this->shareModelPropsToView();
}
}
public function index(Request $request)
{
/** @var \Illuminate\Database\Eloquent\Builder */
$models = static::$modelClass::query();
if ($request->s) {
$model = static::$modelClass;
$col = (new $model())->crudLabelColumn;
$models = $models->where($col, 'LIKE', "%$request->s%");
}
$models = $this->indexQuery($models);
/** @var \Illuminate\Pagination\AbstractPaginator */
$models = $models->paginate(config('crud.paginate', 15));
if ($request->ajax()) {
return response()->json(CrudResource::collection($models));
} else {
$models = $models->withQueryString();
return view('crud.index', compact('models'));
}
}
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
public function show(Model $model)
{
return view('crud.show', compact('model'));
}
public function create()
{
return view('crud.create');
}
public function store(StoreCrudModel $request)
{
$modelClass = static::$modelClass;
$model = new $modelClass();
$model->fill($request->validated());
$this->storeModel($model);
$model->saveOrFail();
$model->saveRelations($request);
return \redirect()->route(sprintf('bo.%s.edit', $model->getTable()), $model)
->with('success', trans(':model à bien été enregisté.', ['model' => $model->getModelName()]));
}
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
public function edit(Model $model)
{
return view('crud.edit', compact('model'));
}
public function update(UpdateCrudModel $request, Model $model)
{
$model->fill($request->validated());
$this->updateModel($model);
$model->saveOrFail();
$model->saveRelations($request);
return \redirect()->route(sprintf('bo.%s.edit', $model->getTable()), $model)
->with('success', trans(':model à bien été enregisté.', ['model' => $model->getModelName()]));
}
public function destroy(Model $model)
{
if ($restrict = $model->gotHasManyRelationWithRestrictOnDelete()) {
return redirect()->back()
->with('error', trans(
':model n\'as pas pu être supprimé car il est encore associé avec des :associated',
[
'model' => $model->getModelName(),
'associated' => Str::plural($restrict)
]
));
}
if ($model->delete()) {
return \redirect()->route(sprintf('bo.%s.index', $model->getTable()))
->with('warning', trans(':model à bien été supprimé.', ['model' => $model->getModelName()]));
} else {
return redirect()->back()
->with('error', trans(':model n\'as pas pu être supprimé', ['model' => $model->getModelName()]));
}
}
public function getModelClass()
{
return static::$modelClass;
}
/**
* Get the current model class
*
* @return void
*/
public static function shareCrudModelsClassesToView(): void
{
$models = [];
foreach (File::allFiles(\app_path('Http/Controllers')) as $file) {
$class = sprintf('App\Http\Controllers\%s', \substr($file->getFilename(), 0, -4));
if (is_subclass_of($class, CrudController::class) and $class::$modelClass) {
$models[] = $class::$modelClass;
}
}
View::share('modelsClasses', $models);
}
/**
* Get the current model class
*
* @return void
*/
private function shareModelClassToView(): void
{
View::share('modelClass', static::$modelClass);
}
/**
* Get the current model table
*
* @return void
*/
private function shareModelTableToView(): void
{
/** @var \Illuminate\Database\Eloquent\Model $model */
$model = static::$modelClass;
View::share('modelTable', (new $model())->getTable());
}
/**
* Get the current model properties
*
* @return void
*/
private function shareModelPropsToView(): void
{
$model = static::$modelClass;
View::share('props', (new $model())->getEditableProperties());
}
}