Entity object to array - symfony

I'm trying to convert an entity to a associative array.
It seems that the method toArray() is not available for entity objects.
Reading Symfony doc, it seems I should use the SerializerInterface.
After enabling it, I can't seems to find the right syntax to convert my entity into an associative array.
Can someone correct my code please?
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
// -----------------------
public function salleAction(Request $request, Projet $projet, SerializerInterface $serializer) {
return this->json(array(
'projet'=>$serializer->serialize($projet, new ObjectNormalizer())
));
}
With the code above, I'm getting this error message
Warning: Illegal offset type in isset or empty
If I replace new ObjectNormalizer() by 'jsons', I'm getting the next error message:
A circular reference has been detected when serializing the object of class "AppBundle\Entity\Projet" (configured limit: 1)

I suggest you to add the following method to an object, that needs to be converted
public function toArray()
{
return get_object_vars($this);
}
and use it everywhere $array = $projet->toArray();

Related

Receive all kind of Entity as an Argument in Symfony

I have a method to get a change set of Entity from the unit of work (entity manager) in Symfony and I would like it to receive all Entities (Post, User...) instead of specific Entity.
public function getChanges(Post $event): array
{
$uow = $this->entityManager->getUnitOfWork();
$uow->computeChangeSets();
return $uow->getEntityChangeSet($event);
}
Do you have any idea to do it?
One solution is getting the object as the argument but I prefer to get only the Symfony Entity objects in the function.
Look for doctrine entity listener.
https://symfony.com/doc/current/doctrine/events.html#doctrine-entity-listeners
And do not filter entity inside it, remove this part from the example:
// if this listener only applies to certain entity types,
// add some code to check the entity type as early as possible
if (!$entity instanceof Product) {
return;
}
if (!$this->entityManager->contains($entity)) {
throw new Exception('The given object must be doctrine entity');
}

How to use Association field in Symfony EasyAdmin 4

When I use:
public function configureFields(string $pageName): iterable
{
return [
AssociationField::new('XYZ')
];
}`
I get error "Object of class App\Entity\XYZ could not be converted to string"
When I add ->autocomplete() to the AssociationField::new('XYZ'), then it works, but on save it displays error "Expected argument of type "?string", "App\Entity\XYZ" given at property path "XYZ".
Whats the CORRECT way to use this field with many to one relation? Symfony Easy Admin documentation https://symfony.com/doc/current/EasyAdminBundle/fields/AssociationField.html doesn't help at all.
Your entity App\Entity\XYZ will be converted to a string in your association field (which is a standard symfony entity type). Otherwise there is no way to set a label in your entity select.
It will try to convert it using the __toString method, so you need to add it in your entity.
For example:
/**
* #ORM\Entity(repositoryClass=XyzRepository::class)
*/
class Xyz
{
public function __toString(){
return $this->name; //or anything else
}
EasyAdmin should be able to guess the entity class, so you don't have to specify it like you would for a simple EntityType.

Symfony: Query Builder: Catchable Fatal Error: Object of class DateTime could not be converted to string

I am trying to do a query in Symfony 3 to select the Commentaries of a Wish (Object Wishcom) with the contributionType included (Object ContributionType) thanks to a JOIN.
When running the webpage I get a:
Error: Method Doctrine\ORM\Query\Expr\Func::__toString() must not throw an >exception, caught Symfony\Component\Debug\Exception\ContextErrorException: >Catchable Fatal Error: Object of class DateTime could not be converted to >string
In the forums I could get that the datetime has to be converted with format. The thing is that I am not manipulating directly the date with my query although I know there is one DateTime attribute in my Wishcom object.
Should I select specifically the date and format it ? In that case were should it be done ? Or does the error come from something else ?
It seems the error comes from the where statement and the function ToString from Expr not being able to convert the date. I don't know what I should do.
$queryBuilder->where($queryBuilder->expr()->in('w.wish', $wish));
Here is my call in the controller:
$arraywishcom=$em->getRepository(Wishcom::class)->getWishcomWithContributionType($wish);
And my repository:
<?php
namespace Shaker\JRQBundle\Repository;
use Shaker\JRQBundle\Entity\Wish;
/**
* WishcomRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class WishcomRepository extends \Doctrine\ORM\EntityRepository
{
public function getWishcomWithContributionType(Wish $wish) {
$queryBuilder = $this
->createQueryBuilder('w')
->leftJoin('w.contributiontype', 'contributiontype')
->addSelect('contributiontype')
;
$queryBuilder->where($queryBuilder->expr()->in('w.wish', $wish));
return $queryBuilder
->getQuery()
->getResult()
;
}
}
I have found a different way of doing the query and it works.
Instead of the where I had with expr(), which was the problem, I did the following:
$queryBuilder->where('w.wish = :wish')->setParameter('wish', $wish);
But I still do not know why I got the error in the first place.

Class not found when trying to index documents using Solr with Symfony2

I am very new to Solr and I am probably missing something simple however, having followed Xavier Briand's presentation I have set up Symfony2, Solarium and Nelmio\SolariumBundle.
"nelmio/solarium-bundle": "2.0.*#dev",
"solarium/solarium": "3.0.*"
Having implemented a toSolrDocument method for my doctrine php object.
public function toSolrDocument(\Solarium_Document_ReadWrite $doc)
{
$doc->id = $this->getId();
$doc->description = $this->getTitle();
$doc->path = "path";
return $doc;
}
I am faced with the following error.
Catchable Fatal Error: Argument 1 passed to ::toSolrDocument() must be an instance of Solarium_Document_ReadWrite, instance of Solarium\QueryType\Update\Query\Document given, called in Controller.php
The controller calling this toSolrDocument method has the following function
public function indexItems(){
$client = $this->get('solarium.client');
// get an update query instance
$update = $client->createUpdate();
// create documents
$documents = array();
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('<Bundle>:<Object>');
$items = $repo->findAll();
foreach ($items as $item) {
$documents[] = $item->toSolrDocument($update->createDocument());
}
// add the documents and a commit command to the update query
$update->addDocuments($documents);
$update->addCommit();
// this executes the query and returns the result
$result = $client->update($update);
}
Most of this method again comes directly from Xavier's presentation and it is clear to see that the method $update->createDocument() does not return the correct type. In fact it returns an instance of the my php object. Does anyone know where I am going wrong here? Another thing that might be of help is that even when I try to pass a Solarium Document directly I get an exception.
foreach ($items as $item) {
$rw_item = new \Solarium_Document_ReadWrite();
$documents[] = $item->toSolrDocument($rw_item);
}
The exception is
FatalErrorException: Error: Class 'Solarium_Document_ReadWrite' not found in
I can't seem to find this class in any of the bundles and I am wondering if my setup might be causing the issues. Any help would be very much appreciated.
One additional point to note is that when I am running the solr jar I see the query requests come in from my symfony2 page it is only this indexing action that I can not work out so the config may be alright and I am miss understanding the use of the bundle.
You just need to use the correct class for the argument.
use Solarium\QueryType\Select\Result\AbstractDocument;
...
public function toSolrDocument(AbstractDocument $doc)
{
You could also not type hint it:
public function toSolrDocument($doc)
{

Symfony2 Form Entity to String Transformer Issue

I am using Symfony 2.1.3-DEV and trying to accomplish transforming entity to string (ID of some kind) and then back from string to entity when form is submitted. The issue is the same if I'm using the transformer given in the cookbook:
http://symfony.com/doc/master/cookbook/form/data_transformers.html
Controller code:
$task = $entityManager->find('AcmeTaskBundle:Task', $id);
$form = $this->createForm(new TaskType(), $task); // so $task->issue is Issue object
I get this error:
The form's view data is expected to be an instance of class
Acme\TaskBundle\Entity\Issue, but is a(n) string. You can avoid this
error by setting the "data_class" option to null or by adding a view
transformer that transforms a(n) string to an instance of
Acme\TaskBundle\Entity\Issue.
The thing is, that I already have a transformer, which transforms TO string.
From the Form.php:
if (null !== $dataClass && !$viewData instanceof $dataClass) {
throw new FormException(
//...
);
}
Why $viewData is checked to be instance of data_class parameter (or the guessed type of given object)? Isn't view data supposed to be string/array etc.? Am I missing something?
After some digging step-by-step I found the problem that I was facing.
View data indeed must be the instance of class specified by data_class parameter. If you are using transformer Object -> string, you must set the data_class parameter to null.
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => null,
));
}
By default, data_class is result of get_class of specified initial data. If you pass object to controller's createForm or some corresponding form-creator function, and no default value for data_class exists, it will be set to class of given object.
Still, the example given in the docs works fine - if form is inner (inside another form), data_class will not be set so it will be null.
As it's very rare to make form only from one field (text field in my transformer case), usually this form with transformer will be inside some other form, so it'll work fine.
I had the same problem because I accidentally typed in my controller:
$em->getRepository('AcmeWhateverBundle:Something')->findBy(array('id' => $id), array());
instead of:
$em->getRepository('AcmeWhateverBundle:Something')->findOneBy(array('id' => $id), array());
So If you're not using any custom data transformers check that $entity in the following line is an object of the same class defined as data_class in your FormType:
Scope Controller:
$form = $this->createForm(new SomethingType(), $entity, array( ....

Resources