Skip to content

feat: consumer hooks to scope field uniqueness + visibility picker#175

Merged
ManukMinasyan merged 1 commit into
3.xfrom
fix/scope-field-uniqueness-and-visibility-to-consumer-context
Jun 27, 2026
Merged

feat: consumer hooks to scope field uniqueness + visibility picker#175
ManukMinasyan merged 1 commit into
3.xfrom
fix/scope-field-uniqueness-and-visibility-to-consumer-context

Conversation

@ManukMinasyan

Copy link
Copy Markdown
Collaborator

Summary

Adds two opt-in consumer hooks so an application can scope custom-field management to a subset of an entity's fields, instead of the package's default "all fields are global per entity_type" behaviour. Both hooks are strict no-ops when not registered, so existing consumers are unaffected.

This is needed by consumers that build multiple separate forms on one entity type (e.g. a versioned form builder), where the same field names/sections are intentionally reused across forms. Today such consumers hit two problems:

  1. Field-name uniqueness is entity-type-wide. Two forms can't both have a field named "Address" — editing one throws "The name has already been taken", even though they belong to different forms.
  2. The conditional-visibility "depends on" picker lists every field of the entity type. A field's visibility condition dropdown shows duplicate-named fields from every other form, so authors can't tell which one to pick.

The section-level analog of (1) already had a hook (ManageCustomFieldSection::resolveUniqueRuleModifierUsing + SectionForm::modifyUniqueRuleUsing). This PR adds the matching field-level hook and a visibility-picker scope hook.

What's added

  • FieldForm::resolveUniqueRuleModifierUsing(?Closure) — register a resolver fn (?CustomFieldSection $section): ?Closure that returns a Unique rule modifier (or null). Applied to the name uniqueness rule only (code remains globally unique, consistent with the package's code-based field resolution). FieldForm::schema() gains an optional ?CustomFieldSection $section param, passed by ManageCustomField::editAction() (the edited field's section) and ManageCustomFieldSection::createFieldAction() (the create-target section).
  • VisibilityComponent::resolveAvailableFieldsScopeUsing(?Closure) — register a resolver fn (string $entityType, ?CustomFieldSection $section): ?Closure that returns a query constraint (or null) applied to getAvailableFields(). make() / makeForSection() gain an optional ?CustomFieldSection so the field/section being edited can be passed through (FieldForm → field-level conditions, SectionForm::scopeVisibilityToSection() → section-level conditions).

Backward compatibility

  • No resolver registered → identical behaviour to before (verified by tests).
  • make() / schema() / makeForSection() new params are optional and default to null.
  • Only the field name rule is scoped; code stays globally unique.

Tests

tests/Feature/ConsumerScopeHooksTest.php:

  • VisibilityComponent lists all entity fields with no resolver (back-compat), constrains to the resolver subset when registered, and falls back to all when the resolver returns null.
  • FieldForm::schema() builds unchanged with no resolver and accepts an optional section.

Exercised end-to-end by the consuming application (a versioned Flex Fund Form builder): editing a field whose name exists in another form now saves, and the visibility dropdown lists only the current form's fields.

@ManukMinasyan ManukMinasyan reopened this Jun 27, 2026
@ManukMinasyan ManukMinasyan force-pushed the fix/scope-field-uniqueness-and-visibility-to-consumer-context branch from 38b2074 to 4661824 Compare June 27, 2026 14:09
Field-name uniqueness and the conditional-visibility 'depends on' picker are
scoped entity-type-wide. Consumers that build multiple forms on one entity type
(e.g. a versioned form builder) need to reuse field names/sections across forms.

Add two opt-in, no-op-by-default hooks mirroring the existing section pattern:
- FieldForm::resolveUniqueRuleModifierUsing() scopes the name uniqueness rule
- VisibilityComponent::resolveAvailableFieldsScopeUsing() scopes the field picker

make()/makeForSection()/schema() gain an optional CustomFieldSection passed by
the management Livewire components. Code uniqueness stays global.

Also brings three pre-existing files into compliance with the newer rector
(unused imports) so the suite is green.
@ManukMinasyan ManukMinasyan force-pushed the fix/scope-field-uniqueness-and-visibility-to-consumer-context branch from 4661824 to dcada94 Compare June 27, 2026 14:40
@ManukMinasyan ManukMinasyan merged commit 0be9935 into 3.x Jun 27, 2026
4 checks passed
@ManukMinasyan ManukMinasyan deleted the fix/scope-field-uniqueness-and-visibility-to-consumer-context branch June 27, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant