Skip to content

Commit d7e38ea

Browse files
committed
refactor: consolidate semver-sort wiring into SemverSortableCrudControllerTrait
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.
1 parent 80aa6f2 commit d7e38ea

7 files changed

Lines changed: 64 additions & 66 deletions

src/Controller/Admin/DockerImageTagCrudController.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,21 @@
55
namespace App\Controller\Admin;
66

77
use App\Admin\Field\VersionField;
8-
use App\Admin\SemverSort;
98
use App\Entity\DockerImageTag;
109
use App\Form\Type\Admin\SemverFilter;
11-
use Doctrine\ORM\QueryBuilder;
12-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
13-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
10+
use App\Trait\SemverSortableCrudControllerTrait;
1411
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
1512
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
1613
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
1714
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
1815
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
19-
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
20-
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
2116
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
2217
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
2318

2419
class DockerImageTagCrudController extends AbstractCrudController
2520
{
21+
use SemverSortableCrudControllerTrait;
22+
2623
public static function getEntityFqcn(): string
2724
{
2825
return DockerImageTag::class;
@@ -65,11 +62,8 @@ public function configureFilters(Filters $filters): Filters
6562
}
6663

6764
#[\Override]
68-
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
65+
protected function semverSortedProperties(): array
6966
{
70-
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
71-
SemverSort::apply($qb, 'tag');
72-
73-
return $qb;
67+
return ['tag'];
7468
}
7569
}

src/Controller/Admin/GitTagCrudController.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,20 @@
55
namespace App\Controller\Admin;
66

77
use App\Admin\Field\VersionField;
8-
use App\Admin\SemverSort;
98
use App\Entity\GitTag;
109
use App\Form\Type\Admin\SemverFilter;
11-
use Doctrine\ORM\QueryBuilder;
12-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
13-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
10+
use App\Trait\SemverSortableCrudControllerTrait;
1411
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
1512
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
1613
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
1714
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
1815
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
19-
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
20-
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
2116
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
2217

2318
class GitTagCrudController extends AbstractCrudController
2419
{
20+
use SemverSortableCrudControllerTrait;
21+
2522
public static function getEntityFqcn(): string
2623
{
2724
return GitTag::class;
@@ -66,11 +63,8 @@ public function configureFilters(Filters $filters): Filters
6663
}
6764

6865
#[\Override]
69-
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
66+
protected function semverSortedProperties(): array
7067
{
71-
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
72-
SemverSort::apply($qb, 'tag');
73-
74-
return $qb;
68+
return ['tag'];
7569
}
7670
}

src/Controller/Admin/InstallationCrudController.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,16 @@
99
use App\Admin\Field\RootDirField;
1010
use App\Admin\Field\ServerTypeField;
1111
use App\Admin\Field\VersionField;
12-
use App\Admin\SemverSort;
1312
use App\Entity\Installation;
1413
use App\Form\Type\Admin\FrameworkFilter;
1514
use App\Form\Type\Admin\SemverFilter;
1615
use App\Trait\ExportCrudControllerTrait;
17-
use Doctrine\ORM\QueryBuilder;
18-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
19-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
16+
use App\Trait\SemverSortableCrudControllerTrait;
2017
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
2118
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
2219
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
2320
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
2421
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
25-
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
26-
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
2722
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
2823
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
2924
use EasyCorp\Bundle\EasyAdminBundle\Field\CodeEditorField;
@@ -32,6 +27,7 @@
3227
class InstallationCrudController extends AbstractCrudController
3328
{
3429
use ExportCrudControllerTrait;
30+
use SemverSortableCrudControllerTrait;
3531

3632
public static function getEntityFqcn(): string
3733
{
@@ -95,11 +91,8 @@ public function configureFilters(Filters $filters): Filters
9591
}
9692

9793
#[\Override]
98-
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
94+
protected function semverSortedProperties(): array
9995
{
100-
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
101-
SemverSort::apply($qb, 'frameworkVersion', 'composerVersion');
102-
103-
return $qb;
96+
return ['frameworkVersion', 'composerVersion'];
10497
}
10598
}

src/Controller/Admin/ModuleVersionCrudController.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,20 @@
55
namespace App\Controller\Admin;
66

77
use App\Admin\Field\VersionField;
8-
use App\Admin\SemverSort;
98
use App\Entity\ModuleVersion;
109
use App\Form\Type\Admin\SemverFilter;
11-
use Doctrine\ORM\QueryBuilder;
12-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
13-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
10+
use App\Trait\SemverSortableCrudControllerTrait;
1411
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
1512
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
1613
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
1714
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
1815
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
19-
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
20-
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
2116
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
2217

2318
class ModuleVersionCrudController extends AbstractCrudController
2419
{
20+
use SemverSortableCrudControllerTrait;
21+
2522
public static function getEntityFqcn(): string
2623
{
2724
return ModuleVersion::class;
@@ -63,11 +60,8 @@ public function configureFilters(Filters $filters): Filters
6360
}
6461

6562
#[\Override]
66-
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
63+
protected function semverSortedProperties(): array
6764
{
68-
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
69-
SemverSort::apply($qb, 'version');
70-
71-
return $qb;
65+
return ['version'];
7266
}
7367
}

src/Controller/Admin/PackageVersionCrudController.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,22 @@
77
use App\Admin\Field\AdvisoryCountField;
88
use App\Admin\Field\LatestStatusField;
99
use App\Admin\Field\VersionField;
10-
use App\Admin\SemverSort;
1110
use App\Entity\PackageVersion;
1211
use App\Form\Type\Admin\SemverFilter;
13-
use Doctrine\ORM\QueryBuilder;
14-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
15-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
12+
use App\Trait\SemverSortableCrudControllerTrait;
1613
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
1714
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
1815
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
1916
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
2017
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
21-
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
22-
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
2318
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
2419
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
2520
use EasyCorp\Bundle\EasyAdminBundle\Field\UrlField;
2621

2722
class PackageVersionCrudController extends AbstractCrudController
2823
{
24+
use SemverSortableCrudControllerTrait;
25+
2926
public static function getEntityFqcn(): string
3027
{
3128
return PackageVersion::class;
@@ -77,11 +74,8 @@ public function configureFilters(Filters $filters): Filters
7774
}
7875

7976
#[\Override]
80-
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
77+
protected function semverSortedProperties(): array
8178
{
82-
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
83-
SemverSort::apply($qb, 'version', 'latest');
84-
85-
return $qb;
79+
return ['version', 'latest'];
8680
}
8781
}

src/Controller/Admin/SiteCrudController.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,22 @@
1111
use App\Admin\Field\ServerTypeField;
1212
use App\Admin\Field\SiteTypeField;
1313
use App\Admin\Field\VersionField;
14-
use App\Admin\SemverSort;
1514
use App\Entity\Site;
1615
use App\Form\Type\Admin\SemverFilter;
1716
use App\Trait\ExportCrudControllerTrait;
18-
use Doctrine\ORM\QueryBuilder;
19-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
20-
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
17+
use App\Trait\SemverSortableCrudControllerTrait;
2118
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
2219
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
2320
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
2421
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
2522
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
26-
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
27-
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
2823
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
2924
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
3025

3126
class SiteCrudController extends AbstractCrudController
3227
{
3328
use ExportCrudControllerTrait;
29+
use SemverSortableCrudControllerTrait;
3430

3531
public function __construct()
3632
{
@@ -88,11 +84,8 @@ public function configureFilters(Filters $filters): Filters
8884
}
8985

9086
#[\Override]
91-
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
87+
protected function semverSortedProperties(): array
9288
{
93-
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
94-
SemverSort::apply($qb, 'phpVersion');
95-
96-
return $qb;
89+
return ['phpVersion'];
9790
}
9891
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Trait;
6+
7+
use App\Admin\SemverSort;
8+
use Doctrine\ORM\QueryBuilder;
9+
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
10+
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
11+
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
12+
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
13+
14+
/**
15+
* Adds semver-aware ORDER BY rewriting to a CRUD controller. The using
16+
* controller declares which root-alias properties hold semver strings
17+
* via {@see semverSortedProperties()}; this trait then transparently
18+
* wraps those properties in SEMVER_NUMERIC() in the index query.
19+
*/
20+
trait SemverSortableCrudControllerTrait
21+
{
22+
/**
23+
* @return list<string> property names on the root entity whose
24+
* ORDER BY should use semver order instead of
25+
* lexicographic string order
26+
*/
27+
abstract protected function semverSortedProperties(): array;
28+
29+
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
30+
{
31+
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
32+
SemverSort::apply($qb, ...$this->semverSortedProperties());
33+
34+
return $qb;
35+
}
36+
}

0 commit comments

Comments
 (0)