'array', 'is_required' => 'boolean', 'is_active' => 'boolean', ]; public function category() { return $this->belongsTo(\Modules\Category\Models\Category::class); } public function scopeActive(Builder $query): Builder { return $query->where('is_active', true); } public function scopeOrdered(Builder $query): Builder { return $query->orderBy('sort_order')->orderBy('id'); } public function scopeForCategory(Builder $query, ?int $categoryId): Builder { return $query->where(function (Builder $subQuery) use ($categoryId): void { $subQuery->whereNull('category_id'); if ($categoryId) { $subQuery->orWhere('category_id', $categoryId); } }); } public static function typeOptions(): array { return [ self::TYPE_TEXT => 'Text', self::TYPE_TEXTAREA => 'Textarea', self::TYPE_NUMBER => 'Number', self::TYPE_SELECT => 'Select', self::TYPE_BOOLEAN => 'Boolean', self::TYPE_DATE => 'Date', ]; } public function selectOptions(): array { $options = collect($this->options ?? []) ->map(fn ($option) => is_scalar($option) ? trim((string) $option) : null) ->filter(fn (?string $option): bool => filled($option)) ->values() ->all(); return collect($options)->mapWithKeys(fn (string $option): array => [$option => $option])->all(); } public static function upsertSeeded(Category $category, array $attributes): self { return static::query()->updateOrCreate( ['name' => (string) ($attributes['name'] ?? '')], [ 'label' => (string) ($attributes['label'] ?? ''), 'type' => (string) ($attributes['type'] ?? self::TYPE_TEXT), 'category_id' => (int) $category->getKey(), 'placeholder' => $attributes['placeholder'] ?? null, 'help_text' => $attributes['help_text'] ?? null, 'options' => $attributes['options'] ?? null, 'is_required' => (bool) ($attributes['is_required'] ?? false), 'is_active' => (bool) ($attributes['is_active'] ?? true), 'sort_order' => (int) ($attributes['sort_order'] ?? 0), ], ); } }