199 lines
6.1 KiB
PHP
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());
|
|
}
|
|
}
|