form()->available_extras_count() <= 0; } /** * Build the step descriptor. * * @param BookingSession $session Session. */ public function descriptor( BookingSession $session ): StepDescriptor { return $this->build_descriptor( $session, [ 'available_count' => $session->form()->available_extras_count() ], [ [ 'key' => 'extras', 'type' => 'array', 'required' => false, ], ] ); } /** * Validate submitted input. * * @param BookingSession $session Session. * @param array $input Payload. */ public function validate( BookingSession $session, array $input ): ValidationResult { unset( $session ); if ( isset( $input['extras'] ) && ! is_array( $input['extras'] ) ) { return ValidationResult::invalid( [ 'extras' => 'Extras must be a list.' ] ); } return ValidationResult::ok(); } /** * Apply validated input. * * @param BookingSession $session Session. * @param array $input Payload. */ public function apply( BookingSession $session, array $input ): BookingSession { $extras = isset( $input['extras'] ) && is_array( $input['extras'] ) ? array_values( $input['extras'] ) : []; $clean = []; foreach ( $extras as $extra ) { if ( ! is_array( $extra ) ) { continue; } $id = (int) ( $extra['extra_id'] ?? $extra['id'] ?? 0 ); if ( $id < 1 ) { continue; } $qty = isset( $extra['quantity'] ) ? max( 1, (int) $extra['quantity'] ) : 1; $clean[] = [ 'extra_id' => $id, 'quantity' => $qty, ]; } $draft = $session->draft()->with_extras( $clean, $session->draft()->price_minor() ); return $session->with_draft( $draft ); } }