How to handle json_array type with formbuilder in symfony? - php

In Symfony form has not to Type for json_array like (EntityType, TextType). So I need to store json_array in DB column with work in new and edit. Anyone have an idea about this?

You can just create a new Form Type with all the data you want to store as json array in your entity. By default, if no data_class is defined the forms will return the data as (associative) array with the keys being the field names and the properties being the values. If you place this data in your entity's property which will be persisted as json_array, it should work right away.
See also: https://symfony.com/doc/current/form/without_class.html

Related

How to get Doctrine entity persistent collection data values with symfony

What is best way to convert Doctrine entity persistent collection to array with symfony 2 ? I want to get the values and later by using that array value, need to get the second entity values which dependent on first entity using form event listener.
If I understand your question correctly, this helps you:
$arrayValues = $persistentCollection->getValues();
$yourCollection->unwrap()->toArray();
That should give you the content of your collection as an array()

How to make form class for 2 different entities using symfony 4?

Hello I am using Symfony 4,
I want to create a formClass which insert data for 2 different entities like 'vendor' and 'address'. Please explain me how can I create form class to accept data for 2 different entities via same form?
I have created form class which accepts data for only one entity but I am not getting to make formclass which accepts data for 2 different entities?
Basically I am not getting to embed form together as one.
combine the forms (preferred)
Assuming you have two entities Vendor and Address and forms for those entities VendorType and AddressType, you could create a form type VendorAddressType that, as a buildForm function has
$builder->add('vendor', VendorType::class)
->add('address', AddressType::class);
and when creating the VendorAddressType form you provide an array ['vendor' => $vendor, 'address' => $address]. (you can similarly pass through options to the sub-forms). The data_class option for each subform can be the appropriate class, the data_class option for the combined form must be null.
now, in the normal symfony form templates, those forms are rendered differently from truly being in one form, but those templates could be extended, such that instead of form_rows, you call form_widget on form.vendor and form.address instead (see https://symfony.com/doc/current/form/form_themes.html#creating-a-form-theme-in-the-same-template-as-the-form)
combine the forms, literally (not preferred)
Same assumption as before, you could copy the contents of each form type into the new VendorAddress form, and then set the property_path attribute for all fields to point to the respective entities, like:
$builder->add('vendorfieldA', SomeType::class, ['property_path' => 'vendor.fieldA'])
which will look into the provided data array (see before) at the key vendor, and select its property fieldA.
I would advise against this approach, since any changes to the single-entity forms must be repeated for the multiple-entity forms. Instead, I would advise to make static buildForm functions (adding a parameter prefix or something) which can be called from the combined form type via VendorType::staticBuildForm($builder, $prefix) ($prefix = 'vendor.'). (you have to transform that prefix into something you can append/prepend to the form field name as well, or provide that explicitly)
First of all, don't use entity type, make your own DTO(Data Transfer Object). I assume that both of these entities share some fields. So you can create a facade that'll help you with converting DTO to your entity types.
Make your DTO based on the request not on the actual entity, this has a great advantage because your code is less coupled and more flexible for changes in the future, it requires some additional work though. For example, yo'llu need to fill the DTO on your own and convert it back to the entities based on some strategy, in your case, it'd be vendor and access.
There's a nice article explaining how to do it in details you can look at it https://blog.martinhujer.cz/symfony-forms-with-request-objects/

Eloquent - Store serialized arrays in database - Method overwriting

So I have a model user in my database that has a column containing a serialized string contact.
My question is: is it possible to ovewrite the method getContactAttribute in order to directly output unserialized data?
Yes this is totally possible, check this section of documentation:
Laravel 4.2 Docs Accessors and Mutators

JMSSerializerBundle, add field in post serialize

I am facing a problem for quite some times and I did not manage to solve it. I use the JMSSerializerBundle to serialize my entities in my web services. So I have to serialize an object A that has a relationship with an object B. In this object B I have to add two new fields whose data are obtained through a call to a repository => so no virtual property because it would mean injecting services in the entity which is bad. Also I don't have to add these fields in all the serialization of object B but only when it is included in object A.
So I thought about listeners, I made a listener who listen the event post serialization for the serialization of my object A, and I wanted to add the fields to the object B included in object A. I thought it would be fairly common but I do not understand how the Visitor (which is given via the ObjectEvent in postSerialize() function) works.
We can quite easily make a
// (here the object A is recovered)
$event->getObject()->getVisitor()->AddData('someKey', 'someValue');
Just like the following example:
Add extra fields using JMS Serializer bundle
But my problem is that I would like to add fields in object B contained in the object A, I have not found any examples or even information in the documentation about this :( anyone can help ?
Thank you in advance.

Symfony2 Doctrine Change Value on Entity Load

I have a database structure which has a field content. In the database this is a BLOB (so a string). content contains a JSON-encoded string.
When I load this, I would like to load it in to a specific Content object (with a different Content subclass for each possible format of the JSON).
Are there any events or anything which I can hook up so I can catch the value right before the Entity is built (so I can have setContent() type-hint the Content class instead of having to be generic, which I'd have to do if the information is loaded in to the Entity before I intercept).
Any ideas?
A bit more details. Basically what I imagine is having some sort of Factory class which takes a JSON string and converts it to a proper object.
{
body: "ABC",
value: 5
}
Goes to an object of a class like this:
class MyContent extends Content
{
protected $body;
protected $value;
}
I can't use typical object mapping because it's a JSON string to an object.
Further clarification
Basically, I have an entity named Box. Box has a content value, which is supposed to be an instance of Content.
Under normal circumstances, if Content was a normal database Entity, I would just hook up a One-to-One relationship between Box and Content, which would load Content properly in to the Box without needing to do anything special.
However, in this case, Content can have many forms. To handle this, it is stored as a JSON object in a BLOB field in Box's table. This means when Doctrine tries to load Box, it will try to load a string.
I could simply have Box::setContent() accept any parameter and deal with it accordingly based on if it is a string or Content object.
However, I'd like it so when it is used it is always a Content object, so I want type-hinting for the function (i.e., Box::setContent(Content $content)). The problem is this would prevent Doctrine from giving that field a string.
Which is why I want to intercept the value Doctrine has for content and replace it with a proper object before it loads it in to the entity Box.
I don't think any of the Doctrine events do exactly what I want, so it may not really be possible. =S
You should be able to add code to the entities get method to do this. You can also check out the lifecycle call backs for doctrine: http://docs.doctrine-project.org/en/2.0.x/reference/events.html#lifecycle-callbacks
You can use JMSSerializer to create entities from JSON - https://github.com/schmittjoh/JMSSerializerBundle.
And I can`t understand you question, but maybe you can use json_array type - http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#doctrine-mapping-types
You need to load data from DB and than create entities? Or load entities with some field that have nested entity deserialized from JSON?
Ultimately what I ended up doing was just creating different tables and Entities for each possible Content type and then using Doctrine's inheritence to let Doctrine handle them. Not idea (since there may be many, many types which means more tables and I can't just dynamically constructor new types), but it works well for now.
Doctrine Inheritence

Resources