Merged
Conversation
Add SCOPED_MANAGEMENT entity feature for entities whose custom fields are managed per-parent record instead of the global management page. - Add EntityFeature::SCOPED_MANAGEMENT enum case - Add EntityCollection::globallyManaged() using withoutFeature() - Add Entities::globallyManaged() facade method - Add onlyGloballyManaged parameter to Entities::getOptions() - Update CustomFieldsManagementPage to use globallyManaged() - Fix SectionForm ignoreRecord bug when embedded in non-section ViewRecord - Add SectionForm::modifyUniqueRuleUsing() for custom unique constraints - Extract buildUniqueRule() to eliminate duplication
Allow form component subclasses to filter or modify validation rules before they are applied. FileUpload-based components need to strip the 'string' rule that DatabaseFieldConstraints adds for string_value columns, since FileUpload submits TemporaryUploadedFile objects.
feat: scoped management and validation extensibility (3.x)
Expand documentation on field type customization, covering settings, multi-value support, unique constraints, table filters, and import handling.
- Use DateConstraintValue::from() for proper Spatie Data hydration - Move validation fieldset into its own tab before Visibility - Reimplement import validation using ValidationService - Add Copilot custom instructions for Filament v5 namespaces
Covers anchor-based data model (today/fixed/custom-field/record-created), preset-driven config UI with progressive disclosure, and runtime changes for submit-time validation and cross-field reactivity.
9-task TDD plan covering enums, DTO, validation rule, capabilities, config UI, reactive field refs, circular reference detection, and integration testing.
Add DateValidationManagementTest with 7 tests verifying persistence of date fields with various validation constraints (today anchor, fixed date, custom field reference, record created, offset, no restrictions). Add DateValidationIntegrationTest with 6 tests verifying runtime validation on CreatePost forms (reject past dates, accept valid dates, max date enforcement, fixed date constraint, offset validation). Fix ValidationService::combineRules() and DatabaseFieldConstraints to handle non-string validation rules (DateConstraintRule objects).
Use $record injection instead of $get() path traversal to read entity_type and code. The hidden entity_type field wasn't being properly hydrated in Filament 5's action form context, causing $get() to return null at any traversal depth. Falling back to $get() for the create-new-field path where $record is null.
…yId during edit Two bugs fixed: 1. UniqueCustomFieldValue compared raw input against stored (normalized) values. For link fields, entering "https://example.com" bypassed the uniqueness check against a stored "example.com" because the protocol was stripped by dehydrateStateUsing after validation ran. 2. AbstractFormComponent never passed the current record's ID to the uniqueness rule during edit, causing records to detect themselves as duplicates when saving unchanged unique values. Changes: - Add setValue()/getValue() to BaseFieldType for value normalization - Override setValue() in LinkFieldType to strip protocol and trim - UniqueCustomFieldValue now normalizes via field type before comparing - AbstractFormComponent passes record ID via closure to rules() - LinkComponent uses field type setValue() instead of inline regex - Add 17 Livewire integration tests for uniqueness validation
blank('0') returns false in Laravel, but the original code treated '0'
as an empty expression. Restore the explicit '0' check to avoid a
subtle behavior change in field visibility.
…closures
- Use getMorphClass() directly instead of two-step Relation::getMorphAlias()
fallback, matching codebase convention
- Collapse nested closures in LinkComponent dehydrateStateUsing to arrow
functions
- Restore '0' check in visibility guard (blank('0') is false in Laravel)
Add defensive checks in date capabilities to handle pre-existing database records saved before sanitizeValidationRules was introduced. Extract AbstractDateCapability to centralize shared logic and guards.
Full round-trip E2E tests covering all anchor types for date and date-time fields. Regression tests for legacy data with preset:none but no anchor key.
Fix incorrect Component namespace imports, add phpstan-ignore for dynamic Field method dispatch, and simplify migration step code.
Remove 11 unit test files (85 tests) and 2 plan documents. Add ValidationCapabilitiesTest with 29 feature tests covering text, numeric, selection, required, and date edge cases through real Livewire form submission.
parseDateConstraint was outputting relative_value/relative_unit/direction keys which don't match DateConstraintValue DTO that expects anchor/offset/offset_unit/offset_direction. Updated to produce the correct format.
…ns and unique validation logic - Add explicit return types to closures and methods for better type safety - Normalize and improve consistency of `Closure` imports and doc annotations - Simplify conditional logic in AbstractFormComponent and cleanup orphaned value checks - Standardize string concatenation with `.` instead of interpolation for warnings/messages - Relocate and restore LinkFieldType `setValue` method for better class organization
Replace direct CustomField::query() and new CustomField/CustomFieldValue with CustomFields::newCustomFieldModel() and CustomFields::newValueModel() to respect configurable model overrides. Add architecture test with datasets to enforce this pattern across all 4 configurable models.
…ation fix: normalize values in unique field validation and wire ignoreEntityId
Remove IntegerOnlyCapability from NumberFieldType and use DecimalPlacesCapability instead (decimal_places=0 for integers). Limit decimal places to 0-4 with placeholder hint. Update migration step to map legacy 'integer' rule to decimal_places=0.
Apply Rector auto-fixes (FQCN imports, sprintf conversions, newlines). Remove stale phpstan ignore patterns no longer needed after Rector fixes.
The argument.type errors in Infolists and Table Columns are caused by Filament's view-string type declarations varying across versions. Use reportUnmatched: false so it works on both local and CI environments.
feat: replace generic validation rules with field-type-owned validation capabilities
Replace deprecated availableValidationRules/ValidationRule enum with withValidationCapabilities in the StarRating example and API reference. Clarify validation_rules column stores capability-driven config.
docs: update field types and data model for validation capabilities
…diff so I can generate the appropriate commit message for you?
…imize cleaning logic Replace `toCollection()` calls with `has()` for validation rule checks, streamlining the logic. Simplify cleaning invalid rules using `keys()->intersect` and `except`.
…vents during lookup field migration
…rule Use `Relation::getMorphedModel` to resolve the actual entity class before determining the morph alias, improving compatibility with custom morph mappings.
Reproduces the CRM-3B production bug where entity_type stores morph aliases (e.g. 'people') instead of class names, causing fatal errors.
There was a problem hiding this comment.
Pull request overview
This pull request represents a major architectural refactoring of the validation system for version 3.x. The changes migrate from an enum-based, array-of-objects validation format to a capability-driven, key-value validation system. This enables more flexible, type-specific validation configuration with better support for complex constraints like date field references and circular dependency detection.
Changes:
- Replaced enum-based validation with capability pattern (
ValidationCapabilityinterface with implementations likeMinLengthCapability,MaxValueCapability, etc.) - Introduced sophisticated date validation with anchors (today, fixed date, custom field, record created), offsets, and cycle detection
- Added migration command
MigrateValidationRulesFormatStepto upgrade existing validation data - Removed 1,000+ lines of legacy validation code (
ValidationRuleenum,ValidationRuleData,CustomFieldValidationComponent) - Updated all test files, factories, and documentation to use new format
Reviewed changes
Copilot reviewed 81 out of 82 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/Validation/Capabilities/*.php | New validation capability implementations for various field types |
| src/Validation/Rules/DateConstraintRule.php | Date constraint validation with runtime resolution |
| src/Validation/DateFieldReferenceValidator.php | Circular reference detection for date fields |
| src/Data/DateConstraintValue.php | Date constraint data structure with resolve logic |
| src/Enums/DateAnchor.php, DateUnit.php, DateOffsetDirection.php | Supporting enums for date constraints |
| src/Contracts/ValidationCapability.php | Interface for validation capabilities |
| src/Services/ValidationService.php | Refactored to use capability-based rules |
| src/FieldTypeSystem/FieldSchema.php | Replaced availableValidationRules() with withValidationCapabilities() |
| src/FieldTypeSystem/Definitions/*.php | Updated field types to use validation capabilities |
| src/Models/CustomField.php | Changed validation_rules casting from DataCollection to AsCollection |
| src/Console/Commands/Upgrade/Steps/MigrateValidationRulesFormatStep.php | Migration logic from old to new format |
| tests/Feature/Rules/UniqueCustomFieldValueTest.php | New comprehensive tests for unique value validation |
| tests/Feature/Integration/ValidationCapabilitiesTest.php | New tests for validation capabilities |
| tests/Feature/Admin/Pages/DateValidationManagementTest.php | New tests for date validation UI |
| tests/Feature/Commands/MigrateValidationRulesFormatStepTest.php | Tests for migration command |
| tests/Pest.php | Updated toHaveValidationRule expectation helper |
| Removed: src/Enums/ValidationRule.php | 446-line enum deleted |
| Removed: src/Data/ValidationRuleData.php | Data transfer object deleted |
| Removed: src/Filament/Management/Forms/Components/CustomFieldValidationComponent.php | 521-line component deleted |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.