build_descriptor( $session, [ 'timezone' => $session->customer_timezone() ?? $session->draft()->timezone(), ], [ [ 'key' => 'start_utc', 'type' => 'datetime', 'required' => true, ], [ 'key' => 'end_utc', 'type' => 'datetime', 'required' => true, ], [ 'key' => 'timezone', 'type' => 'string', 'required' => true, ], [ 'key' => 'agent_id', 'type' => 'integer', 'required' => false, ], ] ); } /** * Validate submitted input. * * @param BookingSession $session Session. * @param array $input Payload. */ public function validate( BookingSession $session, array $input ): ValidationResult { unset( $session ); $errors = []; $start = $this->string_value( $input, 'start_utc' ); $end = $this->string_value( $input, 'end_utc' ); $tz = $this->string_value( $input, 'timezone' ); if ( null === $start ) { $errors['start_utc'] = 'Please choose a start time.'; } if ( null === $end ) { $errors['end_utc'] = 'Please choose an end time.'; } if ( null === $tz ) { $errors['timezone'] = 'Timezone is required.'; } else { try { new DateTimeZone( $tz ); } catch ( \Exception ) { $errors['timezone'] = 'Timezone is not valid.'; } } if ( null !== $start && null !== $end && [] === $errors ) { try { $start_dt = new DateTimeImmutable( $start ); $end_dt = new DateTimeImmutable( $end ); if ( $end_dt <= $start_dt ) { $errors['end_utc'] = 'End time must be after start time.'; } } catch ( \Exception ) { $errors['start_utc'] = 'Start or end time is not valid.'; } } return [] === $errors ? ValidationResult::ok() : ValidationResult::invalid( $errors ); } /** * Apply validated input. * * @param BookingSession $session Session. * @param array $input Payload. */ public function apply( BookingSession $session, array $input ): BookingSession { $start = new DateTimeImmutable( (string) $input['start_utc'] ); $end = new DateTimeImmutable( (string) $input['end_utc'] ); $tz = (string) $input['timezone']; $buf_s = isset( $input['buffer_start_utc'] ) && is_string( $input['buffer_start_utc'] ) ? new DateTimeImmutable( $input['buffer_start_utc'] ) : $start; $buf_e = isset( $input['buffer_end_utc'] ) && is_string( $input['buffer_end_utc'] ) ? new DateTimeImmutable( $input['buffer_end_utc'] ) : $end; $hold = $this->positive_int( $input, 'hold_id' ); $draft = $session->draft()->with_datetime( $start, $end, $buf_s, $buf_e, $tz, $hold ); $agent = $this->positive_int( $input, 'agent_id' ); if ( null !== $agent ) { $draft = $draft->with_agent( $agent, false ); } return $session->with_draft( $draft ); } }