Laminas InputFilter does not translate some validator messages

I have some code like below. I set the data[‘password’] = ‘’ input filter translate the error message well.
But when i set it as data[‘password’] = ‘123’ translator does not translate the error message.
i appreciate any help.

error_reporting(E_ALL);
ini_set('display_erros', 1);

include 'vendor/autoload.php';

use Laminas\I18n\Translator\Translator;
use Laminas\I18n\Translator\Resources;
use Laminas\InputFilter\InputFilter;
use Laminas\Filter\StringTrim;
use Laminas\Filter\StripTags;
use Laminas\Validator\StringLength;

$translator = new Translator;
$translator->setLocale('es');
$translator->addTranslationFilePattern(
    'phpArray',
    Resources::getBasePath(),
    Resources::getPatternForValidator()
);
// $data['password'] = ''; // Se requiere un valor y éste no puede estar vacío
$data['password'] = 123; // The input is less than 6 characters long

$inputFilter = new InputFilter();
$inputFilter->add([
    'name' => 'password',
    'required' => true,
    'filters' => [
        ['name' => StripTags::class],
        ['name' => StringTrim::class],
    ],
    'validators' => [
        [
            'name' => StringLength::class,
            'options' => [
                'encoding' => 'UTF-8',
                'min' => 6,
                'max' => 24,
            ],
        ],
    ],
]);
$inputFilter->setData($data);

if (! $inputFilter->isValid()) {
    foreach ($inputFilter->getInvalidInput() as $field => $error) {
        foreach (array_values($error->getMessages()) as $message) {
        	echo $translator->translate($message).PHP_EOL;
        }
    }
}

Hello,

Maybe you must configure specific error messages in your field for that validator.
Global messages are a precious first step to i18n your application. But they are only a starting point.

Verify you have set your namespace too. Very often, you are query some module scope related translations : $this->translate($message, __NAMESPACE__);

In a full webapplication, I have a full i18n system working very well without any problem, so components are working well. Check your configuration :

'translator' => [
    'locale' => [
        'fr_FR', // default locale
        'en_GB' // fallback locale
    ],
    'translation_file_patterns' => [
        [
            'type' => PhpArray::class,
            'base_dir' => getcwd() . '/data/i18n',
            'pattern' => 'lang-%s.php'
        ],
        [
            'type' => PhpArray::class,
            'base_dir' => __DIR__ . '/../languages',
            'pattern' => 'lang4module-%s.php'
        ],
    ],
],

If you want to translate your routes, do not forget :

'router' => [
    'router_class' => TranslatorAwareTreeRouteStack::class,
    'routes' => [

And of course add aliases to resolve some services :

'service_manager' => [
    'factories' => [
        'MvcTranslator' => TranslatorServiceFactory::class,
    ],
    'aliases' => [
        'translator' => 'MvcTranslator',
    ],
],

hello thanks for your reply i know that it works properly in mvc but this is not a mvc application, it is just a standalone script that i created and i added the service manager to the application as below but i couldn’t find a solution.

<?php

require 'vendor/autoload.php';

use Laminas\ServiceManager\ServiceManager;
use Laminas\I18n\Translator\TranslatorServiceFactory;
use Laminas\ModuleManager\Listener\ServiceListener;
use Laminas\I18n\Translator\Resources;
use Laminas\InputFilter\InputFilter;
use Laminas\InputFilter\InputFilterPluginManager;
use Laminas\InputFilter\InputFilterPluginManagerFactory;

$appConfig = [
    // Additional modules to include when in development mode
    'modules' => [
		'Laminas\I18n',
        'Laminas\InputFilter',
    ],
    // Configuration overrides during development mode
    'module_listener_options' => [
        // 'config_glob_paths' => [realpath(__DIR__) . '/config/autoload/{,*.}{global,local}-development.php'],
        'config_glob_paths' => [realpath(__DIR__) . '/config/autoload/*.php'],

        // Whether or not to enable a configuration cache.
        // If enabled, the merged configuration will be cached and used in
        // subsequent requests.
        // 
        'config_cache_enabled' => true,
        // Whether or not to enable a module class map cache.
        // If enabled, creates a module class map cache which will be used
        // by in future requests, to reduce the autoloading process.
        // 
        'module_map_cache_enabled' => false,
        // The path in which to cache merged configuration.
        // 
        'cache_dir' => 'data/cache/',
    ],
];
$container = new ServiceManager;
$container->setFactory('MvcTranslator', TranslatorServiceFactory::class);
$container->setFactory('InputFilterPluginManager', InputFilterPluginManagerFactory::class);
$container->setFactory(Laminas\Config\Config::class, 'App\Factory\ConfigFactory');
$container->setFactory(Laminas\ModuleManager\ModuleManager::class, 'App\Factory\ModuleManagerFactory');
$container->setAlias('config', Laminas\Config\Config::class);
$container->setAlias('translator', 'MvcTranslator');
$container->setService('ServiceListener', new ServiceListener($container));
$container->setService('appConfig', $appConfig);

$translator = $container->get('translator');
$translator->setLocale('es');
$translator->addTranslationFilePattern(
    'phpArray',
    Resources::getBasePath(),
    Resources::getPatternForValidator()
);
$inputFilter = new InputFilter();
$inputFilter->add([
    'name' => 'password',
    'required' => true,
    'filters' => [
        ['name' => StripTags::class],
        ['name' => StringTrim::class],
    ],
    'validators' => [
        [
            'name' => StringLength::class,
            'options' => [
                'encoding' => 'UTF-8',
                'min' => 6,
                'max' => 24,
            ],
        ],
    ],
]);
$pluginManager = $container->get('InputFilterPluginManager');
$pluginManager->setService('my_filter', $inputFilter);

$myFilter = $pluginManager->get('my_filter');

// $data['password'] = ''; // Se requiere un valor y éste no puede estar vacío
$data['password'] = 123; // The input is less than 6 characters long
$myFilter->setData($data);

if (! $myFilter->isValid()) {
    foreach ($myFilter->getInvalidInput() as $field => $error) {
        foreach (array_values($error->getMessages()) as $message) {
            echo $translator->translate($message).PHP_EOL;
        }
    }
}

This is all correct because if the value is empty then the message can be found with the translator:

"Value is required and can't be empty" => "Se requiere un valor y éste no puede estar vacío",

But then you try to find: “The input is less than 6 characters long” – this message is not included in any translation file. Only this one:

"The input is less than %min% characters long" => "El valor especificado tiene menos de '%min%' caracteres",

Extend your setup:

$translator = new Laminas\I18n\Translator\Translator;
$translator->setLocale('es');
$translator->addTranslationFilePattern(
    Laminas\I18n\Translator\Loader\PhpArray::class,
    Laminas\I18n\Translator\Resources::getBasePath(),
    Laminas\I18n\Translator\Resources::getPatternForValidator()
);

// Set default translator for validators 
Laminas\Validator\AbstractValidator::setDefaultTranslator(
    new Laminas\Mvc\I18n\Translator($translator)
);

$inputFilter = new Laminas\InputFilter\InputFilter();
$inputFilter->add(
    [
        'name'       => 'password',
        'required'   => true,
        'filters'    => [
            ['name' => Laminas\Filter\StripTags::class],
            ['name' => Laminas\Filter\StringTrim::class],
        ],
        'validators' => [
            [
                'name'    => Laminas\Validator\StringLength::class,
                'options' => [
                    'encoding' => 'UTF-8',
                    'min'      => 6,
                    'max'      => 24,
                ],
            ],
        ],
    ]
);
$inputFilter->setData(['password' => 123]);

if (! $inputFilter->isValid()) {
    foreach ($inputFilter->getInvalidInput() as $field => $error) {
        foreach (array_values($error->getMessages()) as $message) {
            echo $message . PHP_EOL;
        }
    }
}

This all is not needed and you should not do this way. Don’t try to rebuild a laminas-mvc application.

This is exactly what I wanted. Thanks. :blush:. Sometimes i need small scripts which does not requires mvc . :beers: