Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

iGenezys's avatar

jQuery - Ajax - Lottery Winner

Hi people.

I'd like to do a lottery system, with a countdown and a winner that win points. I did all the countdown and correctly did the ajax requests for picking up a winner and put his points in the database :

jQuery(function ($) {
    var launch = new Date(2017, 10, 06, 23, 41, 40);
    var days = $('#jours');
    var hours = $('#heures');
    var minuts = $('#minutes');
    var seconds = $('#secondes');

    function setDate(){
        var now = new Date();
        var time = launch.getTime() - now.getTime();
        var s = (launch.getTime() - now.getTime()) / 1000;
        var d = Math.floor(s / 86400);
        var timer = setTimeout(setDate, 1000);
        
        days.html('<strong class="min">'+ d +'</strong><p class="arvo">Jour'+(d>1?'s':'')+'</p>')
        s -= d * 86400;

        var h = Math.floor(s / 3600);
        hours.html('<strong class="min">'+ h +'</strong><p class="arvo">Heure'+(h>1?'s':'')+'</p>')
        s -= h * 3600;

        var m = Math.floor(s / 60);
        minuts.html('<strong class="min">'+ m +'</strong><p class="arvo">Minute'+(m>1?'s':'')+'</p>')
        s -= m * 60;

        s = Math.floor(s);
        seconds.html('<strong class="min">'+ s +'</strong><p class="arvo">Seconde'+(s>1?'s':'')+'</p>');

        if(Math.ceil(time) <= 1000)
        {
            $.ajax({
                url: "/triumphclick/get_user",
                type: "GET",
                dataType: "json",
                success: function ( data ) {
                    var user = data;

                    $('.gagnant').html('<strong class="win">Le gagnant est '+ user.login +'!</strong>' +
                        '<p><h6 class="org"><i><b>Votre compte a été crédité ! Félicitation !</b></i></h6></p>')

                }
            });
            
            clearTimeout(timer);
            $('.bloc-min').addClass('removed');
        }

    }
    setDate();


});

I'm getting the user with this laravel route :

Route::name('get_user')->get('get_user', function(){
    $lien = User_liens::where('chance', true)->inRandomOrder()->first();

    $user = \App\User::where('id', $lien->user_id)->first();
    $solde_pts = $user->solde_points + 20;

    $user->update([
        'solde_points' => $solde_pts,
    ]);

    return \Response::json($user);
});

But the problem is that when I reload the page, it do again the code and the winner get his points again and again.

And something else, I think that this way is not really secure, it's a js code so I guess people can go through, so I wanted to do this code :

if(Math.ceil(time) <= 1000)
        {
            $.ajax({
                url: "/triumphclick/get_user",
                type: "GET",
                dataType: "json",
                success: function ( data ) {
            return data;
                }
            });
        }

On the server side with PHP. But I never did that, and I don't know how to do all the checking and the code, from JS to PHP, I'm really lost here..

Well, I don't know if I was clear, but if you have some ideas that could help me, I thank you !

0 likes
6 replies
bit9labs's avatar

Could you check the updated_at column and only add the points if $user->updated_at < \Carbon\Carbon::today()->subDays(1)

robrogers3's avatar

so 2 things here.

one you want to employ the csrf tokens in the header so other people cannot just call it from there browser. this means you MUST use a GET not a POST. otherwise, Laravel won't check for it.

here's how to set that up for jquery

$.ajaxSetup({ headers: { 'csrftoken' : '{{ csrf_token() }}' } });

two, how to prevent real users from taking advantage of multiple submits. the question is a business rule. Once only, once a day, ...

If it's once only, add a column on the user table to say, something like lottery_submitted.

if it's only once a day, add a column say last_lottery_submit_date.

then check that one like:

if $user->last_lottery_submit_date > \Carbon\Carbon::today()->subDays(1) {
    return nope();
}
1 like
iGenezys's avatar

Hi !

Sorry, long time without any computer or code :(

Well, I tried your response, and I have one problem : I don't have an unique winner.

Here's the code :

Route::name('get_user')->get('get_user', function() {
    $lien = User_liens::where('chance', true)->inRandomOrder()->first();
    
    $user = \App\User::where('id', $lien->user_id)->first();
    $date = date('Y-m-d H:m:s');

    if ($user->lottery_submit < \Carbon\Carbon::today()->subDays(1)){

        $solde_pts = $user->solde_points + 20;

        $user->update([
            'solde_points' => $solde_pts,
            'lottery_submit' => $date
        ]);

        return \Response::json($user);
    }
    else{
        $user = 'nope';
        return \Response::json($user);
    }

});

It's actually working, but if I have 3 potential winners, the code is going to find the first winner, credit his points, and add the date, and he'll not have another credit during >24h; But, if I reload the page, the script is going to search about the 2 others users, and do the same thing, until there is no users left.

Do you have an idea for getting only one winner ?

agenamr's avatar

When the countdown timer reaches zero and a winner is selected, instead of immediately returning the winner's information from the server, you could first save a record of the loterias de ayer winner's ID and the fact that they have won in a database table. This way, even if the page is reloaded, the server will know that the winner has already been selected and credited their points.

Please or to participate in this conversation.