ldc-gen-game-web/app/Models/Settings.php

253 lines
8.7 KiB
PHP

<?php
namespace App\Models;
use App\Casts\AsArrayOfDiscount;
use App\Lib\Discount;
use App\Lib\Helpers\FileStorageHelper;
use App\Traits\Models\IsCachedAsCollection;
use Carbon\CarbonInterval;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
/**
* Settings.
*
* @property string $name The game name
* @property string $company Name of the company that organizes the game
* @property \Illuminate\Support\Carbon $start_date Start date of the game
* @property \Illuminate\Support\Carbon $end_date End date of the game
* @property int $nb_participation_player Max paticipation per player (0 = unlimited)
* @property int $nb_participation_ip Max paticipation per ip (0 = unlimited)
* @property int $nb_unique_code_use Max unique code use (0 = unlimited)
* Dans tous les cas 1 joueur ne peut utiliser
* qu'une seule fois 1 code donné
* @property boolean $use_ean_codes Should the game use ean codes ?
* @property boolean $activated_teaser Is the teaser active ?
* @property boolean $activated_close_page Is the close page active ?
* @property \Illuminate\Support\Carbon $close_page_active_date End date of the close page
* @property string $redirect_close Link to redirect when the game is ended
* @property boolean $discounts_activated Are the discounts active ?
* @property string $discounts_site Discount MesBr site
* @property string $discounts_campaign Discount MesBr campaign
* @property array<\App\Lib\Discount> $web_coupons Array of web coupons
* @property array<string> $notification_emails Array of email to notify when there's a winnner
* @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 ?
*/
class Settings extends Model
{
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',
'use_ean_codes',
'activated_teaser',
'activated_close_page',
'close_page_active_date',
'redirect_close',
'discounts_activated',
'discounts_site',
'discounts_campaign',
'web_coupons',
'notification_emails',
'winning_proof',
'analytics',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'use_ean_codes' => 'bool',
'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,
'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.
*
* Demande Vincent: Methods to check via policy if game can be played
*
* Besoin:
* - Min 1 code unique
* - Min 1 Instant gagnant
* - Min 1 Product si Settings use_ean_codes
* - Min 1 WebCoupon si 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 (!(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->use_ean_codes 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())
);
}
}