Skip to content

Commit

Permalink
feature #28210 [Contracts] Add Translation\TranslatorInterface + deco…
Browse files Browse the repository at this point in the history
…uple symfony/validator from symfony/translation (nicolas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[Contracts] Add Translation\TranslatorInterface + decouple symfony/validator from symfony/translation

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | #15714, #18930
| License       | MIT
| Doc PR        | -

Let's decouple Validator from Translation component \o/!

TODO:
- [x] add `TranslatorInterface`, deprecate it from Translation
- [x] add `TranslatorTrait`, deprecating `MessageSelector`, `Internal` and `PluralizationRules`
- [x] deprecate `ValidatorBuilderInterface(LegacyTranslatorInterface)`
- [x] inject a new `identity_translator` into `translator.formatter.default`, deprecate `translator.selector`
- [x] copy tests in the Contracts namespace to ensure the `TranslatorTrait` behaves properly
- [x] figure out a way to keep throwing `InvalidArgumentException` from the component
- [x] update UPGRADING and CHANGELOG files
- [x] polish the deprecation layer (ensure all needed runtime deprecations are here)

Reviews welcome already.

Commits
-------

064e369 [Contracts] Add Translation\TranslatorInterface + decouple symfony/validator from symfony/translation
  • Loading branch information
fabpot committed Sep 3, 2018
2 parents 19e5218 + 064e369 commit 59fad59
Show file tree
Hide file tree
Showing 58 changed files with 1,011 additions and 203 deletions.
12 changes: 12 additions & 0 deletions UPGRADE-4.2.md
Expand Up @@ -149,3 +149,15 @@ Serializer

* Relying on the default value (false) of the "as_collection" option is deprecated since 4.2.
You should set it to false explicitly instead as true will be the default value in 5.0.

Translation
-----------

* The `TranslatorInterface` has been deprecated in favor of `Symfony\Contracts\Translation\TranslatorInterface`
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been deprecated, use `IdentityTranslator` instead

Validator
---------

* The component is now decoupled from `symfony/translation` and uses `Symfony\Contracts\Translation\TranslatorInterface` instead
* The `ValidatorBuilderInterface` has been deprecated and `ValidatorBuilder` made final
4 changes: 4 additions & 0 deletions UPGRADE-5.0.md
Expand Up @@ -146,6 +146,8 @@ Translation

* The `FileDumper::setBackup()` method has been removed.
* The `TranslationWriter::disableBackup()` method has been removed.
* The `TranslatorInterface` has been removed in favor of `Symfony\Contracts\Translation\TranslatorInterface`
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been removed, use `IdentityTranslator` instead

TwigBundle
----------
Expand All @@ -158,6 +160,8 @@ Validator
* The `Email::__construct()` 'strict' property has been removed. Use 'mode'=>"strict" instead.
* Calling `EmailValidator::__construct()` method with a boolean parameter has been removed, use `EmailValidator("strict")` instead.
* Removed the `checkDNS` and `dnsMessage` options from the `Url` constraint.
* The component is now decoupled from `symfony/translation` and uses `Symfony\Contracts\Translation\TranslatorInterface` instead
* The `ValidatorBuilderInterface` has been removed and `ValidatorBuilder` is now final

Workflow
--------
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bridge/Twig/Extension/TranslationExtension.php
Expand Up @@ -16,7 +16,7 @@
use Symfony\Bridge\Twig\TokenParser\TransChoiceTokenParser;
use Symfony\Bridge\Twig\TokenParser\TransDefaultDomainTokenParser;
use Symfony\Bridge\Twig\TokenParser\TransTokenParser;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Extension\AbstractExtension;
use Twig\NodeVisitor\NodeVisitorInterface;
use Twig\TokenParser\AbstractTokenParser;
Expand Down
Expand Up @@ -11,7 +11,7 @@

namespace Symfony\Bridge\Twig\Tests\Extension\Fixtures;

use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

class StubTranslator implements TranslatorInterface
{
Expand Down
Expand Up @@ -15,6 +15,7 @@
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Translation\TwigExtractor;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
use Twig\Error\Error;
use Twig\Loader\ArrayLoader;
Expand All @@ -33,7 +34,7 @@ public function testExtract($template, $messages)
'cache' => false,
'autoescape' => false,
));
$twig->addExtension(new TranslationExtension($this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock()));
$twig->addExtension(new TranslationExtension($this->getMockBuilder(TranslatorInterface::class)->getMock()));

$extractor = new TwigExtractor($twig);
$extractor->setPrefix('prefix');
Expand Down Expand Up @@ -82,7 +83,7 @@ public function getExtractData()
public function testExtractSyntaxError($resources)
{
$twig = new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock());
$twig->addExtension(new TranslationExtension($this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock()));
$twig->addExtension(new TranslationExtension($this->getMockBuilder(TranslatorInterface::class)->getMock()));

$extractor = new TwigExtractor($twig);

Expand Down Expand Up @@ -124,7 +125,7 @@ public function testExtractWithFiles($resource)
'cache' => false,
'autoescape' => false,
));
$twig->addExtension(new TranslationExtension($this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock()));
$twig->addExtension(new TranslationExtension($this->getMockBuilder(TranslatorInterface::class)->getMock()));

$extractor = new TwigExtractor($twig);
$catalogue = new MessageCatalogue('en');
Expand Down
5 changes: 3 additions & 2 deletions src/Symfony/Bridge/Twig/composer.json
Expand Up @@ -29,7 +29,7 @@
"symfony/polyfill-intl-icu": "~1.0",
"symfony/routing": "~3.4|~4.0",
"symfony/templating": "~3.4|~4.0",
"symfony/translation": "~3.4|~4.0",
"symfony/translation": "~4.2",
"symfony/yaml": "~3.4|~4.0",
"symfony/security": "~3.4|~4.0",
"symfony/security-acl": "~2.8|~3.0",
Expand All @@ -41,8 +41,9 @@
"symfony/workflow": "~3.4|~4.0"
},
"conflict": {
"symfony/console": "<3.4",
"symfony/form": "<4.1.2",
"symfony/console": "<3.4"
"symfony/translation": "<4.2"
},
"suggest": {
"symfony/finder": "",
Expand Down
Expand Up @@ -15,7 +15,7 @@
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* Generates the catalogues for translations.
Expand Down
Expand Up @@ -26,7 +26,7 @@
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Reader\TranslationReaderInterface;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* Helps finding unused or missing translation messages in a given locale
Expand Down
Expand Up @@ -15,7 +15,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\Translation\TranslatorBagInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
Expand Down
Expand Up @@ -6,11 +6,13 @@
<services>
<defaults public="false" />

<service id="translator" class="Symfony\Component\Translation\IdentityTranslator" public="true">
<argument type="service" id="translator.selector" />
</service>
<service id="translator" class="Symfony\Component\Translation\IdentityTranslator" public="true" />
<service id="Symfony\Component\Translation\TranslatorInterface" alias="translator" />
<service id="Symfony\Contracts\Translation\TranslatorInterface" alias="translator" />

<service id="translator.selector" class="Symfony\Component\Translation\MessageSelector" />
<service id="identity_translator" class="Symfony\Component\Translation\IdentityTranslator" />
<service id="translator.selector" class="Symfony\Component\Translation\MessageSelector">
<deprecated>The "%service_id%" service is deprecated since Symfony 4.2, use "identity_translator" instead.</deprecated>
</service>
</services>
</container>
Expand Up @@ -21,6 +21,7 @@
</call>
</service>
<service id="Symfony\Component\Translation\TranslatorInterface" alias="translator" />
<service id="Symfony\Contracts\Translation\TranslatorInterface" alias="translator" />

<service id="translator.logging" class="Symfony\Component\Translation\LoggingTranslator">
<argument type="service" id="translator.logging.inner" />
Expand All @@ -29,7 +30,7 @@
</service>

<service id="translator.formatter.default" class="Symfony\Component\Translation\Formatter\MessageFormatter">
<argument type="service" id="translator.selector" />
<argument type="service" id="identity_translator" />
</service>

<service id="translation.loader.php" class="Symfony\Component\Translation\Loader\PhpFileLoader">
Expand Down
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;

use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* @author Fabien Potencier <fabien@symfony.com>
Expand Down
Expand Up @@ -15,7 +15,7 @@
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\DataCollectorTranslatorPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

class DataCollectorTranslatorPassTest extends TestCase
{
Expand Down
Expand Up @@ -11,7 +11,7 @@

namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures;

use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

class StubTranslator implements TranslatorInterface
{
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/composer.json
Expand Up @@ -47,7 +47,7 @@
"symfony/security-csrf": "~3.4|~4.0",
"symfony/serializer": "^4.1",
"symfony/stopwatch": "~3.4|~4.0",
"symfony/translation": "~3.4|~4.0",
"symfony/translation": "~4.2",
"symfony/templating": "~3.4|~4.0",
"symfony/validator": "^4.1",
"symfony/var-dumper": "~3.4|~4.0",
Expand All @@ -71,7 +71,7 @@
"symfony/property-info": "<3.4",
"symfony/serializer": "<4.1",
"symfony/stopwatch": "<3.4",
"symfony/translation": "<3.4",
"symfony/translation": "<4.2",
"symfony/twig-bridge": "<4.1.1",
"symfony/validator": "<4.1",
"symfony/workflow": "<4.1"
Expand Down
Expand Up @@ -19,6 +19,7 @@
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Translation\Translator;
use Twig\Extension\ExtensionInterface;
use Twig\Extension\RuntimeExtensionInterface;
use Twig\Loader\LoaderInterface;
Expand Down Expand Up @@ -48,7 +49,7 @@ public function load(array $configs, ContainerBuilder $container)
$loader->load('console.xml');
}

if (!interface_exists('Symfony\Component\Translation\TranslatorInterface')) {
if (!class_exists(Translator::class)) {
$container->removeDefinition('twig.translation.extractor');
}

Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Bundle/TwigBundle/composer.json
Expand Up @@ -41,7 +41,8 @@
},
"conflict": {
"symfony/dependency-injection": "<4.1",
"symfony/framework-bundle": "<4.1"
"symfony/framework-bundle": "<4.1",
"symfony/translation": "<4.2"
},
"autoload": {
"psr-4": { "Symfony\\Bundle\\TwigBundle\\": "" },
Expand Down
Expand Up @@ -13,7 +13,7 @@

use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* This extension protects forms by using a CSRF token.
Expand Down
Expand Up @@ -18,7 +18,7 @@
use Symfony\Component\Form\Util\ServerParams;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* @author Bernhard Schussek <bschussek@gmail.com>
Expand Down
Expand Up @@ -19,7 +19,7 @@
use Symfony\Component\Form\Util\ServerParams;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* @author Bernhard Schussek <bschussek@gmail.com>
Expand Down
Expand Up @@ -14,7 +14,7 @@
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
Expand Down
Expand Up @@ -17,6 +17,8 @@
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\Test\TypeTestCase;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

class FormTypeCsrfExtensionTest_ChildType extends AbstractType
{
Expand All @@ -42,8 +44,8 @@ class FormTypeCsrfExtensionTest extends TypeTestCase

protected function setUp()
{
$this->tokenManager = $this->getMockBuilder('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface')->getMock();
$this->translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
$this->tokenManager = $this->getMockBuilder(CsrfTokenManagerInterface::class)->getMock();
$this->translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();

parent::setUp();
}
Expand Down
Expand Up @@ -15,12 +15,13 @@
use Symfony\Component\Form\Test\TypeTestCase;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;

class UploadValidatorExtensionTest extends TypeTestCase
{
public function testPostMaxSizeTranslation()
{
$translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
$translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();

$translator->expects($this->any())
->method('trans')
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/Form/composer.json
Expand Up @@ -33,7 +33,7 @@
"symfony/http-foundation": "~3.4|~4.0",
"symfony/http-kernel": "~3.4|~4.0",
"symfony/security-csrf": "~3.4|~4.0",
"symfony/translation": "~3.4|~4.0",
"symfony/translation": "~4.2",
"symfony/var-dumper": "~3.4|~4.0"
},
"conflict": {
Expand All @@ -42,6 +42,7 @@
"symfony/doctrine-bridge": "<3.4",
"symfony/framework-bundle": "<3.4",
"symfony/http-kernel": "<3.4",
"symfony/translation": "<4.2",
"symfony/twig-bridge": "<3.4.5|<4.0.5,>=4.0"
},
"suggest": {
Expand Down
Expand Up @@ -17,7 +17,7 @@
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* Synchronizes the locale between the request and the translator.
Expand Down
Expand Up @@ -17,6 +17,7 @@
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\EventListener\TranslatorListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

class TranslatorListenerTest extends TestCase
{
Expand All @@ -26,7 +27,7 @@ class TranslatorListenerTest extends TestCase

protected function setUp()
{
$this->translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
$this->translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();
$this->requestStack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->getMock();
$this->listener = new TranslatorListener($this->translator, $this->requestStack);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/HttpKernel/composer.json
Expand Up @@ -37,7 +37,7 @@
"symfony/routing": "~3.4|~4.0",
"symfony/stopwatch": "~3.4|~4.0",
"symfony/templating": "~3.4|~4.0",
"symfony/translation": "~3.4|~4.0",
"symfony/translation": "~4.2",
"symfony/var-dumper": "^4.1.1",
"psr/cache": "~1.0"
},
Expand All @@ -47,6 +47,7 @@
"conflict": {
"symfony/config": "<3.4",
"symfony/dependency-injection": "<4.2",
"symfony/translation": "<4.2",
"symfony/var-dumper": "<4.1.1",
"twig/twig": "<1.34|<2.4,>=2"
},
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Translation/CHANGELOG.md
Expand Up @@ -5,6 +5,8 @@ CHANGELOG
-----

* Started using ICU parent locales as fallback locales.
* deprecated `TranslatorInterface` in favor of `Symfony\Contracts\Translation\TranslatorInterface`
* deprecated `MessageSelector`, `Interval` and `PluralizationRules`; use `IdentityTranslator` instead

4.1.0
-----
Expand Down
Expand Up @@ -12,11 +12,13 @@
namespace Symfony\Component\Translation;

use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
*/
class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface
class DataCollectorTranslator implements LegacyTranslatorInterface, TranslatorBagInterface
{
const MESSAGE_DEFINED = 0;
const MESSAGE_MISSING = 1;
Expand Down

0 comments on commit 59fad59

Please sign in to comment.