Feat/filter types - #20
Open
ericges wants to merge 71 commits into
Open
Conversation
ericges
force-pushed
the
feat/filter-types
branch
from
May 28, 2026 14:14
374d0e0 to
43c7da1
Compare
…e` to modularize filter handling
…pleEquationFilterType` for extensible filter handling in FlareBundle
…ith assertion style configuration
…in configuration files
…r for improved clarity
ericges
force-pushed
the
feat/filter-types
branch
from
July 13, 2026 11:51
43c7da1 to
bb30f1f
Compare
Filter elements now own their entire lifecycle: form building on native Symfony FormBuilderInterface sub-builders, config schema + DCA-row translation via ConfigContract (OptionsResolver), data-to-options transformation in buildFilter(builder, context, data), and backend DCA configuration via DcaContract::configureDca() on both tl_flare_filter and tl_flare_list. - Replace ConfiguredFilter/ConfiguredFilterCollection with immutable Filter DTO held as plain keyed array on ListSpecification - Remove FilterInvocation, FilterFormBuilder, Hydrate/FormData/ Intrinsic/RuntimeValue/FormTypeOptions contracts, and the entire AsFlareCallback/palette machinery (PaletteContract, PaletteEvent, callback registry, MethodInjector) - Add standalone filter channels: Filter::fromCallback()/fromType() and flare_make_filter() Twig function - Nest filter GET params as ?list[alias][value]=x (BC break) - Add unit tests for Filter, FilterConfigResolver, ListSpecification
Restructure the filter subsystem under the Filter\ namespace and align class/interface names with their roles. No behavior changes. - Move filter elements to Filter\Element\ and collectors to Filter\Collector\; suffix element classes consistently (PublishedFilterElement, SearchKeywordsFilterElement, ...) - Rename ConfigContract -> FilterElementOptionsInterface (configureConfig -> configureOptions) and FilterConfigResolver -> Filter\OptionsResolver\FilterOptionsResolver - Rename DcaContract::configureDca -> buildDca; introduce DcaBuilderInterface and DcaFieldBuilderInterface - Rename Form\Type\DateRangeFilterType -> DateRangeFormType, resolving the name collision with the query-side filter type - Drop unused ListItemProviderConfig; update translations - Add unit tests for Filter, FilterOptionsResolver, and ListSpecification; restore FilterFormListener named dispatch
… and ListSpecification classes <!-- This aligns with the existing commit style from the history while mentioning the main action and specific additions. -->
…lter lifecycle and element handling.
…sChoiceFilterElement`
…ent` and update references Revised all occurrences of `AbstractFilterFilterElement` to streamline naming conventions and align with the filter subsystem structure.
…d update references Aligned filter element naming with established conventions (`ArchiveElement` -> `ArchiveFilterElement`, etc.) and adjusted translations accordingly.
…Test` and update method/exception references
ericges
added a commit
that referenced
this pull request
Jul 13, 2026
Rewrites the developer documentation for the v0.2 filter subsystem rework: - Delete pages for removed subsystems: DCA callbacks (callbacks.mdx), filter invokers (spec/invoker.md), and the six removed filter-element contracts (form-data, form-type-options, hydrate-form, intrinsic-value, runtime-value, palette). - New pages: dev/filter-types (custom filter types guide), dev/dca-builder (backend DCA building via DcaContract/DcaBuilder/ElementDcaEvent), dev/contracts/dca-contract, spec/filtering (filter pipeline architecture), reference/filter-types (built-in type catalog), migrating-from-v0.1, removed-in-v0.2, and an unlisted preflight-v0.2 release checklist. - Rewrite dev/filter-elements around the buildForm/buildFilter/buildDca/ configureOptions lifecycle, dev/events for the new event set and named aliases (.building/.built/.form_built/.dca), spec/specifications around the immutable Filter value object and the keyed addFilter() API, and dev/contracts/index for the new contract layout. - Update attribute docs (#[AsFilterElement] without palette/formType/method, #[AsListType] without palette), engine-mods examples to SimpleEquationFilterElement::define() + addFilter(), Twig docs for the new flare_make_filter() helper, and reference tables for the new Filter\Element namespace and per-element form controls. - flare_enclosure_files is documented as removed (code removal tracked on the preflight page). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Moved `FilterOptionsResolver` and `FilterElementResolver` to `Filter\Resolver\` namespace, adjusted imports and references accordingly.
Introduce `ConfigBuilder` (fluent canonical-config accumulator), `TransformerBuilder`
(source-class to transformer map), the `TransformerContract` (`configureTransformers()`),
and `FilterTransformerResolver` (per-element-class memoized transformer execution).
Transformer maps are extensible via `FilterTransformerEvent`, re-dispatched as
`flare.filter_element.{type}.transformers`.
…rogrammatic sugar - Elements now implement `configureTransformers()` (via `AbstractFilterElement`, which registers `transformFilterModel(FilterModel, ConfigBuilder)` for the FilterModel source); `FilterElementOptionsInterface` and `configFromRow()` are gone. `FilterOptionsResolver` checks the generic `OptionsInterface`. - `ListModelFilterCollector` translates via `FilterTransformerResolver`; elements without a matching transformer keep the raw-row passthrough. - New `FilterContextFactory` dedupes the identical `FilterContext` construction in `FilterFormFactory` and `FilterExecutor`. - Removed programmatic sugar: all static `define()` factories, `Filter::fromType()`, `Filter::fromCallback()`, `CallbackFilterElement`, and the `flare_make_filter` Twig function. Internal call sites construct `new Filter(element:, config:)` directly. A proper engine-extending API is a follow-up.
… options
- `Lists\ListSpec`: immutable list DTO (type, dc, filters, canonical config, source)
with `with*()` modifiers, `getAutoItemField()` (validated), and a config-based `hash()`.
- `ListBuilder` owns the list build lifecycle: type's `BuildListContract::buildList()`
hook, `ListBuildEvent` (named dispatch `flare.list.{type}.build`), base + type
transformer config assembly, schema resolution via `ListOptionsResolver`.
- `BaseListOptions`: framework-owned base schema/translation for tl_flare_list columns,
applied unconditionally; `genericPageMeta` replaces the dynamic `eval_generic_page_meta`.
- `AbstractListType` now implements `ListTypeInterface`, `OptionsInterface`, and
`TransformerContract` (`transformListModel()` override point).
- `ListBuilderFactory` replaces `ListSpecificationFactory` (old path still in place
until the consumer sweep).
… by `ListBuilder`
- All consumers now use `Lists\ListSpec`; construction goes through
`ListBuilderFactory::createFromListModel()->build()` (controllers, reader attribute
factory, backend DCA path, breadcrumb listener, filter field options callbacks).
- Dynamic properties are gone: `src/Specification/` deleted entirely (row-dump bag,
`#[\AllowDynamicProperties]`, `AutoItemFieldGetterTrait`, `ListDataSourceInterface`,
`ListSpecificationFactory`). Consumers read the canonical `ListSpec::$config`
(page meta, comments, ptable inference, context factories, sort factory, reader
attribute marshalling).
- List types own their lifecycle: News/Events add their published filter in
`buildList()` instead of `ListSpecificationCreatedEvent` listeners (event deleted,
`ListBuildEvent` + `flare.list.{type}.build` replace it); Generic/DcMultilingual set
`genericPageMeta` in `transformListModel()` (replaces `EnableGenericPageMetaListener`
and the DcMultilingual listener, whose `isPageMetaGeneric` key was never read — this
fixes DcMultilingual generic page meta).
- `ListSpec` is fully immutable: `Engine::setList()` added, `Engine::__clone` no longer
clones the list, `ValidationLoader`/`SimpleEquationMod` use `withFilter()`.
- `FilterCollectorInterface`/`FilterCollectorRegistry` deleted; `ListModelFilterCollector`
stays as the concrete collector consumed by `ListBuilderFactory`.
- `ListExecutionContextFactory` supports inline list type instances.
- `getAutoItemField()` now always validates against the DCA (was unvalidated in the
trait variant used by ChangelanguageListener).
`configureTableRegistry()` / `configureBaseQuery()` become `buildTableRegistry()` / `buildBaseQuery()`, aligning the list-type query hooks with the build* lifecycle family (configure* = declarative setup, build* = per-invocation construction).
New tests: ConfigBuilder, TransformerBuilder, FilterTransformerResolver (memoization + event extensibility), SimpleEquation/Archive `transformFilterModel()` round-trips through their own schemas, ListSpec (immutability, filter keying, hash), ListBuilder (hook, event, override precedence, source provenance), BaseListOptions. AGENTS.md architecture section now describes the Lists domain, the transformer cycle, and the current attribute/event surface; the stale no-test-suite claim is corrected.
…finish `OptionsContract` rename resolve() now checks the source's exact class first (O(1), most-specific registration wins) before falling back to the instanceof scan that covers subclass/interface registrations — previously an earlier base-class registration shadowed a later, more specific one. Also completes the `OptionsInterface` → `OptionsContract` rename (`AbstractFilterElement` still implemented the old name) and fixes a stale docblock.
`HeimrichHannot\FlareBundle\Lists` → `HeimrichHannot\FlareBundle\List` (src/List/, tests/List/). `List` is a valid namespace segment on PHP >= 8.0 (the bundle requires ^8.2); only a bare `class List` would be reserved.
… adapt tests Missed usages: `ChangelanguageListener` still called the removed `ListSpec::getTypeAlias()`; `ListSpecFactory` accepted a nullable `$dc` that `ListSpec` rejects; `ListTransformerEvent::$typeService` renamed to `$driver`; stale inline-element wording in `Filter`/`FilterElementResolver` docblocks and the `fingerprint()` key. Tests adapted to the new APIs: `ListDriverReference` construction, string-only `Filter::$type` (form-factory elements now register in the `FilterElementRegistry`), `ListBuilderTest` renamed to `ListSpecBuilderTest`.
Renamed all occurrences of `ListType` to `ListDriver`, including class names, interfaces, namespaces, attributes, and references. Updated tests, translation files, and documentation accordingly for consistency.
…onstruction with static factory methods Replaced ad-hoc construction of `ListDriverReference` with static factory methods `registered()` and `inline()` for clearer intent and better type management. Updated event dispatchers, listeners, transformers, and tests to use the new structure. Refined `ListTransformerEvent` and related named event handling accordingly.
Introduced `phpunit.yaml` GitHub Actions workflow for running unit tests. Added `phpunit.xml.dist` configuration file and updated documentation to reflect the new setup.
Added a line break after badges for better readability and emphasized the bundle description with bold formatting.
…aContainerName` to `resolveDataContainerTable`
…r and FilterElement handling
…ross ListSpec and related classes
…lity with `readonly`
…oved type safety and clarity
…filter elements and drivers
…t, remove obsolete variants, and enhance immutability
…dling changes and improve consistency
… across events and related classes for improved consistency and immutability
…elated APIs for improved consistency and immutability
… and ListDriver registration, streamline type handling via `TypeNameFactory`
…ltiple components, improve tag registration, and fix minor logic inconsistencies
… ensure better type consistency and enhance filters and projector logic across components
ericges
force-pushed
the
feat/filter-types
branch
from
July 19, 2026 13:08
1a8bea5 to
9eca4d4
Compare
…s across multiple components
ericges
force-pushed
the
feat/filter-types
branch
from
July 19, 2026 13:11
ae0b057 to
5940ad6
Compare
…chitecture, and performance
…ryCache` utility Made `PaginatorConfig` non-nullable in `InteractiveContext` for improved null safety. Introduced a new `EntryCache` utility for handling cached entries in a more structured manner. Replaced positional entry lookups with ID-based indexing. Updated `ValidationLoader` and removed stale `entryCache` logic from `ValidationContextFactory`. Adjusted `composer.json` to require `doctrine/dbal` `^3.6 || ^4.0`. Refined `count()` in `PaginatorConfig` to return `1` by default if `totalItems` is unknown.
…olution mechanics Implemented detection for duplicate filter aliases in `ListModel` and introduced backend error messages for better user feedback. Refactored `ListDriver` resolution with a dedicated `ListDriverResolver` class to centralize logic. Updated `ListSpecBuilder`, `ListSpecFactory`, and related classes to use the resolver. Enhanced backend filter info template to display alias conflicts. Added corresponding translations and adjusted `ElementDcaListener` for alias check logic.
…codebase Aligned all `FlareException` instantiations to use the `method: __METHOD__` parameter for consistency. Updated exception messages and adjusted formatting where necessary to ensure compliance with the revised standard.
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.
This pull request introduces significant refactoring and cleanup to the codebase, focusing on backend configuration, dependency injection, and code quality. The main changes include the removal of several legacy or redundant contracts, the introduction of a new DCA (Data Container Array) configuration API, and updates to service definitions and code quality settings.
Backend configuration and DCA API:
Introduced a new DCA configuration API with
DcaBuilder,DcaBuilderInterface, andDcaContextto standardize and streamline backend configuration for filter elements and list types. This includes the newDcaContractinterface for elements that configure their Contao backend appearance. (src/DataContainer/Builder/DcaBuilder.php[1]src/DataContainer/Builder/DcaBuilderInterface.php[2]src/DataContainer/Builder/DcaContext.php[3]src/Contract/DcaContract.php[4]Removed the legacy
PaletteContractand related configuration classes, as well as several filter element contracts, in favor of the new DCA API. (src/Contract/PaletteContract.php[1]src/Contract/Config/PaletteConfig.php[2]src/Contract/Config/ListItemProviderConfig.php[3]src/Contract/FilterElement/FormDataContract.php[4]src/Contract/FilterElement/FormTypeOptionsContract.php[5]src/Contract/FilterElement/HydrateFormContract.php[6]src/Contract/FilterElement/IntrinsicValueContract.php[7]src/Contract/FilterElement/RuntimeValueContract.php[8]Dependency injection and service configuration:
services.yamlto exclude new directories (DataContainer/Builder, a filter element file) from autowiring and removed the now-unneededFilterInvokerResolverservice definition. (config/services.yaml[1] [2] [3]Code quality and static analysis:
mago.tomlto restrict source paths to onlysrc/, add an assertion style rule, and improve static analysis configuration. (mago.toml[1] [2]Collection and utility classes:
AbstractCollectionandFilterDefinitionCollectionclasses, likely as part of the refactoring and simplification. (src/Collection/AbstractCollection.php[1]src/Collection/FilterDefinitionCollection.php[2]These changes collectively modernize the backend configuration approach, remove dead code, and improve maintainability.This pull request introduces a significant refactor of the filter system, focusing on renaming and replacing the
FilterDefinitionconcept withConfiguredFilter, and removing the custom filter invoker attribute/registration system. It also cleans up configuration and code style, and removes now-unnecessary files related to filter invoker registration.Key changes:
Filter System Refactor
Replaced all uses of
FilterDefinitionwithConfiguredFilterthroughout the codebase, including type hints, method signatures, and documentation. The collection class was renamed fromFilterDefinitionCollectiontoConfiguredFilterCollection, with corresponding updates to methods and type annotations. (src/Collection/ConfiguredFilterCollection.php, [1] [2] [3] [4] [5] [6];src/Contract/FilterElement/HydrateFormContract.php, [7];src/Contract/FilterElement/IntrinsicValueContract.php, [8] [9];src/Contract/FilterElement/RuntimeValueContract.php, [10] [11];src/DataContainer/FilterContainer.php, [12] [13] [14] [15]Removed the
AsFilterInvokerattribute and the compiler passRegisterFilterInvokersPass, effectively eliminating custom filter invoker registration via attributes. Related service configuration and autoconfiguration were also cleaned up. (src/DependencyInjection/Attribute/AsFilterInvoker.php, [1];src/DependencyInjection/Compiler/RegisterFilterInvokersPass.php, [2];config/services.yaml, [3];src/DependencyInjection/HeimrichHannotFlareExtension.php, [4] [5]Configuration and Code Style
Updated
mago.tomlto only include thesrc/directory in the source paths and added a rule for assertion style. (mago.toml, [1] [2]Minor code cleanup, such as removing unnecessary comments and ignoring obsolete PHPStan directives. (
src/DependencyInjection/Configuration.php, src/DependencyInjection/Configuration.phpL17)These changes modernize and streamline the filter system, making it more consistent and easier to maintain by relying on the new
ConfiguredFiltermodel and removing legacy invoker registration code.