bookings = $bookings; $this->cart = $cart; } /** * Print the date fields shown when a dated line is edited. * * @since 1.0.1 * @param int $item_id Line identifier. * @param \WC_Order_Item $item Line shown. */ public function render( $item_id, $item ) { if ( ! $this->is_dated( $item ) || ! $item->get_order() || ! $item->get_order()->is_editable() ) { return; } $two = 'two' === Settings::get( 'dates', $item->get_product_id(), $item->get_variation_id() ); // The page refuses to save dates no stay could have, and says why with these words. $refusals = array( 'no-date' => __( 'Please choose a date.', 'abogo-booking' ), 'no-end' => __( 'Please choose an end date.', 'abogo-booking' ), 'reversed' => __( 'The end date cannot come before the start date.', 'abogo-booking' ), 'too-short' => __( 'Please choose at least one night.', 'abogo-booking' ), ); echo '
$text ) { echo ' data-' . esc_attr( $reason ) . '="' . esc_attr( $text ) . '"'; } echo '>'; $this->field( 'abfw_start', $item_id, $two ? __( 'Arrival', 'abogo-booking' ) : __( 'Date', 'abogo-booking' ), $item->get_meta( '_abfw_start' ) ); if ( $two ) { $this->field( 'abfw_end', $item_id, __( 'Departure', 'abogo-booking' ), $item->get_meta( '_abfw_end' ) ); } echo ''; echo '
'; } /** * Keep the raw booking data off the order screen, where the date fields stand for it. * * @since 1.0.1 * @param array $hidden Line data never shown on the order screen. * @return array */ public function hide_raw_dates( $hidden ) { return array_merge( $hidden, array( '_abfw_start', '_abfw_end', '_abfw_units' ) ); } /** * Apply the dates corrected on the lines of an order. * * @since 1.0.1 * @param int $order_id Order saved. * @param array $items Fields posted with the lines. */ public function save( $order_id, $items ) { $order = wc_get_order( $order_id ); if ( ! $order || ! $order->is_editable() || empty( $items['abfw_start'] ) || ! is_array( $items['abfw_start'] ) ) { return; } foreach ( $items['abfw_start'] as $item_id => $raw_start ) { $item = $order->get_item( absint( $item_id ) ); if ( ! $this->is_dated( $item ) ) { continue; } $start = sanitize_text_field( wp_unslash( $raw_start ) ); $has_end = isset( $items['abfw_end'][ $item_id ] ); $end = $has_end ? sanitize_text_field( wp_unslash( $items['abfw_end'][ $item_id ] ) ) : ''; $same_end = ! $has_end || $end === $item->get_meta( '_abfw_end' ); // Saving the other fields of the line must not move its booking back a step. if ( $start === $item->get_meta( '_abfw_start' ) && $same_end ) { continue; } $dates = Dates::possible( $start, $end, $item->get_product_id(), $item->get_variation_id() ); // The page already refused them; when it could not, the line keeps the dates it had. if ( ! $dates ) { continue; } $this->write( $item, $dates ); $this->bookings->follow_item( $order_id, $item->get_id(), $dates ); } } /** * Whether a line carries booking dates. * * @since 1.0.1 * @param mixed $item Order line. * @return bool */ private function is_dated( $item ) { return $item instanceof \WC_Order_Item_Product && '' !== (string) $item->get_meta( '_abfw_start' ); } /** * Store the new dates on the line. * * @since 1.0.1 * @param \WC_Order_Item_Product $item Line corrected. * @param array $dates New dates. */ private function write( $item, array $dates ) { // The line the customer reads was named in the shop's language at checkout. $switched = switch_to_locale( get_locale() ); $label = __( 'Dates', 'abogo-booking' ); $text = $this->cart->format( $dates ); if ( $switched ) { restore_previous_locale(); } $item->update_meta_data( '_abfw_start', $dates['start'] ); $item->update_meta_data( '_abfw_end', $dates['end'] ); $item->update_meta_data( '_abfw_units', $dates['units'] ); $item->update_meta_data( $label, $text ); $item->save(); } /** * Print one date field of a line. * * @since 1.0.1 * @param string $name Field name. * @param int $item_id Line identifier. * @param string $label Visible label. * @param string $value Date held on the line. */ private function field( $name, $item_id, $label, $value ) { echo '

'; } }