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

artyak's avatar

Laravel correct condition handling

I have a function on my site that creates a promo code for an affiliate automatically once every 24 hours. If 24 hours have passed since the creation of the promo code, it is deleted old promo from the database, and a new one is generated anew. But now there is a problem with this function, it generates a new promo code every time, regardless of whether 24 hours have passed or not.

My function:

    public function autoGroupPromos()
    {

        $userList = Promo::get();
        $userIds = $userList->pluck('user_id');


        foreach ($userIds as $id)  {
            $date = Carbon::now();
            $promoCodes = Promocode::query()->where('vk_user_id', '!=', null)->get();
            foreach ($promoCodes as $promos) {

                // If promo create 24 hours ago
                $hours = $promos->created_at->diffInHours($date);
                if ($hours >= 24) {
                    $promos->delete();
                }
            }

            $permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
            $code = substr(str_shuffle($permitted_chars), 0, 8);

                    Promocode::query()->create([
                        'name' => $code,
                        'sum' => '0.25',
                        'activates' => '100',
                        'vk_user_id' => $id
                    ]);


                    $promoText = Promocode::where('vk_user_id', $id)->orderBy('created_at', 'desc')->first();
                    $promoName = $promoText->name;


                    $message = 'Your new promo: ' . $promoName . ';

                    $url = 'https://api.vk.com/method/messages.send';
                    $params = array(
                        'message' => $message,  
                        'access_token' => 'token',
                        'v' => '5.81',
                        'peer_ids' => $id
                    );

                    $result = file_get_contents($url, false, stream_context_create(array(
                        'http' => array(
                            'method' => 'POST',
                            'header' => 'Content-type: application/x-www-form-urlencoded',
                            'content' => http_build_query($params)
                        )
                    )));
        }
    }

That is, if less than 24 hours have passed since the promo was created - it should not be deleted and a new promo code should not be generated. But now unfortunately there is an error somewhere.

What can be the problem?

0 likes
9 replies
Snapey's avatar

why not create a command to create a new code then call this once every 24 hours using the scheduler?

automica's avatar

why not just create a console command that creates a new promo for each client and run it every 24 hours on a cron?

each user will only ever have 1 promo code as you replace the old one with the new one when the command runs.

artyak's avatar

@automica I already thought about it, but I do not need to give out promo codes for all users, but only for partners, which are listed in the model Promo, I also thought about every 24 hours to run for all, but someone can become a partner sooner, someone later and will not be a mess if the user only get a promo code, and 2 hours later will be the new

automica's avatar

@artyak how are you currently triggering this functionality? is the intention to run this method on a regular frequency and send each code out by email when it's refreshed?

From what I've gathered, each user only has one code so in that case you could simply things massively if you use a model relationship to define the users relationship with the promo.

if User hasOne Promo - then you can do:

<?php

class PromoGenerator
{
    public const permittedChars = '0123456789abcdefghijklmnopqrstuvwxyz';

    public function handle()
    {

        $users = Promo::get();
        $date = Carbon::now();

        $users->each(function($user) use ($date){

            if($user->promoCode->created_at->diffInHours($date) >= 24){
                $user->promoCode->delete();

                $user->promoCode->create([
                    'name' => $this->createCode(),
                    'sum' => '0.25',
                    'activates' => '100',
                    'vk_user_id' => $user->id
                ]);

                $this->sendPromo($user);
            }
        });
    }

    /**
     * @return string
     */
    private function createCode():string
    {
        return substr(str_shuffle(parent::permittedChars), 0, 8);
    }

    /**
     * @param User $user
     * @return void
     */
    private function sendPromo(User $user)
    {
        $url = "https://api.vk.com/method/messages.send";
        $params = [
            'message' => 'Your new promo: ' . $user->name,
            'access_token' => 'token',
            'v' => '5.81',
            'peer_ids' => $user->id
        ];

        $result = file_get_contents($url, false, stream_context_create([
            'http' => [
                'method' => 'POST',
                'header' => 'Content-type: application/x-www-form-urlencoded',
                'content' => http_build_query($params)
            ]
        ]));
    }
}

to be more efficient, you should only query users who's promo code has expired.

    public function smarterHandle()
    {
        $users = PromoCode::whereDate('created_at', '>=', Carbon::now()->subDay())->get();

        $users->each(function ($user) {

            $user->promoCode->delete();

            $user->promoCode->create([
                'name' => $this->createCode(),
                'sum' => '0.25',
                'activates' => '100',
                'vk_user_id' => $user->id
            ]);

            $this->sendPromo($user);
        });
    }

obv I'm not 100% on how you are triggering these methods, or how you're initially creating the promo but the above should hopefully give you some ideas on a simpler approach.

1 like
artyak's avatar

@automica Wow, very well described and understandable, thank you :) just tried to run the code, now i get an error: Trying to get property 'created_at' of non-object at line:

 if($user->promoCode->created_at->diffInHours($date) >= 24){
Snapey's avatar

your logic is flawed in that the code is only deleted if it is over 24 hours, but a new code is created every time.

move the create code into the if check

1 like
artyak's avatar

@Snapey move the create code into the if check

where is it? can you write example, please?

Please or to participate in this conversation.