Skip to content

Commit 7b013a9

Browse files
author
Olivier Dolbeau
committed
Deal with Translator interface coming from component (3.4) & contracts (5.0)
1 parent 8bad7f6 commit 7b013a9

File tree

6 files changed

+113
-10
lines changed

6 files changed

+113
-10
lines changed

Tests/Unit/Translator/EditInPlaceTranslatorTest.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,32 @@
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\RequestStack;
1717
use Symfony\Component\Translation\Loader\ArrayLoader;
18-
use Symfony\Component\Translation\TranslatorInterface;
18+
use Symfony\Contracts\Translation\TranslatorInterface as NewTranslatorInterface;
1919
use Translation\Bundle\EditInPlace\ActivatorInterface;
2020
use Translation\Bundle\Translator\EditInPlaceTranslator;
21+
use Translation\Bundle\Translator\TranslatorInterface;
2122

2223
/**
2324
* @author Damien Alexandre <dalexandre@jolicode.com>
2425
*/
2526
final class EditInPlaceTranslatorTest extends TestCase
2627
{
28+
public function testWithNotLocaleAwareTranslator()
29+
{
30+
if (!\interface_exists(NewTranslatorInterface::class)) {
31+
$this->markTestSkipped('Relevant only when NewTranslatorInterface is available.');
32+
}
33+
34+
$symfonyTranslator = $this->getMockBuilder(NewTranslatorInterface::class)->getMock();
35+
$activator = new FakeActivator(true);
36+
$requestStack = new RequestStack();
37+
38+
$this->expectException(\InvalidArgumentException::class);
39+
$this->expectExceptionMessage('The given translator must implements LocaleAwareInterface.');
40+
41+
new EditInPlaceTranslator($symfonyTranslator, $activator, $requestStack);
42+
}
43+
2744
public function testEnabled(): void
2845
{
2946
$symfonyTranslator = $this->getMockBuilder(TranslatorInterface::class)->getMock();

Tests/Unit/Translator/FallbackTranslatorTest.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
use Nyholm\NSA;
1515
use PHPUnit\Framework\TestCase;
16-
use Symfony\Component\Translation\TranslatorInterface;
16+
use Symfony\Contracts\Translation\TranslatorInterface as NewTranslatorInterface;
1717
use Translation\Bundle\Translator\FallbackTranslator;
18+
use Translation\Bundle\Translator\TranslatorInterface;
1819
use Translation\Translator\Translator;
1920
use Translation\Translator\TranslatorService;
2021

@@ -23,6 +24,21 @@
2324
*/
2425
final class FallbackTranslatorTest extends TestCase
2526
{
27+
public function testWithNotLocaleAwareTranslator()
28+
{
29+
if (!\interface_exists(NewTranslatorInterface::class)) {
30+
$this->markTestSkipped('Relevant only when NewTranslatorInterface is available.');
31+
}
32+
33+
$symfonyTranslator = $this->getMockBuilder(NewTranslatorInterface::class)->getMock();
34+
$translator = new Translator();
35+
36+
$this->expectException(\InvalidArgumentException::class);
37+
$this->expectExceptionMessage('The given translator must implements LocaleAwareInterface.');
38+
39+
new FallbackTranslator('en', $symfonyTranslator, $translator);
40+
}
41+
2642
public function testTranslateWithSubstitutedParameters(): void
2743
{
2844
$symfonyTranslator = $this->getMockBuilder(TranslatorInterface::class)->getMock();

Translator/EditInPlaceTranslator.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@
1414
use Symfony\Component\HttpFoundation\RequestStack;
1515
use Symfony\Component\Translation\MessageCatalogueInterface;
1616
use Symfony\Component\Translation\TranslatorBagInterface;
17-
use Symfony\Component\Translation\TranslatorInterface;
17+
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
18+
use Symfony\Contracts\Translation\LocaleAwareInterface;
19+
use Symfony\Contracts\Translation\TranslatorInterface as NewTranslatorInterface;
1820
use Translation\Bundle\EditInPlace\ActivatorInterface;
1921

2022
/**
2123
* Custom Translator for HTML rendering only (output `<x-trans>` tags).
2224
*
2325
* @author Damien Alexandre <dalexandre@jolicode.com>
2426
*/
25-
final class EditInPlaceTranslator implements TranslatorInterface, TranslatorBagInterface
27+
final class EditInPlaceTranslator implements TranslatorInterface
2628
{
2729
/**
28-
* @var TranslatorInterface|TranslatorBagInterface
30+
* @var LegacyTranslatorInterface|NewTranslatorInterface
2931
*/
3032
private $translator;
3133

@@ -39,8 +41,21 @@ final class EditInPlaceTranslator implements TranslatorInterface, TranslatorBagI
3941
*/
4042
private $requestStack;
4143

42-
public function __construct(TranslatorInterface $translator, ActivatorInterface $activator, RequestStack $requestStack)
44+
/**
45+
* $translator param can't be type hinted as we have to deal with both LegacyTranslatorInterface & NewTranslatorInterface.
46+
* Once we won't support sf ^3.4 anymore, we will be able to type hint $translator with NewTranslatorInterface.
47+
*
48+
* @param LegacyTranslatorInterface|NewTranslatorInterface $translator
49+
*/
50+
public function __construct($translator, ActivatorInterface $activator, RequestStack $requestStack)
4351
{
52+
if (!$translator instanceof LegacyTranslatorInterface && !$translator instanceof LocaleAwareInterface) {
53+
throw new \InvalidArgumentException('The given translator must implements LocaleAwareInterface.');
54+
}
55+
if (!$translator instanceof TranslatorBagInterface) {
56+
throw new \InvalidArgumentException('The given translator must implements TranslatorBagInterface.');
57+
}
58+
4459
$this->translator = $translator;
4560
$this->activator = $activator;
4661
$this->requestStack = $requestStack;

Translator/FallbackTranslator.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,20 @@
1313

1414
use Symfony\Component\Translation\MessageCatalogueInterface;
1515
use Symfony\Component\Translation\TranslatorBagInterface;
16-
use Symfony\Component\Translation\TranslatorInterface;
16+
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
17+
use Symfony\Contracts\Translation\LocaleAwareInterface;
18+
use Symfony\Contracts\Translation\TranslatorInterface as NewTranslatorInterface;
1719
use Translation\Translator\Translator;
1820

1921
/**
2022
* This is a bridge between Symfony's translator service and Translation\Translator\Translator.
2123
*
2224
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
2325
*/
24-
final class FallbackTranslator implements TranslatorInterface, TranslatorBagInterface
26+
final class FallbackTranslator implements TranslatorInterface
2527
{
2628
/**
27-
* @var TranslatorInterface|TranslatorBagInterface
29+
* @var LegacyTranslatorInterface|NewTranslatorInterface
2830
*/
2931
private $symfonyTranslator;
3032

@@ -38,8 +40,22 @@ final class FallbackTranslator implements TranslatorInterface, TranslatorBagInte
3840
*/
3941
private $defaultLocale;
4042

41-
public function __construct(string $defaultLocale, TranslatorInterface $symfonyTranslator, Translator $externalTranslator)
43+
/**
44+
* $symfonyTranslator param can't be type hinted as we have to deal with both LegacyTranslatorInterface & NewTranslatorInterface.
45+
* Once we won't support sf ^3.4 anymore, we will be able to type hint $symfonyTranslator with NewTranslatorInterface.
46+
*
47+
* @param LegacyTranslatorInterface|NewTranslatorInterface $symfonyTranslator
48+
*/
49+
public function __construct(string $defaultLocale, $symfonyTranslator, Translator $externalTranslator)
4250
{
51+
if (!$symfonyTranslator instanceof LegacyTranslatorInterface && !$symfonyTranslator instanceof LocaleAwareInterface) {
52+
throw new \InvalidArgumentException('The given translator must implements LocaleAwareInterface.');
53+
}
54+
55+
if (!$symfonyTranslator instanceof TranslatorBagInterface) {
56+
throw new \InvalidArgumentException('The given translator must implements TranslatorBagInterface.');
57+
}
58+
4359
$this->symfonyTranslator = $symfonyTranslator;
4460
$this->externalTranslator = $externalTranslator;
4561
$this->defaultLocale = $defaultLocale;

Translator/TranslatorInterface.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <tobias.nyholm@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Bundle\Translator;
13+
14+
use Symfony\Component\Translation\TranslatorBagInterface;
15+
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
16+
use Symfony\Contracts\Translation\LocaleAwareInterface;
17+
use Symfony\Contracts\Translation\TranslatorInterface as NewTranslatorInterface;
18+
19+
/*
20+
* This interface is here to allow us to support both sf 3.x with
21+
* LegacyTranslatorInterface & sf 5.x where this interface have been replaced
22+
* by NewLocalAwareInterface.
23+
*
24+
* When sf 3.4 won't be supported anymore, this interface will become useless.
25+
*/
26+
27+
if (\interface_exists(NewTranslatorInterface::class)) {
28+
interface TranslatorInterface extends NewTranslatorInterface, LocaleAwareInterface, TranslatorBagInterface
29+
{
30+
}
31+
} else {
32+
interface TranslatorInterface extends LegacyTranslatorInterface, TranslatorBagInterface
33+
{
34+
}
35+
}

phpstan.neon.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,7 @@ parameters:
3939
-
4040
path: %currentWorkingDirectory%/DependencyInjection/Configuration.php
4141
message: '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder::root()#'
42+
43+
-
44+
path: %currentWorkingDirectory%/Translator
45+
message: '#Call to an undefined method Symfony\\Component\\Translation\\TranslatorInterface|Symfony\\Contracts\\Translation\\TranslatorInterface::getCatalogue().#'

0 commit comments

Comments
 (0)