nette/nette — Issue #449: Form validation error message passed to translator without necessary arguments
Author: ondrej-bouda
Created: 2012-01-03 22:21:40+00:00
State: open

Consider the following piece of code:

$form->addText('persons', 'Persons:')
->setRequired('Fill in the persons.')
->addRule(Form::RANGE,
'Maximum number of persons is %2$d.',
array(null, 12)
);

In the validation error message, we use %2$d to mention just the upper bound. Which is alright until we use a translator, in which case only the lower bound (NULL in this case) is passed as the only argument:

->translate() arguments:
$message: 'Maximum number of persons is %2$d.'
$count: NULL

The bug is caused by an inappropriate Nette\Forms\Rules::formatMessage() method. A fixed one could be the following:

public static function formatMessage($rule, $withValue)
{
$message = $rule->message;
if ($message instanceof Nette\Utils\Html) {
return $message;
}
if (!isset($message)) { // report missing message by notice
$message = static::$defaultMessages[$rule->operation];
}
if ($translator = $rule->control->getForm()->getTranslator()) {
// beginning of the bugfix
if (is_int($rule->arg)) {
$message = $translator->translate($message, $rule->arg);
}
elseif (is_array($rule->arg)) {
$params = $rule->arg;
array_unshift($params, $message);
$message = call_user_func_array(array($translator, 'translate'), $params);
}
else {
$message = $translator->translate($message);
}
// end of the bugfix
// the original code here, passing just a single argument to the translator
//$message = $translator->translate($message, is_int($rule->arg) ? $rule->arg : NULL);
}
$message = vsprintf(preg_replace('#%(name|label|value)#', '%$0', $message), (array) $rule->arg);
$message = str_replace('%name', $rule->control->getName(), $message);
$message = str_replace('%label', $rule->control->translate($rule->control->caption), $message);
if ($withValue && strpos($message, '%value') !== FALSE) {
$message = str_replace('%value', $rule->control->getValue(), $message);
}
return $message;
}

But I don't have a clue if it is 100% correct. The code is taken from the version 2.0 Beta 2.