The way I came up with to solve your problem is to convert your business hours and appointments arrays into a single availability array, which will contain the time slots at which you are available.
With this array, I can easily generate the array of slots you need by counting the number of slots available in a period of time, thanks to the provided slot duration (of 15 minutes in your example).
To be more clear, in your example, you have the following:
But I want to work with availabilities, so I need to convert{-code-2}
and{-code-3}
into an{-code-4}
array, which should be, in this example, the following:
{-code-4} = [
['09:00:00', '10:00:00'],
['10:30:00', '13:00:00'],
['14:00:00', '15:30:00'],
['16:15:00', '18:00:00']
];
I am going to use Carbon for this example implementation. I am going to do a raw implementation of the functionality, then I will refactor into a proper class.
The first thing I needed was an array of breaks. A break is a period during which you are not available. For instance, between 13h00 and 14h00 because it's a business hour pause, and between 10h00 and 10h30 because of an appointment.
So, to put it simply, the breaks are a mapping of the last item of each{-code-2}
's entry and the first item of the next one, as well as every{-code-3}
entry.
Because of this, I need to create a function that returns such mapping. Here is that function:
{-code-8}
This is not a good code, but it gets the work done (and I'll refactor later). This function loops through the given array, takes it last value and the first value of the next one, and add them in another array.
Additionally, it keeps track of the first element and the last element.
Using this function on{-code-2}
, I get the following array:
{-code-10}
Which is exactly what I want. Combined to{-code-3}
, I now have all of the breaks:
{-code-12}
You can notice how they are not in order. To fix that, I use to sort by the first hour in each array:
{-code-13}({-code-18}, fn ($a, $b) => $a[0] {-code-15} $b[0]);
Note: if you didn't know about it,
{-code-15}
is the spaceship operator.
Now that we have the breaks, we can use the same pattern we used on{-code-2}
to get your availabilities.
Because you are available when you are not in break, I just have to reuse the{-code-17}
function on{-code-18}
to get a mapping of the periods during which you are not in a pause nor at an appointment.
Earlier, I used it on{-code-2}
like the following:
[{-code-18}, $startOfDay, $endOfDay] = {-code-17}({-code-2});
Now, I will use it on{-code-18}
like the following:
[{-code-4}, $first, $last] = {-code-17}({-code-18});
Thanks to these two calls, I can have a complete{-code-4}
array:
{-code-4} = [
[$startOfDay, $first],
...{-code-4},
[$last, $endOfDay]
];
Now that we have what we needed, we need to think about the initial problematic: you need to get an array of slots. Earlier, I explained that you could generate it thanks to the slot duration, which is, in this case, of 15 minutes.
To do this, I will create a{-code-25}
function:
function {-code-25}($start, $end) {
$slotDuration = 15;
$start = Carbon::createFromTimeString($start);
$end = Carbon::createFromTimeString($end);
$slotCount = (int) ($start->diffInMinutes($end) / $slotDuration);
$slots = [];
for ($i = 0; $i < $slotCount; $i++) {
$slots[] = [
$start->format('H:i:s'),
$start->addMinutes($slotDuration)->format('H:i:s')
];
}
return $slots;
}
The interesting part is how I get to know the amount of slots for the given starting time, by getting the difference, in minutes, between the ending time and the starting time, and by dividing that amount by the duration of the slot.
For instance, if you are free from 14:00:00 to 16:00:00, the difference in minutes between the two will be 120. Divided by 15, we know that you have 8 slots of 15 minutes of availability.
Next thing, we loop 8 times to add these periods to an array.
Last thing we need to do is to call{-code-25}
for every availability period. This is quite simple:
function generate_slot_array_from_availability_array({-code-4}) {
$slots = [];
foreach ({-code-4} as [$start, $end]) {
$slots = array_merge(
$slots,
{-code-25}($start, $end)
);
}
return $slots;
}
This is it. When called with the{-code-4}
array, this function will return exactly what you wanted: an array of slots, excluding the business hour breaks and the appointments.
generate_slot_array_from_availability_array({-code-4});
Here is the full procedural code, the first one that I implemented to get the functionality ready: https://phpsandbox.io/e/x/jolly-sun-d875
Here is the full, cleaned up, object-oriented, fluent code that I refactorised from the procedural one: https://phpsandbox.io/e/x/quiet-snow-x2xq
{-code-31}
<?php
namespace Calendar;
use Carbon\Carbon;
class Calendar
{
protected array {-code-2};
protected array {-code-3};
protected array {-code-4};
public function __construct()
{
$this->businessHours = [];
$this->appointments = [];
$this->availability = [];
}
/*
|
{-code-33}
{-code-34}
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Find the answer in similar questions on our website.
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.
PHP (from the English Hypertext Preprocessor - hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/
Welcome to the Q&A site for web developers. Here you can ask a question about the problem you are facing and get answers from other experts. We have created a user-friendly interface so that you can quickly and free of charge ask a question about a web programming problem. We also invite other experts to join our community and help other members who ask questions. In addition, you can use our search for questions with a solution.
Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.
Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.