From 4be4dddda034e1443c4f660ed5ef16ebfb81d0ff Mon Sep 17 00:00:00 2001 From: Noah Lancien Date: Fri, 24 Nov 2023 17:22:56 +0100 Subject: [PATCH] Added slides CRUD --- app/Http/Controllers/Bo/SlideController.php | 164 +++++++++ .../Requests/Bo/Slides/StoreSlideRequest.php | 102 ++++++ .../Requests/Bo/Slides/UpdateSlideRequest.php | 7 + app/Models/Slide.php | 4 +- app/Policies/SlidePolicy.php | 120 +++++++ resources/lang/fr/models.php | 1 + resources/lang/fr/validation.php | 5 +- resources/views/bo/layouts/nav-list.blade.php | 8 + .../views/bo/pages/sites/create.blade.php | 4 +- .../views/bo/pages/slides/create.blade.php | 36 ++ .../views/bo/pages/slides/edit.blade.php | 52 +++ .../views/bo/pages/slides/form.blade.php | 324 ++++++++++++++++++ .../bo/pages/slides/index-list.blade.php | 74 ++++ .../views/bo/pages/slides/index.blade.php | 21 ++ routes/breadcrumbs-bo.php | 21 ++ routes/web-bo.php | 8 +- 16 files changed, 946 insertions(+), 5 deletions(-) create mode 100644 app/Http/Controllers/Bo/SlideController.php create mode 100644 app/Http/Requests/Bo/Slides/StoreSlideRequest.php create mode 100644 app/Http/Requests/Bo/Slides/UpdateSlideRequest.php create mode 100644 app/Policies/SlidePolicy.php create mode 100644 resources/views/bo/pages/slides/create.blade.php create mode 100644 resources/views/bo/pages/slides/edit.blade.php create mode 100644 resources/views/bo/pages/slides/form.blade.php create mode 100644 resources/views/bo/pages/slides/index-list.blade.php create mode 100644 resources/views/bo/pages/slides/index.blade.php diff --git a/app/Http/Controllers/Bo/SlideController.php b/app/Http/Controllers/Bo/SlideController.php new file mode 100644 index 0000000..e3be40c --- /dev/null +++ b/app/Http/Controllers/Bo/SlideController.php @@ -0,0 +1,164 @@ +authorizeResource(Slide::class); + } + + /** + * Display a listing of the resource. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Contracts\View\View + */ + public function index(Request $request): \Illuminate\Contracts\View\View + { + /** @var \Illuminate\Database\Eloquent\Builder $slideModels */ + $slideModels = Slide::query(); + + /** @var string $search Search field */ + $search = $request->search; + if ($search) { + $this->searchQuery( + $slideModels, + $search, + null, + 'slider', + 'title', + ); + } + $searchFields = \implode(', ', [ + Str::ucfirst(trans('validation.custom.slider')), + trans('validation.attributes.title'), + ]); + + /** Sort columns with a query */ + $this->sortQuery($slideModels); + + /** Custom pagination */ + $slideModels = $this->paginate($slideModels); + + return view('bo.pages.slides.index', compact('slideModels', 'search', 'searchFields')); + } + + + /** + * Show the form for creating a new resource. + * + * @param \App\Models\Slide $slide + * @return \Illuminate\Contracts\View\View + */ + public function create(Slide $slide): \Illuminate\Contracts\View\View + { + return view('bo.pages.slides.create', ['slideModel' => $slide]); + } + + /** + * Store a newly created resource in storage. + * + * @param \App\Http\Requests\Bo\Slides\StoreSlideRequest $request + * @return \Illuminate\Http\RedirectResponse + */ + public function store(StoreSlideRequest $request): \Illuminate\Http\RedirectResponse + { + return DB::transaction(function () use ($request) { + $slide = new Slide(); + + if ($slide->fill($request->validated())->saveOrFail()) { + return redirect()->route('bo.slides.edit', $slide) + ->with('success', __('crud.messages.has_been_created', [ + 'model' => Str::ucfirst(__('models.classes.slide')) + ])); + } + return redirect()->back() + ->with('error', __('crud.messages.cannot_be_created', [ + 'model' => Str::ucfirst(__('models.classes.slide')) + ])); + }); + } + + /** + * Show the form for editing the specified resource. + * + * @param App\Models\Slide $slide + * @return \Illuminate\Contracts\View\View + */ + public function edit(Slide $slide): \Illuminate\Contracts\View\View + { + return view('bo.pages.slides.edit', ['slideModel' => $slide]); + } + + /** + * Update the specified resource in storage. + * + * @param \App\Http\Requests\Bo\Slides\UpdateSlideRequest $request + * @param \App\Models\Slide $slide + * @return \Illuminate\Http\RedirectResponse + */ + public function update(UpdateSlideRequest $request, Slide $slide): \Illuminate\Http\RedirectResponse + { + return DB::transaction(function () use ($request, $slide) { + if ($slide->fill($request->validated())->saveOrFail()) { + return redirect()->route('bo.slides.edit', $slide) + ->with('success', __('crud.messages.has_been_updated', [ + 'model' => Str::ucfirst(__('models.classes.slide')) + ])); + } + return redirect()->route('bo.slides.edit', $slide) + ->with('error', __('crud.messages.cannot_be_updated', [ + 'model' => Str::ucfirst(__('models.classes.slide')) + ])); + }); + } + + /** + * Remove the specified resource from storage. + * + * @param \App\Models\Slide $slide + * @return \Illuminate\Http\RedirectResponse + */ + public function destroy(Slide $slide): \Illuminate\Http\RedirectResponse + { + if ($slide->deleteOrFail()) { + return redirect()->route('bo.slides.index') + ->with('success', __('crud.messages.has_been_deleted', [ + 'model' => Str::ucfirst(__('models.classes.slide')) + ])); + } + return redirect()->back() + ->with('error', __('crud.messages.cannot_be_deleted', [ + 'model' => Str::ucfirst(__('models.classes.slide')) + ])); + } + + /** + * Duplicate the specified resource. + * + * @param \App\Models\Slide $slide + * @return \Illuminate\Contracts\View\View + */ + public function duplicate(Slide $slide): \Illuminate\Contracts\View\View + { + return $this->create($slide->replicate()); + } +} diff --git a/app/Http/Requests/Bo/Slides/StoreSlideRequest.php b/app/Http/Requests/Bo/Slides/StoreSlideRequest.php new file mode 100644 index 0000000..6de1788 --- /dev/null +++ b/app/Http/Requests/Bo/Slides/StoreSlideRequest.php @@ -0,0 +1,102 @@ +check(); + } + + /** + * Prepare the data for validation. + * + * @return void + */ + protected function prepareForValidation() + { + $this->merge([ + 'button_status' => $this->button_status ? true : false, + 'button_new_tab' => $this->button_new_tab ? true : false + ]); + if (intval($this->slider) !== \App\Enums\Slides\SliderTypeEnum::home->value()) { + $this->merge([ + 'video_id' => '' + ]); + }; + $this->mergePicture('picture'); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules(): array + { + $rules = [ + 'slider' => [ + 'required', + new Enum(\App\Enums\Slides\SliderTypeEnum::class) + ], + 'title' => [ + 'required_unless:slider,' . \App\Enums\Slides\SliderTypeEnum::home->value(), + 'nullable', + 'string', + 'between:3,255' + ], + 'content' => 'required|string|between:3,255', + 'video_id' => 'nullable|string|regex:%([^"&?\/\s]{11})%i', + 'picture_alt' => 'required|string|between:3,255', + 'picture_title' => 'required|string|between:3,255', + 'button_label' => 'required_if:button_status,true|nullable|string|between:3,35', + 'button_url' => 'required_if:button_status,true|nullable|string|between:3,255', + 'button_status' => 'required|boolean', + 'button_new_tab' => 'required|boolean', + ]; + return \array_merge( + $rules, + // FIXME: Mettre à jour les tailles. + $this->pictureRules('picture', 100, 100, 100, 100, null, false), + ); + } + + /** + * Get custom attributes for validator errors. + * + * @return array + */ + public function attributes(): array + { + return [ + + 'video_id' => trans('validation.custom.video_id'), + ]; + } + + /** + * Custom validaton messages. + * + * @return array + */ + public function messages() + { + return [ + 'title' => [ + 'required_unless' => __('Le champ titre est obligatoire si le slider n\'est pas home.'), + ] + ]; + } +} diff --git a/app/Http/Requests/Bo/Slides/UpdateSlideRequest.php b/app/Http/Requests/Bo/Slides/UpdateSlideRequest.php new file mode 100644 index 0000000..2949d67 --- /dev/null +++ b/app/Http/Requests/Bo/Slides/UpdateSlideRequest.php @@ -0,0 +1,7 @@ + */ protected $fillable = [ + 'slider', 'title', - 'text', + 'content', + 'video_id', 'button_status', 'button_label', 'button_url', diff --git a/app/Policies/SlidePolicy.php b/app/Policies/SlidePolicy.php new file mode 100644 index 0000000..aa9f123 --- /dev/null +++ b/app/Policies/SlidePolicy.php @@ -0,0 +1,120 @@ + 'site', 'logo' => 'logo', 'historicalMilestone' => 'jalon historique|jalons historiques', + 'slide' => 'slide', ] ]; diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php index a1b9586..6912c0b 100644 --- a/resources/lang/fr/validation.php +++ b/resources/lang/fr/validation.php @@ -266,6 +266,9 @@ return [ 'button_status' => 'status du bouton', 'button_url' => 'lien du bouton', 'button' => 'bouton', - 'url' => 'url', + 'url' => 'url', + 'video_id' => 'ID de la vidéo', + 'youtube_video' => 'vidéo YouTube', + 'slider' => 'slider', ], ]; diff --git a/resources/views/bo/layouts/nav-list.blade.php b/resources/views/bo/layouts/nav-list.blade.php index ff6b407..5f06e7d 100644 --- a/resources/views/bo/layouts/nav-list.blade.php +++ b/resources/views/bo/layouts/nav-list.blade.php @@ -77,6 +77,14 @@ @endcan + @can('viewAny', \App\Models\Slide::class) + + @endcan @can('viewAny', \App\Models\HistoricalMilestone::class)