From 57e84ab247683884477a97ef6d03abb18555311a Mon Sep 17 00:00:00 2001 From: "noah.lancien" Date: Fri, 20 Oct 2023 07:39:18 +0000 Subject: [PATCH] Close #5 seeders factories --- app/Console/Commands/UpdateNewsStatus.php | 33 +++ .../Commands/UpdateSeasonalSectionsStatus.php | 33 +++ app/Console/Kernel.php | 4 + app/Enums/News/CategoryEnum.php | 27 +++ app/Enums/Products/CookingModeEnum.php | 27 +++ app/Enums/SeasonalSections/BackgroundEnum.php | 23 ++ app/Enums/StaticPageType.php | 37 ++++ app/Jobs/NewsStatusUpdate.php | 46 ++++ app/Jobs/SeasonalSectionStatusUpdate.php | 46 ++++ app/Lib/Helpers/FileStorageHelper.php | 18 ++ app/Models/Commitment.php | 108 ++++++++++ app/Models/Convictionpage.php | 56 +++++ app/Models/Explorerpage.php | 83 ++++++++ app/Models/Homepage.php | 63 ++++++ app/Models/Joinuspage.php | 42 ++++ app/Models/News.php | 201 ++++++++++++++++++ app/Models/Product.php | 192 +++++++++++++++++ app/Models/Range.php | 173 +++++++++++++++ app/Models/SeasonalSection.php | 146 +++++++++++++ app/Models/Stamp.php | 62 ++++++ app/Models/StaticPage.php | 86 ++++++++ app/Models/Testimonial.php | 76 +++++++ database/factories/CommitmentFactory.php | 23 ++ database/factories/ConvictionpageFactory.php | 27 +++ database/factories/ExplorerpageFactory.php | 25 +++ database/factories/HomepageFactory.php | 26 +++ database/factories/JoinuspageFactory.php | 20 ++ database/factories/NewsFactory.php | 40 ++++ database/factories/ProductFactory.php | 50 +++++ database/factories/RangeFactory.php | 36 ++++ database/factories/SeasonalSectionFactory.php | 24 +++ database/factories/StampFactory.php | 22 ++ database/factories/TestimonialFactory.php | 24 +++ .../commitments/default-picture-185x185.png | Bin 0 -> 1594 bytes .../explorerpages/default-picture-265x364.png | Bin 0 -> 3525 bytes .../homepages/default-picture-640x390.png | Bin 0 -> 6384 bytes .../assets/news/default-picture-1002x565.png | Bin 0 -> 7537 bytes .../assets/news/default-picture-265x354.png | Bin 0 -> 3448 bytes .../products/default-picture-327x252.png | Bin 0 -> 3159 bytes .../products/default-picture-332x252.png | Bin 0 -> 2944 bytes .../products/default-picture-774x515.png | Bin 0 -> 4952 bytes .../assets/ranges/default-picture-246x337.png | Bin 0 -> 2957 bytes .../assets/ranges/default-picture-332x442.png | Bin 0 -> 3398 bytes .../assets/ranges/default-picture-466x440.png | Bin 0 -> 4524 bytes .../default-picture-362x542.png | Bin 0 -> 5044 bytes .../assets/stamps/default-picture-120x120.png | Bin 0 -> 720 bytes .../testimonials/default-picture-292x417.png | Bin 0 -> 3298 bytes ..._create_commitment_explorerpage_table.php} | 4 +- ...80112_create_commitment_product_table.php} | 4 +- ...0_18_180112_create_explorerpages_table.php | 6 +- ...023_10_18_180112_create_products_table.php | 2 +- ...180112_create_seasonal_sections_table.php} | 2 +- ...10_18_180112_create_static_pages_table.php | 25 ++- ...keys_to_commitment_explorerpage_table.php} | 8 +- ...eign_keys_to_commitment_product_table.php} | 8 +- database/seeders/CommitmentSeeder.php | 25 +++ database/seeders/ConvictionpageSeeder.php | 25 +++ database/seeders/DatabaseSeeder.php | 11 + database/seeders/ExplorerpageSeeder.php | 43 ++++ database/seeders/HomepageSeeder.php | 31 +++ database/seeders/JoinuspageSeeder.php | 25 +++ database/seeders/NewsSeeder.php | 28 +++ database/seeders/ProductSeeder.php | 37 ++++ database/seeders/RangeSeeder.php | 31 +++ database/seeders/SeasonalSectionSeeder.php | 34 +++ database/seeders/StampSeeder.php | 25 +++ database/seeders/StaticPageSeeder.php | 155 ++++++++++++++ database/seeders/TestimonialSeeder.php | 25 +++ 68 files changed, 2428 insertions(+), 25 deletions(-) create mode 100644 app/Console/Commands/UpdateNewsStatus.php create mode 100644 app/Console/Commands/UpdateSeasonalSectionsStatus.php create mode 100644 app/Enums/News/CategoryEnum.php create mode 100644 app/Enums/Products/CookingModeEnum.php create mode 100644 app/Enums/SeasonalSections/BackgroundEnum.php create mode 100644 app/Enums/StaticPageType.php create mode 100644 app/Jobs/NewsStatusUpdate.php create mode 100644 app/Jobs/SeasonalSectionStatusUpdate.php create mode 100644 app/Models/Commitment.php create mode 100644 app/Models/Convictionpage.php create mode 100644 app/Models/Explorerpage.php create mode 100644 app/Models/Homepage.php create mode 100644 app/Models/Joinuspage.php create mode 100644 app/Models/News.php create mode 100644 app/Models/Product.php create mode 100644 app/Models/Range.php create mode 100644 app/Models/SeasonalSection.php create mode 100644 app/Models/Stamp.php create mode 100644 app/Models/StaticPage.php create mode 100644 app/Models/Testimonial.php create mode 100644 database/factories/CommitmentFactory.php create mode 100644 database/factories/ConvictionpageFactory.php create mode 100644 database/factories/ExplorerpageFactory.php create mode 100644 database/factories/HomepageFactory.php create mode 100644 database/factories/JoinuspageFactory.php create mode 100644 database/factories/NewsFactory.php create mode 100644 database/factories/ProductFactory.php create mode 100644 database/factories/RangeFactory.php create mode 100644 database/factories/SeasonalSectionFactory.php create mode 100644 database/factories/StampFactory.php create mode 100644 database/factories/TestimonialFactory.php create mode 100644 database/factories/assets/commitments/default-picture-185x185.png create mode 100644 database/factories/assets/explorerpages/default-picture-265x364.png create mode 100644 database/factories/assets/homepages/default-picture-640x390.png create mode 100644 database/factories/assets/news/default-picture-1002x565.png create mode 100644 database/factories/assets/news/default-picture-265x354.png create mode 100644 database/factories/assets/products/default-picture-327x252.png create mode 100644 database/factories/assets/products/default-picture-332x252.png create mode 100644 database/factories/assets/products/default-picture-774x515.png create mode 100644 database/factories/assets/ranges/default-picture-246x337.png create mode 100644 database/factories/assets/ranges/default-picture-332x442.png create mode 100644 database/factories/assets/ranges/default-picture-466x440.png create mode 100644 database/factories/assets/seasonalsections/default-picture-362x542.png create mode 100644 database/factories/assets/stamps/default-picture-120x120.png create mode 100644 database/factories/assets/testimonials/default-picture-292x417.png rename database/migrations/{2023_10_18_180112_create_explorerpage_commitment_table.php => 2023_10_18_180112_create_commitment_explorerpage_table.php} (81%) rename database/migrations/{2023_10_18_180112_create_product_commitment_table.php => 2023_10_18_180112_create_commitment_product_table.php} (82%) rename database/migrations/{2023_10_18_180112_create_seasonal_section_table.php => 2023_10_18_180112_create_seasonal_sections_table.php} (95%) rename database/migrations/{2023_10_18_180115_add_foreign_keys_to_explorerpage_commitment_table.php => 2023_10_18_180115_add_foreign_keys_to_commitment_explorerpage_table.php} (72%) rename database/migrations/{2023_10_18_180115_add_foreign_keys_to_product_commitment_table.php => 2023_10_18_180115_add_foreign_keys_to_commitment_product_table.php} (71%) create mode 100644 database/seeders/CommitmentSeeder.php create mode 100644 database/seeders/ConvictionpageSeeder.php create mode 100644 database/seeders/ExplorerpageSeeder.php create mode 100644 database/seeders/HomepageSeeder.php create mode 100644 database/seeders/JoinuspageSeeder.php create mode 100644 database/seeders/NewsSeeder.php create mode 100644 database/seeders/ProductSeeder.php create mode 100644 database/seeders/RangeSeeder.php create mode 100644 database/seeders/SeasonalSectionSeeder.php create mode 100644 database/seeders/StampSeeder.php create mode 100644 database/seeders/StaticPageSeeder.php create mode 100644 database/seeders/TestimonialSeeder.php diff --git a/app/Console/Commands/UpdateNewsStatus.php b/app/Console/Commands/UpdateNewsStatus.php new file mode 100644 index 0000000..a657df6 --- /dev/null +++ b/app/Console/Commands/UpdateNewsStatus.php @@ -0,0 +1,33 @@ +job(NewsStatusUpdate::class)->everyMinute(); + $schedule->job(SeasonalSectionStatusUpdate::class)->everyMinute(); } /** diff --git a/app/Enums/News/CategoryEnum.php b/app/Enums/News/CategoryEnum.php new file mode 100644 index 0000000..a5f8190 --- /dev/null +++ b/app/Enums/News/CategoryEnum.php @@ -0,0 +1,27 @@ +name => 'La vie d\'Entreprise', + self::convictions->name => 'Nos convictions', + self::recipes->name => 'Nos recettes', + self::jobs->name => 'Nos métiers', + self::communication->name => 'Communication', + ]; +} diff --git a/app/Enums/Products/CookingModeEnum.php b/app/Enums/Products/CookingModeEnum.php new file mode 100644 index 0000000..2b2824c --- /dev/null +++ b/app/Enums/Products/CookingModeEnum.php @@ -0,0 +1,27 @@ +name => 'Micro-ondes', + self::furnace->name => 'Four traditionnel', + self::waterbath->name => 'Bain-marie', + self::pan->name => 'Poêle', + self::fresh->name => 'Se consomme frais', + ]; +} diff --git a/app/Enums/SeasonalSections/BackgroundEnum.php b/app/Enums/SeasonalSections/BackgroundEnum.php new file mode 100644 index 0000000..daa6790 --- /dev/null +++ b/app/Enums/SeasonalSections/BackgroundEnum.php @@ -0,0 +1,23 @@ +name => 'Chandeleur', + self::chinesenewyear->name => 'Nouvel an chinois', + self::endofyear->name => 'Fin d\'année', + ]; +} diff --git a/app/Enums/StaticPageType.php b/app/Enums/StaticPageType.php new file mode 100644 index 0000000..6af3f76 --- /dev/null +++ b/app/Enums/StaticPageType.php @@ -0,0 +1,37 @@ +name => 'Contact', + self::legals->name => 'Mentions légales', + self::confidentiality->name => 'Confidentialité', + self::home->name => 'Accueil', + self::conviction->name => 'Nos Convictions', + self::explorer->name => 'Explorate & Gastronome', + self::joinus->name => 'Rejoignez-nous', + self::ranges->name => 'Nos Gammes de Produits', + self::aboutus->name => 'Nous Connaître', + self::news->name => 'Actualités', + ]; +} diff --git a/app/Jobs/NewsStatusUpdate.php b/app/Jobs/NewsStatusUpdate.php new file mode 100644 index 0000000..5e13fe4 --- /dev/null +++ b/app/Jobs/NewsStatusUpdate.php @@ -0,0 +1,46 @@ + */ + $newsListToPublish = News::query() + ->where('publish_at', '<=', Carbon::now()->toDateTime()) + ->whereNotNull('publish_at') + ->where('published', false)->get(); + Log::debug(__CLASS__ . " news to publish " . $newsListToPublish->count()); + foreach ($newsListToPublish as $news) { + $news->publish_at = null; + $news->published = true; + $news->saveOrFail(); + } + /** @var \Illuminate\Database\Eloquent\Collection */ + $newsListToUnPublish = News::query() + ->where('unpublish_at', '<=', Carbon::now()->toDateTime()) + ->whereNotNull('unpublish_at') + ->where('published', true)->get(); + Log::debug(__CLASS__ . " news to unpublish " . $newsListToPublish->count()); + foreach ($newsListToUnPublish as $news) { + $news->publish_at = null; + $news->unpublish_at = null; + $news->published = false; + $news->saveOrFail(); + } + } +} diff --git a/app/Jobs/SeasonalSectionStatusUpdate.php b/app/Jobs/SeasonalSectionStatusUpdate.php new file mode 100644 index 0000000..22ca262 --- /dev/null +++ b/app/Jobs/SeasonalSectionStatusUpdate.php @@ -0,0 +1,46 @@ + */ + $seasonalsectionsListToPublish = SeasonalSection::query() + ->where('publish_at', '<=', Carbon::now()->toDateTime()) + ->whereNotNull('publish_at') + ->where('published', false)->get(); + Log::debug(__CLASS__ . " seasonalsections to publish " . $seasonalsectionsListToPublish->count()); + foreach ($seasonalsectionsListToPublish as $seasonalsections) { + $seasonalsections->publish_at = null; + $seasonalsections->published = true; + $seasonalsections->saveOrFail(); + } + /** @var \Illuminate\Database\Eloquent\Collection */ + $seasonalsectionsListToUnPublish = SeasonalSection::query() + ->where('unpublish_at', '<=', Carbon::now()->toDateTime()) + ->whereNotNull('unpublish_at') + ->where('published', true)->get(); + Log::debug(__CLASS__ . " seasonalsections to unpublish " . $seasonalsectionsListToPublish->count()); + foreach ($seasonalsectionsListToUnPublish as $seasonalsections) { + $seasonalsections->publish_at = null; + $seasonalsections->unpublish_at = null; + $seasonalsections->published = false; + $seasonalsections->saveOrFail(); + } + } +} diff --git a/app/Lib/Helpers/FileStorageHelper.php b/app/Lib/Helpers/FileStorageHelper.php index 45ccec9..f5b864b 100644 --- a/app/Lib/Helpers/FileStorageHelper.php +++ b/app/Lib/Helpers/FileStorageHelper.php @@ -451,4 +451,22 @@ class FileStorageHelper $filename = trim($filename, '.-'); return $filename; } + + /** + * Remove all model files for the given Model. + * + * @param Model $model + * @return void + */ + public static function removeModelFiles(Model $model): void + { + $tableName = $model::query()->getModel()->getTable(); + + if (!empty(Storage::disk('public')->allFiles("modelfiles/{$tableName}"))) { + Storage::disk('public')->deleteDirectory("modelfiles/{$tableName}"); + } + if (!empty(Storage::disk('private')->allFiles("modelfiles/{$tableName}"))) { + Storage::disk('private')->deleteDirectory("modelfiles/{$tableName}"); + } + } } diff --git a/app/Models/Commitment.php b/app/Models/Commitment.php new file mode 100644 index 0000000..8c65194 --- /dev/null +++ b/app/Models/Commitment.php @@ -0,0 +1,108 @@ + + */ + protected $fillable = [ + 'title', + 'picture', + 'picture_alt', + 'picture_title', + 'published', + 'order', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'published' => 'bool', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function (self $model) { + self::setOrder($model); + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + }); + static::updating(function (self $model) { + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture'); + }); + + static::deleted(function (self $model) { + FileStorageHelper::removeFile($model, 'picture'); + }); + } + + // * METHODS + + /** + * Set order after the last element of the list. + * + * @param self $model + * @return void + */ + private static function setOrder(self $model): void + { + $model->order = \intval(self::query()->max('order')) + 1; + } + + // * RELATIONS + + /** + * The products that belong to the commitment. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function products(): \Illuminate\Database\Eloquent\Relations\BelongsToMany + { + return $this->belongsToMany(Product::class); + } + + /** + * The page that belong to the commitment. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function explorerpage(): \Illuminate\Database\Eloquent\Relations\BelongsToMany + { + return $this->belongsToMany(Explorerpage::class); + } +} diff --git a/app/Models/Convictionpage.php b/app/Models/Convictionpage.php new file mode 100644 index 0000000..e22e77c --- /dev/null +++ b/app/Models/Convictionpage.php @@ -0,0 +1,56 @@ + + */ + protected $fillable = [ + 'key_feed', + 'key_earth_1', + 'key_earth_2', + 'key_together_1', + 'key_together_2', + 'key_together_3', + 'key_together_4', + 'key_territory', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function () { + throw new \RuntimeException("Creating a new page is not authorized"); + }); + static::deleting(function () { + throw new \RuntimeException('Deleting a page is not authorized'); + }); + } +} diff --git a/app/Models/Explorerpage.php b/app/Models/Explorerpage.php new file mode 100644 index 0000000..a767d5b --- /dev/null +++ b/app/Models/Explorerpage.php @@ -0,0 +1,83 @@ + + */ + protected $fillable = [ + 'picture_1', + 'picture_1_alt', + 'picture_1_title', + 'picture_2', + 'picture_2_alt', + 'picture_2_title', + 'picture_3', + 'picture_3_alt', + 'picture_3_title', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function () { + throw new \RuntimeException("Creating a new page is not authorized"); + }); + static::updating(function (self $model) { + $model->picture_1 = FileStorageHelper::storeFile($model, $model->picture_1, true); + $model->picture_2 = FileStorageHelper::storeFile($model, $model->picture_2, true); + $model->picture_3 = FileStorageHelper::storeFile($model, $model->picture_3, true); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture_1'); + FileStorageHelper::removeOldFile($model, 'picture_2'); + FileStorageHelper::removeOldFile($model, 'picture_3'); + }); + static::deleting(function () { + throw new \RuntimeException('Deleting a page is not authorized'); + }); + } + + // * RELATIONS + + /** + * The commitments that belong to the page. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function commitments(): \Illuminate\Database\Eloquent\Relations\BelongsToMany + { + return $this->belongsToMany(Commitment::class); + } +} diff --git a/app/Models/Homepage.php b/app/Models/Homepage.php new file mode 100644 index 0000000..b8f8178 --- /dev/null +++ b/app/Models/Homepage.php @@ -0,0 +1,63 @@ + + */ + protected $fillable = [ + 'title_part_1', + 'title_part_2', + 'title_part_3', + 'picture', + 'picture_alt', + 'picture_title', + 'presentation_title', + 'presentation_content', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function () { + throw new \RuntimeException("Creating a new page is not authorized"); + }); + static::updating(function (self $model) { + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture'); + }); + static::deleting(function () { + throw new \RuntimeException('Deleting a page is not authorized'); + }); + } +} diff --git a/app/Models/Joinuspage.php b/app/Models/Joinuspage.php new file mode 100644 index 0000000..81ba675 --- /dev/null +++ b/app/Models/Joinuspage.php @@ -0,0 +1,42 @@ + + */ + protected $fillable = [ + 'video_url', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function () { + throw new \RuntimeException("Creating a new page is not authorized"); + }); + static::deleting(function () { + throw new \RuntimeException('Deleting a page is not authorized'); + }); + } +} diff --git a/app/Models/News.php b/app/Models/News.php new file mode 100644 index 0000000..4c30334 --- /dev/null +++ b/app/Models/News.php @@ -0,0 +1,201 @@ + + */ + protected $fillable = [ + 'seo_title', + 'seo_description', + 'title', + 'slug', + 'category', + 'picture_thumbnail', + 'picture_thumbnail_alt', + 'picture_thumbnail_title', + 'picture', + 'picture_alt', + 'picture_title', + 'subtitle', + 'content', + 'published', + 'publish_at', + 'unpublish_at', + 'order', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'category' => CategoryEnum::class, + 'published' => 'bool', + 'publish_at' => 'datetime', + 'unpublish_at' => 'datetime', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function (self $model) { + self::assertFieldIsUnique('title', $model->title); + self::setOrder($model); + self::manageFields($model); + }); + static::updating(function (self $model) { + self::manageFields($model); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture'); + }); + + static::deleted(function (self $model) { + FileStorageHelper::removeFile($model, 'picture'); + }); + } + + // * METHODS + + /** + * Manage model fields. + * + * @param self $model + * @return void + */ + private static function manageFields(self $model): void + { + self::setSlug($model, $model->title); + self::makeStatusSense($model); + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + $model->picture_thumbnail = FileStorageHelper::storeFile($model, $model->picture_thumbnail, true); + } + + /** + * Set the slug. + * + * @param self $model + * @param string $original + * + * @return void + */ + private static function setSlug(self $model, string $original): void + { + $model->slug = Str::slug($original); + } + + /** + * Set order after the last element of the list. + * + * @param self $model + * @return void + */ + private static function setOrder(self $model): void + { + $model->order = \intval(self::query()->max('order')) + 1; + } + + /** + * Asserts using validation that the field is unique. + * + * @param string $nameField + * @param string $valueField + * @param integer|null $id + * @return void + */ + private static function assertFieldIsUnique(string $nameField, string $valueField, ?int $id = null): void + { + $table = (new self())->getTable(); + ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id); + } + + /** + * Adjusts model status using current status and publish dates + * + * @param self $model + * @return void + */ + private static function makeStatusSense(self $model): void + { + /** @var \Carbon\Carbon|null */ + $publish_at = $model->publish_at; + /** @var \Carbon\Carbon|null */ + $unpublish_at = $model->unpublish_at; + $wantedStatus = $model->published; + if ($publish_at or $unpublish_at) { + $model->published = $model->planificated_status; + } + if ($wantedStatus !== $model->published) { + $previousMessage = session()->get('bo.info', ''); + session()->flash('bo.info', \trans( + 'La publication est modifiée en concordance avec les dates enregistrées. + Pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.' + ) . " \n{$previousMessage}"); + } + } + + /** + * Getter the current status following planification dates planificated_status + * + * @return boolean + */ + public function getPlanificatedStatusAttribute(): bool + { + /** @var \Carbon\Carbon|null */ + $publish_at = $this->publish_at; + /** @var \Carbon\Carbon|null */ + $unpublish_at = $this->unpublish_at; + if ($publish_at and $unpublish_at) { + return $unpublish_at->greaterThanOrEqualTo(now()) and $publish_at->lessThan(now()); + } + if ($publish_at) { + return $publish_at->lessThan(now()); + } + if ($unpublish_at) { + return $unpublish_at->greaterThanOrEqualTo(now()); + } + return false; + } +} diff --git a/app/Models/Product.php b/app/Models/Product.php new file mode 100644 index 0000000..18dc339 --- /dev/null +++ b/app/Models/Product.php @@ -0,0 +1,192 @@ + + */ + protected $fillable = [ + 'seo_title', + 'seo_description', + 'title', + 'slug', + 'subtitle', + 'picture_thumbnail', + 'picture_thumbnail_alt', + 'picture_thumbnail_title', + 'picture_ambiance', + 'picture_ambiance_alt', + 'picture_ambiance_title', + 'picture_packshot', + 'picture_packshot_alt', + 'picture_packshot_title', + 'description', + 'cooking_mode', + 'cooking_advice', + 'ingredients', + 'nutritionnal_values', + 'published', + 'order', + 'range_id' + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'cooking_mode' => CookingModeEnum::class, + 'published' => 'bool', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function (self $model) { + self::assertFieldIsUnique('title', $model->title); + self::setOrder($model); + self::manageFields($model); + }); + static::updating(function (self $model) { + self::manageFields($model); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture_thumbnail'); + FileStorageHelper::removeOldFile($model, 'picture_ambiance'); + FileStorageHelper::removeOldFile($model, 'picture_packshot'); + }); + + static::deleted(function (self $model) { + FileStorageHelper::removeFile($model, 'picture_thumbnail'); + FileStorageHelper::removeFile($model, 'picture_ambiance'); + FileStorageHelper::removeFile($model, 'picture_packshot'); + }); + } + + // * METHODS + + /** + * Manage model fields. + * + * @param self $model + * @return void + */ + private static function manageFields(self $model): void + { + self::setSlug($model, $model->title); + $model->picture_thumbnail = FileStorageHelper::storeFile($model, $model->picture_thumbnail, true); + $model->picture_ambiance = FileStorageHelper::storeFile($model, $model->picture_ambiance, true); + $model->picture_packshot = FileStorageHelper::storeFile($model, $model->picture_packshot, true); + } + + /** + * Set the slug. + * + * @param self $model + * @param string $original + * + * @return void + */ + private static function setSlug(self $model, string $original): void + { + $model->slug = Str::slug($original); + } + + /** + * Set order after the last element of the list. + * + * @param self $model + * @return void + */ + private static function setOrder(self $model): void + { + $model->order = \intval(self::query()->max('order')) + 1; + } + + /** + * Asserts using validation that the field is unique. + * + * @param string $nameField + * @param string $valueField + * @param integer|null $id + * @return void + */ + private static function assertFieldIsUnique(string $nameField, string $valueField, ?int $id = null): void + { + $table = (new self())->getTable(); + ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id); + } + + // * RELATIONS + + /** + * Get the range that owns the product. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function range(): \Illuminate\Database\Eloquent\Relations\BelongsTo + { + return $this->belongsTo(Range::class); + } + + /** + * The commitments that belong to the product. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function commitments(): \Illuminate\Database\Eloquent\Relations\BelongsToMany + { + return $this->belongsToMany(Commitment::class); + } +} diff --git a/app/Models/Range.php b/app/Models/Range.php new file mode 100644 index 0000000..724f112 --- /dev/null +++ b/app/Models/Range.php @@ -0,0 +1,173 @@ + + */ + protected $fillable = [ + 'seo_title', + 'seo_description', + 'title', + 'slug', + 'subtitle', + 'tagline', + 'picture', + 'picture_alt', + 'picture_title', + 'picture_productsheet', + 'picture_productsheet_alt', + 'picture_productsheet_title', + 'picture_thumbnail', + 'picture_thumbnail_alt', + 'picture_thumbnail_title', + 'published', + 'order', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'cooking_mode' => CookingModeEnum::class, + 'published' => 'bool', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function (self $model) { + self::assertFieldIsUnique('title', $model->title); + self::setOrder($model); + self::manageFields($model); + }); + static::updating(function (self $model) { + self::manageFields($model); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture'); + FileStorageHelper::removeOldFile($model, 'picture_productsheet'); + FileStorageHelper::removeOldFile($model, 'picture_thumbnail'); + }); + + static::deleted(function (self $model) { + FileStorageHelper::removeFile($model, 'picture'); + FileStorageHelper::removeFile($model, 'picture_productsheet'); + FileStorageHelper::removeFile($model, 'picture_thumbnail'); + }); + } + + // * METHODS + + /** + * Manage model fields. + * + * @param self $model + * @return void + */ + private static function manageFields(self $model): void + { + self::setSlug($model, $model->title); + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + $model->picture_productsheet = FileStorageHelper::storeFile($model, $model->picture_productsheet, true); + $model->picture_thumbnail = FileStorageHelper::storeFile($model, $model->picture_thumbnail, true); + } + + /** + * Set the slug. + * + * @param self $model + * @param string $original + * + * @return void + */ + private static function setSlug(self $model, string $original): void + { + $model->slug = Str::slug($original); + } + + /** + * Set order after the last element of the list. + * + * @param self $model + * @return void + */ + private static function setOrder(self $model): void + { + $model->order = \intval(self::query()->max('order')) + 1; + } + + /** + * Asserts using validation that the field is unique. + * + * @param string $nameField + * @param string $valueField + * @param integer|null $id + * @return void + */ + private static function assertFieldIsUnique(string $nameField, string $valueField, ?int $id = null): void + { + $table = (new self())->getTable(); + ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id); + } + + // * RELATIONS + + /** + * Get the products in the range. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function products(): \Illuminate\Database\Eloquent\Relations\HasMany + { + return $this->hasMany(Product::class); + } +} diff --git a/app/Models/SeasonalSection.php b/app/Models/SeasonalSection.php new file mode 100644 index 0000000..0fb7f6b --- /dev/null +++ b/app/Models/SeasonalSection.php @@ -0,0 +1,146 @@ + + */ + protected $fillable = [ + 'title', + 'text', + 'picture', + 'picture_alt', + 'picture_title', + 'background', + 'published', + 'publish_at', + 'unpublish_at', + 'order', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'background' => BackgroundEnum::class, + 'published' => 'bool', + 'publish_at' => 'datetime', + 'unpublish_at' => 'datetime', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function (self $model) { + self::manageFields($model); + }); + static::updating(function (self $model) { + self::manageFields($model); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture'); + }); + + static::deleted(function (self $model) { + FileStorageHelper::removeFile($model, 'picture'); + }); + } + + // * METHODS + + /** + * Manage model fields. + * + * @param self $model + * @return void + */ + private static function manageFields(self $model): void + { + self::makeStatusSense($model); + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + } + + + /** + * Adjusts model status using current status and publish dates + * + * @param self $model + * @return void + */ + private static function makeStatusSense(self $model): void + { + /** @var \Carbon\Carbon|null */ + $publish_at = $model->publish_at; + /** @var \Carbon\Carbon|null */ + $unpublish_at = $model->unpublish_at; + $wantedStatus = $model->published; + if ($publish_at or $unpublish_at) { + $model->published = $model->planificated_status; + } + if ($wantedStatus !== $model->published) { + $previousMessage = session()->get('bo.info', ''); + session()->flash('bo.info', \trans( + 'La publication est modifiée en concordance avec les dates enregistrées. + Pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.' + ) . " \n{$previousMessage}"); + } + } + + /** + * Getter the current status following planification dates planificated_status + * + * @return boolean + */ + public function getPlanificatedStatusAttribute(): bool + { + /** @var \Carbon\Carbon|null */ + $publish_at = $this->publish_at; + /** @var \Carbon\Carbon|null */ + $unpublish_at = $this->unpublish_at; + if ($publish_at and $unpublish_at) { + return $unpublish_at->greaterThanOrEqualTo(now()) and $publish_at->lessThan(now()); + } + if ($publish_at) { + return $publish_at->lessThan(now()); + } + if ($unpublish_at) { + return $unpublish_at->greaterThanOrEqualTo(now()); + } + return false; + } +} diff --git a/app/Models/Stamp.php b/app/Models/Stamp.php new file mode 100644 index 0000000..407e414 --- /dev/null +++ b/app/Models/Stamp.php @@ -0,0 +1,62 @@ + + */ + protected $fillable = [ + 'picture', + 'picture_alt', + 'picture_title', + 'published', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'published' => 'bool', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function (self $model) { + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + }); + static::updating(function (self $model) { + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture'); + }); + static::deleted(function (self $model) { + FileStorageHelper::removeFile($model, 'picture'); + }); + } +} diff --git a/app/Models/StaticPage.php b/app/Models/StaticPage.php new file mode 100644 index 0000000..4751c94 --- /dev/null +++ b/app/Models/StaticPage.php @@ -0,0 +1,86 @@ + + */ + protected $fillable = [ + 'seo_title', + 'seo_description', + 'title', + 'content', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'type' => StaticPageType::class, + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function () { + throw new \RuntimeException("Creating a new page is not authorized"); + }); + static::updating(function (self $model) { + // * ASSERTIONS + static::assertTitleIsUnique($model->title, $model->id); + + // * CHANGES + $model->slug = Str::slug($model->title); + }); + static::deleting(function () { + throw new \RuntimeException('Deleting a page is not authorized'); + }); + } + + // * METHODS + + /** + * Asserts using validation that the title is unique + * + * @param string|null $title + * @param integer|null $id + * @return void + * @throws \Illuminate\Validation\ValidationException If an actu title already exists. + */ + private static function assertTitleIsUnique(string|null $title, ?int $id = null) + { + $table = (new self())->getTable(); + ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id); + ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id); + } +} diff --git a/app/Models/Testimonial.php b/app/Models/Testimonial.php new file mode 100644 index 0000000..a2bd756 --- /dev/null +++ b/app/Models/Testimonial.php @@ -0,0 +1,76 @@ + + */ + protected $fillable = [ + 'picture', + 'picture_alt', + 'picture_title', + 'description', + 'job', + 'statut', + 'order', + ]; + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted(): void + { + static::creating(function (self $model) { + self::setOrder($model); + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + }); + static::updating(function (self $model) { + $model->picture = FileStorageHelper::storeFile($model, $model->picture, true); + }); + static::updated(function (self $model) { + FileStorageHelper::removeOldFile($model, 'picture'); + }); + + static::deleted(function (self $model) { + FileStorageHelper::removeFile($model, 'picture'); + }); + } + + // * METHODS + + /** + * Set order after the last element of the list. + * + * @param self $model + * @return void + */ + private static function setOrder(self $model): void + { + $model->order = \intval(self::query()->max('order')) + 1; + } +} diff --git a/database/factories/CommitmentFactory.php b/database/factories/CommitmentFactory.php new file mode 100644 index 0000000..d9cdfc7 --- /dev/null +++ b/database/factories/CommitmentFactory.php @@ -0,0 +1,23 @@ + + */ + public function definition() + { + return [ + 'title' => fake()->sentence(), + 'picture_alt' => fake()->sentence(), + 'picture_title' => fake()->sentence(), + 'published' => fake()->boolean(75), + ]; + } +} diff --git a/database/factories/ConvictionpageFactory.php b/database/factories/ConvictionpageFactory.php new file mode 100644 index 0000000..b4a2ae7 --- /dev/null +++ b/database/factories/ConvictionpageFactory.php @@ -0,0 +1,27 @@ + + */ + public function definition() + { + return [ + 'key_feed' => fake()->randomFloat(2, 0, 999999), + 'key_earth_1' => fake()->randomFloat(2, 0, 999999), + 'key_earth_2' => fake()->randomFloat(2, 0, 999999), + 'key_together_1' => fake()->randomFloat(2, 0, 999999), + 'key_together_2' => fake()->randomFloat(2, 0, 999999), + 'key_together_3' => fake()->randomFloat(2, 0, 999999), + 'key_together_4' => fake()->randomFloat(2, 0, 999999), + 'key_territory' => fake()->randomFloat(2, 0, 999999), + ]; + } +} diff --git a/database/factories/ExplorerpageFactory.php b/database/factories/ExplorerpageFactory.php new file mode 100644 index 0000000..09ba213 --- /dev/null +++ b/database/factories/ExplorerpageFactory.php @@ -0,0 +1,25 @@ + + */ + public function definition() + { + return [ + 'picture_1_alt' => fake()->sentence(), + 'picture_1_title' => fake()->sentence(), + 'picture_2_alt' => fake()->sentence(), + 'picture_2_title' => fake()->sentence(), + 'picture_3_alt' => fake()->sentence(), + 'picture_3_title' => fake()->sentence(), + ]; + } +} diff --git a/database/factories/HomepageFactory.php b/database/factories/HomepageFactory.php new file mode 100644 index 0000000..e5fea30 --- /dev/null +++ b/database/factories/HomepageFactory.php @@ -0,0 +1,26 @@ + + */ + public function definition() + { + return [ + 'title_part1' => fake()->sentence(), + 'title_part2' => fake()->sentence(), + 'title_part3' => fake()->sentence(), + 'picture_alt' => fake()->sentence(), + 'picture_title' => fake()->sentence(), + 'presentation_title' => fake()->sentence(), + 'presentation_content' => \clean(\fake()->randomHtml(6, 7)), + ]; + } +} diff --git a/database/factories/JoinuspageFactory.php b/database/factories/JoinuspageFactory.php new file mode 100644 index 0000000..d0abb0d --- /dev/null +++ b/database/factories/JoinuspageFactory.php @@ -0,0 +1,20 @@ + + */ + public function definition() + { + return [ + 'video_url' => 'https://www.youtube.com/watch?v=6B4O-_1CQoI', + ]; + } +} diff --git a/database/factories/NewsFactory.php b/database/factories/NewsFactory.php new file mode 100644 index 0000000..90d14e1 --- /dev/null +++ b/database/factories/NewsFactory.php @@ -0,0 +1,40 @@ + + */ + public function definition() + { + $title = fake()->sentence(); + $publish_at = now()->subDays(rand(1, 30)); + $unpublish_at = $publish_at->copy()->addDays(rand(1, 30)); + $published = now() > $publish_at && now() < $unpublish_at ? true : false; + + return [ + 'seo_title' => fake()->word(), + 'seo_description' => fake()->text(160), + 'title' => $title, + 'slug' => Str::slug($title), + 'category' => \collect(CategoryEnum::cases())->random(), + 'picture_thumbnail_alt' => fake()->sentence(), + 'picture_thumbnail_title' => fake()->sentence(), + 'picture_alt' => fake()->sentence(), + 'picture_title' => fake()->sentence(), + 'subtitle' => fake()->sentence(), + 'content' => \clean(\fake()->randomHtml(6, 7)), + 'published' => $published, + 'publish_at' => $publish_at, + 'unpublish_at' => $unpublish_at, + ]; + } +} diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php new file mode 100644 index 0000000..bdc1154 --- /dev/null +++ b/database/factories/ProductFactory.php @@ -0,0 +1,50 @@ + + */ + public function definition() + { + $title = fake()->sentence(); + + return [ + 'seo_title' => fake()->word(), + 'seo_description' => fake()->text(160), + 'title' => $title, + 'slug' => Str::slug($title), + 'subtitle' => fake()->sentence(), + 'picture_thumbnail_alt' => fake()->sentence(), + 'picture_thumbnail_title' => fake()->sentence(), + 'picture_ambiance_alt' => fake()->sentence(), + 'picture_ambiance_title' => fake()->sentence(), + 'picture_packshot_alt' => fake()->sentence(), + 'picture_packshot_title' => fake()->sentence(), + 'description' => \clean(\fake()->randomHtml(6, 7)), + 'cooking_mode' => \collect(CookingModeEnum::cases())->random(), + 'cooking_advice' => \clean(\fake()->randomHtml(6, 7)), + 'ingredients' => \clean(\fake()->randomHtml(6, 7)), + 'nutritionnal_values' => json_encode([ + 'Energie en Kj' => fake()->randomFloat(2), + 'Energie en kcal' => fake()->randomFloat(2), + 'Matières grasses' => fake()->randomFloat(2), + 'dont acides gras saturés' => fake()->randomFloat(2), + 'Glucides' => fake()->randomFloat(2), + 'Protéines' => fake()->randomFloat(2), + 'Sel' => fake()->randomFloat(2), + ]), + 'published' => fake()->boolean(75), + 'range_id' => Range::all()->random()->id, + ]; + } +} diff --git a/database/factories/RangeFactory.php b/database/factories/RangeFactory.php new file mode 100644 index 0000000..e5e4af8 --- /dev/null +++ b/database/factories/RangeFactory.php @@ -0,0 +1,36 @@ + + */ + public function definition() + { + $title = fake()->sentence(); + + return [ + 'seo_title' => fake()->word(), + 'seo_description' => fake()->text(160), + 'title' => $title, + 'slug' => Str::slug($title), + 'subtitle' => fake()->sentence(), + 'tagline' => fake()->sentence(), + 'description' => \clean(\fake()->randomHtml(6, 7)), + 'picture_alt' => fake()->sentence(), + 'picture_title' => fake()->sentence(), + 'picture_productsheet_alt' => fake()->sentence(), + 'picture_productsheet_title' => fake()->sentence(), + 'picture_thumbnail_alt' => fake()->sentence(), + 'picture_thumbnail_title' => fake()->sentence(), + 'published' => fake()->boolean(75), + ]; + } +} diff --git a/database/factories/SeasonalSectionFactory.php b/database/factories/SeasonalSectionFactory.php new file mode 100644 index 0000000..d41df9a --- /dev/null +++ b/database/factories/SeasonalSectionFactory.php @@ -0,0 +1,24 @@ + + */ + public function definition() + { + return [ + 'title' => fake()->sentence(), + 'text' => fake()->text(), + 'picture_alt' => fake()->sentence(), + 'picture_title' => fake()->sentence(), + 'published' => false, + ]; + } +} diff --git a/database/factories/StampFactory.php b/database/factories/StampFactory.php new file mode 100644 index 0000000..c8f1f54 --- /dev/null +++ b/database/factories/StampFactory.php @@ -0,0 +1,22 @@ + + */ + public function definition() + { + return [ + 'picture_alt' => fake()->sentence(), + 'picture_title' => fake()->sentence(), + 'published' => fake()->boolean(75), + ]; + } +} diff --git a/database/factories/TestimonialFactory.php b/database/factories/TestimonialFactory.php new file mode 100644 index 0000000..65eaac9 --- /dev/null +++ b/database/factories/TestimonialFactory.php @@ -0,0 +1,24 @@ + + */ + public function definition() + { + return [ + 'picture_alt' => fake()->sentence(), + 'picture_title' => fake()->sentence(), + 'description' => fake()->sentence(), + 'job' => fake()->jobTitle(), + 'statut' => fake()->word(), + ]; + } +} diff --git a/database/factories/assets/commitments/default-picture-185x185.png b/database/factories/assets/commitments/default-picture-185x185.png new file mode 100644 index 0000000000000000000000000000000000000000..2a271feee89ef5af8cec2a986f49ad2e35ae9462 GIT binary patch literal 1594 zcmds&|5MTj7{@J5%P-Mx%bYXoI)_fv%%L{(%T=i9DSpY5{Dx_2YAKQ^_ysAyUZT>D zu|fnkoikVBAu1{%OLCkNagIDfBt{;Yk|Cm^kh)L*Mn61X?w)&oc%Jv`p66aXEYiW& z+1A3s!XfH1G!clSpY7m&z?&t9>?|y-_eDW3Bw;&NUZ-7|!@4x--Rdu$OFDe`N`gmu z{G4$w;OYB}C2Y3G{-a6LKist*I7Z2(6>?Q_)UW4oq44&cx5(9~HPAb`oU-rWlMK)u zcwO>uokt(#AMi}Q+x%sx1DKG%`34++wva5++#daeHRrLvwYLU=K;t^$f}Y3Y)zw*w zOg+0)Dpg&wC6%vjSMv~iQgHQG3CLWwd{9xOGUDf4t)6K#n(9yxKBF&Lpe|uug*ZD% zA%a%=;#sv_GukVx=2JdLp&*)BdTcO5LYm6yOD=U0mMLL9KQbgITwR+dv#~AOvEHO* zK@$kSR)5B0OiSi+xyg_H8Isb`c`1)DIpNzP5C~$x*HeP#bKv#&zZz zPqK;RUY#<->$h*Zq!=a=i8Ad5I%uZ=x%CQEdyV`3Qx+0#sa{c{Tr@~=9-BZQKu_uQ z3&Iu4x1tAUnA!m6)>{Ew!=bK|V|^~Ju6gVfDTI&T+eITo8GIgZWutPq=zQBk1%jjS zx9^JgsJ9tm-gIirO_9lD(xq1rak>wtq~v}Km_hfZia+Xf#E33+i4!v}vg>EmE0Kc*SpS$Aszx*l}i*ZETQM}A#~m^ zUgYTKQsHqhF@*)^1dWG8PTntI4_wdO6)RFt)t9@}g+qui0gdCbvhL(hsa>4ACD}!&h$CpEstaEtPXI z7|duoGqKl=G&Nf|t20J+B^ zr|!fhBd3)XGmDk$7ClI_*V{p4Dz7d6wbvd+U$e?&qec-(DX| z-C2I2n0)@`4Fcjm|2tehT{vW0dy)nVtBH8{CuJ(9_T-k><~Y-S7#S32Y!t-_e2a^V z1E{gD!1H}@d2^AXG3&G=L5Te0A5~_-^X#)KV;Ih~zHL|(R^e2j%)pwV+b;Ij^hI)X zcVh2gx{rCM=5woTE;@h;PzuP#)LLKouL8kU9_Cxef=Rsc)??=(v5H~4hKp=@OpjE(uWg}&PH&VwDrg5VNcUlMbOcvTHO4Wr zStB@Oh2dQ+>*{(i($@)^HR0hadHJ$D#1hdYtIT}1NBpv{n8_|-_ LVNmA9YqkFaZ?Y2m literal 0 HcmV?d00001 diff --git a/database/factories/assets/explorerpages/default-picture-265x364.png b/database/factories/assets/explorerpages/default-picture-265x364.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec67559099d52b4902e353cd4476bfbf2cf3bb GIT binary patch literal 3525 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 literal 0 HcmV?d00001 diff --git a/database/factories/assets/homepages/default-picture-640x390.png b/database/factories/assets/homepages/default-picture-640x390.png new file mode 100644 index 0000000000000000000000000000000000000000..020a5e3663d3e2e0caaba989c0f910340b3065a9 GIT binary patch literal 6384 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 literal 0 HcmV?d00001 diff --git a/database/factories/assets/news/default-picture-265x354.png b/database/factories/assets/news/default-picture-265x354.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5a92b3519d04961701fec5f4d2df131c0953b0 GIT binary patch literal 3448 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 F{%^8EJ|h4C literal 0 HcmV?d00001 diff --git a/database/factories/assets/products/default-picture-327x252.png b/database/factories/assets/products/default-picture-327x252.png new file mode 100644 index 0000000000000000000000000000000000000000..86655581b8e323eeeceefc35e613ad0b336a1596 GIT binary patch literal 3159 zcmeH~>o?ok8plGRdu(8R}`-OTrztzGK|R@b(-T-y2A&~dm%laQXCdAQI9t|5k zs2Oh#F*o?gww4bz7PhiA3HF&YR?zm>8{E5Z8QgEH>z*pA&IxW_r4;P?8DV5M{79StQevHem~ggei6kp>v7>@;GC%NTr%b6(=o!{E)Y2~20?}>U*N;DQiF^rs|3%WT zb4vqpQBhF>fq>H;?Q8icczCmV;evSXufUp ztZDAuPh6z4-Ti05z*1>sbF}LJPN)USX0AAQV9e?BN6@3McbdD zJ*jgQn~R5!PV6|#7xyt3U{T)fuV?v8GBUDYh7w7p(P#i}_0k$NSK@tZotyLQ zqT1=yBkuTkCH=_YhJDpY5N5WGmoniV2eYx&&k_jMRFaud5dhOlmAt*PlQce0COZvh zwec6US`6N8HLc*tzFKjXI6hJC6^<(?n8F8=$LFV}KempJ4&Z3!qS5*Ul4*I{Jq!k; z-B?F&)x2zKYEmc^7ov{VO98yAQ_=fw{#JyWp&1v_dVA|LU=?3I2;ie2=h#6{g*?`O)({Wx9j2XRJ521nR)#ko45iG-Oe7efKGfSaqU`+#Al)38}tT{N0z zZ7n5owp^Tc{W|B`J2y1T-U#PE@k5!LUre3!{Ks!*=eEPmwKLz)S#^Z#-*Iz@HMuQ8sOJXCWW`ig(< zaOI06*HjX2h7#cjpkFVA5I85|`avL2>6!Nn`G|(lCyP%5?Nt&EfroAv$Vl4+H>BBa z*Af%iHo;?3m81#@IU_#*y$jb8zopmg9-Hk`a=BbKyGS_G&t&3m7$^UG2P5TjRK;Kt zk|Hc9C;;J%!)T(@o}Mziw2bP3!(y-5Cv;6bUEPDGPYr}$b*(ApT3djpEs1Ejpb+C` zRYnAdUynGwjS5L8olkSBWv5AIe~3O%rsAq_GiRD{Rb$63cOj|KI`PWNN^Gwo$y)5Z zT1!o*dA{*0U*|?xemh%PJeVM{{4aAQbwIDjHH11RrxZP#W!zjGdb;fwUP`rfg_crP zYl=PGE{1ZD)JQTXuP$xD#T?944ooFGmbN*7F>!ritrO^DfEeTP_zjVR!X5{+A&vx7 zve0Poljy9%!or-KlWLES=pkq+Qw{lS=hI*A;C~Cedr|Ek$0~$G zdg;f2!`RnH_Ll(Q2Ice$m0{d0-)U5j{3=TFJQ`5hoKsS%bn!Kl@a9v8Ly7d*P2D2v z&@iB#wqAvxRcEY;eo*9vjD2GIFa1J>T-S=ASTLF?BE=+RVL(Fk@J=VWySr;N8V8J2 zi2VjMd~g-+RJnrlB94j35H!8+^yEz-4&dnXdxKs47!lugyegS-n}Y^7k9X;Ij@>i^ z_AV)IV-@=~O6rs9`a=B{(|*{TpV1WVC~yjUgmY~32%*XBRu*Lyj@prVN_I! zSUWw+=RfcWL3ZxC2^YkElCX&ZjFJ}=JYMEvRW|v>(p~Slb@zwWO(@MnWAnY-{woLe zUcy(sNE-EN}gm1+zValDH2 zK}5??IQZIEx=^N6Fx}t@N-d@oaHA18;CIW*SxsT7Ju$hhHnz5+knTYHah6T}$anBS zWpfB|Qz2Ng&CbtHr6{ccwB4~-?CLP82gQ1Q1!Qe)J+{~iqz38qVUQKvCXgMnwI!I& z0+0g5q}$RiEoEXbC_uYDK;3^Bh5C8+?e6XEl|RTt|KGGM0K2aVL{1>J)V!5uzf0`8+LAm$Pt8KcFtEX8{M*W+| zB_b{-Qpw}--lJ2&<-D|e4wWwgnqH=y)K;NjHZv0wdCR^l)Ar$srl3&ve(2xt%D?g{ by=fes{nE)dei{aR7z{4>2K#h+U-|BT&&Nw6 literal 0 HcmV?d00001 diff --git a/database/factories/assets/products/default-picture-332x252.png b/database/factories/assets/products/default-picture-332x252.png new file mode 100644 index 0000000000000000000000000000000000000000..4c9bbccb7b858392600c26a41b30e3c6898ec0f6 GIT binary patch literal 2944 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 Udx8YuGutBYRIp$Bi3`{M2Pq1>p8x;= literal 0 HcmV?d00001 diff --git a/database/factories/assets/ranges/default-picture-332x442.png b/database/factories/assets/ranges/default-picture-332x442.png new file mode 100644 index 0000000000000000000000000000000000000000..f5936c15794dccc7007becd7034fc161b757aba3 GIT binary patch literal 3398 zcmeHK`&ZIw9(Ko*HksKpo>QYGvvnMtENLS(MPzr(oNktvbaX^aceT7gfq6lJab3sB zytKLIG@@>rYetBdV}@Ue%3Dcd#vwF8LP1ml6ca>l`?mWx?Echy-tRB(c`wiBd7jVb zeZSYvg@-wBaob{NXXkw4`(u%IcE39fzP`<$fsywk3tPds^NC}Biq4~}#c@$zE)ERK z!oTkNYWoe>uC}OsZ|GwN+g6X4yO+voF-{SK9nWw6G0&xM#E%!T69fNe1~?egCUN4($cVeU`}Fj*qoZSecxwz}&0wgi ztgI|Ak7h{8r2ge6Oeb}rq{U=leb7S5DwQfD zBO^58C7%yw;6^5KxkReZ-)U2PKL7RW*Ao*F27hJ@SeZp27}nOt#>SkTov~`L`5Tc) z`j}EcB)+zct^B9SWU~4B`Q_zhu{eRC%`zhZx&o74-BW3~3RkvvL)J|w6v}3j+QLi8 zZ^3Mph-J|0+b<_YxH1?FfTJ~b7WuHZ*Jd$D=jP^M>rVLSRzX~R{Kl|1*ZdJ0-dsomC+-V@If@f1#4cO0|2 zy1J#MMR#buAI_l`zDEQG^p>UQZ1+HfR->{P*3ISOd_JtLVLxuNMz%mH*P9mbgO4Bi zqM8MZ{e{M^ggLDQGMJ644Gj&*s;Q}|e9OjFb`TP|x-1*e2CFYgie<-}BUmD+bSxI7 z5Bx^i-sy>HOzn=-YzO87RJre(6jG`dG+z{k^u$xl>sJg1o&ZJoLGKn8E?&CSmf+#x z5loONzG5|bIXF0Ypvl=ODct#lYLaO3rtL-!!~q~@W+SbsIXU{UoO6hv<#LHcq9F$b z1)2ASI5;}O;c#BvX+MAeu;a(WVPV;bdEmVULwUBLPqf&3(|wo8cjvEkRH$6q$>rLX zgbYFKMG%!g8g1#Z*YaG<3BZb2?7>x`IK&V9xdwY9_goG$eJSbP&2fycY z+2zI3QhNT50y4P|>@z$}ohX4TH64(3k2=Tn61@v3EKIKt$j>RUANLxMs8KfF7cQ~& z1n-*BxsfVf^Gb7b^WmR491d|c(RFBWa4_GW0>e-bu=bUgm(vY;A+Oxh#5>KG{9dQM z*gLHdvdEmoH<2^hD*&_Z{(6l|kXkPPbAEn)Mh3%t1&`PCkI)sG5VkneuWoF9b~f3l z5lE%9nf<_?#&F=G)U-50=KGykDp9i;Qc3?196TeLr_sz8RYA`_U>u1llk+MloXKZW2xO}ZYm`cmj}5^TvM20TFr{`KB)(p+XNR+W>&A57 zQ$b3De6|kni;amHHJt|;qf{yp0s8Wc-{_eSaOE|8EP$wrR1^<~6C(FLw*#d$?J=1K^wmLi4P;QBmFx)GO_4T|97w+`CMuR$% zdk2@7bcsM`Y7(*Ass3G?tOrJ5A>i}^uYTO090 zZmvPWt5q1b126qUx_4ct;Auwc+$)9`$E&e)Q!L%{EAthR$0~0t$or9U8IQ!@~!Gps6pUwL4(*-i=hjpgIAQ z$>dr$RMV`>nVIjyf+HiTd(N{HSfaByBqN4FB9Uz7)w3%$QSUc!IM?(y%#iOHetq&O z>n4Ff08YeB!yiQN2lSn72x8wa+G*XmOZYJ{(MQ{;UR*R5a$s(5ONohzIGpXR=#({E zbR;0R?4YsM*R28=xuT+?zP=u)2(BN{M50)h2wW80m55fSt^JkFvjWk}V6KFDBp@J; z8c@hSWd_xfBvFu&c-yzd)2xs0%0`RZPZ`;&8FmrFleiiFsefYNf5w1;CM$ZEw6eSO S8u&l5I}sXwto^&Bzy2G%X-3!p literal 0 HcmV?d00001 diff --git a/database/factories/assets/ranges/default-picture-466x440.png b/database/factories/assets/ranges/default-picture-466x440.png new file mode 100644 index 0000000000000000000000000000000000000000..49826f51e9984f4a6d588dfca54419c1d6e48940 GIT binary patch literal 4524 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 b2k%?C?N%t$<`eh}W8!_(_ejm5i$DGcz!Zj_ literal 0 HcmV?d00001 diff --git a/database/factories/assets/seasonalsections/default-picture-362x542.png b/database/factories/assets/seasonalsections/default-picture-362x542.png new file mode 100644 index 0000000000000000000000000000000000000000..fc669bc2645923847bf823ea295dd58d4504556f GIT binary patch literal 5044 zcmeHL`Cn4${`aai&GvMjJJ|xiL1W<$?hU3JB9U^Ys>^ zGCnVOOsnuELHh6tz#h~WJ=-(S9eM9&Yr;Bd}!p7Z&+Z`{_D3Vl&!pG%?vqIdk&sz~o%{V92Gd*PpbE ze)*RTA3pancYEQ>%dO2(tXeL|L^;-FXYP&bG(GjVrk$+~Mf}*vv<+HD_24nl#h()Y z`Yb^3E<_#ltwEZNu`@wk(idP%l+nA9U!6w(aEEHLQ)hB~{!c%BSpR9O>0j<5KL7IL zA0JEd5e)xFgSR6{!#d+pUq3$*iR48$QmNDdEZ5Z3RHj~j|Ni~r;-XTiR9noe##{VY z=)BzA-2D8Y67l25kGs0Mrl+T$KYuPeFgiOMmyn=FFZU0pYb)d_q47*UnARaMT;&Q&!vt_KgkrSFtTBvw{ddA@}j1{+otBbUp+Ie-3u zlM})$e3|}%;Z#7~o#FjGfk23gnrOYZR~)0Zrwt}N7009&>`sV_+a|B+W~JH~uWb%5 zdn+dn*QZq0)~3vD>5HY)SGmJ94^K~d-pVgFskt7p-h6ZANBLLnBgC4I?8XZG}+2`jmx<3XL=! zfn3sPIH9LY#LLRj=E!r}72QJCxuQV3j;IBLUelK{L0WQ{@4|A2`4m#e-qnr0qs&($ zPg(cw-GhgmXKmfO^~jMUyLRnTlleWC<2{MCzF>4j+>d85lN(W`Vfzl zK%>#1uQzTeXJ<>rG4Tlr*$FZx(#s{M1DZIr+uFuP?HG}mm`Efp84Y@vF_@j7n`>=t z9Ty*;#q&aX(N@fy~La|tQ-p~+^h8u)lzFaIek_r>9{V}dwxe^;2 z8z0Zsjv0-{TIynhVsdiQV*7TofT9@U*Vfhom{yG%K}S^OiXZI-m-diJ5QN1+{d)@i zvd%sYDhYGz)yA$Bz44rvG+#J1buGbz>`7axITnOzSU8*EU7!ij6tZY`lCD@9t>IWI zLACEY-QoX9PZ#kO=hm-Z4;Xi_pmp#U6%$%*%|KJaZX^I}^W50jSe9sYt)F-JOqvlE zfzjp0RJj8}x!g;|fsVHNeP~-op@V~i+AW{nFPceo-@A9OaNIa~7?=cTZ($G&UFII_~Y#89S`IX?@RYA`iHVE4g~>iI-sOpc z2NAd)i4#SYhO@&MjFUdA@G_qxxT-w2R(DzhY@| zz@)6KtYMm-{m+r5rKL1egyY=jz=8KIg-(Z{KY9 zbaj2--@o5iZO$5RR8 zK07p#iGfJMJsbqmC?}%RWh&&IODx3fh&=I)&&%7@4UM$pgJ=%GvAX! z?B6z2aRmqqt3r`2`&7;{rP*C(&ULP26}s5Dr8+%5J^TKB$2q0OcPGHi3DYop1VhA952#mpT$8vIV5Vptmp(RWvvz;IUB9&PQDRV}KQOovByrFI8j+y2{20-Zg7}%24sYLApwD)U{b`R zygYs!S>o*A=xA$eyFJ~mx38~#H)6|{uxMhhg@cn5#;v!gPbSLu)T{e2jMO_{bVxT; zipAn5<={1RtukWiup>bxQ_kH8pDEdFX6ESNu%=?#$?56qZsryK#kn44b@lZt!Ze-m zv)A|wZ?7FKBkZa8J7xta%2()yCj z@(<1_tk})G6KHH>b2_43)M_vo@Z*ZXAy7m8`Ajeh>GUsHE=4LVhN7=wlb<;bF@URX zKq8S|8kGkMrAh6)vNT6D=UD-Ka}z3Fyhvma>Kdlq>vwGq$F{tC7kCJ(Ao4(WA6O1j z6fAqE#i`Wet0kuyX;kUWS0E*D1+Vb4&W^$2bC}wjNvP7OJMaNYpNR8 zjREYSc1aC3KK>hD-=W0gCl!hc9?!$ei{9^ARudMY>tTqsKnQ!$JCJbts(x5FjwS`K zqGd|oL&>#)>>zu;4ckaN4P!(4uC8wtVZJS|UXe+M$ePP*bl2ZiyL)(049iJwE49fc zoSx~$xdcvWDV3o~#py7*0MJ;Onv9F8qjm~$9a*24nzmQE2sb8RLNg%zsAYXpZd6nh zRuj{ws05LqAPsLsqU_3Ah%;6hub_C)DaQ9tK=Ji@Jph_7X%_NEzVY+3Ky7^%Xa@|0 z_$mx@fltQeLQqO+S8p(zi0ka0n21WbFaj7Jp7JkKtJU~m13>ihbFkO>OZzgPK`}It zTilM?V<+5EC=?n^>yIhzlX20gS$%0U&l|mLX=Ro3@ZtV+b9PW{Qc{&@0qIFj#Jy}N zFTW6;k0}l`Lm(&!LTG4HZSj`1Tspr5_ZiA5Tv9RVE91-AV!Cmqwm!HtoWruZ>X|bC zzcnbIr~dtegKOE)IDF&T%5dNyo=Q@^@#Tz>?@2u6^J}2Hs>J^+6bfUpc93N;#~fW< zU9}4$FU(|^tEXowZeYj*A-4i!;nTB6#y0c-!G}CEK~UO_wjGf{K|y6HZ?C4L=)B|W zGS^tJM^|&aDmWE#IDl<=vk)RmTU%SCMq3hS2g(M9t~g>3&~Z3$fU0V`gXYx`POe!EzMYz$l#H^h4{e9(A=k7E za1by$F#(7`AP@}kKT5>lO|M_ShN!Y<&z^=Zw|5DA zGezl)lVD}uNASsrU+c)mk8l4U_dP!Dd;GtBk14u|%EjL%#M2u#<4jD>obo+ccKo{^ F{|k>C!3O{U literal 0 HcmV?d00001 diff --git a/database/factories/assets/stamps/default-picture-120x120.png b/database/factories/assets/stamps/default-picture-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..b6334aa511f58bb898440bf313bdb27b708d2dcc GIT binary patch literal 720 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1SGeyEo^0AV4Cjf;uumf=j|PD@5cc$4j*lz zqD69!OjBZ1e&qM@cRk1V*sIf$xWaNjhAyp`9a&Pq#@5C-SNP!P=%;O`_dj%yTYXGi zTzulc{Y&0)|Ip*%H8eSLLBQF0Kp0Y`e?MHld^yL=+Rm&3fWH{ZOY^ZawA%<=T}bbWpO#TPX^Cp|5y ztg8C;<3~klX=zc>A^txlUu~?S)?T}K@#1fwng2h0Fz}pIwtMcfm!Cg>zIQKf*0RWH zYr|HrT4i=SFF)UXaiECnzxn=~ zpP&D4-T%#ON&8%0T+K3_>C?67MTu3Q$lEt>&OHCTef##KNgKCr6+QkjEjlzbHS$?y z+_b0n^Z(b&c&vK6`f>T@n>jmU_}H4ye){vLrneE06%xb@;r zGyIlU&Z{p_(EQfFOEUh^#gDQQQb`#d3l-bi=*#%TeD5WzUFIY46~L6r;OXk;vd$@? F2>@(kMBe}a literal 0 HcmV?d00001 diff --git a/database/factories/assets/testimonials/default-picture-292x417.png b/database/factories/assets/testimonials/default-picture-292x417.png new file mode 100644 index 0000000000000000000000000000000000000000..15769fecaf1f592efde395f0735f9b4cbe9dc31f GIT binary patch literal 3298 zcmeH~`&ZIw9><+JM?0C;Oc{-)ZZ*4BuHuwoURg_X%@d|Jm|#%WSSmtFgNg{#IC-CO zTgTiYan<2it3+yu3TW+kS+9A?3!$JQpecAq?(Eb40dw{b=sD;6%lCZ0&-3}bKkwJ) zd7k{sh!C6I_PZ@CENnvm8Wd?^@!414sob>#ya|zGhAb@hJP!>DypsM@DMCj_P5iri z)^5k4!Q5S`>UX3`wVq~8$o$OFDdMH&(e zId?D^eQg4F}>6Xot&y5|GM@S8Qe*=qR!T`HB*HvedRt=sfipXQ~pF#_EbeHpCXQ{n=t zK3PyD#0AhyhLOEtN|JtYw8qNHN^&+xtX7k1$6Dp(4nK8aX~r#OHu7ZY?CdOo#xQ#u z&o+L?o1S1}%eXEsE(*Ckk@J3LW@d45QKiCH4}(lu$R(wSYi(^U$mLVC4Sau3&sQ&B zdYn1)4GS5LK-mA(1-|5prl+P1TN79-OG`W~2;=<*qhJ7Ol9HAR(=ag~hjxk}Y0Khq zINu!T92pr|SXhV_ymLMeAH)sBZvbJA7mx)eph|vzJ`m<2Gj(a4#bh$a#>Uq1D`LTt z|1BELyu4g@ya2?GrD~ZN_Fh|CkP3>`)Y{t0=f@f(sj9B?KXOFMb*Z$lqz|maY znn&u58?zs>xhNL$#jVz9yfy}dND7Xi@U0{59UOeUy%RX7a>VWH*JmuxQ%1n7Ivv?N z)U-Jo4yp^GWu~S!w6$UIsR8881)az(Gc$8V(he<%OHNjP`0nQ87!K+h3iYpvB_O6i zz7LX2Ae7O$VPRnvq9&yksAg7#cJPqB{Yl96;D}!~!kLka#`(WvJV0^19Og=La&pME z|19RBVP0N+SCB~L3+(&F#e^0HpQspQlHo`eQlU`L^hz#SKpjxD&ucWze$E~+7|ho< zv(ZKSb)K@Jy1H5%5w(&lL$`>ORJ@dzHZ@7#*-pxP``=U*o2VYlC~lq8Hwbe1f~sar2AMw)m0R#b*;p3s6&nQDIb)}<0B4~ zUX;!0ZsBls{FFt0Oag(xhRj0JHsD?zcF5@HzV{M-MpPGtL_)UZ=jPD6|Zn*xlXzmf_FaTm@!X|5a@_+BtSU zHW^eI!(LIToDLtZW3$WXu3KcIk5v^@+S`HgXLn;HqpUp;>)?jzP>)0cYVVvK*_p6d?qQQ|hwZ3~?{w=pu9k(1a?i>raV|zqTh=|JQKY+ zt;s0eIm1xAttj)NnzRanr2h^FCClxbpP%1?AE4s0907Nj7RhB65}qM6ZIxO#ffU0; zb~NceyO6`t230;Oj{o?4y1ZdEr%%o9t%; zGx>YA{ahk&ykNg&ZEfwhui4mkcXlg(ZPY~UC4LV)hz`I~J+kaYV5!<@c0tu4M@L{X z;KaAUUaqAVxuRrG`>3cWNOUZiMiylkoRY%OzCZG!sih?b^NIsHB_M}HY7z*pVTj<* z-=F~$z%o&P^kWP@s|3Tj+gy=bacvUk$<6;TsD@&|iR@3Bp`jt8ew$qq$U(WmE8!H) z>awsApogd-QmJiRE*EqOOy(J|AJK()j}AMvTHWiv3A~)z;{}IfsbNg+#@e+L?9biY zWB2@JxZ<>Ea1gQLQv^3@qy?EKlYT{z{R&hizEP+ofkx_{75+-IKvvUj){06NZ6L_q^z_L)o^2Jx zZrOUnJ`t_fk803Js5V0o(1pJ+*?l?~emWKZe>a7{nJxO&X;ANKr@i3rVi6jQ2zqhu H`VapFp>{4Y literal 0 HcmV?d00001 diff --git a/database/migrations/2023_10_18_180112_create_explorerpage_commitment_table.php b/database/migrations/2023_10_18_180112_create_commitment_explorerpage_table.php similarity index 81% rename from database/migrations/2023_10_18_180112_create_explorerpage_commitment_table.php rename to database/migrations/2023_10_18_180112_create_commitment_explorerpage_table.php index cf7aa6f..28a5b79 100644 --- a/database/migrations/2023_10_18_180112_create_explorerpage_commitment_table.php +++ b/database/migrations/2023_10_18_180112_create_commitment_explorerpage_table.php @@ -13,7 +13,7 @@ return new class extends Migration */ public function up() { - Schema::create('explorerpage_commitment', function (Blueprint $table) { + Schema::create('commitment_explorerpage', function (Blueprint $table) { $table->unsignedBigInteger('explorerpage_id'); $table->unsignedBigInteger('commitment_id'); }); @@ -26,6 +26,6 @@ return new class extends Migration */ public function down() { - Schema::dropIfExists('explorerpage_commitment'); + Schema::dropIfExists('commitment_explorerpage'); } }; diff --git a/database/migrations/2023_10_18_180112_create_product_commitment_table.php b/database/migrations/2023_10_18_180112_create_commitment_product_table.php similarity index 82% rename from database/migrations/2023_10_18_180112_create_product_commitment_table.php rename to database/migrations/2023_10_18_180112_create_commitment_product_table.php index 34a649d..570fa85 100644 --- a/database/migrations/2023_10_18_180112_create_product_commitment_table.php +++ b/database/migrations/2023_10_18_180112_create_commitment_product_table.php @@ -13,7 +13,7 @@ return new class extends Migration */ public function up() { - Schema::create('product_commitment', function (Blueprint $table) { + Schema::create('commitment_product', function (Blueprint $table) { $table->unsignedBigInteger('product_id'); $table->unsignedBigInteger('commitment_id'); }); @@ -26,6 +26,6 @@ return new class extends Migration */ public function down() { - Schema::dropIfExists('product_commitment'); + Schema::dropIfExists('commitment_product'); } }; diff --git a/database/migrations/2023_10_18_180112_create_explorerpages_table.php b/database/migrations/2023_10_18_180112_create_explorerpages_table.php index 485407e..b6de403 100644 --- a/database/migrations/2023_10_18_180112_create_explorerpages_table.php +++ b/database/migrations/2023_10_18_180112_create_explorerpages_table.php @@ -15,13 +15,13 @@ return new class extends Migration { Schema::create('explorerpages', function (Blueprint $table) { $table->id(); - $table->string('picture_1')->comment('Path de la première illustration'); + $table->string('picture_1')->comment('Path de la première illustration (265px * 364px'); $table->string('picture_1_alt')->comment('Attribut alt de l\'image 1'); $table->string('picture_1_title')->comment('Attribut title de l\'image 1'); - $table->string('picture_2')->comment('Path de la deuxième illustration'); + $table->string('picture_2')->comment('Path de la deuxième illustration (265px * 364px'); $table->string('picture_2_alt')->comment('Attribut alt de l\'image 2'); $table->string('picture_2_title')->comment('Attribut title de l\'image 2'); - $table->string('picture_3')->comment('Path de la troisième illustration'); + $table->string('picture_3')->comment('Path de la troisième illustration (265px * 364px'); $table->string('picture_3_alt')->comment('Attribut alt de l\'image 3'); $table->string('picture_3_title')->comment('Attribut title de l\'image 3'); $table->timestamps(); diff --git a/database/migrations/2023_10_18_180112_create_products_table.php b/database/migrations/2023_10_18_180112_create_products_table.php index 7619f2c..36c674a 100644 --- a/database/migrations/2023_10_18_180112_create_products_table.php +++ b/database/migrations/2023_10_18_180112_create_products_table.php @@ -34,7 +34,7 @@ return new class extends Migration ->comment('Mode de cuisson (enum \\App\\Enums\\Products\\CookingModeEnum)'); $table->text('cooking_advice')->comment('WYSIWYG - Conseil de réchauffage'); $table->text('ingredients')->comment('WYSIWYG - Ingrédients qui composent le produit'); - $table->json('nutrionnal_values')->comment('JSON des valeurs nutritionnelles pour 100g'); + $table->json('nutritionnal_values')->comment('JSON des valeurs nutritionnelles pour 100g'); $table->boolean('published')->comment('Le produit est-il visible ?'); $table->unsignedInteger('order')->comment('Numéro permettant d\'ordonner les produits'); $table->unsignedBigInteger('range_id'); diff --git a/database/migrations/2023_10_18_180112_create_seasonal_section_table.php b/database/migrations/2023_10_18_180112_create_seasonal_sections_table.php similarity index 95% rename from database/migrations/2023_10_18_180112_create_seasonal_section_table.php rename to database/migrations/2023_10_18_180112_create_seasonal_sections_table.php index d19954b..d3cf606 100644 --- a/database/migrations/2023_10_18_180112_create_seasonal_section_table.php +++ b/database/migrations/2023_10_18_180112_create_seasonal_sections_table.php @@ -13,7 +13,7 @@ return new class extends Migration */ public function up() { - Schema::create('seasonal_section', function (Blueprint $table) { + Schema::create('seasonal_sections', function (Blueprint $table) { $table->id(); $table->string('title')->comment('Titre de la section saisonnière'); $table->text('text')->comment('WYSIWYG - Texte de la section saisonnière'); diff --git a/database/migrations/2023_10_18_180112_create_static_pages_table.php b/database/migrations/2023_10_18_180112_create_static_pages_table.php index 5683ab4..a28d0c0 100644 --- a/database/migrations/2023_10_18_180112_create_static_pages_table.php +++ b/database/migrations/2023_10_18_180112_create_static_pages_table.php @@ -2,6 +2,7 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Schema; return new class extends Migration @@ -11,18 +12,26 @@ return new class extends Migration * * @return void */ - public function up() + public function up(): void { Schema::create('static_pages', function (Blueprint $table) { $table->id(); - $table->unsignedTinyInteger('type')->unique() - ->comment('Type de la page (enum \\App\\Enums\\StaticPage\\PageTypeEnum)'); - $table->string('seo_title')->comment('Utilisé pour la balise title de la page'); - $table->string('seo_description')->comment('Utilisé pour la balise meta description de la page'); - $table->string('title')->comment('Utilisé pour la balise h1 de la page'); - $table->text('content')->comment('WYSIWYG - Contenu de la page. Peut être une chaîne vide selon le type'); + + $table->unsignedTinyInteger('type')->unique()->comment('Page type (StaticPageEnum)'); + + $table->string('seo_title')->comment('Seo title about 70 chars as recommended'); + $table->string('seo_description')->comment('Seo description about 160 chars as recommended'); + + $table->string('title')->comment('Title for the page'); + $table->string('slug')->unique()->comment('Unique title slug'); + + $table->text('content')->comment('WYSIWYG text content using ckeditor'); + $table->timestamps(); }); + Artisan::call('db:seed', [ + 'class' => 'StaticPageSeeder' + ]); } /** @@ -30,7 +39,7 @@ return new class extends Migration * * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('static_pages'); } diff --git a/database/migrations/2023_10_18_180115_add_foreign_keys_to_explorerpage_commitment_table.php b/database/migrations/2023_10_18_180115_add_foreign_keys_to_commitment_explorerpage_table.php similarity index 72% rename from database/migrations/2023_10_18_180115_add_foreign_keys_to_explorerpage_commitment_table.php rename to database/migrations/2023_10_18_180115_add_foreign_keys_to_commitment_explorerpage_table.php index 04ab240..6a974c9 100644 --- a/database/migrations/2023_10_18_180115_add_foreign_keys_to_explorerpage_commitment_table.php +++ b/database/migrations/2023_10_18_180115_add_foreign_keys_to_commitment_explorerpage_table.php @@ -13,7 +13,7 @@ return new class extends Migration */ public function up() { - Schema::table('explorerpage_commitment', function (Blueprint $table) { + Schema::table('commitment_explorerpage', function (Blueprint $table) { $table->foreign(['explorerpage_id'])->references(['id'])->on('explorerpages'); $table->foreign(['commitment_id'])->references(['id'])->on('commitments'); }); @@ -26,9 +26,9 @@ return new class extends Migration */ public function down() { - Schema::table('explorerpage_commitment', function (Blueprint $table) { - $table->dropForeign('explorerpage_commitment_explorerpage_id_foreign'); - $table->dropForeign('explorerpage_commitment_commitment_id_foreign'); + Schema::table('commitment_explorerpage', function (Blueprint $table) { + $table->dropForeign('commitment_explorerpage_explorerpage_id_foreign'); + $table->dropForeign('commitment_explorerpage_commitment_id_foreign'); }); } }; diff --git a/database/migrations/2023_10_18_180115_add_foreign_keys_to_product_commitment_table.php b/database/migrations/2023_10_18_180115_add_foreign_keys_to_commitment_product_table.php similarity index 71% rename from database/migrations/2023_10_18_180115_add_foreign_keys_to_product_commitment_table.php rename to database/migrations/2023_10_18_180115_add_foreign_keys_to_commitment_product_table.php index 0295c21..f7c3033 100644 --- a/database/migrations/2023_10_18_180115_add_foreign_keys_to_product_commitment_table.php +++ b/database/migrations/2023_10_18_180115_add_foreign_keys_to_commitment_product_table.php @@ -13,7 +13,7 @@ return new class extends Migration */ public function up() { - Schema::table('product_commitment', function (Blueprint $table) { + Schema::table('commitment_product', function (Blueprint $table) { $table->foreign(['product_id'])->references(['id'])->on('products'); $table->foreign(['commitment_id'])->references(['id'])->on('commitments'); }); @@ -26,9 +26,9 @@ return new class extends Migration */ public function down() { - Schema::table('product_commitment', function (Blueprint $table) { - $table->dropForeign('product_commitment_product_id_foreign'); - $table->dropForeign('product_commitment_commitment_id_foreign'); + Schema::table('commitment_product', function (Blueprint $table) { + $table->dropForeign('commitment_product_product_id_foreign'); + $table->dropForeign('commitment_product_commitment_id_foreign'); }); } }; diff --git a/database/seeders/CommitmentSeeder.php b/database/seeders/CommitmentSeeder.php new file mode 100644 index 0000000..5bff0e7 --- /dev/null +++ b/database/seeders/CommitmentSeeder.php @@ -0,0 +1,25 @@ +create([ + 'picture' => FileStorageHelper::storeFile(new Commitment(), new \SplFileInfo(\resource_path( + '../database/factories/assets/commitments/default-picture-185x185.png' + ))) + ]); + } +} diff --git a/database/seeders/ConvictionpageSeeder.php b/database/seeders/ConvictionpageSeeder.php new file mode 100644 index 0000000..88c3862 --- /dev/null +++ b/database/seeders/ConvictionpageSeeder.php @@ -0,0 +1,25 @@ +create(); + } finally { + Convictionpage::setEventDispatcher(new \Illuminate\Events\Dispatcher()); + } + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index bf08078..7e25de1 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -15,6 +15,17 @@ class DatabaseSeeder extends Seeder { $this->call([ UserSeeder::class, + CommitmentSeeder::class, + RangeSeeder::class, + ProductSeeder::class, + NewsSeeder::class, + SeasonalSectionSeeder::class, + StampSeeder::class, + TestimonialSeeder::class, + ConvictionpageSeeder::class, + ExplorerpageSeeder::class, + HomepageSeeder::class, + JoinuspageSeeder::class, ]); } } diff --git a/database/seeders/ExplorerpageSeeder.php b/database/seeders/ExplorerpageSeeder.php new file mode 100644 index 0000000..9616728 --- /dev/null +++ b/database/seeders/ExplorerpageSeeder.php @@ -0,0 +1,43 @@ +create([ + 'picture_1' => FileStorageHelper::storeFile(new Explorerpage(), new \SplFileInfo( + \resource_path('../database/factories/assets/explorerpages/default-picture-265x364.png') + )), + 'picture_2' => FileStorageHelper::storeFile(new Explorerpage(), new \SplFileInfo( + \resource_path('../database/factories/assets/explorerpages/default-picture-265x364.png') + )), + 'picture_3' => FileStorageHelper::storeFile(new Explorerpage(), new \SplFileInfo( + \resource_path('../database/factories/assets/explorerpages/default-picture-265x364.png') + )), + ]); + + $commitments = Commitment::query()->get(); + Explorerpage::query()->each(function (Explorerpage $explorerpage) use ($commitments) { + $explorerpage->commitments()->saveMany($commitments->random(\rand(3, 12))); + }); + } finally { + Explorerpage::setEventDispatcher(new \Illuminate\Events\Dispatcher()); + } //end try + } +} diff --git a/database/seeders/HomepageSeeder.php b/database/seeders/HomepageSeeder.php new file mode 100644 index 0000000..e67aaa7 --- /dev/null +++ b/database/seeders/HomepageSeeder.php @@ -0,0 +1,31 @@ +create([ + 'picture' => FileStorageHelper::storeFile(new Homepage(), new \SplFileInfo(\resource_path( + '../database/factories/assets/homepages/default-picture-640x390.png' + ))), + ]); + } finally { + Homepage::setEventDispatcher(new \Illuminate\Events\Dispatcher()); + } + } +} diff --git a/database/seeders/JoinuspageSeeder.php b/database/seeders/JoinuspageSeeder.php new file mode 100644 index 0000000..d9f0640 --- /dev/null +++ b/database/seeders/JoinuspageSeeder.php @@ -0,0 +1,25 @@ +create(); + } finally { + Joinuspage::setEventDispatcher(new \Illuminate\Events\Dispatcher()); + } + } +} diff --git a/database/seeders/NewsSeeder.php b/database/seeders/NewsSeeder.php new file mode 100644 index 0000000..45f9239 --- /dev/null +++ b/database/seeders/NewsSeeder.php @@ -0,0 +1,28 @@ +create([ + 'picture_thumbnail' => FileStorageHelper::storeFile(new News(), new \SplFileInfo(\resource_path( + '../database/factories/assets/news/default-picture-265x354.png' + ))), + 'picture' => FileStorageHelper::storeFile(new News(), new \SplFileInfo(\resource_path( + '../database/factories/assets/news/default-picture-1002x565.png' + ))), + ]); + } +} diff --git a/database/seeders/ProductSeeder.php b/database/seeders/ProductSeeder.php new file mode 100644 index 0000000..0ee156b --- /dev/null +++ b/database/seeders/ProductSeeder.php @@ -0,0 +1,37 @@ +create([ + 'picture_thumbnail' => FileStorageHelper::storeFile(new Product(), new \SplFileInfo(\resource_path( + '../database/factories/assets/products/default-picture-332x252.png' + ))), + 'picture_ambiance' => FileStorageHelper::storeFile(new Product(), new \SplFileInfo(\resource_path( + '../database/factories/assets/products/default-picture-774x515.png' + ))), + 'picture_packshot' => FileStorageHelper::storeFile(new Product(), new \SplFileInfo(\resource_path( + '../database/factories/assets/products/default-picture-327x252.png' + ))) + ]); + + $commitments = Commitment::query()->get(); + Product::query()->each(function (Product $product) use ($commitments) { + $product->commitments()->saveMany($commitments->random(\rand(0, 4))); + }); + } +} diff --git a/database/seeders/RangeSeeder.php b/database/seeders/RangeSeeder.php new file mode 100644 index 0000000..4f94f01 --- /dev/null +++ b/database/seeders/RangeSeeder.php @@ -0,0 +1,31 @@ +create([ + 'picture' => FileStorageHelper::storeFile(new Range(), new \SplFileInfo(\resource_path( + '../database/factories/assets/ranges/default-picture-466x440.png' + ))), + 'picture_productsheet' => FileStorageHelper::storeFile(new Range(), new \SplFileInfo(\resource_path( + '../database/factories/assets/ranges/default-picture-332x442.png' + ))), + 'picture_thumbnail' => FileStorageHelper::storeFile(new Range(), new \SplFileInfo(\resource_path( + '../database/factories/assets/ranges/default-picture-246x337.png' + ))), + ]); + } +} diff --git a/database/seeders/SeasonalSectionSeeder.php b/database/seeders/SeasonalSectionSeeder.php new file mode 100644 index 0000000..09f0f73 --- /dev/null +++ b/database/seeders/SeasonalSectionSeeder.php @@ -0,0 +1,34 @@ +subDays(rand(1, 10)); + $unpublish_at = $publish_at->copy()->addDays(rand(10, 20)); + foreach (BackgroundEnum::cases() as $i => $background) { + SeasonalSection::factory(1)->create([ + 'background' => $background, + 'published' => $i === array_key_first(BackgroundEnum::cases()) ? true : false, + 'publish_at' => $publish_at->subMonths(), + 'unpublish_at' => $unpublish_at->subMonths(), + 'picture' => FileStorageHelper::storeFile(new SeasonalSection(), new \SplFileInfo( + \resource_path('../database/factories/assets/seasonalsections/default-picture-362x542.png') + )), + ]); + } + } +} diff --git a/database/seeders/StampSeeder.php b/database/seeders/StampSeeder.php new file mode 100644 index 0000000..5c81e80 --- /dev/null +++ b/database/seeders/StampSeeder.php @@ -0,0 +1,25 @@ +create([ + 'picture' => FileStorageHelper::storeFile(new Stamp(), new \SplFileInfo( + \resource_path('../database/factories/assets/stamps/default-picture-120x120.png') + )), + ]); + } +} diff --git a/database/seeders/StaticPageSeeder.php b/database/seeders/StaticPageSeeder.php new file mode 100644 index 0000000..ce563f8 --- /dev/null +++ b/database/seeders/StaticPageSeeder.php @@ -0,0 +1,155 @@ +updateOrCreate( + [ + 'type' => StaticPageType::contact, + ], + [ + 'seo_title' => 'Seo title pour la page contactez nous', + 'seo_description' => 'Seo description pour la page contactez nous', + 'title' => 'Contactez-nous', + 'slug' => Str::slug('Contactez-nous'), + 'type' => StaticPageType::contact, + 'content' => '', + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::legals, + ], + [ + 'seo_title' => 'Seo title pour la page mentions légales', + 'seo_description' => 'Seo description pour la page mentions légales', + 'title' => 'Mentions légales', + 'slug' => Str::slug('Mentions légales'), + 'type' => StaticPageType::legals, + 'content' => \clean(\fake()->randomHtml(6, 7)), + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::confidentiality, + ], + [ + 'seo_title' => 'Seo title pour la page charte de confidentialitée', + 'seo_description' => 'Seo description pour la page charte de confidentialitée', + 'title' => 'Charte de confidentialitée', + 'slug' => Str::slug('Charte de confidentialitée'), + 'type' => StaticPageType::confidentiality, + 'content' => \clean(\fake()->randomHtml(6, 7)), + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::home, + ], + [ + 'seo_title' => 'Seo title pour la page d\'accueil', + 'seo_description' => 'Seo description pour la page d\'accueil', + 'title' => 'Accueil', + 'slug' => Str::slug('Accueil'), + 'type' => StaticPageType::home, + 'content' => '', + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::conviction, + ], + [ + 'seo_title' => 'Seo title pour la page Nos Convictions', + 'seo_description' => 'Seo description pour la page Nos Convictions', + 'title' => 'Nos Convictions', + 'slug' => Str::slug('Nos Convictions'), + 'type' => StaticPageType::conviction, + 'content' => '', + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::explorer, + ], + [ + 'seo_title' => 'Seo title pour la page Explorateur & Gastronome', + 'seo_description' => 'Seo description pour la page Explorateur & Gastronome', + 'title' => 'Explorateur & Gastronome', + 'slug' => Str::slug('Explorateur & Gastronome'), + 'type' => StaticPageType::explorer, + 'content' => '', + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::joinus, + ], + [ + 'seo_title' => 'Seo title pour la page Rejoignez-nous', + 'seo_description' => 'Seo description pour la page Rejoignez-nous', + 'title' => 'Rejoignez-nous', + 'slug' => Str::slug('Rejoignez-nous'), + 'type' => StaticPageType::joinus, + 'content' => '', + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::ranges, + ], + [ + 'seo_title' => 'Seo title pour la page Nos Gammes de Produits', + 'seo_description' => 'Seo description pour la page Nos Gammes de Produits', + 'title' => 'Nos Gammes de Produits', + 'slug' => Str::slug('Nos Gammes de Produits'), + 'type' => StaticPageType::ranges, + 'content' => '', + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::aboutus, + ], + [ + 'seo_title' => 'Seo title pour la page Nous Connaître', + 'seo_description' => 'Seo description pour la page Nous Connaître', + 'title' => 'Nous Connaître', + 'slug' => Str::slug('Nous Connaître'), + 'type' => StaticPageType::aboutus, + 'content' => '', + ] + ); + StaticPage::query()->updateOrCreate( + [ + 'type' => StaticPageType::news, + ], + [ + 'seo_title' => 'Seo title pour la page Actualités', + 'seo_description' => 'Seo description pour la page Actualités', + 'title' => 'Actualités', + 'slug' => Str::slug('Actualités'), + 'type' => StaticPageType::news, + 'content' => '', + ] + ); + } finally { + StaticPage::setEventDispatcher(new \Illuminate\Events\Dispatcher()); + } //end try + } +} diff --git a/database/seeders/TestimonialSeeder.php b/database/seeders/TestimonialSeeder.php new file mode 100644 index 0000000..599b2fa --- /dev/null +++ b/database/seeders/TestimonialSeeder.php @@ -0,0 +1,25 @@ +create([ + 'picture' => FileStorageHelper::storeFile(new Testimonial(), new \SplFileInfo( + \resource_path('../database/factories/assets/testimonials/default-picture-292x417.png') + )), + ]); + } +}