# fluent-booking/2.2.0/app/Hooks/Scheduler/FiveMinuteScheduler.php

Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution, version 2.2.0. 156 lines.

- Page: https://pluginprobe.com/plugins/fluent-booking/2.2.0/code/app/Hooks/Scheduler/FiveMinuteScheduler.php
- Raw: https://pluginprobe.com/plugins/fluent-booking/2.2.0/raw/app/Hooks/Scheduler/FiveMinuteScheduler.php
- Modified: 2026-05-12T13:33:04+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/fluent-booking/2.2.0/code/app/Hooks/Scheduler/FiveMinuteScheduler.php#L10-L20`.

```php
<?php

namespace FluentBooking\App\Hooks\Scheduler;

use FluentBooking\App\Models\Booking;
use FluentBooking\App\Models\Calendar;
use FluentBooking\App\Models\Meta;
use FluentBooking\App\Services\Helper;

class FiveMinuteScheduler
{
    public function register()
    {
        add_action('fluent_booking_five_minutes_tasks', [$this, 'handle']);
    }

    public function handle()
    {
        $this->maybeAutoCancelBooking();
        $this->maybeAutoCompleteBookings();
        $this->maybeAutoCancelPastBookings();
        $this->maybeAutoDeleteReservations();
        $this->maybeAutoExpireCalendarEvents();
        $this->maybeAutoExpireCalendars();
    }

    private function maybeAutoCompleteBookings()
    {
        $autoCompleteTimeOut = (int)Helper::getGlobalAdminSetting('auto_complete_timing', 60) * 60; // 10 minutes

        $bookings = Booking::with('calendar_event')
            ->where('status', 'scheduled')
            ->where('end_time', '<', gmdate('Y-m-d H:i:s', time() - $autoCompleteTimeOut)) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            ->limit(500)
            ->get();

        if ($bookings->isEmpty()) {
            return true;
        }

        Booking::whereIn('id', $bookings->pluck('id'))
            ->update(['status' => 'completed']);

        foreach ($bookings as $booking) {
            $booking->status = 'completed';
            do_action('fluent_booking/booking_schedule_completed', $booking, $booking->calendar_event);
        }

        return true;
    }

    private function maybeAutoCancelPastBookings()
    {
        $autoCompleteTimeOut = (int)Helper::getGlobalAdminSetting('auto_complete_timing', 60) * 60; // 10 minutes

        $bookings = Booking::with('calendar_event')
            ->where('status', 'pending')
            ->where('end_time', '<', gmdate('Y-m-d H:i:s', time() - $autoCompleteTimeOut)) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            ->limit(500)
            ->get();

        if ($bookings->isEmpty()) {
            return true;
        }

        Booking::whereIn('id', $bookings->pluck('id'))
            ->update([
                'status'     => 'cancelled',
                'updated_at' => gmdate('Y-m-d H:i:s'), // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            ]);

        foreach ($bookings as $booking) {
            $booking->status = 'cancelled';
            do_action('fluent_booking/booking_schedule_auto_cancelled', $booking, $booking->calendar_event);
        }

        return true;
    }

    private function maybeAutoCancelBooking()
    {
        $autoCancelTimeOut = (int)Helper::getGlobalAdminSetting('auto_cancel_timing', 10) * 60; // 10 minutes

        $bookings = Booking::query()
            ->with('calendar_event')
            ->where('created_at', '<=', gmdate('Y-m-d H:i:s', time() - $autoCancelTimeOut)) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            ->where('status', 'pending')
            ->where('payment_status', 'pending')
            ->where('payment_method', '!=', 'offline')
            ->limit(500)
            ->get();

        if ($bookings->isEmpty()) {
            return true;
        }

        Booking::whereIn('id', $bookings->pluck('id'))
            ->update([
                'status'     => 'cancelled',
                'updated_at' => gmdate('Y-m-d H:i:s'), // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            ]);

        foreach ($bookings as $booking) {
            $booking->status = 'cancelled';
            do_action('fluent_booking/booking_schedule_auto_cancelled', $booking, $booking->calendar_event);
        }

        return true;
    }

    private function maybeAutoExpireCalendars()
    {
        Calendar::query()
            ->where('type', 'event')
            ->where('status', 'active')
            ->whereDoesntHave('events', function ($query) {
                $query->whereIn('status', ['active', 'draft']);
            })
            ->update(['status' => 'expired']);

        return true;
    }

    private function maybeAutoExpireCalendarEvents()
    {
        Meta::query()
            ->where('object_type', 'calendar_event')
            ->where('key', 'expire_time')
            ->where('value', '<=', gmdate('Y-m-d H:i:s', time())) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            ->whereHas('calendar_event', function ($query) {
                $query->where('status', 'active');
            })
            ->with(['calendar_event' => function ($query) {
                $query->where('status', 'active');
            }])
            ->limit(500)
            ->get()
            ->each(function ($meta) {
                $meta->calendar_event->update(['status' => 'expired']);
            });

        return true;
    }

    private function maybeAutoDeleteReservations()
    {
        Booking::query()
            ->whereIn('event_type', ['single_event', 'group_event'])
            ->where('status', 'reserved')
            ->where('start_time', '<=', gmdate('Y-m-d H:i:s', time())) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            ->delete();

        return true;
    }
}

```
