prefix . 'yacht_availability'; // Get all dates in range that are not available $unavailable = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $table WHERE yacht_id = %d AND date >= %s AND date < %s AND status != 'available'", $yacht_id, $start_date, $end_date ) ); return 0 === (int) $unavailable; } /** * Mark dates as booked * * @param int $yacht_id Yacht post ID. * @param string $start_date Start date (Y-m-d). * @param string $end_date End date (Y-m-d). * @param int $booking_id Booking post ID. * @return bool */ public static function mark_as_booked( $yacht_id, $start_date, $end_date, $booking_id ) { global $wpdb; $table = $wpdb->prefix . 'yacht_availability'; $dates = self::get_date_range( $start_date, $end_date ); foreach ( $dates as $date ) { $wpdb->replace( $table, array( 'yacht_id' => $yacht_id, 'date' => $date, 'status' => 'booked', 'booking_id' => $booking_id, 'created_at' => current_time( 'mysql' ), 'updated_at' => current_time( 'mysql' ), ), array( '%d', '%s', '%s', '%d', '%s', '%s' ) ); } return true; } /** * Mark dates as blocked (from Google Calendar sync) * * @param int $yacht_id Yacht post ID. * @param string $start_date Start date (Y-m-d). * @param string $end_date End date (Y-m-d). * @return bool */ public static function mark_as_blocked( $yacht_id, $start_date, $end_date ) { global $wpdb; $table = $wpdb->prefix . 'yacht_availability'; $dates = self::get_date_range( $start_date, $end_date ); foreach ( $dates as $date ) { $wpdb->replace( $table, array( 'yacht_id' => $yacht_id, 'date' => $date, 'status' => 'blocked', 'booking_id' => null, 'created_at' => current_time( 'mysql' ), 'updated_at' => current_time( 'mysql' ), ), array( '%d', '%s', '%s', '%d', '%s', '%s' ) ); } return true; } /** * Mark dates as available (when booking is cancelled) * * @param int $yacht_id Yacht post ID. * @param string $start_date Start date (Y-m-d). * @param string $end_date End date (Y-m-d). * @return bool */ public static function mark_as_available( $yacht_id, $start_date, $end_date ) { global $wpdb; $table = $wpdb->prefix . 'yacht_availability'; $wpdb->delete( $table, array( 'yacht_id' => $yacht_id, ), array( '%d' ) ); // Alternative: update to available instead of delete // $dates = self::get_date_range( $start_date, $end_date ); // foreach ( $dates as $date ) { // $wpdb->update( // $table, // array( 'status' => 'available', 'booking_id' => null ), // array( 'yacht_id' => $yacht_id, 'date' => $date ), // array( '%s', '%d' ), // array( '%d', '%s' ) // ); // } return true; } /** * Clear availability for booking * * @param int $booking_id Booking post ID. * @return bool */ public static function clear_booking_availability( $booking_id ) { global $wpdb; $table = $wpdb->prefix . 'yacht_availability'; $wpdb->delete( $table, array( 'booking_id' => $booking_id ), array( '%d' ) ); return true; } /** * Get availability calendar for yacht and month * * @param int $yacht_id Yacht post ID. * @param string $start Start date (Y-m-d). * @param string $end End date (Y-m-d). * @return array */ public static function get_availability_calendar( $yacht_id, $start, $end ) { global $wpdb; $table = $wpdb->prefix . 'yacht_availability'; $results = $wpdb->get_results( $wpdb->prepare( "SELECT date, status, booking_id FROM $table WHERE yacht_id = %d AND date >= %s AND date <= %s ORDER BY date ASC", $yacht_id, $start, $end ), ARRAY_A ); // Create associative array with date as key $calendar = array(); foreach ( $results as $row ) { $calendar[ $row['date'] ] = array( 'status' => $row['status'], 'booking_id' => $row['booking_id'], ); } // Fill in missing dates as available $all_dates = self::get_date_range( $start, $end ); foreach ( $all_dates as $date ) { if ( ! isset( $calendar[ $date ] ) ) { $calendar[ $date ] = array( 'status' => 'available', 'booking_id' => null, ); } } return $calendar; } /** * Count days between two dates * * @param string $start_date Start date (Y-m-d). * @param string $end_date End date (Y-m-d). * @return int */ public static function count_days( $start_date, $end_date ) { $start = new \DateTime( $start_date ); $end = new \DateTime( $end_date ); $diff = $start->diff( $end ); return (int) $diff->days; } /** * Get array of dates between start and end (exclusive of end date) * * @param string $start_date Start date (Y-m-d). * @param string $end_date End date (Y-m-d). * @return array */ private static function get_date_range( $start_date, $end_date ) { $dates = array(); $start = new \DateTime( $start_date ); $end = new \DateTime( $end_date ); while ( $start < $end ) { $dates[] = $start->format( 'Y-m-d' ); $start->modify( '+1 day' ); } return $dates; } }