View file Lottery/Controllers/IndexController.php

File size: 4.22Kb
<?php

declare(strict_types=1);

namespace Modules\Lottery\Controllers;

use App\Classes\Validator;
use App\Controllers\BaseController;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Http\Request;
use Modules\Lottery\Models\Lottery;
use Throwable;

class IndexController extends BaseController
{
    /**
     * Main page
     *
     * @return string
     */
    public function index(): string
    {
        $this->rewardWinners();

        $lottery = Lottery::query()
            ->orderByDesc('day')
            ->limit(2)
            ->get();

        $lottery = $lottery->pad(2, null);

        [$today, $yesterday] = $lottery;

        if ($yesterday) {
            $yesterday->winners = $yesterday->lotteryUsers()
                ->where('number', $yesterday->number)
                ->get();
        }

        $config = Lottery::getConfig();

        return view('Lottery::index', compact('today', 'yesterday', 'config'));
    }

    /**
     * Buy ticket
     *
     * @param  Request  $request
     * @param  Validator  $validator
     *
     * @throws Throwable
     */
    public function buy(Request $request, Validator $validator): void
    {
        $number      = check($request->input('number'));
        $token       = check($request->input('token'));
        $ticketPrice = Lottery::getConfig('ticketPrice');
        $numberRange = Lottery::getConfig('numberRange');

        if (! $user = getUser()) {
            abort(403);
        }

        $lottery = Lottery::query()
            ->orderByDesc('day')
            ->first();

        if (!$lottery) {
            abort('default', __('Lottery::lottery.lottery_not_activated'));
        }

        $lotteryUser = $lottery->lotteryUsers()
            ->where('user_id', $user->id)
            ->first();

        $validator
            ->equal($token, $_SESSION['token'], ['number' => __('validator.token')])
            ->empty($lotteryUser, ['number' => __('Lottery::lottery.already_bought_ticket')])
            ->lte($ticketPrice, getUser('money'), ['number' => __('Lottery::lottery.no_money')])
            ->between($number, $numberRange[0], $numberRange[1], ['number' => __('Lottery::lottery.must_enter_number')]);

        if ($validator->isValid()) {
            DB::connection()->transaction(
                static function () use ($user, $number, $lottery, $ticketPrice) {
                $user->decrement('money', $ticketPrice);
                $lottery->increment('amount', $ticketPrice);

                $lottery->lotteryUsers()->create([
                    'user_id'    => $user->id,
                    'number'     => $number,
                    'created_at' => SITETIME
                ]);
            });

            setFlash('success', __('Lottery::lottery.ticket_success_purchased'));
        } else {
            setInput($request->all());
            setFlash('danger', $validator->getErrors());
        }

        redirect('/lottery');
    }

    /**
     * Reward winners
     */
    private function rewardWinners(): void
    {
        $amount = Lottery::getConfig('jackpot');
        $range  = Lottery::getConfig('numberRange');

        $lottery = Lottery::query()
            ->orderByDesc('day')
            ->first();

        if ($lottery && $lottery->day !== date('Y-m-d', SITETIME)) {
            // Search winners
            $winners = $lottery->lotteryUsers()
                ->where('number', $lottery->number)
                ->get();

            if ($winners->isNotEmpty()) {
                $moneys = (int) ($lottery->amount / $winners->count());

                $message = __('Lottery::lottery.congratulations_winning', ['jackpot' => plural($moneys, setting('moneyname'))]);

                foreach ($winners as $winner) {
                    $winner->user->increment('money', $moneys);
                    $winner->user->sendMessage(null, $message);
                }
            } else {
                $amount = $lottery->amount;
            }
        }

        if (! $lottery || $lottery->day !== date('Y-m-d', SITETIME)) {
            // Update lottery
            Lottery::query()->create([
                'day'     => date('Y-m-d', SITETIME),
                'amount'  => $amount,
                'number'  => mt_rand($range[0], $range[1]),
            ]);
        }
    }
}