profiles->get( $user_id ); $required = [ 'first_name', 'last_name', 'email' ]; if ( $this->profiles->requirePhone() ) { $required[] = 'abece_booking_phone'; } $missing = array_values( array_filter( $required, static fn( $key ) => '' === trim( $data[ $key ] ) || ( 'email' === $key && ! is_email( $data[ $key ] ) ) ) ); return $data + [ 'require_phone' => $this->profiles->requirePhone(), 'profile_complete' => [] === $missing, 'missing_fields' => $missing ]; } public function save( array $input, int $user_id ): array { BookingValidator::login( $user_id ); BookingValidator::fields( $input, [ 'first_name', 'last_name', 'email', 'abece_booking_phone' ] ); $current = $this->profiles->get( $user_id ); if (isset($input['email']) && (!is_string($input['email']) || strcasecmp(trim($input['email']),$current['email'])!==0)) { CatalogValidator::invalid('email', __('Change your email through the WordPress account settings so the new address can be verified.', 'abece-booking')); } $data = array_replace( $current, $input ); $data = $this->validate( $data ); $this->profiles->save( $user_id, $data ); return $this->get( $user_id ); } public function validate( array $input ): array { $data = []; foreach ( [ 'first_name', 'last_name' ] as $key ) { $data[ $key ] = MembershipValidator::text( $input[ $key ] ?? null, $key, 100 ); } $email = $input['email'] ?? null; if ( ! is_string( $email ) || ! is_email( trim( $email ) ) ) { CatalogValidator::invalid( 'email', __( 'A valid email address is required.', 'abece-booking' ) ); } $data['email'] = sanitize_email( trim( $email ) ); $data['abece_booking_phone'] = MembershipValidator::text( $input['abece_booking_phone'] ?? null, 'abece_booking_phone', 50, ! $this->profiles->requirePhone() ) ?? ''; return $data; } public function requireComplete( int $user_id ): void { if ( ! $this->get( $user_id )['profile_complete'] ) { throw new CatalogException( 'abece_booking_profile_incomplete', __( 'Complete your first name, last name, email and required phone number before booking.', 'abece-booking' ), 400 ); } } }