release/1.11.0#79
Merged
Merged
Conversation
Add a reusable EasyAdmin filter for dotted-version columns that compares using semver order (=, !=, >, >=, <, <=) instead of the default lexicographic string comparison, so e.g. "10.5.9" correctly sorts above "9.5.1" and "v5.5.40" sorts identically to "5.5.40". Comparison runs in SQL via a new Doctrine DQL function SEMVER_NUMERIC(version) that strips an optional leading v/V, then packs major/minor/patch/extra into a sortable BIGINT using SUBSTRING_INDEX + CAST AS UNSIGNED. A REGEXP guard on the column excludes non-semver rows (?, unknown, "main", ...) from results when the filter is active. Wired into the version columns on Installation (frameworkVersion, composerVersion), PackageVersion (version, latest), ModuleVersion (version), Site (phpVersion), GitTag (tag) and DockerImageTag (tag).
Three independent bugs were hiding behind each other and meant the filter silently no-oped (matched everything). Browser test against ?filters[type]=drupal&filters[frameworkVersion][comparison]=<= &filters[frameworkVersion][value]=10.6.3 returned 11.x rows. 1. SemverFilter::apply() assumed FilterDataDto::getValue() returned the full compound-form array and did `if (!is_array($data)) return;`. In EasyAdmin 5 the DTO already splits compound forms into getValue() (the scalar) and getComparison() (the operator), so the early return fired and no constraint was added. Switched to the documented API. 2. Once the WHERE clause was added, the original draft used a DQL-level REGEXP keyword for the non-semver guard. DQL doesn't recognise REGEXP and Doctrine threw a syntax error. Moved the regex into SEMVER_NUMERIC itself: the function now wraps its arithmetic in CASE WHEN col REGEXP '...' THEN ... ELSE NULL END, so non-semver rows collapse to NULL and are excluded by any comparison. 3. Passing the user input through SEMVER_NUMERIC a second time emitted the argument-placeholder five times (the function references its argument once for the regex and four times for the segments), so PDO saw five `?` but only one bound value. Computed the numeric in PHP (toSemverNumeric) and bind it as a single BIGINT. Multipliers shrunk from 10^6 to 10^4 per segment so the precomputed value fits in PHP_INT_MAX. Adds a regression test against FilterDataDto's actual shape to keep all three from coming back.
Adds two range operators so the admin can filter by a version interval in a single filter: * between (inclusive) → SEMVER_NUMERIC(col) >= a AND <= b * between (exclusive) → SEMVER_NUMERIC(col) > a AND < b The exclusive variant covers the common "greater than X, lower than Y" case directly (e.g. >10 AND <11.3 in one filter). SemverFilterType gains a `value2` text field used as the upper bound for the range operators (ignored otherwise). SemverFilter::apply() validates both ends through composer/semver and binds the precomputed BIGINTs as two parameters. Also fixes a latent bug in the COMPARISON_CHOICES validity check that was using values as keys; it happened to work for =/!=/etc. because the key and value were identical, but broke once between-style entries had distinct labels.
Clicking the column header on a version column (ver., Comp., PHP, Tag, version/latest) now sorts in semver order instead of lexicographic, so 10.5.9 correctly comes above 9.5.1 and 11.2.10 above 11.2.8. Implemented with a tiny SemverSort helper that walks the QueryBuilder's existing orderBy parts and rewrites "entity.<prop> <dir>" into "SEMVER_NUMERIC(entity.<prop>) <dir>" for the listed properties. Each affected CRUD controller overrides createIndexQueryBuilder() to invoke it for its version columns: * InstallationCrudController: frameworkVersion, composerVersion * PackageVersionCrudController: version, latest * ModuleVersionCrudController: version * SiteCrudController: phpVersion * GitTagCrudController: tag * DockerImageTagCrudController: tag Non-matching ORDER BY parts are left untouched, so combined sorts (e.g. ORDER BY type ASC, frameworkVersion DESC) still work.
…ollerTrait
The six CRUD controllers all had the same createIndexQueryBuilder()
override calling SemverSort::apply() with a property list — plus
seven matching use statements each.
Extracted the boilerplate into App\Trait\SemverSortableCrudControllerTrait,
which declares one abstract semverSortedProperties(): array hook and
provides the override. Each controller now reduces to:
use SemverSortableCrudControllerTrait;
protected function semverSortedProperties(): array
{
return ['frameworkVersion', 'composerVersion'];
}
Net −38 lines across the six controllers; behavior unchanged.
feat: add semver filter to admin version columns
Filling the upper-bound field together with >=, >, <=, or < used to silently drop the upper bound, so ?comparison=>=&value=11.0.0&value2=11.2.0 returned everything >= 11.0.0 instead of [11.0.0, 11.2.0]. apply() now auto-promotes to a range whenever value2 is supplied with a directional operator. The operator carries inclusivity (>=/<= → inclusive, >/< → exclusive) and the two values are sorted numerically so the order the user typed them in doesn't matter. = and != still treat the second value as ignored (exact match semantics). Form placeholder updated to "upper bound (optional, makes it a range)" so it no longer reads as exclusive to between.
fix: SemverFilter must respect value2 with directional operators
Adds a "Server type" dropdown filter (Prod / Stg / DevOps / GPU via ServerTypeType::CHOICES) and makes the Type column header clickable to sort on those three admin lists. ServerTypeFilter learned to handle dotted property names by joining the relation itself — EasyAdmin doesn't auto-join for filters on nested paths (EasyCorp/EasyAdminBundle#4120). The filter reuses the plain relation name as the join alias to match EA's own sort-side auto-join, so combining filter + sort on the same association produces a single JOIN in the generated SQL.
Codecov flagged 0% patch coverage on the new dotted-path handling. Three KernelTest cases cover: * flat property → no JOIN, compares on root alias * nested property → auto-LEFT-JOINs the relation under the plain alias * nested property when the alias already exists → no duplicate JOIN
feat: add server.type filter and sort to Installation, Site, Domain
* composer update — minor/patch bumps across Symfony 8.0.9→8.0.11, EasyAdmin 5.0.7→5.0.8, php-cs-fixer 3.95.1→3.95.2, PHPUnit 13.1.8→13.1.10, PHPStan, Doctrine and friends. No security advisories. composer.json validates strict. * Replace the deprecated PHP_CS_FIXER_IGNORE_ENV=1 env var on the coding-standards scripts with $config->setUnsupportedPhpVersionAllowed(true) in .php-cs-fixer.dist.php (the supported replacement; the env var is removed in php-cs-fixer 4.0).
chore: update composer dependencies, fix php-cs-fixer deprecation
API Specification - Non-breaking changesAPI Changelog 1.0.0 vs. 1.0.0No changes detected |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #79 +/- ##
=======================================
Coverage ? 41.63%
Complexity ? 866
=======================================
Files ? 125
Lines ? 2738
Branches ? 0
=======================================
Hits ? 1140
Misses ? 1598
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
1.11.0 — 2026-05-19
Cuts a minor release (last release was 1.10.1). The four PRs accumulated under `[Unreleased]` are dominated by new features, so this is a MINOR bump per semver.
Included PRs
Changes in this PR
Test plan