Skip to content

Commit e0cfa3a

Browse files
committed
Fix filter labels not translated with correct domain
Filter labels were not being translated the same way as on other CRUD pages because the label was passed as a plain string while filters use translation_domain 'EasyAdminBundle'. Now CommonConfigurator: - Preserves TranslatableInterface labels from fields - Wraps string labels in t() with the application's translation domain Fix #7373
1 parent 640e870 commit e0cfa3a

2 files changed

Lines changed: 136 additions & 4 deletions

File tree

src/Filter/Configurator/CommonConfigurator.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
99
use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterDto;
1010
use EasyCorp\Bundle\EasyAdminBundle\Generator\LabelGenerator;
11-
use Symfony\Component\Translation\TranslatableMessage;
11+
use Symfony\Contracts\Translation\TranslatableInterface;
12+
use function Symfony\Component\Translation\t;
1213

1314
/**
1415
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
@@ -24,10 +25,16 @@ public function configure(FilterDto $filterDto, ?FieldDto $fieldDto, EntityDto $
2425
{
2526
if (null === $filterDto->getLabel()) {
2627
$fieldLabel = $fieldDto?->getLabel();
27-
if ($fieldLabel instanceof TranslatableMessage) {
28-
$fieldLabel = $fieldLabel->getMessage();
28+
$translationDomain = $context->getI18n()->getTranslationDomain();
29+
30+
if ($fieldLabel instanceof TranslatableInterface) {
31+
$label = $fieldLabel;
32+
} elseif (null !== $fieldLabel) {
33+
$label = t($fieldLabel, [], $translationDomain);
34+
} else {
35+
$label = t(LabelGenerator::humanize($filterDto->getProperty()), [], $translationDomain);
2936
}
30-
$label = $fieldLabel ?? LabelGenerator::humanize($filterDto->getProperty());
37+
3138
$filterDto->setLabel($label);
3239
}
3340
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
namespace EasyCorp\Bundle\EasyAdminBundle\Tests\Unit\Filter\Configurator;
4+
5+
use Doctrine\ORM\Mapping\ClassMetadata;
6+
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
7+
use EasyCorp\Bundle\EasyAdminBundle\Context\I18nContext;
8+
use EasyCorp\Bundle\EasyAdminBundle\Context\RequestContext;
9+
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
10+
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
11+
use EasyCorp\Bundle\EasyAdminBundle\Filter\Configurator\CommonConfigurator;
12+
use EasyCorp\Bundle\EasyAdminBundle\Filter\TextFilter;
13+
use PHPUnit\Framework\TestCase;
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\Translation\TranslatableMessage;
16+
use Symfony\Contracts\Translation\TranslatableInterface;
17+
18+
class CommonConfiguratorTest extends TestCase
19+
{
20+
private EntityDto $entityDto;
21+
private CommonConfigurator $configurator;
22+
23+
protected function setUp(): void
24+
{
25+
$metadata = new ClassMetadata('App\Entity\Product');
26+
$metadata->setIdentifier(['id']);
27+
$this->entityDto = new EntityDto('App\Entity\Product', $metadata);
28+
$this->configurator = new CommonConfigurator();
29+
}
30+
31+
public function testSupportsAllFilters(): void
32+
{
33+
$filter = TextFilter::new('name');
34+
$filterDto = $filter->getAsDto();
35+
$adminContext = $this->createAdminContext();
36+
37+
$this->assertTrue($this->configurator->supports($filterDto, null, $this->entityDto, $adminContext));
38+
}
39+
40+
public function testConfigureUsesFieldLabelAndWrapsInTranslatable(): void
41+
{
42+
$filter = TextFilter::new('name');
43+
$filterDto = $filter->getAsDto();
44+
45+
$field = TextField::new('name', 'Product Name');
46+
$fieldDto = $field->getAsDto();
47+
48+
$adminContext = $this->createAdminContext();
49+
50+
$this->configurator->configure($filterDto, $fieldDto, $this->entityDto, $adminContext);
51+
52+
$this->assertInstanceOf(TranslatableInterface::class, $filterDto->getLabel());
53+
}
54+
55+
public function testConfigurePreservesTranslatableInterfaceFromField(): void
56+
{
57+
$filter = TextFilter::new('name');
58+
$filterDto = $filter->getAsDto();
59+
60+
$translatableLabel = new TranslatableMessage('product.name', [], 'messages');
61+
$field = TextField::new('name');
62+
$fieldDto = $field->getAsDto();
63+
$fieldDto->setLabel($translatableLabel);
64+
65+
$adminContext = $this->createAdminContext();
66+
67+
$this->configurator->configure($filterDto, $fieldDto, $this->entityDto, $adminContext);
68+
69+
$this->assertSame($translatableLabel, $filterDto->getLabel());
70+
}
71+
72+
public function testConfigureHumanizesLabelAndWrapsInTranslatable(): void
73+
{
74+
$filter = TextFilter::new('productName');
75+
$filterDto = $filter->getAsDto();
76+
77+
$adminContext = $this->createAdminContext();
78+
79+
$this->configurator->configure($filterDto, null, $this->entityDto, $adminContext);
80+
81+
$label = $filterDto->getLabel();
82+
$this->assertInstanceOf(TranslatableInterface::class, $label);
83+
$this->assertSame('Product Name', $label->getMessage());
84+
}
85+
86+
public function testConfigureUsesCorrectTranslationDomain(): void
87+
{
88+
$filter = TextFilter::new('name');
89+
$filterDto = $filter->getAsDto();
90+
91+
$field = TextField::new('name', 'custom.translation.key');
92+
$fieldDto = $field->getAsDto();
93+
94+
$adminContext = $this->createAdminContext('my_domain');
95+
96+
$this->configurator->configure($filterDto, $fieldDto, $this->entityDto, $adminContext);
97+
98+
$label = $filterDto->getLabel();
99+
$this->assertInstanceOf(TranslatableMessage::class, $label);
100+
$this->assertSame('custom.translation.key', $label->getMessage());
101+
$this->assertSame('my_domain', $label->getDomain());
102+
}
103+
104+
public function testConfigureDoesNotOverrideExplicitFilterLabel(): void
105+
{
106+
$filter = TextFilter::new('name')->setLabel('Custom Label');
107+
$filterDto = $filter->getAsDto();
108+
109+
$adminContext = $this->createAdminContext();
110+
111+
$this->configurator->configure($filterDto, null, $this->entityDto, $adminContext);
112+
113+
$this->assertSame('Custom Label', $filterDto->getLabel());
114+
}
115+
116+
private function createAdminContext(string $translationDomain = 'messages'): AdminContext
117+
{
118+
return AdminContext::forTesting(
119+
RequestContext::forTesting(new Request()),
120+
null,
121+
null,
122+
I18nContext::forTesting('en', 'ltr', $translationDomain)
123+
);
124+
}
125+
}

0 commit comments

Comments
 (0)