id) ->ordered() ->get(); } public function createField(Event $event, array $data): RegistrationFormField { $data['slug'] = $this->generateUniqueSlug($event, $data['label']); $field = RegistrationFormField::create([ 'event_id' => $event->id, ...$data, ]); $activityLogger = activity('registration_fields') ->performedOn($field) ->withProperties(['attributes' => $data]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_field.created'); return $field; } public function updateField(RegistrationFormField $field, array $data): RegistrationFormField { $old = $field->toArray(); if (isset($data['label']) && $data['label'] !== $field->label) { $data['slug'] = $this->generateUniqueSlug($field->event, $data['label'], $field->id); } $field->update($data); $activityLogger = activity('registration_fields') ->performedOn($field) ->withProperties(['old' => $old, 'attributes' => $data]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_field.updated'); return $field->fresh(); } public function deleteField(RegistrationFormField $field): void { $activityLogger = activity('registration_fields') ->withProperties(['deleted_field' => $field->toArray()]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_field.deleted'); $field->delete(); } public function reorderFields(Event $event, array $orderedIds): void { DB::transaction(function () use ($event, $orderedIds): void { foreach ($orderedIds as $index => $id) { RegistrationFormField::where('id', $id) ->where('event_id', $event->id) ->update(['sort_order' => $index]); } }); } public function upsertPersonValues(Person $person, array $values): void { $fields = RegistrationFormField::where('event_id', $person->event_id) ->get() ->keyBy('slug'); DB::transaction(function () use ($person, $values, $fields): void { foreach ($values as $slug => $rawValue) { $field = $fields->get($slug); if ($field === null) { continue; } $data = ['person_id' => $person->id, 'registration_form_field_id' => $field->id]; if ($field->isMultiValue()) { $data['value'] = null; $data['selected_options'] = is_array($rawValue) ? $rawValue : [$rawValue]; } else { $data['value'] = $rawValue === null ? null : (string) $rawValue; $data['selected_options'] = null; } PersonFieldValue::updateOrCreate( ['person_id' => $person->id, 'registration_form_field_id' => $field->id], $data, ); } }); $activityLogger = activity('registration_values') ->performedOn($person) ->withProperties(['slugs' => array_keys($values)]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('person.field_values.upserted'); $this->tagSyncService->syncFromRegistration($person); } public function getPersonValues(Person $person): Collection { return PersonFieldValue::where('person_id', $person->id) ->with('registrationFormField') ->get(); } public function importFromEvent(Event $targetEvent, Event $sourceEvent): Collection { $sourceFields = RegistrationFormField::where('event_id', $sourceEvent->id) ->ordered() ->get(); $maxOrder = RegistrationFormField::where('event_id', $targetEvent->id)->max('sort_order') ?? -1; $created = collect(); foreach ($sourceFields as $sourceField) { $slug = $this->generateUniqueSlug($targetEvent, $sourceField->label); $field = RegistrationFormField::create([ 'event_id' => $targetEvent->id, 'label' => $sourceField->label, 'slug' => $slug, 'field_type' => $sourceField->field_type, 'options' => $sourceField->options, 'tag_category' => $sourceField->tag_category, 'is_required' => $sourceField->is_required, 'is_portal_visible' => $sourceField->is_portal_visible, 'is_admin_only' => $sourceField->is_admin_only, 'is_filterable' => $sourceField->is_filterable, 'section' => $sourceField->section, 'help_text' => $sourceField->help_text, 'sort_order' => ++$maxOrder, ]); $created->push($field); } $activityLogger = activity('registration_fields') ->withProperties([ 'source_event_id' => $sourceEvent->id, 'target_event_id' => $targetEvent->id, 'fields_copied' => $created->count(), ]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_field.imported_from_event'); return $created; } private function generateUniqueSlug(Event $event, string $label, ?string $excludeId = null): string { $base = Str::slug($label); $slug = $base; $counter = 1; while (true) { $query = RegistrationFormField::where('event_id', $event->id) ->where('slug', $slug); if ($excludeId) { $query->where('id', '!=', $excludeId); } if (!$query->exists()) { return $slug; } $counter++; $slug = "{$base}-{$counter}"; } } }