ldc-gen-game-web/app/Http/Controllers/Bo/InstantWinController.php

187 lines
6.1 KiB
PHP
Raw Normal View History

2020-10-21 15:26:21 +02:00
<?php
2026-10-02 12:09:46 +02:00
declare(strict_types=1);
namespace App\Http\Controllers\Bo;
2020-10-21 15:26:21 +02:00
use App\Http\Controllers\Controller;
use App\Models\InstantWin;
use App\Models\Prize;
2020-10-21 15:26:21 +02:00
use App\Models\Settings;
2026-10-02 12:09:46 +02:00
use Carbon\Carbon;
use Carbon\CarbonInterface;
2023-12-05 12:33:25 +01:00
use Carbon\CarbonInterval;
2026-10-02 12:09:46 +02:00
use Illuminate\Contracts\View\View;
2023-12-05 12:33:25 +01:00
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
2026-10-02 12:09:46 +02:00
use stdClass;
2020-10-21 15:26:21 +02:00
class InstantWinController extends Controller
{
2023-12-05 12:33:25 +01:00
/**
* Create the controller instance.
*/
public function __construct()
{
$this->authorizeResource(InstantWin::class);
}
/**
* Display a listing of the resource.
*/
2026-10-02 12:09:46 +02:00
public function index(): View
2021-08-18 17:08:02 +02:00
{
2026-10-02 12:09:46 +02:00
$instantWinModelList = InstantWin::query()->oldest('available_at')->get();
2020-10-21 15:26:21 +02:00
2026-10-02 12:09:46 +02:00
/** @var view-string $view */
$view = 'back::pages.instant-win.index';
return view($view, [
'instantWinModelList' => $instantWinModelList,
2020-10-21 15:26:21 +02:00
]);
}
/**
* Returns generated instant win.
*/
2023-12-05 12:33:25 +01:00
public function generate(): JsonResponse
2021-08-18 17:08:02 +02:00
{
2023-12-05 12:33:25 +01:00
$this->authorize('generate', InstantWin::class);
return DB::transaction(function () {
/**
* À partir de quelle heure on peut gagner
* ! Seul l'heure sera prize en compte
*/
$day_start = now()->setTime(6, 0);
/**
* Jusqu'à quelle heure on peut gagner
* ! Seul l'heure sera prize en compte
*/
$day_end = now()->setTime(22, 29);
2026-10-02 12:09:46 +02:00
/** @var Settings */
$settings = resolve(Settings::class);
2023-12-05 12:33:25 +01:00
$prizeModelList = Prize::all();
2026-10-02 12:09:46 +02:00
/** @var Collection<array-key, WinDayCalendar> */
2023-12-05 12:33:25 +01:00
$datesGlobal = collect();
2026-10-02 12:09:46 +02:00
/** @var Collection<array-key, WinTimeElement> Liste de tous les lots à gagner */
2023-12-05 12:33:25 +01:00
$lotsGlobal = collect();
2020-10-21 15:26:21 +02:00
2023-12-05 12:33:25 +01:00
// * Seed srand !
\mt_srand(time());
2020-10-21 15:26:21 +02:00
2023-12-05 12:33:25 +01:00
// * Init prize list
2026-10-02 12:09:46 +02:00
$prizeModelList->each(function (Prize $prize) use ($lotsGlobal, $day_start, $day_end): void {
2023-12-05 12:33:25 +01:00
for ($i = 0; $i < $prize->quantity; $i++) {
$el = new WinTimeElement();
$el->prize = $prize;
$el->time = now()->setTime(
mt_rand($day_start->hour, $day_end->hour),
mt_rand($day_start->minute, $day_end->minute)
);
$lotsGlobal->push($el);
}
});
2026-10-02 12:09:46 +02:00
$lotsGlobal->shuffle();
2023-12-05 12:33:25 +01:00
// * Init days calendar
foreach ($settings->start_date->toPeriod($settings->end_date, CarbonInterval::make('1day')) as $date) {
$el = new WinDayCalendar();
$el->lots = collect();
$el->time = $date->setTime(0, 0);
$datesGlobal->push($el);
2020-10-21 15:26:21 +02:00
}
2023-12-05 12:33:25 +01:00
// * Save Instant wins
2026-10-02 12:09:46 +02:00
$this->generateArray($lotsGlobal, $datesGlobal, 0)->each(function (WinDayCalendar $winDayCalendar): void {
$winDayCalendar->lots->each(function (WinTimeElement $winTimeElement): void {
$instantWin = new InstantWin();
$instantWin->available_at = $winTimeElement->time;
2023-12-05 12:33:25 +01:00
$instantWin->prize()->associate($winTimeElement->prize);
$instantWin->saveOrFail();
});
});
// * Output instant wins to ajax response
return response()->json(InstantWin::all());
});
2020-10-21 15:26:21 +02:00
}
/**
* Generate instant win.
*
2023-12-05 12:33:25 +01:00
* Même algo que celui implémenté par Romain.
*
2026-10-02 12:09:46 +02:00
* @param Collection<array-key, WinTimeElement> $lotsGlobal
* Liste de tous les lots à gagner
* @param Collection<array-key, WinDayCalendar> $dateGlobal
* @return Collection<array-key, WinDayCalendar>
*
2023-12-05 12:33:25 +01:00
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
*/
2023-12-05 12:33:25 +01:00
private function generateArray(Collection $lotsGlobal, Collection $dateGlobal, int $prizesDone): Collection
2021-08-18 17:08:02 +02:00
{
2023-12-05 12:33:25 +01:00
// phpcs:enable
/** @var array-key Un jour sélectionné aléatoire. */
$rKey = $dateGlobal->keys()->random(1)->firstOrFail();
// ? À-t-on déjà assigné un lot par jour (au moins) ?
// ? Le jour aléatoire sélectionné à déja un lot ?
2026-10-02 12:09:46 +02:00
if ($prizesDone < $dateGlobal->count() && $dateGlobal->get($rKey)->lots->count() > 0) {
2023-12-05 12:33:25 +01:00
return $this->generateArray($lotsGlobal, $dateGlobal, $prizesDone);
2020-10-21 15:26:21 +02:00
}
2023-12-05 12:33:25 +01:00
// * Insert next prize on a randowm day
$dateGlobal->get($rKey)->lots->push($lotsGlobal->get($prizesDone++));
// ? On a distribué assez de lots ?
if ($prizesDone < $lotsGlobal->count()) {
return $this->generateArray($lotsGlobal, $dateGlobal, $prizesDone);
2021-08-18 17:08:02 +02:00
}
2023-12-05 12:33:25 +01:00
// * Tri par heure et assignation du jour correct.
2026-10-02 12:09:46 +02:00
$dateGlobal->each(function (WinDayCalendar $date): void {
$date->lots = $date->lots->sort(fn (WinTimeElement $a, WinTimeElement $b): int | float => $a->time->timestamp - $b->time->timestamp)
->map(function (WinTimeElement $time) use ($date): WinTimeElement {
2023-12-05 12:33:25 +01:00
$time->time->setDate(
$date->time->year,
$date->time->month,
$date->time->day
);
2026-10-02 12:09:46 +02:00
2023-12-05 12:33:25 +01:00
return $time;
});
});
2020-10-21 15:26:21 +02:00
return $dateGlobal;
}
2023-12-05 12:33:25 +01:00
}
2020-10-21 15:26:21 +02:00
2023-12-05 12:33:25 +01:00
/**
2026-10-02 12:09:46 +02:00
* @property Prize $prize Le lot à gagner.
* @property Carbon $time Une heure aléatoire.
*
2023-12-05 12:33:25 +01:00
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
*/
2026-10-02 12:09:46 +02:00
class WinTimeElement extends stdClass
2023-12-05 12:33:25 +01:00
{
// phpcs:enable
}
/**
2026-10-02 12:09:46 +02:00
* @property Carbon|CarbonInterface $time
* Un jour dans le temps.
* @property Collection<array-key, WinTimeElement> $lots
* Liste des lots tombant ce jour.
*
2023-12-05 12:33:25 +01:00
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
*/
2026-10-02 12:09:46 +02:00
class WinDayCalendar extends stdClass
2023-12-05 12:33:25 +01:00
{
// phpcs:enable
2020-10-21 15:26:21 +02:00
}