/** * Checks booking data is correctly set, and that the chosen blocks are indeed available. * * @param array $data * @return WP_Error on failure, true on success */ public function is_bookable($data) { // Validate resources are set if ($this->product->has_resources() && $this->product->is_resource_assignment_type('customer')) { if (empty($data['_resource_id'])) { return new WP_Error('Error', __('Please choose a resource type', 'woocommerce-bookings')); } } elseif ($this->product->has_resources() && $this->product->is_resource_assignment_type('automatic')) { $data['_resource_id'] = 0; } else { $data['_resource_id'] = ''; } // Validate customer set durations if ($this->product->is_duration_type('customer')) { if (empty($data['_duration'])) { return new WP_Error('Error', __('Duration is required - please enter a duration greater than zero above', 'woocommerce-bookings')); } if ($data['_duration'] > $this->product->get_max_duration()) { return new WP_Error('Error', sprintf(__('The maximum duration is %d', 'woocommerce-bookings'), $this->product->wc_booking_max_duration)); } if ($data['_duration'] < $this->product->get_min_duration()) { return new WP_Error('Error', sprintf(__('The minimum duration is %d', 'woocommerce-bookings'), $this->product->wc_booking_min_duration)); } } // Validate date and time if (empty($data['date'])) { return new WP_Error('Error', __('Date is required - please choose one above', 'woocommerce-bookings')); } if (in_array($this->product->get_duration_unit(), array('minute', 'hour')) && empty($data['time'])) { return new WP_Error('Error', __('Time is required - please choose one above', 'woocommerce-bookings')); } if ($data['_date'] && date('Ymd', strtotime($data['_date'])) < date('Ymd', current_time('timestamp'))) { return new WP_Error('Error', __('You must choose a future date and time.', 'woocommerce-bookings')); } if ($data['_date'] && !empty($data['_time']) && date('YmdHi', strtotime($data['_date'] . ' ' . $data['_time'])) < date('YmdHi', current_time('timestamp'))) { return new WP_Error('Error', __('You must choose a future date and time.', 'woocommerce-bookings')); } // Validate min date and max date if (in_array($this->product->get_duration_unit(), array('minute', 'hour'))) { $now = current_time('timestamp'); } elseif ('month' === $this->product->get_duration_unit()) { $now = strtotime('midnight first day of this month', current_time('timestamp')); } else { $now = strtotime('midnight', current_time('timestamp')); } if ($min = $this->product->get_min_date()) { $min_date = $this->product->get_min_timestamp_for_date(strtotime($data['date'])); if (strtotime($data['_date'] . ' ' . $data['_time']) < $min_date) { return new WP_Error('Error', sprintf(__('The earliest booking possible is currently %s.', 'woocommerce-bookings'), date_i18n(wc_date_format() . ' ' . get_option('time_format'), $min_date))); } } if ($max = $this->product->get_max_date()) { $max_date = strtotime("+{$max['value']} {$max['unit']}", $now); if (strtotime($data['_date'] . ' ' . $data['_time']) > $max_date) { return new WP_Error('Error', sprintf(__('The latest booking possible is currently %s.', 'woocommerce-bookings'), date_i18n(wc_date_format() . ' ' . get_option('time_format'), $max_date))); } } // Validate persons if ($this->product->has_persons()) { $persons = array_sum($data['_persons']); if (empty($persons)) { return new WP_Error('Error', __('Persons are required - please enter the number of persons above', 'woocommerce-bookings')); } if ($this->product->get_max_persons() && $persons > $this->product->get_max_persons()) { return new WP_Error('Error', sprintf(__('The maximum persons per group is %d', 'woocommerce-bookings'), $this->product->wc_booking_max_persons_group)); } if ($persons < $this->product->get_min_persons()) { return new WP_Error('Error', sprintf(__('The minimum persons per group is %d', 'woocommerce-bookings'), $this->product->wc_booking_min_persons_group)); } if ($this->product->has_person_types()) { $person_types = $this->product->get_person_types(); foreach ($person_types as $person) { $person_max = get_post_meta($person->ID, 'max', true); if (is_numeric($person_max) && isset($data['_persons'][$person->ID]) && $data['_persons'][$person->ID] > $person_max) { return new WP_Error('Error', sprintf(__('The maximum %s per group is %d', 'woocommerce-bookings'), $person->post_title, $person_max)); } $person_min = get_post_meta($person->ID, 'min', true); if (is_numeric($person_min) && isset($data['_persons'][$person->ID]) && $data['_persons'][$person->ID] < $person_min) { return new WP_Error('Error', sprintf(__('The minimum %s per group is %d', 'woocommerce-bookings'), $person->post_title, $person_min)); } } } } // Get availability for the dates $available_bookings = $this->product->get_available_bookings($data['_start_date'], $data['_end_date'], $data['_resource_id'], $data['_qty']); if (is_array($available_bookings)) { $this->auto_assigned_resource_id = current(array_keys($available_bookings)); } if (is_wp_error($available_bookings)) { return $available_bookings; } elseif (!$available_bookings) { return new WP_Error('Error', __('Sorry, the selected block is not available', 'woocommerce-bookings')); } return true; }