PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.2
Booktics – Appointment Booking Calendar for Service Businesses v1.0.2
1.0.29 1.0.28 1.0.27 1.0.26 1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.2 1.0.3 All 31 releases
booktics / core / appointment / schedule / time-slot-manager.php

time-slot-manager.php in Booktics – Appointment Booking Calendar for Service Businesses 1.0.2, at core/appointment/schedule/time-slot-manager.php

217 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Time_Slot_Manager class
4 *
5 * @package Booktics\Appointment\Schedule
6 */
7
8 namespace Booktics\Appointment\Schedule;
9
10 use Booktics\Models\Appointment_Model;
11 use DateTime;
12 use Exception;
13
14 /**
15 * Class Time_Slot_Manager
16 */
17 class Time_Slot_Manager {
18 /**
19 * Store Service Schedule Object
20 *
21 * @var Service_Schedule
22 */
23 private $service_schedule;
24
25 /**
26 * Store Team member Schedule Object
27 *
28 * @var Team_Member_Schedule
29 */
30 private $team_member_schedule;
31
32 /**
33 * Store Default Schedule Object
34 *
35 * @var Default_Schedule
36 */
37 private $default_schedule;
38
39 /**
40 * Store service duration in minutes
41 *
42 * @var integer
43 */
44 private $service_duration;
45
46 /**
47 * Store slot length in minutes
48 *
49 * @var integer
50 */
51 private $slot_length;
52
53 /**
54 * Store time format (12 or 24 hour)
55 *
56 * @var string
57 */
58 private $slot_format = '12'; // Default to 12 hour format.
59
60 /**
61 * Constructor
62 *
63 * @param Service_Schedule $service Service schedule object.
64 * @param Team_Member_Schedule $team_member Team member schedule object.
65 * @param Default_Schedule $default_schedule Default schedule object.
66 * @param integer $service_duration Service duration in minutes.
67 * @param integer $slot_length Slot length in minutes.
68 */
69 public function __construct( Service_Schedule $service, Team_Member_Schedule $team_member, Default_Schedule $default_schedule = null, int $service_duration = 30, int $slot_length = 30 ) {
70 $this->service_schedule = $service;
71 $this->team_member_schedule = $team_member;
72 $this->default_schedule = $default_schedule;
73 $this->service_duration = $service_duration;
74 $this->slot_length = $slot_length;
75 }
76
77 /**
78 * Generate time slots for a specific date
79 *
80 * @param DateTime $date
81 *
82 * @return array
83 */
84 public function generate_slots( DateTime $date ): array {
85 $service_entry = $this->service_schedule->get_first_date( $date );
86 $team_member_entry = $this->team_member_schedule->get_first_date( $date );
87 $default_entry = $this->default_schedule ? $this->default_schedule->get_first_date( $date ) : null;
88
89 $strategy = Time_Slot_Strategy_Factory::get_strategy($service_entry, $team_member_entry, $default_entry);
90 return $strategy->generate_slots($service_entry, $team_member_entry, $default_entry, $this, $date);
91 }
92
93 /**
94 * Generate time slots for a date range.
95 *
96 * Creates an array of available time slots for each day in the given date range.
97 * The slots are marked as booked if they overlap with existing appointments.
98 *
99 * @param string $start_date Start date for the date range in Y-m-d format
100 * @param string $end_date End date for the date range in Y-m-d format
101 *
102 * @return array Collection of daily time slots indexed by date in Y-m-d format
103 * @throws Exception When date parsing fails or invalid date range is provided
104 */
105 public function generate_slots_for_range( string $start_date, string $end_date ): array {
106 $slots_by_day = [];
107 $start = new DateTime( $start_date );
108 $end = new DateTime( $end_date );
109
110 while ( $start <= $end ) {
111 $daily_slots = $this->generate_slots( clone $start );
112 $slots_by_day[ $start->format( 'Y-m-d' ) ] = $this->mark_booked_slots( clone $start, $daily_slots );
113 $start->modify( '+1 day' );
114 }
115
116 return $slots_by_day;
117 }
118
119 /**
120 * Get all available slots
121 *
122 * @param DateTime $date
123 *
124 * @return array
125 * @throws Exception
126 */
127 public function get_available_slots( DateTime $date ): array {
128 $slots = $this->generate_slots( $date );
129 $slots = $this->mark_booked_slots( $date, $slots );
130
131 return array_filter( $slots, fn( $slot ) => $slot->is_available );
132 }
133
134 /**
135 * Mark booked slots
136 *
137 * @param DateTime $date
138 * @param array $slots
139 *
140 * @return array
141 * @throws Exception
142 */
143 public function mark_booked_slots( DateTime $date, array $slots ): array {
144 $booked_slots = $this->get_booked_slots( $date );
145 foreach ( $slots as $slot ) {
146 $slot_start = strtotime( $slot->start );
147 $slot_end = strtotime( $slot->end );
148
149 foreach ( $booked_slots as $booked ) {
150 $booked_start = strtotime( $booked['start'] );
151 $booked_end = strtotime( $booked['end'] );
152 if ( $slot_start < $booked_end && $slot_end > $booked_start ) {
153 if ( $booked['team_member_id'] == $this->team_member_schedule->get_id() ) {
154 $slot->is_available = false;
155 break;
156 }
157 }
158 }
159 }
160
161 return $slots;
162 }
163
164 /**
165 * Get booked slots
166 *
167 * @param DateTime $date
168 *
169 * @return array
170 * @throws Exception
171 */
172 private function get_booked_slots( DateTime $date ): array {
173 $appointments = ( new Appointment_Model() )
174 ->get_appointments_for_slot(
175 $date->format( 'Y-m-d' ),
176 $this->team_member_schedule->get_id()
177 );
178
179 return array_map(
180 function ( $appointment ) use ( $date ) {
181 $start_time = strtotime( $appointment->start_time );
182 $appointment_duration = 30;
183 if ( $appointment->duration ) {
184 $appointment_duration = $appointment->duration;
185 }
186 $actual_end_time = $start_time + ( $appointment_duration * 60 );
187
188 return array(
189 'start' => date_i18n( 'H:i', $start_time ),
190 'end' => date_i18n( 'H:i', $actual_end_time ),
191 'service_id' => $appointment->service_id,
192 'team_member_id' => $appointment->team_member_id,
193 );
194 },
195 $appointments
196 );
197 }
198
199 /**
200 * Get the length of time slots in minutes
201 *
202 * @return integer Slot length in minutes
203 */
204 public function get_slot_length(): int {
205 return $this->slot_length;
206 }
207
208
209 /**
210 * Get the service duration in minutes
211 *
212 * @return integer Service duration in minutes
213 */
214 public function get_service_duration(): int {
215 return $this->service_duration;
216 }
217 }