Skip to main content

Adding Scheduled Notifications to DB

Premium
3 min read

Comments & Discussion

RA
Richard A. Hoyle ✓ Link copied!

Haveing a little dificalty hear In the github laravel-timezones-course-lesson-3-SendingScheduledNotifications

The above $startTime = CarbonImmutable::parse(toUserDateTime($booking->start, $booking->user), $booking->user->timezone); is in the Models\Booking.php file not the BookingController.php as you have it hear

Content of the BookingController.php file in the GitHub file I downlowed:

M
Modestas ✓ Link copied!

Could you rephrase the issue you are facing here? Not sure I understood.

RA
Richard A. Hoyle ✓ Link copied!

tryed to get the copy of the gethub repository I downloaded to work however I am getting errors dealing with the phpunit file:

  • Installing phpunit/php-code-coverage (10.1.2): Cloning db1497ec8d from cache db1497ec8dd382e82c962f7abbe0320e4882ee4e is gone (history was rewritten?) Install of phpunit/php-code-coverage failed

    • Installing phpunit/phpunit (10.2.1): Cloning 599b332943 from cache 599b33294350e8f51163119d5670512f98b0490d is gone (history was rewritten?) Install of phpunit/phpunit failed

      In GitDownloader.php line 500:
      

    Failed to execute git checkout db1497ec8dd382e82c962f7abbe0320e4882ee4e -- && git reset --hard db1497ec8dd382e82
    c962f7abbe0320e4882ee4e --

    HEAD is now at db1497ec Prepare release
    error: unable to create file tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_an
    d_anonymous_function.php.html: Filename too long
    ate phpunit/php-code-coverage" to resolve this.

the system tryed to update to Laravel 10.13.2 the latest out as of this time. 6/6/2023 4:14 PM

Help !! ??

M
Modestas ✓ Link copied!

I'm not sure why you are getting this, but it seems like you are trying to run phpunit with code coverage. Don't use that flag and it should work just fine.

RA
Richard A. Hoyle ✓ Link copied!

I was able to re-download from the GitHub repository and it works just fine. I even got the version I am creating to pass the phpUnit test all went well up to this point. Above you have us entering what I find in the class Booking extends Model of the download and not in the Booking Controller where you have us putting it. Even then they are not the same Hear you have: Public function store(StoreBookingRequest $request): RedirectResponse { $booking = $request->user()->bookings()->create($request->validated()); $startTime = CarbonImmutable::parse(toUserDateTime($booking->start, $booking->user), $booking->user->timezone); // Schedule 1H reminder $oneHourTime = fromUserDateTime($startTime->subHour(), $booking->user); if (now('UTC')->lessThan($oneHourTime)) { $booking->user->scheduledNotifications()->create([ 'notification_class' => BookingReminder1H::class, 'notifiable_id' => $booking->id, 'notifiable_type' => Booking::class, 'sent' => false, 'processing' => false, 'scheduled_at' => $oneHourTime, 'sent_at' => null, 'tries' => 0, ]); } Return redirect()->route(‘booking.index’); }

And on the GitHub repository you have

public function createReminderNotifications(Booking $booking, CarbonImmutable $startTime): void { // Schedule 2H reminder $twoHoursTime = fromUserDateTime($startTime->subHours(2), $booking->user); if (now('UTC')->lessThan($twoHoursTime)) { $booking->user->scheduledNotifications()->create([ 'notification_class' => BookingReminder2H::class, 'notifiable_id' => $booking->id, 'notifiable_type' => CLASS, 'sent' => false, 'processing' => false, 'scheduled_at' => $twoHoursTime, 'sent_at' => null, 'tries' => 0, ]); } // Schedule 1H reminder $oneHourTime = fromUserDateTime($startTime->subHour(), $booking->user); if (now('UTC')->lessThan($oneHourTime)) { $booking->user->scheduledNotifications()->create([ 'notification_class' => BookingReminder1H::class, 'notifiable_id' => $booking->id, 'notifiable_type' => CLASS, 'sent' => false, 'processing' => false, 'scheduled_at' => $oneHourTime, 'sent_at' => null, 'tries' => 0, ]); } // Schedule 5 min reminder $fiveMinutesTime = fromUserDateTime($startTime->subMinutes(5), $booking->user); if (now('UTC')->lessThan($fiveMinutesTime)) { $booking->user->scheduledNotifications()->create([ 'notification_class' => BookingReminder5MIN::class, 'notifiable_id' => $booking->id, 'notifiable_type' => CLASS, 'sent' => false, 'processing' => false, 'scheduled_at' => $fiveMinutesTime, 'sent_at' => null, 'tries' => 0, ]); } // Schedule started reminder $startingTime = fromUserDateTime($startTime, $booking->user); if (now('UTC')->lessThan($startingTime)) { $booking->user->scheduledNotifications()->create([ 'notification_class' => BookingStartedNotification::class, 'notifiable_id' => $booking->id, 'notifiable_type' => CLASS, 'sent' => false, 'processing' => false, 'scheduled_at' => $startingTime, 'sent_at' => null, 'tries' => 0, ]); } }

Remember this is in the class Booking extends Model

Not the class BookingController extends Controller; hear you have:

public function store(StoreBookingRequest $request): RedirectResponse { $booking = $request->user()->bookings()->create([ 'start' => fromUserDateTime($request->validated('start'), $request->user()), 'end' => fromUserDateTime($request->validated('end'), $request->user()), ]);

    event(new BookingCreatedEvent($booking));

    return redirect()->route('booking.index');
}

What should I do? keep following the GitHub download that I know works! Or you from hear?

M
Modestas ✓ Link copied!

There's so much written here but... I understood that the tutorial has skipped these lines:

[
		'start' => fromUserDateTime($request->validated('start'), $request->user()),
		'end' => fromUserDateTime($request->validated('end'), $request->user()),
]

So I've added that. If There's anything else I've missed - please correct the formatting and I'll take a look!

M
Modestas ✓ Link copied!

We are using the toUserDateTime function to transform the start date from UTC to user timezone (in your case, it would be UTC + 7). This is required as we need to have the notification specifically for that users timezone.

As for why $data['start'] is UTC - that's because it does not do automatic transformation. You could enable it with cast on your model to tell that it should be a Carbon instance, but that could bring some issues at a later point. So I like to keep them as strings and mutate manually (easier to debug) :)

HN
Huy Nguyen ✓ Link copied!

I see, I think we can change the code from $startTime = CarbonImmutable::parse(toUserDateTime($booking->start, $booking->user), $booking->user->timezone); to $startTime = CarbonImmutable::parse($request->start). As I tested it, it produce the same result

M
Modestas ✓ Link copied!

Could be! there's many ways to write the same thing!

R
Rishikant ✓ Link copied!

Class "App\Models\ScheduledNotification" not found while there is code written in \app\Models\User

use App\Models\ScheduledNotification;

public function scheduledNotifications(): HasMany { return $this->hasMany(ScheduledNotification::class); }

	what is wrong there?