registrationFieldTemplates() ->ordered() ->get(); } public function createTemplate(Organisation $organisation, array $data): RegistrationFieldTemplate { $data['slug'] = $this->generateUniqueSlug($organisation, $data['label']); $template = $organisation->registrationFieldTemplates()->create($data); $activityLogger = activity('registration_templates') ->performedOn($template) ->withProperties(['attributes' => $data]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_template.created'); return $template; } public function updateTemplate(RegistrationFieldTemplate $template, array $data): RegistrationFieldTemplate { $old = $template->toArray(); if (isset($data['label']) && $data['label'] !== $template->label) { $data['slug'] = $this->generateUniqueSlug($template->organisation, $data['label'], $template->id); } $template->update($data); $activityLogger = activity('registration_templates') ->performedOn($template) ->withProperties(['old' => $old, 'attributes' => $data]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_template.updated'); return $template->fresh(); } public function deleteTemplate(RegistrationFieldTemplate $template): void { if ($template->is_system) { $template->update(['is_active' => false]); $activityLogger = activity('registration_templates') ->performedOn($template); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_template.deactivated'); return; } $activityLogger = activity('registration_templates') ->withProperties(['deleted_template' => $template->toArray()]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_template.deleted'); $template->delete(); } public function createFieldFromTemplate(Event $event, RegistrationFieldTemplate $template): RegistrationFormField { $slug = $this->generateUniqueFieldSlug($event, $template->label); $maxOrder = RegistrationFormField::where('event_id', $event->id)->max('sort_order') ?? -1; $field = RegistrationFormField::create([ 'event_id' => $event->id, 'label' => $template->label, 'slug' => $slug, 'field_type' => $template->field_type, 'options' => $template->options, 'tag_category' => $template->tag_category, 'is_required' => $template->is_required, 'is_portal_visible' => $template->is_portal_visible, 'is_admin_only' => $template->is_admin_only, 'is_filterable' => $template->is_filterable, 'section' => $template->section, 'help_text' => $template->help_text, 'sort_order' => $maxOrder + 1, ]); $activityLogger = activity('registration_fields') ->performedOn($field) ->withProperties(['from_template_id' => $template->id]); if (auth()->user()) { $activityLogger->causedBy(auth()->user()); } $activityLogger->log('registration_field.created_from_template'); return $field; } /** * Seed system templates for a newly created organisation. */ public static function seedSystemTemplates(Organisation $organisation): void { $templates = [ ['label' => 'Shirtmaat', 'field_type' => 'select', 'options' => ['XS', 'S', 'M', 'L', 'XL', 'XXL', 'XXXL'], 'is_filterable' => true, 'sort_order' => 1], ['label' => 'Dieetwensen', 'field_type' => 'multiselect', 'options' => ['Vegetarisch', 'Veganistisch', 'Halal', 'Glutenvrij', 'Lactosevrij', 'Geen pinda\'s', 'Geen noten'], 'is_filterable' => true, 'sort_order' => 2], ['label' => 'Vergoeding', 'field_type' => 'radio', 'options' => ['Pro Deo', 'Entreeticket', 'Vrijwilligersvergoeding'], 'section' => 'Vergoeding', 'sort_order' => 3], ['label' => 'Toestemming gegevensverwerking', 'field_type' => 'boolean', 'is_required' => true, 'section' => 'Toestemming', 'help_text' => 'Ik geef toestemming voor de verwerking van mijn persoonsgegevens ten behoeve van de organisatie van dit evenement, conform de Algemene Verordening Gegevensbescherming (AVG).', 'sort_order' => 4], ['label' => 'Noodcontact naam', 'field_type' => 'text', 'section' => 'Noodcontact', 'sort_order' => 5], ['label' => 'Noodcontact telefoon', 'field_type' => 'text', 'section' => 'Noodcontact', 'sort_order' => 6], ['label' => 'EHBO / BHV diploma', 'field_type' => 'boolean', 'is_filterable' => true, 'sort_order' => 7], ['label' => 'Rijbewijs', 'field_type' => 'boolean', 'is_filterable' => true, 'sort_order' => 8], ['label' => 'Eerder vrijwilliger geweest', 'field_type' => 'boolean', 'is_filterable' => true, 'sort_order' => 9], ['label' => 'Certificaten & vaardigheden', 'field_type' => 'tag_picker', 'tag_category' => null, 'is_filterable' => true, 'sort_order' => 10], ['label' => 'Opmerkingen', 'field_type' => 'textarea', 'sort_order' => 11], ]; foreach ($templates as $data) { $organisation->registrationFieldTemplates()->create([ ...$data, 'slug' => Str::slug($data['label']), 'is_system' => true, 'is_active' => true, 'is_required' => $data['is_required'] ?? false, 'is_filterable' => $data['is_filterable'] ?? false, 'is_portal_visible' => true, 'is_admin_only' => false, ]); } } private function generateUniqueSlug(Organisation $organisation, string $label, ?string $excludeId = null): string { $base = Str::slug($label); $slug = $base; $counter = 1; while (true) { $query = RegistrationFieldTemplate::where('organisation_id', $organisation->id) ->where('slug', $slug); if ($excludeId) { $query->where('id', '!=', $excludeId); } if (!$query->exists()) { return $slug; } $counter++; $slug = "{$base}-{$counter}"; } } private function generateUniqueFieldSlug(Event $event, string $label): string { $base = Str::slug($label); $slug = $base; $counter = 1; while (RegistrationFormField::where('event_id', $event->id)->where('slug', $slug)->exists()) { $counter++; $slug = "{$base}-{$counter}"; } return $slug; } }