silexphp / Silex

[DEPRECATED -- Use Symfony instead] The PHP micro-framework based on the Symfony Components
https://silex.symfony.com
MIT License
3.58k stars 718 forks source link

Cannot override validation messages' translations #1041

Closed neemzy closed 9 years ago

neemzy commented 9 years ago

Hi,

The following code demonstrates the issue (excerpt from my index.php) :

$app['locale'] = 'fr';

$app->register(new TranslationServiceProvider());
$app->register(new ValidatorServiceProvider());

$app['translator'] = $app->share(
    $app->extend(
        'translator',
        function ($translator, $app) {
            $translator->addLoader('yaml', new YamlFileLoader());
            $translator->addResource('yaml', 'path/to/validators.fr.yml', 'fr', 'validators');

            return $translator;
        }
    )
);

Trying to validate a form with a required field left blank issues "Cette valeur ne doit pas être vide." instead of my custom validation message (in my validators.fr.yml file). And yes, I tried to register the validator service after that file, it doesn't change anything.

The reason to this behavior is that the translation service provider loads Symfony's own XLIFF file, which always overrides mine since it is always loaded last, regardless of the declarations' order.

The following works as expected (ping @alexandresalome ) :

$app['locale'] = 'fr';

$app->register(new TranslationServiceProvider());
$app->register(new ValidatorServiceProvider());

$app['validator'];
$app['translator'] = $app->share(
    $app->extend(
        'translator',
        function ($translator, $app) {
            $translator->addLoader('yaml', new YamlFileLoader());
            $translator->addResource('yaml', 'path/to/validators.fr.yml', 'fr', 'validators');

            return $translator;
        }
    )
);

Calling up $app['validator'] first causes its register method to be triggered (I guess), so my own file gets loaded after that, and my translations can be used.

Isn't there some kind of small optimization to bring in order to fix this ?

Thank you all for your attention and for this great project that is Silex :)

neemzy commented 9 years ago

You're right, I forgot to "anonymize" the second snippet, just fixed that.

Regarding your first observation, the translation service provider is registered in the beginning, but as $app['translator'] isn't explicitly summoned before $app['validator'], you are probably right - the register method of a service provider being lazy-loaded on its first call as a "key" of $app, if I correctly understand.

Here's an excerpt of my composer.lock file as of now (I set up the project and ran composer install this very morning) :

"name": "silex/silex",
"version": "1.2.x-dev",
"source": {
    "type": "git",
    "url": "https://github.com/silexphp/Silex.git",
    "reference": "2603afb3d2d902a3dbc19075d91f0b39a9d46c40"
},

...

"name": "symfony/translation",
"version": "dev-master",
"target-dir": "Symfony/Component/Translation",
"source": {
    "type": "git",
    "url": "https://github.com/symfony/Translation.git",
    "reference": "adc92684c607801186cc9e3179314b738f0d62d7"
},