/** * Output the calendar view */ public function output() { wp_enqueue_script('chosen'); $product_filter = isset($_REQUEST['filter_bookings']) ? absint($_REQUEST['filter_bookings']) : ''; $view = isset($_REQUEST['view']) && $_REQUEST['view'] == 'day' ? 'day' : 'month'; if ($view == 'day') { $day = isset($_REQUEST['calendar_day']) ? wc_clean($_REQUEST['calendar_day']) : date('Y-m-d'); $this->bookings = WC_Bookings_Controller::get_bookings_in_date_range(strtotime('midnight', strtotime($day)), strtotime('midnight +1 day', strtotime($day)), $product_filter); } else { $month = isset($_REQUEST['calendar_month']) ? absint($_REQUEST['calendar_month']) : date('n'); $year = isset($_REQUEST['calendar_year']) ? absint($_REQUEST['calendar_year']) : date('Y'); if ($year < date('Y') - 10 || $year > 2100) { $year = date('Y'); } if ($month > 12) { $month = 1; $year++; } if ($month < 1) { $month = 1; $year--; } $start_week = (int) date('W', strtotime("first day of {$year}-{$month}")); $end_week = (int) date('W', strtotime("last day of {$year}-{$month}")); if ($end_week == 1) { $end_week = 53; } $this->bookings = WC_Bookings_Controller::get_bookings_in_date_range(strtotime($year . 'W' . str_pad($start_week, 2, '0', STR_PAD_LEFT)), strtotime($year . 'W' . str_pad($end_week + 1, 2, '0', STR_PAD_LEFT)), $product_filter); } include 'views/html-calendar-' . $view . '.php'; wc_enqueue_js('$( "select#calendar-bookings-filter" ).chosen();'); }
/** * Output the calendar view */ public function output() { if (version_compare(WOOCOMMERCE_VERSION, '2.3', '<')) { wp_enqueue_script('chosen'); wc_enqueue_js('$( "select#calendar-bookings-filter" ).chosen();'); } else { wp_enqueue_script('wc-enhanced-select'); } $product_filter = isset($_REQUEST['filter_bookings']) ? absint($_REQUEST['filter_bookings']) : ''; $view = isset($_REQUEST['view']) && $_REQUEST['view'] == 'day' ? 'day' : 'month'; if ($view == 'day') { $day = isset($_REQUEST['calendar_day']) ? wc_clean($_REQUEST['calendar_day']) : date('Y-m-d'); $this->bookings = WC_Bookings_Controller::get_bookings_in_date_range(strtotime('midnight', strtotime($day)), strtotime('midnight +1 day', strtotime($day)), $product_filter); } else { $month = isset($_REQUEST['calendar_month']) ? absint($_REQUEST['calendar_month']) : date('n'); $year = isset($_REQUEST['calendar_year']) ? absint($_REQUEST['calendar_year']) : date('Y'); if ($year < date('Y') - 10 || $year > 2100) { $year = date('Y'); } if ($month > 12) { $month = 1; $year++; } if ($month < 1) { $month = 1; $year--; } $start_of_week = absint(get_option('start_of_week', 1)); $last_day = date('t', strtotime("{$year}-{$month}-01")); $start_date_w = absint(date('w', strtotime("{$year}-{$month}-01"))); $end_date_w = absint(date('w', strtotime("{$year}-{$month}-{$last_day}"))); // Calc day offset $day_offset = $start_date_w - $start_of_week; $day_offset = $day_offset >= 0 ? $day_offset : 7 - abs($day_offset); // Cald end day offset $end_day_offset = 7 - $last_day % 7 - $day_offset; $end_day_offset = $end_day_offset >= 0 && $end_day_offset < 7 ? $end_day_offset : 7 - abs($end_day_offset); $start_timestamp = strtotime("-{$day_offset} day", strtotime("{$year}-{$month}-01")); $end_timestamp = strtotime("+{$end_day_offset} day", strtotime("{$year}-{$month}-{$last_day}")); $this->bookings = WC_Bookings_Controller::get_bookings_in_date_range($start_timestamp, $end_timestamp, $product_filter); } include 'views/html-calendar-' . $view . '.php'; }
/** * Get existing bookings in a given date range * * @param string $start-date * @param string $end_date * @param int $resource_id * @return array */ public function get_bookings_in_date_range($start_date, $end_date, $resource_id = null) { if ($this->has_resources() && $resource_id) { return WC_Bookings_Controller::get_bookings_in_date_range($start_date, $end_date, $resource_id); } else { return WC_Bookings_Controller::get_bookings_in_date_range($start_date, $end_date, $this->id); } }
/** * Return an array of resources which can be booked for a defined start/end date * @param string $start_date * @param string $end_date * @param int $resource_id * @param integer $qty being booked * @return bool|WP_ERROR if no blocks available, or int count of bookings that can be made, or array of available resources */ public function get_available_bookings($start_date, $end_date, $resource_id = '', $qty = 1) { // Check the date is not in the past if (date('Ymd', $start_date) < date('Ymd', current_time('timestamp'))) { return false; } // Check we have a resource if needed $booking_resource = $resource_id ? $this->get_resource($resource_id) : null; if ($this->has_resources() && !is_numeric($resource_id)) { return false; } $min_date = $this->get_min_date(); $max_date = $this->get_max_date(); $check_from = strtotime("midnight +{$min_date['value']} {$min_date['unit']}", current_time('timestamp')); $check_to = strtotime("midnight +{$max_date['value']} {$max_date['unit']}", current_time('timestamp')); // Min max checks if ('month' === $this->get_duration_unit()) { $check_to = strtotime('midnight', strtotime(date('Y-m-t', $check_to))); } if ($end_date < $check_from || $start_date > $check_to) { return false; } // Get availability of each resource - no resource has been chosen yet if ($this->has_resources() && !$resource_id) { $resources = $this->get_resources(); $available_resources = array(); foreach ($resources as $resource) { $availability = $this->get_available_bookings($start_date, $end_date, $resource->ID, $qty); if ($availability && !is_wp_error($availability)) { $available_resources[$resource->ID] = $availability; } } if (empty($available_resources)) { return new WP_Error('Error', __('This block cannot be booked.', 'woocommerce-bookings')); } return $available_resources; // If we are checking for bookings for a specific resource, or have none... } else { $available_qtys = array(); $check_date = $start_date; while ($check_date < $end_date) { if (!$this->check_availability_rules_against_date($check_date, $resource_id)) { return false; } if ('start' === $this->wc_booking_check_availability_against) { break; // Only need to check first day } $check_date = strtotime("+1 day", $check_date); } if (in_array($this->get_duration_unit(), array('minute', 'hour')) && !$this->check_availability_rules_against_time($start_date, $end_date, $resource_id)) { return false; } $blocks = $this->get_blocks_in_range($start_date, $end_date, '', $resource_id); if (!$blocks) { return false; } /** * Grab all existing bookings for the date range * @var array */ if ($this->has_resources() && $resource_id) { $existing_bookings = WC_Bookings_Controller::get_bookings_in_date_range($start_date, $end_date, $resource_id); } else { $existing_bookings = WC_Bookings_Controller::get_bookings_in_date_range($start_date, $end_date, $this->id); } foreach ($blocks as $block) { $available_qty = $this->has_resources() && $booking_resource->has_qty() ? $booking_resource->get_qty() : $this->get_qty(); $qty_booked_in_block = 0; foreach ($existing_bookings as $existing_booking) { if ($existing_booking->is_booked_on_day($block)) { $qty_to_add = $this->has_person_qty_multiplier() ? max(1, array_sum($existing_booking->get_persons())) : 1; if ($this->has_resources()) { if ($existing_booking->get_resource_id() === absint($resource_id) || !$booking_resource->has_qty() && $existing_booking->get_resource() && !$existing_booking->get_resource()->has_qty()) { $qty_booked_in_block += $qty_to_add; } } else { $qty_booked_in_block += $qty_to_add; } } } $available_qty = $available_qty - $qty_booked_in_block; if ($available_qty < $qty) { if (in_array($this->get_duration_unit(), array('hour', 'minute'))) { return new WP_Error('Error', sprintf(_n('There is %d place remaining', 'There are %d places remaining', $available_qty, 'woocommerce-bookings'), $available_qty)); } elseif (!$available_qtys) { return new WP_Error('Error', sprintf(_n('There is %d place remaining on %s', 'There are %d places remaining on %s', $available_qty, 'woocommerce-bookings'), $available_qty, date_i18n(get_option('date_format'), $block))); } else { return new WP_Error('Error', sprintf(_n('There is %d place remaining on %s', 'There are %d places remaining on %s', $available_qty, 'woocommerce-bookings'), max($available_qtys), date_i18n(get_option('date_format'), $block))); } } $available_qtys[] = $available_qty; } return min($available_qtys); } }