$web_coupons Array of web coupons * @property array $notification_emails Array of email to notify when there's a winnner * @property array $authorized_countries All countries eligible to participate. * @property boolean $winning_proof Is the winning proof needed * @property-read \Illuminate\Support\Carbon $created_at Creation Date. * @property-read \Illuminate\Support\Carbon $updated_at Last update Date. * * @property-read boolean $game_is_open Le jeu est ouvert ? * @property-read boolean $game_has_begun Le jeu à démarré ? * @property-read boolean $game_has_ended Le jeu est terminé ? * @property-read boolean $should_display_teaser_page Doit afficher la page de teaser ? * @property-read boolean $should_display_end_page Doit afficher la page fin de jeu ? * * @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship. */ class Settings extends Model { use ActivityLog; use IsCachedAsCollection; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'company', 'start_date', 'end_date', 'nb_participation_player', 'nb_participation_ip', 'nb_unique_code_use', 'code_type', 'activated_teaser', 'activated_close_page', 'close_page_active_date', 'redirect_close', 'discounts_activated', 'discounts_site', 'discounts_campaign', 'web_coupons', 'authorized_countries', 'notification_emails', 'winning_proof', 'analytics', 'notify_prize_sent', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'notify_prize_sent' => 'bool', 'code_type' => CodeType::class, 'activated_teaser' => 'bool', 'activated_close_page' => 'bool', 'discounts_activated' => 'bool', 'winning_proof' => 'bool', 'start_date' => 'datetime', 'end_date' => 'datetime', 'close_page_active_date' => 'datetime', 'web_coupons' => AsArrayOfDiscount::class, 'authorized_countries' => 'array', 'notification_emails' => 'array', ]; // * EVENTS /** * Perform any actions required after the model boots. * * @return void */ protected static function booted() { static::created(function () { self::removeCached(); }); static::updated(function (self $model) { self::removeCached(); FileStorageHelper::removeOldFiles( $model->fetchCouponsPictures(true), $model->fetchCouponsPictures() ); }); static::deleted(function () { self::removeCached(); }); } // * METHODS /** * Fetch all widget Files * * @param boolean $useOldAttribute * @return array */ public function fetchCouponsPictures(bool $useOldAttribute = false): array { $files = []; \collect(!$useOldAttribute ? $this->web_coupons : $this->getOriginal('web_coupons')) ->each(function (Discount $coupon) use (&$files) { $files = \array_merge($files, [$coupon->picture]); }); return FileStorageHelper::onlyUploadedFilesWithFileStorageHelper(collect($files)->filter()->all()); } /** * Check if the game can be play and report if it cannot. * Methods to check via policy if game can be played * * Needed: * - Min 1 code unique if Settings code_type is unique or both codes. * - Min 1 Instant gagnant. * - Min 1 Product if Settings code_type is ean or both codes. * - Min 1 WebCoupon if Settings discounts_activated * * @return boolean */ public function checkGameCanBePlayed(): bool { /** @var \App\Models\Settings */ $settings = app(Settings::class); if (!(bool) Prize::getCached()->count()) { report(new \RuntimeException('Need prizes to enable the game')); return false; } if ( ($settings->code_type->equals(CodeType::unique) || $settings->code_type->equals(CodeType::both)) and !(bool) Cache::remember('codes.count', CarbonInterval::day(), fn() => Code::query()->count()) ) { report(new \RuntimeException('Need codes to enable the game')); return false; } if (!(bool) InstantWin::getCached()->count()) { report(new \RuntimeException('Need instant win to enable the game')); return false; } if ( ($settings->code_type->equals(CodeType::ean) || $settings->code_type->equals(CodeType::both)) and !(bool) Product::getCached()->count() ) { report(new \RuntimeException('Need products to enable the game using ean codes')); return false; } if ($settings->discounts_activated and !(bool) collect($this->web_coupons)->count()) { report(new \RuntimeException('Need MesBr coupons to enable the game using discounts')); return false; } return true; } // * GETTERS /** * Get game_has_begun attribute * * The game has started ? * * @return \Illuminate\Database\Eloquent\Casts\Attribute */ public function gameHasBegun(): Attribute { return Attribute::make( get: fn (): bool => $this->start_date->lte(now()) ); } /** * Get game_has_ended attribute * * The game has ended ? * * @return \Illuminate\Database\Eloquent\Casts\Attribute */ public function gameHasEnded(): Attribute { return Attribute::make( get: fn (): bool => $this->game_has_begun and $this->end_date->lte(now()) ); } /** * Get game_is_open attribute * * The game is oppen ? * * @return \Illuminate\Database\Eloquent\Casts\Attribute */ public function gameIsOpen(): Attribute { return Attribute::make( get: fn (): bool => $this->game_has_begun and !$this->game_has_ended ); } /** * Get should_display_teaser_page attribute * * The teaser page has to be displayed ? * * @return \Illuminate\Database\Eloquent\Casts\Attribute */ public function shouldDisplayTeaserPage(): Attribute { return Attribute::make( get: fn (): bool => !$this->game_has_begun and !$this->game_has_ended and $this->activated_teaser ); } /** * Get should_display_end_page attribute * * The end page has to be displayed ? * * @return \Illuminate\Database\Eloquent\Casts\Attribute */ public function shouldDisplayEndPage(): Attribute { return Attribute::make( get: fn (): bool => $this->game_has_begun and $this->game_has_ended and $this->activated_close_page and $this->close_page_active_date->gte(now()) ); } /** * Get all authorized countries. * * @return \Illuminate\Support\Collection */ public function getAuthorizedCountries(): \Illuminate\Support\Collection { /** @var \App\Models\Settings $settings */ $settings = app(Settings::class); if (count($settings->authorized_countries)) { // * Authorized countries defined in settings. $countries = collect(Country::toArray()) ->filter(fn($enum) => in_array($enum->value, $settings->authorized_countries)); } else { // * Only DROM-COM + France. $franceCountries = collect(Country::getValidCountries()) ->filter(fn($enum) => !in_array($enum, [Country::belgium(), Country::luxembourg()])); $otherCountries = collect(Country::getValidCountries()) ->filter(fn($enum) => !$franceCountries->contains($enum)); $countries = $franceCountries->merge($otherCountries); } return $countries; } // * RELATIONS /** * Activities logs One-to-many relationship. * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function activityLogs(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(ActivityLog::class); } }