PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.23
Booktics – Appointment Booking Calendar for Service Businesses v1.0.23
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 / base / services / schedule-manager.php

schedule-manager.php in Booktics – Appointment Booking Calendar for Service Businesses 1.0.23, at base/services/schedule-manager.php

377 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Booktics\Services;
4
5 use Booktics\Abstracts\Booktics_Database;
6 use Booktics\Contracts\Database_Interface;
7 use DateTime;
8 use Exception;
9 use InvalidArgumentException;
10
11 /**
12 * Schedule Manager for team member and service
13 *
14 * @package Booktics/Services
15 */
16 class Schedule_Manager {
17
18 /**
19 * Store Team member id
20 *
21 * @var int
22 */
23 private $team_member_id = 0;
24
25 /**
26 * Store Service id
27 *
28 * @var int
29 */
30 private $service_id = 0;
31
32 /**
33 * Store duration of each slot
34 *
35 * @var int
36 */
37 private $duration = 30;
38
39 /**
40 * Store schedules map
41 *
42 * @var array
43 */
44 private $schedules = array();
45
46 /**
47 * Store custom schedule map
48 *
49 * @var array
50 */
51 private $custom_schedules = array();
52
53 /**
54 * Store holidays map
55 *
56 * @var array
57 */
58 private $holidays = array();
59
60 /**
61 * Week day map
62 *
63 * @var array
64 */
65 public static $day_map = array(
66 'Mon' => 1,
67 'Tue' => 2,
68 'Wed' => 3,
69 'Thu' => 4,
70 'Fri' => 5,
71 'Sat' => 6,
72 'Sun' => 7,
73 );
74
75 /**
76 * WP Database instance
77 *
78 * @var Database_Interface
79 */
80 private $database;
81
82 /**
83 * Schedule data
84 *
85 * @var array
86 */
87 private $schedule_data;
88
89 /**
90 * Construct object and set schedule data
91 *
92 * @param $schedule_data
93 */
94 private function __construct( $schedule_data ) {
95 $this->database = new Booktics_Database();
96 $this->schedule_data = $schedule_data;
97 if ( ! isset( $this->schedule_data['enable_custom_holiday'] ) || ! $this->schedule_data['enable_custom_holiday'] ) {
98 $this->schedule_data['holiday'] = array();
99 }
100 if ( ! isset( $this->schedule_data['enable_custom_schedule'] ) || ! $this->schedule_data['enable_custom_schedule'] ) {
101 $this->schedule_data['custom'] = array();
102 }
103 $this->init(
104 $this->schedule_data['schedule'] ?? array(),
105 $this->schedule_data['custom'] ?? array(),
106 $this->schedule_data['holiday'] ?? array()
107 );
108 }
109
110 /**
111 * Make a schedule manager instance
112 *
113 * @param $schedule_data
114 *
115 * @return self
116 */
117 public static function make( $schedule_data ): self {
118 return new static( $schedule_data );
119 }
120
121 /**
122 * Initialize schedules, Custom Schedules and holidays
123 *
124 * @param $schedules
125 * @param $custom_schedules
126 * @param $holidays
127 *
128 * @return void
129 */
130 private function init( $schedules, $custom_schedules, $holidays ): void {
131 $this->schedules = $schedules;
132
133 if ( ! empty( $custom_schedules ) ) {
134 foreach ( $custom_schedules as $custom_data ) {
135 if ( ! is_array( $custom_data ) || count( $custom_data ) < 2 ) {
136 continue;
137 }
138 $start = $custom_data[0];
139 $end = $custom_data[1];
140 if ( ! isset( $custom_data[2] ) ) {
141 $end = $start;
142 $time_period = $custom_data[1];
143 } else {
144 $time_period = $custom_data[2];
145 }
146
147 $this->add_custom_schedule( $start, $end, $time_period );
148 }
149 }
150
151 if ( ! empty( $holidays ) ) {
152 foreach ( $holidays as $holiday_data ) {
153 if ( ! is_array( $holiday_data ) || empty( $holiday_data ) ) {
154 continue;
155 }
156 $start = $holiday_data[0];
157 $end = $holiday_data[1] ?? $holiday_data[0];
158
159 $this->with_holidays( $start, $end );
160 }
161 }
162 }
163
164 /**
165 * Set team member id for team member schedule
166 *
167 * @param int $team_member_id
168 *
169 * @return $this
170 */
171 public function with_team_member_id( int $team_member_id ): self {
172 if ( $team_member_id <= 0 ) {
173 throw new InvalidArgumentException( 'Team member ID must be positive' );
174 }
175 $this->team_member_id = $team_member_id;
176
177 return $this;
178 }
179
180 /**
181 * Set service id for service schedule
182 *
183 * @param int $service_id
184 *
185 * @return $this
186 */
187 public function with_service_id( int $service_id ): self {
188 if ( $service_id <= 0 ) {
189 throw new InvalidArgumentException( 'Service ID must be positive' );
190 }
191 $this->service_id = $service_id;
192
193 return $this;
194 }
195
196 /**
197 * Set schedule map to store
198 *
199 * @param array $schedules
200 *
201 * @return $this
202 */
203 public function with_schedules( array $schedules ): self {
204 $this->schedules = $schedules;
205
206 return $this;
207 }
208
209 /**
210 * Set holidays map to store
211 *
212 * @param string $start_date
213 * @param string $end_date
214 *
215 * @return $this
216 */
217 public function with_holidays( string $start_date, string $end_date ): self {
218 $this->holidays[] = array(
219 'start_date' => $start_date,
220 'end_date' => $end_date,
221 );
222
223 return $this;
224 }
225
226 /**
227 * Set a custom schedule map to store
228 *
229 * @param string $start_date
230 * @param string $end_date
231 * @param array $schedule
232 *
233 * @return $this
234 */
235 public function add_custom_schedule( string $start_date, string $end_date, array $schedule ): self {
236 $this->custom_schedules[] = array(
237 'start_date' => $start_date,
238 'end_date' => $end_date,
239 'schedule' => $schedule,
240 );
241
242 return $this;
243 }
244
245 /**
246 * Execute schedule save action
247 *
248 * @return void
249 * @throws Exception
250 */
251 public function save(): void {
252 $this->database->begin_transaction();
253 try {
254 $this->clear_existing_schedules();
255 $this->save_schedules();
256 $this->database->commit();
257 } catch ( Exception $e ) {
258 $this->database->roll_back();
259 throw $e;
260 }
261 }
262
263 /**
264 * Remove existing schedules from database
265 *
266 * @return void
267 */
268 private function clear_existing_schedules(): void {
269 $this->database->delete(
270 booktics_get_table_name( 'booktics_schedules' ), array(
271 'service_id' => $this->service_id,
272 'team_member_id' => $this->team_member_id,
273 )
274 );
275 }
276
277 /**
278 * Insert Schedule into database
279 *
280 * @return void
281 * @throws Exception
282 */
283 private function save_schedules(): void {
284 $records = $this->build_schedule_records();
285
286 if ( empty( $records ) ) {
287 return;
288 }
289
290 $this->database->insert_batch( booktics_get_table_name( 'booktics_schedules' ), $records );
291 }
292
293 /**
294 * build map for schedule records
295 *
296 * @return array
297 * @throws Exception
298 */
299 private function build_schedule_records(): array {
300 $records = array();
301
302 foreach ( $this->schedules as $day_name => $day_values ) {
303 $formatted_day_name = ucfirst( substr( strtolower( $day_name ), 0, 3 ) );
304 $day_number = static::$day_map[ $formatted_day_name ];
305 foreach ( $day_values as $day_value ) {
306 $records[] = $this->create_schedule_record(
307 $day_value['start_time'] ?? '0',
308 $day_value['end_time'] ?? '0',
309 $day_number,
310 0
311 );
312 }
313 }
314
315 if ( count( $this->custom_schedules ) > 0 ) {
316 foreach ( $this->custom_schedules as $custom_schedule ) {
317 $dates = booktics_date_range_loop( $custom_schedule['start_date'], $custom_schedule['end_date'] );
318 foreach ( $dates as $date ) {
319 $day_name = ( new DateTime( $date ) )->format( 'D' );
320 $day_number = static::$day_map[ $day_name ];
321 $records[] = $this->create_schedule_record(
322 $custom_schedule['schedule']['start_time'],
323 $custom_schedule['schedule']['end_time'],
324 $day_number,
325 $date
326 );
327 }
328 }
329 }
330
331 foreach ( $this->holidays as $holiday ) {
332 $dates = booktics_date_range_loop( $holiday['start_date'], $holiday['end_date'] );
333 foreach ( $dates as $date ) {
334 $day_name = ( new DateTime( $date ) )->format( 'D' );
335 $day_number = static::$day_map[ $day_name ];
336 $records[] = $this->create_schedule_record(
337 '0',
338 '0',
339 $day_number,
340 $date
341 );
342 }
343 }
344
345 return $records;
346 }
347
348 /**
349 * Format schedule records
350 *
351 * @param string $start_time
352 * @param string $end_time
353 * @param string $week_day
354 * @param string $custom_date
355 *
356 * @return array
357 */
358 private function create_schedule_record(
359 string $start_time,
360 string $end_time,
361 string $week_day,
362 string $custom_date
363 ): array {
364 $utc_start_time = booktics_time_to_gmt( $start_time, $custom_date );
365 $utc_end_time = booktics_time_to_gmt( $end_time, $custom_date );
366
367 return array(
368 'team_member_id' => $this->team_member_id,
369 'service_id' => $this->service_id,
370 'start_time' => $utc_start_time,
371 'end_time' => $utc_end_time,
372 'week_day' => $week_day,
373 'custom_date' => $custom_date,
374 );
375 }
376 }
377