form()->settings(); $require_phone = ! empty( $settings['require_phone'] ); $marketing_opt_in = ! empty( $settings['marketing_opt_in'] ); $fields = [ [ 'key' => 'first_name', 'type' => 'string', 'required' => true, ], [ 'key' => 'last_name', 'type' => 'string', 'required' => false, ], [ 'key' => 'email', 'type' => 'email', 'required' => true, ], [ 'key' => 'phone', 'type' => 'tel', 'required' => $require_phone, ], [ 'key' => 'terms_accepted', 'type' => 'boolean', 'required' => true, ], ]; if ( $marketing_opt_in ) { $fields[] = [ 'key' => 'marketing_consent', 'type' => 'boolean', 'required' => false, ]; } foreach ( CustomFields::descriptors( CustomFields::from_settings( $settings ) ) as $custom ) { $fields[] = $custom; } return $this->build_descriptor( $session, [], $fields ); } /** * Validate submitted input. * * @param BookingSession $session Session. * @param array $input Payload. */ public function validate( BookingSession $session, array $input ): ValidationResult { $settings = $session->form()->settings(); $require_phone = ! empty( $settings['require_phone'] ); $marketing_opt_in = ! empty( $settings['marketing_opt_in'] ); $errors = []; $first = $this->string_value( $input, 'first_name' ); if ( null === $first ) { $errors['first_name'] = 'Please enter your first name.'; } $email = $this->string_value( $input, 'email' ); if ( null === $email ) { $errors['email'] = 'Please enter your email address.'; } else { try { new EmailAddress( $email ); } catch ( \Bookline\Domain\Shared\DomainException ) { $errors['email'] = 'Please enter a valid email address.'; } } $phone = $this->string_value( $input, 'phone' ); if ( $require_phone && null === $phone ) { $errors['phone'] = 'Please enter your phone number.'; } elseif ( null !== $phone ) { try { new PhoneNumber( $phone ); } catch ( \Bookline\Domain\Shared\DomainException ) { $errors['phone'] = 'Please enter a valid phone number.'; } } if ( ! isset( $input['terms_accepted'] ) || true !== $input['terms_accepted'] ) { $errors['terms_accepted'] = 'You must accept the terms to continue.'; } if ( $marketing_opt_in && isset( $input['marketing_consent'] ) && ! is_bool( $input['marketing_consent'] ) ) { $errors['marketing_consent'] = 'Marketing consent must be true or false.'; } $custom_errors = CustomFields::validate( CustomFields::from_settings( $settings ), $input['custom_fields'] ?? null ); foreach ( $custom_errors as $key => $message ) { $errors[ $key ] = $message; } 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 { $defs = CustomFields::from_settings( $session->form()->settings() ); $custom = CustomFields::values( $defs, $input['custom_fields'] ?? null ); $draft = new CustomerDraft( (string) $this->string_value( $input, 'first_name' ), $this->string_value( $input, 'last_name' ), (string) $this->string_value( $input, 'email' ), $this->string_value( $input, 'phone' ), isset( $input['marketing_consent'] ) && true === $input['marketing_consent'], true, $custom, $this->string_value( $input, 'notes' ), ); return $session->with_customer( $draft ); } }