1, 'Tue' => 2, 'Wed' => 3, 'Thu' => 4, 'Fri' => 5, 'Sat' => 6, 'Sun' => 7, ); /** * WP Database instance * * @var Database_Interface */ private $database; /** * Schedule data * * @var array */ private $schedule_data; /** * Construct object and set schedule data * * @param $schedule_data */ private function __construct( $schedule_data ) { $this->database = new Booktics_Database(); $this->schedule_data = $schedule_data; $this->init( $this->schedule_data['schedule'] ?? array(), $this->schedule_data['custom'] ?? array(), $this->schedule_data['holiday'] ?? array() ); } /** * Make a schedule manager instance * * @param $schedule_data * * @return self */ public static function make( $schedule_data ): self { return new static( $schedule_data ); } /** * Initialize schedules, Custom Schedules and holidays * * @param $schedules * @param $custom_schedules * @param $holidays * * @return void */ private function init( $schedules, $custom_schedules, $holidays ): void { $this->schedules = $schedules; if ( ! empty( $custom_schedules ) ) { foreach ( $custom_schedules as $custom_data ) { if ( ! is_array( $custom_data ) || count( $custom_data ) < 2 ) { continue; } $start = $custom_data[0]; $end = $custom_data[1]; if ( ! isset( $custom_data[2] ) ) { $end = $start; $time_period = $custom_data[1]; } else { $time_period = $custom_data[2]; } $this->add_custom_schedule( $start, $end, $time_period ); } } if ( ! empty( $holidays ) ) { foreach ( $holidays as $holiday_data ) { if ( ! is_array( $holiday_data ) || empty( $holiday_data ) ) { continue; } $start = $holiday_data[0]; $end = $holiday_data[1] ?? $holiday_data[0]; $this->with_holidays( $start, $end ); } } } /** * Set team member id for team member schedule * * @param int $team_member_id * * @return $this */ public function with_team_member_id( int $team_member_id ): self { if ( $team_member_id <= 0 ) { throw new InvalidArgumentException( 'Team member ID must be positive' ); } $this->team_member_id = $team_member_id; return $this; } /** * Set service id for service schedule * * @param int $service_id * * @return $this */ public function with_service_id( int $service_id ): self { if ( $service_id <= 0 ) { throw new InvalidArgumentException( 'Service ID must be positive' ); } $this->service_id = $service_id; return $this; } /** * Set schedule map to store * * @param array $schedules * * @return $this */ public function with_schedules( array $schedules ): self { $this->schedules = $schedules; return $this; } /** * Set holidays map to store * * @param string $start_date * @param string $end_date * * @return $this */ public function with_holidays( string $start_date, string $end_date ): self { $this->holidays[] = array( 'start_date' => $start_date, 'end_date' => $end_date, ); return $this; } /** * Set a custom schedule map to store * * @param string $start_date * @param string $end_date * @param array $schedule * * @return $this */ public function add_custom_schedule( string $start_date, string $end_date, array $schedule ): self { $this->custom_schedules[] = array( 'start_date' => $start_date, 'end_date' => $end_date, 'schedule' => $schedule, ); return $this; } /** * Execute schedule save action * * @return void * @throws Exception */ public function save(): void { $this->database->begin_transaction(); try { $this->clear_existing_schedules(); $this->save_schedules(); $this->database->commit(); } catch ( Exception $e ) { $this->database->roll_back(); throw $e; } } /** * Remove existing schedules from database * * @return void */ private function clear_existing_schedules(): void { $this->database->delete( 'booktics_schedules', array( 'service_id' => $this->service_id, 'team_member_id' => $this->team_member_id, ) ); } /** * Insert Schedule into database * * @return void * @throws Exception */ private function save_schedules(): void { $records = $this->build_schedule_records(); if ( empty( $records ) ) { return; } $this->database->insert_batch( 'booktics_schedules', $records ); } /** * build map for schedule records * * @return array * @throws Exception */ private function build_schedule_records(): array { $records = array(); foreach ( $this->schedules as $day_name => $day_values ) { $formatted_day_name = ucfirst( substr( strtolower( $day_name ), 0, 3 ) ); $day_number = static::$day_map[ $formatted_day_name ]; foreach ( $day_values as $day_value ) { $records[] = $this->create_schedule_record( $day_value['start_time'] ?? '0', $day_value['end_time'] ?? '0', $day_number, 0 ); } } if ( count( $this->custom_schedules ) > 0 ) { foreach ( $this->custom_schedules as $custom_schedule ) { $dates = booktics_date_range_loop( $custom_schedule['start_date'], $custom_schedule['end_date'] ); foreach ( $dates as $date ) { $day_name = ( new DateTime( $date ) )->format( 'D' ); $day_number = static::$day_map[ $day_name ]; $records[] = $this->create_schedule_record( $custom_schedule['schedule']['start_time'], $custom_schedule['schedule']['end_time'], $day_number, $date ); } } } foreach ( $this->holidays as $holiday ) { $dates = booktics_date_range_loop( $holiday['start_date'], $holiday['end_date'] ); foreach ( $dates as $date ) { $day_name = ( new DateTime( $date ) )->format( 'D' ); $day_number = static::$day_map[ $day_name ]; $records[] = $this->create_schedule_record( '0', '0', $day_number, $date ); } } return $records; } /** * Format schedule records * * @param string $start_time * @param string $end_time * @param string $week_day * @param string $custom_date * * @return array */ private function create_schedule_record( string $start_time, string $end_time, string $week_day, string $custom_date ): array { return array( 'team_member_id' => $this->team_member_id, 'service_id' => $this->service_id, 'start_time' => $start_time, 'end_time' => $end_time, 'week_day' => $week_day, 'custom_date' => $custom_date, ); } }