Symfony form error message parameters usage - php

What is the purpose of the message parameters array in a Symfony form error ?
For example, I have the following case: on a form I have a subscriber in which, based on the information given by the user an API may be called and some additional errors could be added to the Symfony form.
As such, when an error occurs, I add a new error on a field:
$myForm->get('name')->addError(
new FormError('name.api_invalid', null, array('{{ api_name }}' => $someValue))
);
where 'name.api_invalid' is defined in message.en.yml as
name.api_invalid: "The API says the name is actually {{ api_name }}. Please fix before proceeding."
While the message is translated, the "parameters" are not replaced.
Is this not how form error parameters are supposed to work ?
Note: I can make it work by using
$myForm->get('name')->addError(
new FormError(
$this->translator->trans('name.api_invalid', array('{{ api_name }}' => $someValue))
)
);
but I'm really curious about those error parameters.
Thank you!

The behavior you are looking at was changed in Symfony 2.2:
Translating validation errors is now optional. You can still do so manually if you like, or you can simplify your templates to simply output the already translated message.
If you look at the form_errors block in 2.1 vs. the form_errors block in 2.2 you will see the difference in how the errors are displayed. You could override the block and do it the old way and then import that template wherever you need it, or you can simply translate the error message the way you're doing above (which is how I've typically done it and is perfectly acceptable).
If you're going the route of $translator->trans then I would use %..% in the parameters, as stated in the Symfony documentation:
The placeholders can take on any form as the full message is reconstructed using the PHP strtr function. But the %...% form is recommended, to avoid problems when using Twig.
The {{ }} you are using is more relegated to using Symfony Validators and how they build their violations (example here).
Now, if you want your messages and parameters automatically translated without manually throwing a FormError, then I would simply suggest creating a custom validator for whatever you are trying to do, and build out the message there. Otherwise, just translate it manually the way you already figured it out.

Related

You have requested a non-existent parameter "name" error when trying to load a template using Symfony templating component

I am using the Symfony templating component to add templating functionality to the project I am working on, I am following the docs here but I am using the service container Symfony component and adding the code in the docs using this code:
$containerBuilder->register('template_name_parser', Symfony\Component\Templating\TemplateNameParser::class);
$containerBuilder->register('file_system_loader', Symfony\Component\Templating\Loader\FilesystemLoader::class)
->setArguments([realpath('./') . '/app/Views/%name%']);
$containerBuilder->register('templating', Symfony\Component\Templating\PhpEngine::class)
->setArguments([new Reference('template_name_parser'), new Reference('file_system_loader')]);
But when I try to load a template file using this code:
container->get('templating')->render('home.php')
I get this error:
Something went wrong! (You have requested a non-existent parameter
"name".)
So as #yceruto mentioned Symfony DI will treat strings between %% as parameters so to escape it we need to add % in front of those strings as mentioned here, so I updated my code like this:
$containerBuilder->register('file_system_loader', Symfony\Component\Templating\Loader\FilesystemLoader::class)
->setArguments([realpath('./') . '/app/Views/%%name%']);

Using Respect/Validation in another language

I want to use the Respect/Validation library in PHP. I know how to use it but currently I'm using it in a project in German language and of course, I also want the error messages in German.
For language translation, there is a section in the documentation but I don't really get it and I did not found any answer yet.
They're talking about a translator that should handle the translation of the messages. As a second parameter they're giving "gettext" but I don't know what this should be and how this should handle the translation.
Can anybody explain me how this works?
Respect/Validation won't do the translation for you, you should use a different project, library or function to do that. It won't leave you empty handed though, as the documentation states.
First, you should try to understand how translation libraries work (such as gettext()) and then read PHP documentation on Callables. Then it is a matter of choosing a library, creating the translations and calling setParam('translator', 'callable') method on the exception instance.
A quick introduction to your problem:
Translations are done based on a source: it can be a file, a database or something else, depending on which library you use.
Respect/Validation exception messages use the same pattern: {{name}} is invalid.. Where {{name}} will be replaced by the input given or the name if setName() was called on that rule.
You can see all messages you need to translate under the Respect\Validation\Exceptions namespace.
Usually, every library provide a single function/method to translate a given string. This is the method/function you want to set on the $exception->setParam() call.
If you ever translate all exception messages, we would love to make them available to everyone else.
PS: You could also make this question on the repository page, more people would help and we could also improve the way translations are handled by the library in the future.
I just changed all Exception defaultTemplates property, it works for me.
class Localization
{
public function init()
{
$this->validation();
}
public function validation()
{
$prefix = '\\Respect\\Validation\\Exceptions\\';
$localize = [
'EmailException' => 'local message',
'NotEmptyException' => 'local message'
];
foreach($localize as $class => $message) {
($prefix.$class)::$defaultTemplates[
ValidationException::MODE_DEFAULT][ValidationException::STANDARD] = $message;
}
}
}
$localization = new Localization();
$localization->init();

Laravel 5 > Using monolog introspection processor

I have configured Laravel 5 to use a custom logging configuration (default is way too simple). I've added monolog's IntrospectionProcessor to log the file name and line number of the log call.
The problem is that all lines get the same file and line number:
[2015-06-29 17:31:46] local.DEBUG (/home/vagrant/project/vendor/laravel/framework/src/Illuminate/Log/Writer.php#201): Loading view... [192.168.10.1 - GET /loans/create]
Is there a way to config the IntrospectionProcessor to print the actual lines and not the facade ones?
If I do Log::getMonolog()->info('Hello'); it works and prints the correct file and line number... but I don't know how safe is to avoid calling the Writer.writeLog function because it fires a log event (is it safe to not fire that event?).
(Only tried in Laravel 4.2!)
When pushing the Introspection Processor to Monolog it is possible to give an skipClassesPartial array as second parameter in the IntrospectionProcessor contructor. With this array it is possible to skip the Laravel Illuminate classes and the logger logs the class calling the log method.
$log->pushProcessor(new IntrospectionProcessor(Logger::DEBUG, array('Illuminate\\')));
also see: https://github.com/Seldaek/monolog/blob/master/src/Monolog/Processor/IntrospectionProcessor.php
I know this is an old question but I thought I'd give a quick update because it's pretty easy to get this done now.
I haven't tried with Laravel but My own logging mechanism is within a LoggingService wrapper class. As such the introspection was only giving details about the service rather than the caller.
after reading Matt Topolski's answer, I had a look in the IntrospectionProcessor.php. the constructor looks like this:
__construct($level = Logger::DEBUG, array $skipClassesPartials = array(), $skipStackFramesCount = 0)
All I had to do was add the processor like this:
log->pushProcessor(new IntrospectionProcessor(Logger::DEBUG, array(), 1));
This is actually the expected functionality unless you're having the handler process the logs directly (check out the comments at the top of IntrospectionProcessor.php). My guess is you have a wrapper function around the logger and you're calling it from Writer.php -- BUT
If you look at the code for IntrospectionProcessor.php you'll see a bit of code on lines 81 to 87 that decides how to format that stack trace, and it still has access to the stack. If you bump the $i values for $trace[$i - 1] / $trace[$i] up one (aka $trace[$i]/$trace[$i + 1] respectively) you can 'climb' the stack back to where you want.
It's important to note that the 'class' and 'function' parts of the trace need to be one level of the stack higher than the 'file' and 'line.'
On a personal (plz dont mod me bruhs) note, I'd like to see functionality to include a stack offset when throwing the log in. I know what function I want to blame if an error shoots out when I write the error_log('ut oh') but I might(will) forget that by the time the 'ut oh' comes.

Cakephp email official example not working?

I am new to Cakephp (and I have asked a few question on Cakephp here recently) and I am learning by trying out the example on the official site. The following is the link.
http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
I added the to my Posts controller which I created before following the official example code.
public function emailTesting(){
$Email = new CakeEmail();
$Email->config('default');
$Email->from(array('me#example.com' => 'My Site'));
$Email->to('myWorkingEmail#gmail.com');
$Email->subject('Testing Subject');
$Email->send('Testing email content');
}
According to the configuration section,
It is not required to create app/Config/email.php, CakeEmail can be used without it and use respective methods to set all configurations separately or load an array of configs.
So, I think the above code should work even if I don't create app/Config/email.php. Then,when I try to open the page
http://localhost/cakephpTesting/emailTesting/
It gives a blank page with no error message (the debug is already 2, which should shows all kind of error message if there is any error) but I didn't receive any email. I also tried different email service provider like Yahoo and my school email. All of them fails, so I think it should be the problem of my code?
So, anybody got any idea on what have I missed?
As mentioned in your question, it is not required to create a app/Config/email.php, IF you use respective methods to set all configurations separately or load an array of configs.
You are using Email::config() method to load a $default config array which is supposed to be defined somewhere. As good practise, it can be defined in the app/Config/email.php or define it in your controller's action (don't recommend the latter). CakeEmail needs to know the transport type, host, port, etc.
Read the section after the line that you have mentioned in your question which tells you how to either use the constructor of CakeEmail or use the $config array.

Symfony ExceptionListener: how to handle dependencies?

I'm experimenting with my own framework based on symfony2 components, like described in a tutorial series by Fabien Potencier. Everything is clear to me so far except for one thing.
I've established a container builder described in the last part of the tutorial:
http://fabien.potencier.org/article/62/create-your-own-framework-on-top-of-the-symfony2-components-part-12
I've added twig to the containerbuilder:
$sc->register('twigLoader', 'Twig_Loader_Filesystem')
->setArguments(array('%templatePath%'));
$sc->register('twig', 'Twig_Environment')
->setArguments(array(new Reference('twigLoader'), array()));
Than there is the part with the ErrorController which will be called when an exception occurs:
$sc->register('listener.exception', 'Symfony\Component\HttpKernel\EventListener\ExceptionListener')
->setArguments(array('Calendar\\Controller\\ErrorController::exceptionAction'));
But to display a proper error page which is rendered by twig I need the twig dependency in the error controller. How can I do this?
Please note that I don't use the full symfony framework, just the components!
D'Oh... I already had it. The only thing I had to change is that the error controller doesn't have to return a response object. Instead it's returning an array now and than my normal response listener with the twig object is reacting and I have a custom error page processed by twig...

Categories