Collection in ParamConverter Symfony - symfony

I was trying to create a Payload where one of the fields is Collection of another objects. So I created something like this.
use DateTimeInterface;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\Collection;
class MyPayload
{
/**
* #var int
*
* #Serializer\Type("int")
* #Assert\Positive()
*/
private int $someNumber;
/**
* #var DateTimeInterface
*
* #Serializer\Type("DateTime<'Y-m-d'>")
*/
private DateTimeInterface $someDate;
/**
* #Assert\Collection(
* fields={
* "label"=#Assert\NotBlank(),
* "someNumber2"=#Assert\Positive(),
* }
* )
*/
private Collection $someCollection;
}
I'm sending something like this by postman (number of elements in some_collection is unknow, can be 1 can be 10):
{
"some_number": 123,
"some_date": "2021-01-01",
"some_collection": [
{
"label": "test1",
"some_number2": 10000
},
{
"label": "test2",
"some_number2": 15000
}
]
}
To my controller which looks like this:
/**
* #param MyPayload $myPayload
* #param ConstraintViolationListInterface $validationErrors
*
* #return JsonResponse
* #ParamConverter("myPayload", converter="fos_rest.request_body",
* class="App\Request\Payload\MyPayload")
*
*/
public function doSomething(
ContractPayload $myPayload,
ConstraintViolationListInterface $validationErrors
): JsonResponse {
try {
if (count($validationErrors) > 0) {
throw new ValidationException($validationErrors);
}
...
}
And the only answear I've got was :
'contractRate' - This value should be of type array|(Traversable&ArrayAccess).
I was looking for solution, but couldn't find any working one, do you know what to do to make it work?

your problem is exactly on the type you passed on the function, you passed ContractPayload instead of MyPayload,
suddenly you will encounter another problem with serialization compared to the collection on the MyPayload type .. like that I made a little evolution hope that is clear.
First create a new type for collection it's usefull instead of collection of type any
<?php
namespace App\Request\Payload;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
class SomeItem
{
/**
* #Assert\NotBlank()
* #Serializer\Type("string")
*/
private $label;
/**
* #Assert\Positive()
* #Serializer\Type("int")
*/
private $someNumber2;
/**
* #return string
*/
public function getLabel():string
{
return $this->label;
}
/**
* #param string $label
*/
public function setLabel(string $label)
{
$this->label = $label;
}
/**
* #return int
*/
public function getSomeNumber2():int
{
return $this->someNumber2;
}
/**
* #param mixed $someNumber2
*/
public function setSomeNumber2(int $someNumber2)
{
$this->someNumber2 = $someNumber2;
}
}
make a little change on MyPayload
<?php
namespace App\Request\Payload;
use DateTimeInterface;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\Collection;
class MyPayload
{
/**
* #var int
*
* #Serializer\Type("int")
* #Assert\Positive()
*/
private int $someNumber;
/**
* #var DateTimeInterface
*
* #Serializer\Type("DateTime<'Y-m-d'>")
*/
private DateTimeInterface $someDate;
/**
* #Serializer\Type("ArrayCollection<App\Request\Payload\SomeItem>")
*/
private Collection $someCollection;
public function getSomeNumber():int
{
return $this->someNumber;
}
/**
* #param int $someNumber
*/
public function setSomeNumber(int $someNumber)
{
$this->someNumber = $someNumber;
}
/**
* #return DateTimeInterface
*/
public function getSomeDate():DateTimeInterface
{
return $this->someDate;
}
/**
* #param DateTimeInterface $someDate
*/
public function setSomeDate(DateTimeInterface $someDate)
{
$this->someDate = $someDate;
}
/**
* #return mixed
*/
public function getSomeCollection():Collection
{
return $this->someCollection;
}
// todo implmentation of add remove someItem ...;)
}
Last change ,Controller
use App\Request\Payload\MyPayload;
// ..
/**
* #param MyPayload $myPayload
* #param ConstraintViolationListInterface $validationErrors
*
* #return JsonResponse
* #ParamConverter("myPayload", converter="fos_rest.request_body", class="App\Request\Payload\MyPayload")
*
*/
public function doSomething(MyPayload $myPayload, ConstraintViolationListInterface $validationErrors): JsonResponse {
try {
if (count($validationErrors) > 0) {
throw new ValidationException($validationErrors);
}
...
}

Related

Fetching Related Objects exception when work with mutil database

when i use mutil database with doctrine to related objects ,it can't find the table in the right way.
ta is table name ,in the acc database.
tb is table name too,in the trade database.
ta record:
id name
1 ta名称
tb record:
id name
1 tb名称
$em=$this->getDoctrine()->getRepository(ta::class,'customer');
$ta=$em->find(2);//now ,it can fetch the data,and the data is right
$tb=$ta->getTbTable();
$szName=$tb->getName(); //i want to get the tb record,it will throw an exception :
...................................
'acc.tb' doesn't exist"
actully,tb is in the trade database.
how to fix these problem
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\PrePersist;
use Doctrine\ORM\Mapping\PreUpdate;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Table(name="ta")
* #ORM\Entity(repositoryClass = "AppBundle\Entity\taRepository")
* #ORM\HasLifecycleCallbacks()
* #package AppBundle\Entity
*/
class ta {
/**
* #ORM\Column(type="integer",unique=true)
* #Assert\NotBlank(message="账号ID不能为空")
* #ORM\Id
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\EntityTrade\tb")
* #ORM\JoinColumn(name="id",referencedColumnName="id")
*/
private $tb_table;
/**
* Set id.
*
* #param int $id
*
* #return ta
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name.
*
* #param string $name
*
* #return ta
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name.
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set tbTable.
*
* #param \AppBundle\EntityTrade\tb|null $tbTable
*
* #return ta
*/
public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
{
$this->tb_table = $tbTable;
return $this;
}
/**
* Get tbTable.
*
* #return \AppBundle\EntityTrade\tb|null
*/
public function getTbTable()
{
return $this->tb_table;
}
}
<?php
namespace AppBundle\EntityTrade;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\PrePersist;
use Doctrine\ORM\Mapping\PreUpdate;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Table(name="tb")
* #ORM\Entity(repositoryClass = "AppBundle\EntityTrade\tbRepository")
* #ORM\HasLifecycleCallbacks()
* #package AppBundle\EntityTrade
*/
class tb {
/**
* #ORM\Column(type="integer",unique=true)
* #Assert\NotBlank(message="账号ID不能为空")
* #ORM\Id
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* Set id.
*
* #param int $id
*
* #return tb
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name.
*
* #param string $name
*
* #return tb
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name.
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
class defaultController{
public function indexAction(){
$em=$this->getDoctrine()->getRepository(ta::class,'customer');
$ta=$em->find(2);
$tb=$ta->getTbTable();
$szName=$tb->getName();
}
}
It will not work in this way. Doctrine's EntityManager only support management of entities within single database, so your cross-database relation between ta and tb will not be established. Please refer this issue in Doctrine bug tracker for more information.
However your goal can be accomplished into slightly different way. You can't establish cross-database relations between entities, but you can, of course, store ids that refers entities into different databases. Hence you can move all cross-database relations logic into repositories. For example let's assume that you have 2 EntityManager for each database: $accEm for acc database and $tradeEm for trade database. Taking in mind that you're using Symfony - they can be configured into DoctrineBundle configuration and then injected into services.
You will need to create some changes into your code:
ta.php, I've omitted most of code to express changes that needs to be made.
namespace AppBundle\Entity;
class ta
{
/**
* #ORM\Column(type="integer", nullable=true)
* #var int
*/
private $tb_table; // Notice that it is not a reference anymore, but simple integer
/**
* Set tbTable.
*
* #param \AppBundle\EntityTrade\tb|null $tbTable
*
* #return ta
*/
public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
{
// You can also consider updating this method to accept plain integers aswel
$this->tb_table = $tbTable instanceof \AppBundle\EntityTrade\tb ? $tbTable->getId() : null;
return $this;
}
/**
* Get tbTable.
*
* #return int|null
*/
public function getTbTable()
{
// Also notice that plain integer is returned, you may want to rename column and method names to reflect this change of column meaning
return $this->tb_table;
}
}
taRepository.php, I've also omitted most of code that can be there
namespace AppBundle\Entity;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
class taRepository extends EntityRepository {
/**
* #var EntityManager
*/
private $tradeEm;
/**
* #param EntityManager $tradeEm
*/
public function setTradeEntityManader(EntityManager $tradeEm)
{
// It is required to pass instance of EntityManager for "trade" database here. It should be done via Symfony services configuration, please refer Symfony documentation on this topic if needed
$this->tradeEm = $tradeEm;
}
/**
* #param ta $ta
* #return \AppBundle\EntityTrade\tb|null
*/
public function getTbTable(ta $ta) {
// This method should be used instead of $ta::getTbTable()
$tbId = $ta->getTbTable();
if ($tbId === null) {
return null;
}
return $this->tradeEm->find(\AppBundle\EntityTrade\tb::class, $tbId);
}
}
defaultController.php
namespace AppBundle\Controller;
use Doctrine\ORM\EntityManager;
class defaultController
{
/**
* #var EntityManager
*/
private $tradeEm;
/**
* #param EntityManager $tradeEm
*/
public function __construct(EntityManager $tradeEm)
{
// Same as before, this should be instance of EntityManager for "trade" database
$this->tradeEm = $tradeEm;
}
public function indexAction()
{
$em = $this->getDoctrine()->getRepository(ta::class, 'customer');
$ta = $em->find(2);
// Notice that we're not receiving "trade" database entity directly, but using corresponding EntityManager instead
$tb = $this->tradeEm->getTbTable($ta);
if ($tb !== null) {
$szName = $tb->getName();
}
}
}

API Platform Sonata Media Bundle Gallery - Circular Reference

New in SF3, I use API Platform and Sonata Media Bundle.
I'm blocked while getting Gallery entity of Sonata using API Platform GET request.
"A circular reference has been detected when serializing the object of class \"Application\\Sonata\\MediaBundle\\Entity\\Gallery\" (configured limit: 1)"
The admin of the entity works great, I can add a gallery to the entity.
When the entity have a gallery it cause this error, when it does not it's ok.
Entity Technic
GET /technics in API Platform
[
{
"id": 0,
"type": "string",
"comment": "string",
"links": [
"string"
],
"gallery": "string"
}
]
Entity Class
<?php
// src/AppBundle/Entity/Technic.php
namespace AppBundle\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ORM\Entity
* #ApiResource
*/
class Technic
{
/**
* #var int The id of this evaluation.
*
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #var string $type TechnicType of the evaluation
*
* #ORM\OneToOne(targetEntity="TechnicType")
* #Assert\NotBlank
*/
public $type;
/**
* #var string $note Note of the evaluation
*
* #ORM\Column(type="string", length=255, nullable=true)
*/
public $comment;
/**
* #var Link[] Link Links of this technic.
*
* #ORM\ManyToMany(targetEntity="Link", cascade={"persist"})
*/
private $links;
/**
* #ORM\OneToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Gallery",cascade={"persist"})
* #ORM\JoinColumn(name="gallery", referencedColumnName="id", nullable=true)
*/
private $gallery;
/**
* Constructor
*/
public function __construct()
{
$this->links = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set type
*
* #param \AppBundle\Entity\TechnicType $type
*
* #return Technic
*/
public function setType(\AppBundle\Entity\TechnicType $type = null)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return \AppBundle\Entity\TechnicType
*/
public function getType()
{
return $this->type;
}
/**
* Add link
*
* #param \AppBundle\Entity\Link $link
*
* #return Technic
*/
public function addLink(\AppBundle\Entity\Link $link)
{
$this->links[] = $link;
return $this;
}
/**
* Remove link
*
* #param \AppBundle\Entity\Link $link
*/
public function removeLink(\AppBundle\Entity\Link $link)
{
$this->links->removeElement($link);
}
/**
* Get links
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getLinks()
{
return $this->links;
}
/**
* Set comment
*
* #param string $comment
*
* #return Technic
*/
public function setComment($comment)
{
$this->comment = $comment;
return $this;
}
/**
* Get comment
*
* #return string
*/
public function getComment()
{
return $this->comment;
}
/**
* Set gallery
*
* #param \Application\Sonata\MediaBundle\Entity\Gallery $gallery
*
* #return Technic
*/
public function setGallery(\Application\Sonata\MediaBundle\Entity\Gallery $gallery = null)
{
$this->gallery = $gallery;
return $this;
}
/**
* Get gallery
*
* #return \Application\Sonata\MediaBundle\Entity\Gallery
*/
public function getGallery()
{
return $this->gallery;
}
}
Thank a lot guys, I'm desesperate I try a lot of things in StackQ/A, annotations, seraliazer config...
You need to configure serialization correctly. Either setup serialization groups, so that on GETting some entity serializer would only pick (for example) IDs of related entities, or set up circualr reference handler in normalizer and inject this normalizer into serializer.
$normalizer = new GetSetMethodNormalizer();
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
There might be more specific answer for api-platform, which I don't know, because serialization of related entities is popular issue.

Doctrine 2 - ManyToMany relationship - empty collection

I have many to many relationship between user and groups, but when I want to access all groups for user I get empty collection.
namespace LoginBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="User")
*/
class User
{
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $_iId;
/**
* #ORM\Column(type="string", name="login", length=45)
*/
private $_sLogin;
/**
* #ORM\ManyToMany(targetEntity="GroupBundle\Entity\Group", inversedBy="_aUser")
* #ORM\JoinTable(name="Group_x_User",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
private $_aGroup;
public function __construct() {
$this->_aGroup = new ArrayCollection();
}
/**
* Get iId
*
* #return integer
*/
public function getId()
{
return $this->_iId;
}
/**
* Set sLogin
*
* #param string $sLogin
*
* #return User
*/
public function setLogin($sLogin)
{
$this->_sLogin = $sLogin;
return $this;
}
/**
* Get sLogin
*
* #return string
*/
public function getLogin()
{
return $this->_sLogin;
}
public function getGroups()
{
return $this->_aGroup;
}
User and Group use Group_x_User table to store their relationships.
namespace GroupBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="Group")
*/
class Group
{
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $_iId;
/**
* #ORM\Column(type="string", name="name", length=45)
*/
private $_sName;
/**
* #ORM\ManyToMany(targetEntity="LoginBundle\Entity\User", mappedBy="_aGroup")
*/
private $_aUser;
public function __construct() {
$this->_aUser = new ArrayCollection();
}
/**
* Get iId
*
* #return integer
*/
public function getId()
{
return $this->_iId;
}
/**
* Set sName
*
* #param string $sName
*
* #return Group
*/
public function setName($sName)
{
$this->_sName = $sName;
return $this;
}
/**
* Get sName
*
* #return string
*/
public function getName()
{
return $this->_sName;
}
public function getUsers()
{
return $this->_aUser;
}
}
For restoring data from database I use code:
$oUser = $this->getDoctrine()
->getRepository('LoginBundle:User')
->find(2);
$aGroup = $oUser->getGroups();
Unfortunatelly $aGroup collection contains array of 0 elements while in database are records which are matching. What am I missing in my mapping?
There is something missing from your User class. You only declare _aGroup with ArrayCollection. This is not enough. You have to store the data into ArrayCollection.
Add this into User class.
public class addGroups(\GroupBundle\Entity\Group $group)
{
$group->addUsers($this);
$this->_aGroup->add($group);
}
This is for Group class.
public class addUsers(\LoginBundle\Entity\User $user)
{
if (!$this->_aUser->contains($user)) {
$this->_aUser->add($user);
}
}
For more information, you can visit this link.
#ORM\JoinTable() annotation syntax on User::$_aGroup definition is intended to be used for self-referencing relations Doctrine documentation.
Try using simplified syntax :
#JoinTable(name="Group_x_User")
If you use common conventions ('id' as column name for identifiers, and so on) Doctrine and Symfony will do the rest for you.

Symfony and Doctrine databases

I am working on some new project and the project is nearly done using Symfony framework, but the problem that i am used to CodeIgnitor Framework and basically as a Java developer/Android a lot of stuff i got confused with when working on Web development so here is the situation:
The website have a user end and an admin end (i am working on the Admin end), so there are these tables in the database which i really don't understand why they are built like this but this is not the problem
what i would like to know is how to add a service_category field with the corresponding translations in the service_category_translation using forms or any other way
this is the ServiceCategory Entity
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use JMS\Serializer\Annotation as Serializer;
/**
* class ServiceCategory
*
* #ORM\Table(name="service_category")
* #ORM\Entity
*
* #Serializer\ExclusionPolicy("all")
*/
class ServiceCategory
{
use ORMBehaviors\Timestampable\Timestampable;
use ORMBehaviors\SoftDeletable\SoftDeletable;
use ORMBehaviors\Translatable\Translatable;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*
* #Serializer\Expose
* #Serializer\Groups({"general-information", "service-offer"})
*/
private $id;
/**
* #var ServiceGroup
*
* #ORM\OneToMany(targetEntity="ServiceGroup", mappedBy="serviceCategory")
*
* #Serializer\Expose
* #Serializer\Groups({"service-offer"})
*/
private $serviceGroup;
/**
* Constructor
*/
public function __construct()
{
$this->serviceGroup = new ArrayCollection();
}
/**
* {#inheritdoc}
*/
public function __toString()
{
return $this->getName() ? $this->getName() : '';
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Get translated name
*
* #return string
*
* #Serializer\VirtualProperty
* #Serializer\SerializedName("name")
* #Serializer\Groups({"invoice-list", "service-offer"})
*/
public function getName()
{
if($this->getTranslations()->get($this->getCurrentLocale()) == null){
return 'sorry';
}
return $this->getTranslations()->get($this->getCurrentLocale())->getName();
}
/**
* Add serviceGroup
*
* #param ServiceGroup $serviceGroup
*
* #return ServiceCategory
*/
public function addServiceGroup(ServiceGroup $serviceGroup)
{
$this->serviceGroup[] = $serviceGroup;
return $this;
}
/**
* Remove serviceGroup
*
* #param ServiceGroup $serviceGroup
*/
public function removeServiceGroup(ServiceGroup $serviceGroup)
{
$this->serviceGroup->removeElement($serviceGroup);
}
/**
* Get serviceGroup
*
* #return Collection
*/
public function getServiceGroup()
{
return $this->serviceGroup;
}
}
and this is the ServiceCategoryTranslation Entity
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* Class ServiceCategoryTranslation
*
* #package CoreBundle\Entity
*
* #ORM\Entity
* #ORM\Table(name="service_category_translation")
*/
class ServiceCategoryTranslation
{
use ORMBehaviors\Translatable\Translation;
use ORMBehaviors\Timestampable\Timestampable;
use ORMBehaviors\SoftDeletable\SoftDeletable;
/**
* #ORM\Column(type="string", length=255)
*/
protected $name;
/**
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #param string
* #return null
*/
public function setName($name)
{
$this->name = $name;
}
public function __toString() {
return $this->name;
}
}
how can i achieve this ?
please don't guide me to symfony or doctrine documentation i have been lost there for two days now and i am running late on the schedule
Thanks in advance
You have a one-to-many-association from ServiceCategory (1) to ServiceCategoryTranslations (many) since I assume you
will manage the transaltions from the category. This have to be a bidirectional association, have a look
here
You have to add a property to manage the entities and describe the association. I will do it with annotations.
use Doctrine\Common\Collections\ArrayCollection;
class ServiceCategory
{
/**
* #OneToMany(targetEntity="ServiceCategoryTranslation", mappedBy="serviceCategory")
**/
private $translations;
public function __construct()
{
$this->translations = new ArrayCollection();
}
/**
* #return ServiceCategoryTranslation[]
*/
public function getStandort(){
return $this->translations;
}
/**
* #param ArrayCollection $translations
* #return ServiceCategory
*/
public function setTranslations(ArrayCollection $translations)
{
$this->translations->clear();
foreach ($translations as $translation){
$this->addTranslation($translation);
}
return $this;
}
/**
* #param ServiceCategoryTranslation $translation
* #return ServiceCategory
*/
public function addTranslation(ServiceCategoryTranslation $translation){
/* this is a way to keep the integerity */
$translation->setServiceCategory($this);
if(!$this->translation){
$this->translations = new ArrayCollection();
}
$this->translations->add($translation);
return $this;
}
/**
* #param ServiceCategoryTranslation $translation
* #return ServiceCategory
*/
public function removeStandort(ServiceCategoryTranslation $translation){
$this->translations->removeElement($translation);
return $this;
}
}
class ServiceCategoryTranslation
{
/**
* #ManyToOne(targetEntity="ServiceCategory", inversedBy="translations")
* #JoinColumn(name="translatable_id", referencedColumnName="id")
**/
private $serviceCategory;
/**
* #param ServiceCategoryTranslation $translation
* #return ServiceCategoryTranslation
*/
public function setServiceCategory(ServiceCategory $serviceCategory){
$this->serviceCategory = $serviceCategory;
return $this;
}
/* getter analog */
}

Symfony 2 - Retrieve Entity with Json, return another Entity

I have a problem while json_encodeing a Entity.
public function jsonvoteAction($id) {
$em = $this->getDoctrine()->getEntityManager();
$entity = $em->getRepository('KorumAGBundle:AGVote')->findOneById($id);
$response = new Response(json_encode($entity, 200));
$response->headers->set('Content-Type',' application/json');
return $response;
}
This code returns me a the users entity
{"users":{"__isInitialized__":false,"id":null,"nickname":null,"pwd":null,"email":null,"firstname":null,"lastname":null,"poste":null,"addr1":null,"addr2":null,"pc":null,"country":null,"phone":null,"province":null,"acess":null,"site":null,"crew":null,"utilisateur":null}}
And when I var dymp my $entity, it returns both my AGVote and USers entity.
Here is my AGVote Entity
<?php
namespace Korum\AGBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Korum\AGBundle\Entity\AGVote
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class AGVote
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $question;
/**
* #ORM\Column(type="smallint")
*/
private $actif;
/**
* #ORM\ManyToOne(targetEntity="\Korum\KBundle\Entity\Users", cascade={"all"})
*/
public $users;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set question
* Nb : Only AG admin can set a question
* #param text $question
*/
public function setQuestion($question)
{
$this->question = $question;
}
/**
* Get question
*
* #return text
*/
public function getquestion()
{
return $this->question;
}
/**
* Set actif
*
* #param smallint $actif
*/
public function setActif($actif)
{
$this->actif = $actif;
}
/**
* Get actif
*
* #return smallint
*/
public function getActif()
{
return $this->actif;
}
/**
* Set Users
*
* #param Korum\KBundle\Entity\Province $Users
*/
public function setUsers(\Korum\KBundle\Entity\Users $users)
{
$this->users = $users;
}
/**
* Get Users
*
* #return Korum\KBundle\Entity\Users
*/
public function getUsers()
{
return $this->users;
}
}
Does anyone have an idea of what happened ?
I tried to install the JSMSerializerBundle but event with Metadata library at version 1.1.
When I want to clear my cache, it failed with error :
See :
JMSSerializerBundle Installation : Catchable Fatal Error: Argument 1 passed to JMSSerializerBundle\Twig\SerializerExtension::__construct()
By default, json_encode only uses public properties.
So it serialized the only public property of AGVote: $users. The content of $users was an instance of User; which public fields were serialized.
You could work around these by adding a toArray() method to your entities, and then doing json_encode($entity->toArray()), but i highly recommend you to have a look and use the JMSSerializedBundle.

Resources