value vs. data in Symfony Forms - What is the difference and how to control the content? - forms

what is the difference between the two fields data and value in Symfony Forms?
I have created a custom Form Type for my custom Task class which works fine in all my forms. To understand the internal workflow behind form better, I have observed the operation by adding some {{ dump(...) }}statements to my Twig files.
In all my forms the value and data fields of my Task type both hold the same information: A reference to the Task object.
However I have recognized, that some third party Form Types have different values for the two value and data fields: While the data fields holds a reference the underlying object the value field just contains an ID of this object (member field of the object). How is this achieved?
What exactly is the purpose of these two fields?
What is the difference between them?
How do I control/chance the content of
value field while still having the object reference in the data
field?

Related

Custom Model Binding - Changing Property type in Post

I am working on a project where i receive objects from a client in a Post body and i map them to a model i created so i can store them in a db. One of the child classes in the body is an attributes class shown below attributes
When i use it in a Post, we have been getting the following data and the value field can be any type. In the end i want them all to be converted to strings Post Body
In my HttpPost in the controller, it fails to convert the json to this type because the one record is a bool. How do i allow multiple types?

Yii2 adding parameters to the model with a function

I have two types of data. Articles and article types. They are stored a postgres DB. Every article instance should have particular type. All articles have common properties like "name", "create_date" and so on that are in every article and fields that are specific for the specific type like "some_image", "ingredients", and so on for the type1 and "images" and "points" for type2.
The additional properties for the specific type are stored in a single json column in the db table.
When the url "some_path/articles/create/2" is opened a form for creating an article of type 2 is displayed
I have an Articles ActiveRecord model and ArticlesController.
My problem is that in the model I have only have the common properties. And the additional properties are always different.
I need a method in the model or in the controller with which I can add the additional properties with the proper rules and all (like the common properties in the model) and then in the view I can render all fields without difference.
Is there a way this to be done and how?
I read how this can be done with Javascript, but I want it to be dobe before page rendering, not after that
May be this can help.
Use Scenario in your model
Model class has scenario function which you can inherit.
User Register Scenario - Required - username, password, email
User Login Scenario - Required - username, email
public function scenarios() {
$scenarios = parent::scenarios();
$scenarios['login'] = ['name','password'];//Scenario Values Only Accepted
return $scenarios;
}
and you can use it as

Symfony: get new ID in a form

I have an object displaying within a form, a hidden field being related to its PK (field id).
When I create a new object, the field has a null value. Submitting the form, the object is inserted into the DB and it now has an ID, but the field in the page still has a null value.
If a reload the page, now the ID is indeed set in the hidden field.
In my opinion, this is due to the form processing of Symfony: when a create an object, it creates a form, with this form valid the object is saved but the form still uses the data before it was saved.
The question is: how to get the auto-incremented key in the form up-to-date? Shouldn't the form only have a reference to the object? Can't the value be updated?
make sur that you call $entityManager->flush() method after insert and that you bind your form whene you have same data in your request object
$form->submit($request->request->get($form->getName()));
You should have an Entity assigned to your Form by FormFactory. Then Symfony will fill that Entity with submitted values. What's left is only persist the Entity and flush to database.
You can find steb-by-step form submission in Symfony Cookbook

Using FormBuilder to generate an edit form for a many-to-many join-entity with extra fields

tl;dr
I need an edit form for a uni-directional many-to-many relationship (doctrine), where the resulting join table has extra inherited properties. Is there a way to achieve this through the FormBuilder?
Entities
I have a uni-directional many-to-many relationship (doctrine), where the resulting join table has a relation to a third entity.
Form
The User edit-form should allow (un)crossing Deals easily through a checkbox, while also showing the relations' inherited fields from Discount. The discount's properties should be inherited from Deal by default and overridden on the UserDeal object if modified.
My approach
The way I have approached this, is by creating an auxiliary object UserDealState with two properties: a boolean active and a reference to the UserDeal. UserDealState has its own Type (checkbox and Discount fields).
I also added a transformer that converts the array of UserDeals to an array of UserDealStates, adding all the non-joined Deals (and setting active to false).
When I check the form inspector in the Symfony Profiler, I can see the transformation has taken place (the view data holds a collection of UserDealStates and is a much longer collection than the model data that holds a collection of UserDeals, which makes sense), but the form object only holds the amount of UserDealStates formViews that the original collection had of UserDeals had, not the much larger number it should.
Just to give a concrete example: say we have 10 Deals, and only one crossed UserDeals. On my form {{ form.userDeals.vars.value|length }} returns 10, {{ form.userDeals.children|length }} returns 1. Only one subform is rendered instead of 10.
Hera are my form-types: UserType, UserDealStateType, UserDealType, DiscountType.
Transformer: UserDealStateToUserDealTransformer
The question
How do you render a form with FormBuilder to edit the mapping between two entities in a many-to-many relationship and the relations' extra fields (as shown on the form mock-up above)?

Foreign entity in form into different kind of input

I have two entities: product and category (Symfony 2.3).
I want to create a form in which an user can choose a product by first selecting the category. A user selects the category by clicking on image, then I want to set the image's value into a hidden input, but I don't see how can I change a foreign entity choice list to a hidden input (http://symfony.com/doc/current/reference/forms/types/entity.html).
How can I accomplish this? (how to change form input to hidden)
If I set cascade validation to true, will it for example check if a category really exist. (To prevent putting products with non-existing category from malicious users) ?
Part 1
To do this you need to use a data transformer to do two things:
transform an entity into an identifier that is either a string or integer so a form can render it as a hidden field.
transform the string or integer identifier into the entity when the form is submitted so that the parent entity can be saved with the correct relationship
The symfony docs I linked to above (here too) actually walk though an entire example of using a data transformer with a form.
As a shameless plug (because I believe it is helpful) I have written a little tutorial on using a data transformer for a hidden field with an entity id: http://lrotherfield.com/blog/symfony2-forms-entity-as-hidden-field/
Part 2
If you are using the data transformer then you don't need to worry about malicious users. The data transformer will fail because it will not be able to reverse transform the category from the fake id. In my tutorial the transformer will throw a Symfony\Component\Form\Exception\TransformationFailedException exception.
You can also write a validator (potentially using a call back) if you wanted that checks that the submitted category is real if you want an error to show in the form. Doctrine wont allow you to persist a fake category relationship as the foreign key constraint will fail.