Nature Nature - 3 months ago 8
PHP Question

Count the amount of 'is available'

I have tried to figure out a solution for this problem, but can't really seem to figure out a way in my head, so hopefully someone has a simple and smart solution for this problem.

As you can see for the output example. It echoes " is available" next to the available timeslots for my code, but I would like to somehow make, so I can count or echo something like "There is no available times", if a day is fully booked.

I have tried some solutions with using $i = 0 and then $i++, but can't really seems to get it to work like I would.

Output example for code below:


2015-11-18 09:00:00 to 2015-11-18 09:30:00 is available

2015-11-18 09:30:00 to 2015-11-18 10:00:00 is available

2015-11-18 10:00:00 to 2015-11-18 10:30:00 is available

2015-11-18 10:30:00 to 2015-11-18 11:00:00

2015-11-18 11:00:00 to 2015-11-18 11:30:00

2015-11-18 11:30:00 to 2015-11-18 12:00:00

2015-11-18 12:00:00 to 2015-11-18 12:30:00

2015-11-18 12:30:00 to 2015-11-18 13:00:00 is available

2015-11-18 13:00:00 to 2015-11-18 13:30:00 is available

2015-11-18 13:30:00 to 2015-11-18 14:00:00 is available

2015-11-18 14:00:00 to 2015-11-18 14:30:00 is available

2015-11-18 14:30:00 to 2015-11-18 15:00:00

2015-11-18 15:00:00 to 2015-11-18 15:30:00

2015-11-18 15:30:00 to 2015-11-18 16:00:00 is available

2015-11-18 16:00:00 to 2015-11-18 16:30:00 is available


I use http://carbon.nesbot.com/ for the Carbon required in the top.

<?php
require 'Carbon.php';
use Carbon\Carbon;

$schedule = [
'start' => '2015-11-18 06:00:00',
'end' => '2015-11-18 18:00:00',
];

$start = Carbon::instance(new DateTime($schedule['start']));
$end = Carbon::instance(new DateTime($schedule['end']));

$minInterval = new DateInterval('PT30M');
$reqInterval = new DateInterval('PT45M');

$events = [
[
'created_at' => '2015-11-18 10:00:00',
'updated_at' => '2015-11-18 13:00:00',
],
[
'created_at' => '2015-11-18 14:00:00',
'updated_at' => '2015-11-18 16:00:00',
],
];

function slotAvailable($from, $to, $events, $workEnd){
foreach($events as $event){
$eventStart = new DateTime($event['created_at']);
$eventEnd = new DateTime($event['updated_at']);

if(($from >= $eventStart && $to <= $eventEnd) || ($from < $eventEnd && $to > $eventEnd) || ($from < $eventStart && $to > $eventStart) || ($to > $workEnd)){
return false;
}
}
return true;
}

foreach(new DatePeriod($start, $minInterval, $end) as $slot){
$to = $slot->copy()->add($reqInterval);
$workEnd = $schedule['end'];

echo $slot->toDateTimeString() . ' to ' . $to->toDateTimeString();

if(slotAvailable($slot, $to, $events, $workEnd)){
echo ' is available';
}
echo '<br />';
}
}
?>

Answer

Add a counter before your last foreach loop.

$available = 0;

Then each time you echo "is available" you add 1 to it

$available++;

Then at the end...

if ($available == 0) echo "Day is fully booked";

If you meant that you wanted to show "Day is fully booked" instead of showing any of the schedule items, you should add all the things you echo to a string list instead and display it at the end if $available > 0.

$output = array();

...

// change all instances of echo ... to something like this...
// echo $slot->toDateTimeString() . ' to ' . $to->toDateTimeString();
array_push($output, $slot->toDateTimeString() . ' to ' . $to->toDateTimeString());

...

if ($available > 0) {
    foreach ($output as $item) {
        echo $item;
    }
} else {
    echo "Schedule is fully booked.";
}