Home > database >  Laravel correct condition handling
Laravel correct condition handling

Time:05-19

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?

CodePudding user response:

function autoGroupPromos()
{
  // removed for loop to clean outdated promos in single request
  // note that this way of deleting rows won't fire model events (if any)
  Promocode::whereNotNull('vk_user_id')
    ->where('created_at', '<=', Carbon::now()->subDay(1))
    ->delete();

  $permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';

  $userIds = Promo::pluck('user_id');  
  
  foreach ($userIds as $id) {
    /* in the begining we cleaned all outdated codes, so if user still has 
     some - no need to create new */
    if (Promocode::where('vk_user_id', $id)->exists()){
      continue;
    }

    $code = substr(str_shuffle($permitted_chars), 0, 8);
    /* you can immidiately get create model like this - 
       no need to make another request
    $createdPromo = Promocode::create([*/
    Promocode::create([
      'name' => $code,
      'sum' => '0.25',
      'activates' => '100',
      'vk_user_id' => $id
    ]);

    /* didn't get why you were requesting newly created 
    promo to get name field if you put there $code value */
    $message = `Your new promo: $code`;

    $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)
      )
    )));
  }
}

upd: here can be a bit cleaner way with hasOneOfMany and skipping each user request to check if promocode exists

// User model
public function promocodes() {
  return $this->hasMany(Promocode::class);
}

public function promocode() {
  return $this->hasOne(Promocode::class)->latestOfMany();
}
function autoGroupPromos()
{
  // note that this way of deleting rows won't fire model events (if any)
  Promocode::whereNotNull('vk_user_id')
    ->where('created_at', '<=', Carbon::now()->subDay(1))
    ->delete();

  $permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';

  // taking users without promo after cleanup
  User::whereDoesntHave('promo')->get()
    ->each(function (User $user) use ($permitted_chars) {
      $code = substr(str_shuffle($permitted_chars), 0, 8);
      // pay attention on relation name - using hasMany
      $user->promocodes()->save(
        new Promocode([
          'name' => $code,
          'sum' => '0.25',
          'activates' => '100',
        ])
      );

      $message = `Your new promo: $code`;

      $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)
        )
      )));
    });
}

link Inserting & Updating Related Models

  • Related