-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No form data when using a closure as factory #60
Comments
Thank you for the report. Could you please create a small application that allows us to reproduce the issue? I am not sure yet if this is a bug or some misuse here (which maybe could be prevented by improving the documentation). |
Thanks for your response, Christian. I've made a small application here: https://github.com/hjkl/rich-model-closure-factory.git |
Thanks, this helped a lot. 👍 Your case can be solved by setting the |
I noticed the same problem but didn't have time to set reproducer. I solved it different way (this is really big form, I removed some fields for brevity): public function buildForm(FormBuilderInterface $builder, array $options): void
{
//....
$builder->add('invoicedToClient', DateType::class, [
'label' => 'Date the Supplier issued invoice to customer',
'constraints' => [
new NotNull(),
],
]);
//....
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Invoice::class,
'factory' => [$this, 'factory'],
'exception_handling_strategy' => 'ignore',
]);
}
/** @noinspection PhpTooManyParametersInspection */
public function factory(Campaign $campaign, DateTime $invoicedToClient, DateTime $sentAt): Invoice
{
return new Invoice($campaign, $invoicedToClient, $sentAt);
}
This trick is to name parameters in factory() as form fields. Hope this helps. I didn't want to use |
You are right. Currently, that's indeed a limitation (see also #50 (comment)). |
@xabbuh To be honest, I don't think of this as limitation. I prefer creating instances manually because it is easy to find usages of More important is that static analysis tools could also easily detect problems. Example: I add new requirement to constructor, phpstan will see the problem in Btw, I really love this bundle. No more wasting time on DTO classes, thank you guys! |
@zmitic That's really helpful. Your code works as the callback isn't a closure. SensioLabs\RichModelForms\Instantiator\ObjectInstantiator's instantiateObject method explicitly checks if the factory is a \Closure: if ($this->factory instanceof \Closure) {
return ($this->factory)($this->getData());
} As in the docs, for a closure it's supposed to give the form data as a single argument (but doesn't work). Whereas for your |
@hjkl Exactly! I had to take a look at the code to figure how to use it and I am really impressed with argument unpacking solution; you just can't make a mistake. I think the Closure version should work the same way as callable. User can typehint every parameter, bundle will catch TypeErrors, static analysis will always work... Also, argument unpacking is much cleaner. Smaller example, with future arrow functions: 'factory' => fn(Campaign $campaign) => new Invoice($campaign), It is clean, readable and foolproof. @xabbuh What do you think about that? Given that bundle is not 1.0.0 tagged, BC is not a problem, right? |
@zmitic I am not sure I completely got what you would like to see supported. Could you create a new issue further described your feature request so we can keep things separated and not lose your idea when this bug is fixed? |
Thanks @xabbuh, I can confirm that's fixed it. |
@hjkl Thank you for the confirmation. |
Hi, thank you for your work on this project.
I intend to use a form to instantiate an object via its constructor. Only one of the constructor parameters is a form field, the other is to be supplied via a form option.
I attempted to use a closure for the 'factory' option, which the documentation states should receive the form data as its argument:
Unfortunately on submitting the form, $formData is null so I have no way of getting the form field's data to construct the object.
It looks as though SensioLabs\RichModelForms\Instantiator\FormDataInstantiator->getData() is always null at that point - the child form field is submitted and has data but the overall form is not and has none.
Any advice would be appreciated. I'm also not sure how I'm going to supply the factory closure with another parameter for the constructor from the form options but I'm not there yet :)
The text was updated successfully, but these errors were encountered: