diff --git a/app/Http/Controllers/Bo/SlideController.php b/app/Http/Controllers/Bo/SlideController.php index cb346ca..055b675 100644 --- a/app/Http/Controllers/Bo/SlideController.php +++ b/app/Http/Controllers/Bo/SlideController.php @@ -7,6 +7,7 @@ use App\Http\Requests\Bo\Slides\StoreSlideRequest; use App\Http\Requests\Bo\Slides\UpdateSlideRequest; use App\Models\Slide; use App\Traits\Controllers\ChangesModelOrder; +use App\Traits\Controllers\UpdateModelPublished; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; @@ -14,6 +15,7 @@ use Illuminate\Support\Str; class SlideController extends Controller { use ChangesModelOrder; + use UpdateModelPublished; /** * Display a listing of the resource. diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index a2eccb0..5838ee6 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -237,7 +237,7 @@ class Controller extends BaseController */ protected function getProductQuery(string $search): Builder { - return Product::query()->where('status', true)->where(function ($query) use ($search) { + return Product::query()->where('published', true)->where(function ($query) use ($search) { // Par leur désignation. $query->where('label', 'like', "%{$search}%"); // Par ingrédients. @@ -279,7 +279,7 @@ class Controller extends BaseController */ protected function getNewsQuery(string $search): Builder { - return News::query()->where('status', true)->where(function ($query) use ($search) { + return News::query()->where('published', true)->where(function ($query) use ($search) { $query->where('title', 'like', "%{$search}%"); $query->orWhere('subtitle', 'like', "%{$search}%"); $query->orWhere('content', 'like', "%{$search}%"); @@ -298,7 +298,7 @@ class Controller extends BaseController */ protected function getRecipeQuery(string $search): Builder { - return Advice::query()->where('status', true) + return Advice::query()->where('published', true) ->where('type', '=', AdviceTypeEnum::recipes->value) ->where(function ($query) use ($search) { $query->where('title', 'like', "%{$search}%"); diff --git a/app/Http/Controllers/Fo/ExpertiseController.php b/app/Http/Controllers/Fo/ExpertiseController.php index efc1094..aedbe94 100644 --- a/app/Http/Controllers/Fo/ExpertiseController.php +++ b/app/Http/Controllers/Fo/ExpertiseController.php @@ -107,7 +107,7 @@ class ExpertiseController extends Controller $productVipModels = ExpertiseProduct::query()->where('page', $enumExpertiseProductPage->value())->get(); /** @var \App\Models\Product $productModels */ - $productModels = Product::query()->where('status', true) + $productModels = Product::query()->where('published', true) ->where('species', $enumProductSpecies->value()) ->inRandomOrder() ->limit(3) diff --git a/app/Http/Controllers/Fo/HomeController.php b/app/Http/Controllers/Fo/HomeController.php index d96f457..e0228b1 100644 --- a/app/Http/Controllers/Fo/HomeController.php +++ b/app/Http/Controllers/Fo/HomeController.php @@ -28,7 +28,7 @@ class HomeController extends Controller $ranges = Range::all(); // VIP Products. - $threeproducts = Product::where('status', true) + $threeproducts = Product::where('published', true) ->where('is_vip', true) ->take(3) ->orderBy('order', 'DESC') @@ -37,13 +37,13 @@ class HomeController extends Controller // Get Agenda. // Events starting in the future. - $events = News::query()->where('status', true) + $events = News::query()->where('published', true) ->where('event_start', '>', now()) ->orderBy('event_start', 'desc') ->take(2)->get()->reverse(); // Get last 3 News. - $news = News::query()->latest()->where('status', true) + $news = News::query()->latest()->where('published', true) ->take(3)->with('categories')->get(); return view('fo.pages.home', compact( diff --git a/app/Http/Controllers/Fo/NewsController.php b/app/Http/Controllers/Fo/NewsController.php index 0855412..8bad4dd 100644 --- a/app/Http/Controllers/Fo/NewsController.php +++ b/app/Http/Controllers/Fo/NewsController.php @@ -35,7 +35,7 @@ class NewsController extends Controller } } })) - )->where('status', true)->orderBy('created_at')->paginate(6); + )->where('published', true)->orderBy('created_at')->paginate(6); return view('fo.pages.news.index', compact('categories', 'news', 'filters_activated')); } diff --git a/app/Http/Controllers/Fo/ProductsController.php b/app/Http/Controllers/Fo/ProductsController.php index 91e1585..43df227 100644 --- a/app/Http/Controllers/Fo/ProductsController.php +++ b/app/Http/Controllers/Fo/ProductsController.php @@ -61,7 +61,7 @@ class ProductsController extends Controller $search = htmlspecialchars($request->query('search') ?? ''); $productsQuery = !empty($search) ? $this->getProductQuery($search) : Product::query(); $productsQuery->with('subrange.range'); - $productsQuery->where('status', true); + $productsQuery->where('published', true); // * Range filter (obligatoire). $productsQuery->whereHas('subrange', function (Builder $q) use ($range) { @@ -97,9 +97,9 @@ class ProductsController extends Controller public function show(Product $publishedProduct): \Illuminate\Contracts\View\View { /** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */ - $recipes = $publishedProduct->recipesQuery()->where('status', true)->get(); + $recipes = $publishedProduct->recipesQuery()->where('published', true)->get(); /** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */ - $tips = $publishedProduct->tipsQuery()->where('status', true)->get(); + $tips = $publishedProduct->tipsQuery()->where('published', true)->get(); // Force load subrange and range. $publishedProduct->load('subrange.range'); @@ -113,7 +113,7 @@ class ProductsController extends Controller $randomProducts = Product::query() ->with('subrange.range') ->where('id', '!=', $publishedProduct->id) - ->where('status', true) + ->where('published', true) ->whereHas('subrange', function (Builder $q) use ($range) { $q->whereHas('range', function (Builder $q) use ($range) { $q->where('id', $range->id); diff --git a/app/Http/Controllers/Fo/RecipesController.php b/app/Http/Controllers/Fo/RecipesController.php index aaefd33..3461cb9 100644 --- a/app/Http/Controllers/Fo/RecipesController.php +++ b/app/Http/Controllers/Fo/RecipesController.php @@ -43,32 +43,32 @@ class RecipesController extends Controller /** @var \App\Enums\Advices\AdviceTimeEnum|null $cooking_time */ /** @var \App\Enums\Advices\AdviceTimeEnum|null $preparation_time */ - $query = Advice::query()->with('tags')->where('type', 1)->where('status', true)->when( + $query = Advice::query()->with('tags')->where('type', 1)->where('published', true)->when( is_numeric($search_range), - fn (Builder $q) => + fn(Builder $q) => $q->whereHas( 'products', - fn (Builder $q) => + fn(Builder $q) => $q->whereHas( 'subrange', - fn (Builder $q) => + fn(Builder $q) => $q->whereHas( 'range', - fn (Builder $q) => + fn(Builder $q) => $q->where('id', 'LIKE', $search_range) ) ) ) )->when( $cooking_time, - fn (Builder $q) => + fn(Builder $q) => $q->whereBetween('cooking_time', [ Arr::get($cooking_time->times(), 0), Arr::get($cooking_time->times(), 1) ]) )->when( $preparation_time, - fn (Builder $q) => + fn(Builder $q) => $q->whereBetween('preparation_time', [ Arr::get($preparation_time->times(), 0), Arr::get($preparation_time->times(), 1) diff --git a/app/Http/Controllers/Fo/TipsController.php b/app/Http/Controllers/Fo/TipsController.php index 9989800..403e247 100644 --- a/app/Http/Controllers/Fo/TipsController.php +++ b/app/Http/Controllers/Fo/TipsController.php @@ -17,7 +17,7 @@ class TipsController extends Controller { $advices = Advice::query()->with('tags') ->where('type', AdviceTypeEnum::tips) - ->where('status', true) + ->where('published', true) ->paginate(9); return view('fo.pages.ideas.tips', \compact('advices')); } @@ -31,7 +31,9 @@ class TipsController extends Controller public function show(Advice $publishedAdvice): \Illuminate\Contracts\View\View { $publishedAdvice->load([ - 'advices', 'products.subrange.range', 'tags' + 'advices', + 'products.subrange.range', + 'tags' ]); return view('fo.pages.ideas.tip', [ 'adviceModel' => $publishedAdvice diff --git a/app/Http/Requests/Bo/Advice/StoreAdviceRequest.php b/app/Http/Requests/Bo/Advice/StoreAdviceRequest.php index 4d31eb8..90b7b81 100644 --- a/app/Http/Requests/Bo/Advice/StoreAdviceRequest.php +++ b/app/Http/Requests/Bo/Advice/StoreAdviceRequest.php @@ -35,7 +35,7 @@ class StoreAdviceRequest extends FormRequest //phpcs:enable $this->merge([ 'slug' => Str::slug(strip_tags($this->input('title'))), - 'status' => $this->boolean('status'), + 'published' => $this->boolean('published'), 'tags' => $this->input('tags', []), 'products' => $this->input('products', []), 'associated_tips_list' => $this->input('associated_tips_list', []), @@ -82,8 +82,10 @@ class StoreAdviceRequest extends FormRequest 'preparation' => 'required|string|min:15', 'advice' => 'nullable|string|min:15', 'ingredients' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if (count($value) < 1 || count($value) > 15) { $fail(\trans('Vous devez associer 1 à 15 lignes d\'ingrédients.')); } @@ -118,7 +120,11 @@ class StoreAdviceRequest extends FormRequest ) { $fail(\trans('Le nombre de convives est obligatoire')); } - }, 'nullable', 'numeric', 'min:1', 'max:99' + }, + 'nullable', + 'numeric', + 'min:1', + 'max:99' ], 'youtube_title' => 'required_with:youtube_video_id|nullable|min:3|max:255', 'youtube_video_id' => 'required_with:youtube_title|nullable|regex:%([^"&?\/\s]{11})%i', @@ -127,7 +133,9 @@ class StoreAdviceRequest extends FormRequest Rule::requiredIf(function () { return $this->type === AdviceTypeEnum::recipes->value(); }), - 'numeric', 'min:0', 'max:65535' + 'numeric', + 'min:0', + 'max:65535' ], 'difficulty' => [ Rule::requiredIf(function () { @@ -135,10 +143,12 @@ class StoreAdviceRequest extends FormRequest }), new Enum(AdviceDifficultyEnum::class) ], - 'status' => 'required|boolean', + 'published' => 'required|boolean', 'tags' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if (count($value) > 2) { $fail(\trans('Vous devez associer au maximum 2 tags.')); } @@ -148,8 +158,10 @@ class StoreAdviceRequest extends FormRequest 'tags.*.id' => 'required|numeric|exists:tags,id|distinct', 'tags.*.label' => 'required|string', 'products' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if ($this->type == AdviceTypeEnum::recipes->value()) { if (count($value) < 1 || count($value) > 3) { $fail(\trans('Vous devez associer 1 à 3 produits.')); @@ -165,8 +177,10 @@ class StoreAdviceRequest extends FormRequest 'products.*.value' => 'required|exists:products,id', 'products.*.label' => 'required|string', 'associated_tips_list' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if (count($value) > 3) { $fail(\trans('Vous devez associer au maximum 3 astuces.')); } @@ -176,8 +190,10 @@ class StoreAdviceRequest extends FormRequest 'associated_tips_list.*.value' => 'required|exists:advice,id', 'associated_tips_list.*.label' => 'required|string', 'associated_recipes_list' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if (count($value) > 3) { $fail(\trans('Vous devez associer au maximum 3 recettes.')); } diff --git a/app/Http/Requests/Bo/News/StoreNewsRequest.php b/app/Http/Requests/Bo/News/StoreNewsRequest.php index d89c3b9..7a52074 100644 --- a/app/Http/Requests/Bo/News/StoreNewsRequest.php +++ b/app/Http/Requests/Bo/News/StoreNewsRequest.php @@ -31,7 +31,7 @@ class StoreNewsRequest extends FormRequest //phpcs:enable $this->merge([ 'slug' => Str::slug($this->title), - 'status' => $this->status ? true : false, + 'published' => $this->published ? true : false, 'categories' => $this->categories ?? [], 'products' => $this->products ?? [], 'associated_news_list' => $this->associated_news_list ?? [], @@ -81,7 +81,7 @@ class StoreNewsRequest extends FormRequest 'min:3', 'max:255' ], - 'status' => 'required|boolean', + 'published' => 'required|boolean', 'categories' => [ 'present', 'array', @@ -153,7 +153,7 @@ class StoreNewsRequest extends FormRequest 'event_start' => trans('Date de début de l\'évènement'), 'event_end' => trans('Date de fin de l\'évènement'), 'event_text' => trans('Description de l\'évènement'), - 'status' => trans('Status'), + 'published' => trans('Status'), ]; } } diff --git a/app/Http/Requests/Bo/Products/StoreProductRequest.php b/app/Http/Requests/Bo/Products/StoreProductRequest.php index 116d36f..b1a1012 100644 --- a/app/Http/Requests/Bo/Products/StoreProductRequest.php +++ b/app/Http/Requests/Bo/Products/StoreProductRequest.php @@ -35,7 +35,7 @@ class StoreProductRequest extends FormRequest 'is_frenchpoultry' => $this->is_frenchpoultry ? true : false, 'is_vip' => $this->is_vip ? true : false, 'is_egalim' => $this->is_egalim ? true : false, - 'status' => $this->status ? true : false + 'published' => $this->published ? true : false ]); $this->mergePicture('sticker_sm'); $this->mergePictures('slider_pictures'); @@ -61,8 +61,10 @@ class StoreProductRequest extends FormRequest 'advantage' => 'required|string|min:15', 'preparation' => 'required|string|min:15', 'packaging' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if (1 > count($value) || count($value) > 6) { $fail(\trans('Vous devez remplir au moins 1 ligne et au plus 6 lignes de conditionnement.')); } @@ -71,8 +73,10 @@ class StoreProductRequest extends FormRequest 'packaging.*' => 'required|array', 'packaging.*.value' => 'required|string|min:2|max:255', 'caliber' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if (1 > count($value) || count($value) > 6) { $fail(\trans('Vous devez remplir au moins 1 ligne et au plus 6 lignes de calibre.')); } @@ -81,8 +85,10 @@ class StoreProductRequest extends FormRequest 'caliber.*' => 'required|array', 'caliber.*.value' => 'required|string|min:1|max:255', 'nutritionnal_values' => [ + 'present', + 'array', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed - 'present', 'array', function ($attribute, array $value, $fail) { + function ($attribute, array $value, $fail) { if (count($value) != 9) { $fail(\trans('Vous devez remplir seulement 9 lignes de valeurs nutritionnelles.')); } @@ -94,7 +100,7 @@ class StoreProductRequest extends FormRequest 'is_frenchpoultry' => 'required|boolean', 'is_vip' => 'required|boolean', 'is_egalim' => 'required|boolean', - 'status' => 'required|boolean' + 'published' => 'required|boolean' ]; return \array_merge( $rules, @@ -133,7 +139,7 @@ class StoreProductRequest extends FormRequest 'is_frenchpoultry' => trans('Label volaille française'), 'is_vip' => trans('Produit VIP'), 'is_egalim' => trans('Produit Égalim'), - 'status' => trans('publish') + 'published' => trans('publish') ]; } } diff --git a/app/Http/Requests/Bo/Slides/StoreSlideRequest.php b/app/Http/Requests/Bo/Slides/StoreSlideRequest.php index 4c7164f..facb676 100644 --- a/app/Http/Requests/Bo/Slides/StoreSlideRequest.php +++ b/app/Http/Requests/Bo/Slides/StoreSlideRequest.php @@ -27,8 +27,9 @@ class StoreSlideRequest extends FormRequest protected function prepareForValidation(): void { $this->merge([ - 'button_display' => $this->button_display ? true : false, - 'button_targetblank' => $this->button_targetblank ? true : false, + 'button_display' => $this->boolean('button_display'), + 'button_targetblank' => $this->boolean('button_targetblank'), + 'published' => $this->boolean('published'), ]); $this->mergePicture('picture'); $this->mergePicture('picture_thumbnail'); @@ -51,7 +52,8 @@ class StoreSlideRequest extends FormRequest 'picture_alt' => 'required|min:3|max:255', 'picture_title' => 'required|min:3|max:255', 'picture_thumbnail_alt' => 'required|min:3|max:255', - 'picture_thumbnail_title' => 'required|min:3|max:255' + 'picture_thumbnail_title' => 'required|min:3|max:255', + 'published' => 'required|boolean', ]; return \array_merge( $rules, diff --git a/app/Lib/Helpers/FileStorageHelper.php b/app/Lib/Helpers/FileStorageHelper.php index dc1ef30..f88e6f2 100644 --- a/app/Lib/Helpers/FileStorageHelper.php +++ b/app/Lib/Helpers/FileStorageHelper.php @@ -70,7 +70,8 @@ class FileStorageHelper * @param array $array * @return void */ - public static function removeFiles(Model $model, array $array): void { + public static function removeFiles(Model $model, array $array): void + { foreach ($array as $item) { self::removeFile($model, $item); } diff --git a/app/Models/Advice.php b/app/Models/Advice.php index ccf22d3..597f7e3 100644 --- a/app/Models/Advice.php +++ b/app/Models/Advice.php @@ -43,7 +43,7 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper; * @property integer|null $cooking_time Time of cooking. * @property integer|null $preparation_time Time of preparation. * @property \App\Enums\Advices\AdviceDifficultyEnum|null $difficulty Difficulty. - * @property boolean $status Status. + * @property boolean $published Status. * @property-read \Illuminate\Support\Carbon $created_at Created date. * @property-read \Illuminate\Support\Carbon $updated_at Updated date. * @@ -92,7 +92,7 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable 'cooking_time', 'preparation_time', 'difficulty', - 'status' + 'published' ]; /** @@ -102,7 +102,7 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable */ protected $casts = [ 'ingredients' => 'array', - 'status' => 'bool', + 'published' => 'bool', 'type' => AdviceTypeEnum::class, 'difficulty' => AdviceDifficultyEnum::class, ]; @@ -271,7 +271,7 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable protected function recipes(): Attribute { return Attribute::make( - get: fn () => $this->recipesQuery(), + get: fn() => $this->recipesQuery(), ); } @@ -293,7 +293,7 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable protected function tips(): Attribute { return Attribute::make( - get: fn () => $this->tipsQuery(), + get: fn() => $this->tipsQuery(), ); } @@ -340,7 +340,7 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable \trans($this->getTable()), $this->seo_title, $this->seo_description, - $this->status ?? false, + $this->published ?? false, \route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this), $this->type === AdviceTypeEnum::recipes ? route('fo.recipes.show', $this) : route('fo.tips.show', $this) ); diff --git a/app/Models/News.php b/app/Models/News.php index fafb5da..dcfeed9 100644 --- a/app/Models/News.php +++ b/app/Models/News.php @@ -14,6 +14,7 @@ use Uwil\Seo\Laravel\Interfaces\SeoInterface; use Uwil\Seo\Laravel\Traits\SeoTrait; use Spatie\Sitemap\Contracts\Sitemapable; use Spatie\Sitemap\Tags\Url; +use Uwil\Seo\Laravel\Objects\SeoItem; use Uwil\SitemapGenerator\Lib\SitemapHelper; /** @@ -36,7 +37,7 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper; * @property \Illuminate\Support\Carbon|null $event_start Start of the event. * @property \Illuminate\Support\Carbon|null $event_end End of the event. * @property string|null $event_text Text of the event. - * @property boolean $status Status. + * @property boolean $published Status. * @property-read string $reading_time Time reading of a news' page * @property-read \Illuminate\Support\Carbon $created_at Created date. * @property-read \Illuminate\Support\Carbon $updated_at Updated date. @@ -77,7 +78,7 @@ class News extends Authenticatable implements SeoInterface, Sitemapable 'event_start', 'event_end', 'event_text', - 'status', + 'published', ]; /** @@ -88,7 +89,7 @@ class News extends Authenticatable implements SeoInterface, Sitemapable protected $casts = [ 'event_start' => 'datetime', 'event_end' => 'datetime', - 'status' => 'bool', + 'published' => 'bool', ]; /** @@ -127,7 +128,7 @@ class News extends Authenticatable implements SeoInterface, Sitemapable public function calLink(): Attribute { return Attribute::make( - get: fn () => ( + get: fn() => ( $this->exists() and ($this->event_start && $this->event_end && $this->event_text) ) ? Link::create( @@ -291,4 +292,21 @@ class News extends Authenticatable implements SeoInterface, Sitemapable $params = ['actu' => $model]; return SitemapHelper::generateUrl($route, $params, $model); } + + /** + * Transform to seoModel + * + * @return \Uwil\Seo\Laravel\Objects\SeoItem + */ + public function toSeoItem(): SeoItem + { + return new SeoItem( + \trans($this->getTable()), + $this->seo_title, + $this->seo_description, + $this->published ?? false, + \route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this), + route('fo.news.show', $this) + ); + } } diff --git a/app/Models/Product.php b/app/Models/Product.php index 8449e3f..a2bbe34 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -14,6 +14,7 @@ use Uwil\Seo\Laravel\Interfaces\SeoInterface; use Uwil\Seo\Laravel\Traits\SeoTrait; use Spatie\Sitemap\Contracts\Sitemapable; use Spatie\Sitemap\Tags\Url; +use Uwil\Seo\Laravel\Objects\SeoItem; use Uwil\SitemapGenerator\Lib\SitemapHelper; /** @@ -38,7 +39,7 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper; * @property boolean $is_frenchpoultry Is frenchpoultry or not. * @property boolean $is_vip Is vip or not. * @property boolean $is_egalim Is egalim or not. - * @property boolean $status Status. + * @property boolean $published Status. * @property integer $order Order. * @property-read \Illuminate\Support\Carbon $created_at Created date. * @property-read \Illuminate\Support\Carbon $updated_at Updated date. @@ -80,7 +81,7 @@ class Product extends Model implements SeoInterface, Sitemapable 'is_frenchpoultry', 'is_vip', 'is_egalim', - 'status' + 'published' ]; /** @@ -96,7 +97,7 @@ class Product extends Model implements SeoInterface, Sitemapable 'is_frenchpoultry' => 'bool', 'is_vip' => 'bool', 'is_egalim' => 'bool', - 'status' => 'bool', + 'published' => 'bool', 'species' => ProductSpeciesEnum::class, 'nutriscore' => NutriscoreEnum::class ]; @@ -271,4 +272,21 @@ class Product extends Model implements SeoInterface, Sitemapable $params = ['publishedProduct' => $model]; return SitemapHelper::generateUrl($route, $params, $model); } + + /** + * Transform to seoModel + * + * @return \Uwil\Seo\Laravel\Objects\SeoItem + */ + public function toSeoItem(): SeoItem + { + return new SeoItem( + \trans($this->getTable()), + $this->seo_title, + $this->seo_description, + $this->published ?? false, + \route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this), + route('fo.product.show', $this) + ); + } } diff --git a/app/Models/Slide.php b/app/Models/Slide.php index 42c7930..a6b3015 100644 --- a/app/Models/Slide.php +++ b/app/Models/Slide.php @@ -23,6 +23,7 @@ use Illuminate\Validation\ValidationException; * @property string $picture_thumbnail_alt Thumbnail picture's attribute alt. * @property string $picture_thumbnail_title Thumbnail picture's attribute title. * @property integer $order Order. + * @property boolean $published Is the slide published ? * @property-read \Illuminate\Support\Carbon $created_at Created date. * @property-read \Illuminate\Support\Carbon $updated_at Updated date. */ @@ -48,7 +49,8 @@ class Slide extends Model 'picture_thumbnail', 'picture_thumbnail_alt', 'picture_thumbnail_title', - 'order' + 'order', + 'published' ]; /** @@ -57,8 +59,9 @@ class Slide extends Model * @var array */ protected $casts = [ - 'button_display' => 'bool', - 'button_targetblank' => 'bool' + 'button_display' => 'bool', + 'button_targetblank' => 'bool', + 'published' => 'bool' ]; /** @@ -69,9 +72,6 @@ class Slide extends Model protected static function booted(): void { static::creating(function (self $model) { - if (count(self::get()) >= 4) { - self::assertNumberOfSlides(); - } self::manageFields($model); $model->order = \intval(self::query()->max('order')) + 1; }); @@ -82,10 +82,8 @@ class Slide extends Model FileStorageHelper::removeOldFile($model, 'picture'); FileStorageHelper::removeOldFile($model, 'picture_thumbnail'); }); - static::deleting(function () { - if (1 >= count(self::get())) { - self::assertNumberOfSlides(); - } + static::deleting(function (self $model) { + self::assertNumberOfSlides($model, true); }); static::deleted(function (self $model) { FileStorageHelper::removeFile($model, 'picture'); @@ -104,6 +102,7 @@ class Slide extends Model private static function manageFields(self $model): void { self::assertTitleIsUnique($model->title, $model->id); + self::assertNumberOfSlides($model); ToolboxHelper::assertNoInternalBoUrls($model->content, 'content'); $model->content = clean($model->content); if ($model->button_url) { @@ -117,14 +116,31 @@ class Slide extends Model /** * Asserts the number of slides in the slider. * + * @param self $model + * @param boolean $isDeleting * @return void * @throws \Illuminate\Validation\ValidationException If there is less 1 or more than 4 slides. */ - private static function assertNumberOfSlides(): void + private static function assertNumberOfSlides(self $model, bool $isDeleting = false): void { - throw ValidationException::withMessages([ - 'Opération impossible, minimum un et maximum quatre slides doivent être présentes.' - ]); + if ( + $isDeleting && + $model->published && + self::query()->where('published', true)->count() <= 1 + ) { + throw ValidationException::withMessages( + [trans('Minimum 1 slide doit être publiée, la slide n\'a pas été supprimée.')] + ); + } + if ($model->published !== $model->getOriginal('published')) { + if (self::query()->where('published', true)->count() + 1 > 4 && $model->published) { + $model->published = false; + \session()->flash('info', \trans('Maximum 4 slides peuvent être publiées, la slide a été dépubliée.')); + } elseif (self::query()->where('published', true)->count() <= 1 && !$model->published) { + $model->published = true; + \session()->flash('info', \trans('Minimum 1 slide doit être publiée, la slide a été publiée.')); + } + } } /** diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 17f71bf..b2a7fce 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -65,7 +65,7 @@ class RouteServiceProvider extends ServiceProvider // * Front binded Models Route::bind('publishedAdvice', function ($value) { - return Advice::where('slug', $value)->where('status', true)->firstOrFail(); + return Advice::where('slug', $value)->where('published', true)->firstOrFail(); }); } @@ -110,8 +110,11 @@ class RouteServiceProvider extends ServiceProvider })->all(); // * Filter array keys $cspReport = collect(array_intersect_key($cspReport, [ - 'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '', - 'referrer' => '', 'violated-directive' => '' + 'blocked-uri' => '', + 'document-uri' => '', + 'original-policy' => '', + 'referrer' => '', + 'violated-directive' => '' ])); \Illuminate\Support\Facades\Log::warning(sprintf( "CSP REPORT for %s : \n %s", diff --git a/config/sitemap-generator.php b/config/sitemap-generator.php index ed0d643..fdc87b1 100644 --- a/config/sitemap-generator.php +++ b/config/sitemap-generator.php @@ -63,7 +63,7 @@ return [ [ 'model' => 'App\Models\Advice', 'filters' => [ - ['status', '=', true] + ['published', '=', true] ] ], [ @@ -73,13 +73,13 @@ return [ [ 'model' => 'App\Models\Product', 'filters' => [ - ['status', '=', true] + ['published', '=', true] ] ], [ 'model' => 'App\Models\News', 'filters' => [ - ['status', '=', true] + ['published', '=', true] ] ] ], diff --git a/database/factories/AdviceFactory.php b/database/factories/AdviceFactory.php index 26badb6..9b66f83 100644 --- a/database/factories/AdviceFactory.php +++ b/database/factories/AdviceFactory.php @@ -81,7 +81,7 @@ class AdviceFactory extends Factory 'cooking_time' => $cooking_time, 'preparation_time' => $preparation_time, 'difficulty' => $difficulty, - 'status' => $this->faker->boolean(75) + 'published' => $this->faker->boolean(75) ]; } } diff --git a/database/factories/NewsFactory.php b/database/factories/NewsFactory.php index 12e4f8d..8c30aa1 100644 --- a/database/factories/NewsFactory.php +++ b/database/factories/NewsFactory.php @@ -56,7 +56,7 @@ class NewsFactory extends Factory 'event_start' => $eventStart, 'event_end' => $eventEnd, 'event_text' => $eventText, - 'status' => $this->faker->boolean(75) + 'published' => $this->faker->boolean(75) ]; } } diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php index b402094..b428006 100644 --- a/database/factories/ProductFactory.php +++ b/database/factories/ProductFactory.php @@ -66,7 +66,7 @@ class ProductFactory extends Factory 'is_frenchpoultry' => $this->faker->boolean(75), 'is_vip' => $this->faker->boolean(25), 'is_egalim' => $this->faker->boolean(25), - 'status' => $this->faker->boolean(75) + 'published' => $this->faker->boolean(75) ]; } } diff --git a/database/migrations/2025_01_06_142121_add_published_column_to_slides_table.php b/database/migrations/2025_01_06_142121_add_published_column_to_slides_table.php new file mode 100644 index 0000000..ce9655e --- /dev/null +++ b/database/migrations/2025_01_06_142121_add_published_column_to_slides_table.php @@ -0,0 +1,35 @@ +boolean('published')->comment('Is the slide published ?') + ->after('order'); + }); + Slide::query()->update(['published' => true]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down(): void + { + Schema::table('slides', function (Blueprint $table) { + $table->dropColumn('published'); + }); + } +}; diff --git a/database/migrations/2025_01_06_145623_rename_status_as_published.php b/database/migrations/2025_01_06_145623_rename_status_as_published.php new file mode 100644 index 0000000..ee49f63 --- /dev/null +++ b/database/migrations/2025_01_06_145623_rename_status_as_published.php @@ -0,0 +1,44 @@ +renameColumn('status', 'published'); + }); + Schema::table('news', function (Blueprint $table) { + $table->renameColumn('status', 'published'); + }); + Schema::table('products', function (Blueprint $table) { + $table->renameColumn('status', 'published'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down(): void + { + Schema::table('advice', function (Blueprint $table) { + $table->renameColumn('published', 'status'); + }); + Schema::table('news', function (Blueprint $table) { + $table->renameColumn('published', 'status'); + }); + Schema::table('products', function (Blueprint $table) { + $table->renameColumn('published', 'status'); + }); + } +}; diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php index a38a78f..9c450a9 100644 --- a/resources/lang/fr/validation.php +++ b/resources/lang/fr/validation.php @@ -191,7 +191,7 @@ return [ 'seo_title' => 'Titre SEO', 'seo' => 'Contenu SEO', 'species' => 'Espèce', - 'status' => 'État de publication', + 'published' => 'État de publication', 'subtitle' => 'Sous-titre', 'title' => 'Titre', 'updated_at' => 'Mis à jour le', diff --git a/resources/ts/bo/utilities/fontawesome.ts b/resources/ts/bo/utilities/fontawesome.ts index a683baf..50b69d7 100644 --- a/resources/ts/bo/utilities/fontawesome.ts +++ b/resources/ts/bo/utilities/fontawesome.ts @@ -16,6 +16,7 @@ import { faChevronRight, faCircleCheck, faCircleExclamation, + faCircleInfo, faCircleNotch, faCircleXmark, faCrop, @@ -70,6 +71,7 @@ library.add(faArrowAltCircleUp); library.add(faListUl); library.add(faCircleCheck); library.add(faCircleExclamation); +library.add(faCircleInfo); // Front library.add(faChevronLeft); diff --git a/resources/views/bo/modules/change-published-status.blade.php b/resources/views/bo/modules/change-published-status.blade.php index 8d54fc9..6c3fbf4 100644 --- a/resources/views/bo/modules/change-published-status.blade.php +++ b/resources/views/bo/modules/change-published-status.blade.php @@ -1,9 +1,9 @@
@csrf -