json_encode() recursion detected Symfony2 JMSSerializerBundle - symfony

I'm currently trying to expose groups for an ajax call.
If I user #Expose on each field it works like a charm but if I replace it with #Groups it throws the error recursion detected in JsonSerializationVisitor.php on line 29 and the results in my ajax return has a 'null' value.
Warning: json_encode() [function.json-encode]: recursion detected in /Applications/MAMP/htdocs/xxx-ref/vendor/jms/serializer/src/JMS/Serializer/JsonSerializationVisitor.php on line 29
{"datas":[{"datas":null,"errors":[],"redirect":null},{},{},{},{},{},{},{},{},{},{},{}],"errors":[],"redirect":null}
This is my call to the serializer =>
$context = new SerializationContext(false, 1);
$context->setSerializeNull(true);
$context->setGroups(array('details'));
$response->setContent($this->get('serializer')->serialize(array( 'datas'=>$datas, 'errors'=>$errors, 'redirect'=>$redirect), 'json', $context));
And this is the entity used
<?php
namespace XXX\CoreBundle\Entity\Geo;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Exclude;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\Groups;
use XXX\CommonBundle\Entity\interfaces\TranslatableInterface;
use XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation;
use XXX\CoreBundle\Proxy\AddressTranslatorProxy;
/**
* #ORM\Entity(repositoryClass="XXX\CoreBundle\Repository\Geo\AddressRepository")
* #ORM\HasLifecycleCallbacks()
* #ORM\Table(name="geo_address",
* indexes={#ORM\Index(name="address_idx", columns={"geolocation","formattedAddress","slug","valid"})})
* #Gedmo\TranslationEntity(class="XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation")
* #ExclusionPolicy("all")
*/
class Address {
/**
* #ORM\Id
* #ORM\Column(type="bigint")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Country", inversedBy="addresses", fetch="EXTRA_LAZY")
* #ORM\JoinColumn(name="country_id", referencedColumnName="id")
*
*/
protected $country;
/**
* #ORM\Column(type="string", length=128, unique=true)
* #Gedmo\Slug(fields={"formattedAddress"})
*
*/
protected $slug;
/**
* #ORM\Column(type="string", length=255, nullable=false)
* #Gedmo\Translatable(fallback=true)
*
*/
protected $formattedAddress;
/**
* #ORM\Column(type="point", unique=true)
*
*/
protected $geolocation;
/**
* #ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Street", inversedBy="addresses")
* #ORM\JoinColumn(name="street_id", referencedColumnName="id")
*
*/
protected $street;
/**
* #ORM\Column(type="string", length=32, nullable=true)
* #Groups({"details"})
*/
protected $number;
/**
* #ORM\Column(type="string", length=32, nullable=true)
*
*/
protected $postbox;
/**
* #ORM\Column(type="string", length=16, nullable=true)
*
*/
protected $postalCode;
/**
* #ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Locality", inversedBy="addresses")
* #ORM\JoinColumn(name="locality_id", referencedColumnName="id", nullable=true)
*
*/
protected $locality;
/**
* #ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\Sublocality", inversedBy="addresses")
* #ORM\JoinColumn(name="sublocality_id", referencedColumnName="id", nullable=true)
*
*/
protected $sublocality;
/**
* #ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\AdministrativeAreaLevel1", inversedBy="addresses")
* #ORM\JoinColumn(name="al1_id", referencedColumnName="id")
*
*/
protected $administrativeAreaLevel1;
/**
* #ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\AdministrativeAreaLevel2", inversedBy="addresses")
* #ORM\JoinColumn(name="al2_id", referencedColumnName="id")
*
*/
protected $administrativeAreaLevel2;
/**
* #ORM\ManyToOne(targetEntity="XXX\CoreBundle\Entity\Geo\AdministrativeAreaLevel3", inversedBy="addresses")
* #ORM\JoinColumn(name="al3_id", referencedColumnName="id")
*
*/
protected $administrativeAreaLevel3;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $geolocationType;
/**
* #ORM\Column(type="point")
*
*/
protected $viewportSouthWest;
/**
* #ORM\Column(type="point")
*
*/
protected $viewportNorthEast;
/**
* #ORM\Column(type="boolean", nullable=false)
*
*
*/
protected $valid;
/**
* #ORM\OneToMany(targetEntity="XXX\CoreBundle\Entity\Geo\ChangeRequest", mappedBy="address")
*/
protected $changeRequest;
/**
* #ORM\OneToMany(targetEntity="XXX\CoreBundle\Entity\Ads\Hybrid", mappedBy="address")
*/
protected $hybrids;
/**
* #ORM\OneToMany(
* targetEntity="XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation",
* mappedBy="object",
* cascade={"persist","remove"}, fetch="EXTRA_LAZY"
* )
* #ORM\JoinColumn(name="translatable_id", referencedColumnName="id", nullable=true)
*/
protected $translations;
function __construct() {
$this->hybrids = new \Doctrine\Common\Collections\ArrayCollection();
$this->changeRequest = new \Doctrine\Common\Collections\ArrayCollection();
$this->translations = new \Doctrine\Common\Collections\ArrayCollection();
$this->valid = false;
}
public function getLocalityAsText() {
if ($this->postalCode != null) {
return strtolower( $this->country->getIso3166Alpha2()."-".$this->postalCode );
} else {
return strtolower( $this->country->getIso3166Alpha2()."-".$this->locality->getName() );
}
}
public function __toString() {
return $this->getFormattedAddress();
}
public function translate($locale = null)
{
return new AddressTranslatorProxy(
$this,
$locale,
array('formattedAddress'),
'XXX\CoreBundle\Entity\Geo\Translation\AddressTranslation',
$this->translations
);
}
public function isPrecise() {
return ( $this->getGeolocationType() === 'ROOFTOP' || $this ->getGeolocationType() === 'RANGE_INTERPOLATED' );
}
public function getTranslations()
{
return $this->translations;
}
public function addTranslation(AddressTranslation $t)
{
if (!$this->translations->contains($t)) {
$this->translations[] = $t;
$t->setObject($this);
}
}
public function removeTranslation(AddressTranslation $t)
{
if ($this->translations->contains($t)) {
$this->translations->remove($t);
}
}
public function getHybrids() {
return $this->hybrids;
}
public function setHybrids($hybrids) {
$this->hybrids = $hybrids;
return $this;
}
public function getFormattedAddress($locale=null) {
return $this->formattedAddress;
}
public function getId() {
return $this->id;
}
public function getGeolocation() {
return $this->geolocation;
}
public function setGeolocation($geolocation) {
$this->geolocation = $geolocation;
return $this;
}
public function getStreet() {
return $this->street;
}
public function setStreet($street) {
$this->street = $street;
return $this;
}
public function getNumber() {
return $this->number;
}
public function setNumber($number) {
$this->number = $number;
return $this;
}
public function getPostbox() {
return $this->postbox;
}
public function setPostbox($postbox) {
$this->postbox = $postbox;
return $this;
}
public function getLocality() {
return $this->locality;
}
public function setLocality($locality) {
$this->locality = $locality;
return $this;
}
public function getSublocality() {
return $this->sublocality;
}
public function setSublocality($sublocality) {
$this->sublocality = $sublocality;
return $this;
}
public function getCountry() {
return $this->country;
}
public function setCountry($country) {
$this->country = $country;
return $this;
}
public function getAdministrativeAreaLevel1() {
return $this->administrativeAreaLevel1;
}
public function setAdministrativeAreaLevel1($administrativeAreaLevel1) {
$this->administrativeAreaLevel1 = $administrativeAreaLevel1;
return $this;
}
public function getAdministrativeAreaLevel2() {
return $this->administrativeAreaLevel2;
}
public function setAdministrativeAreaLevel2($administrativeAreaLevel2) {
$this->administrativeAreaLevel2 = $administrativeAreaLevel2;
return $this;
}
public function getAdministrativeAreaLevel3() {
return $this->administrativeAreaLevel3;
}
public function setAdministrativeAreaLevel3($administrativeAreaLevel3) {
$this->administrativeAreaLevel3 = $administrativeAreaLevel3;
return $this;
}
public function getGeolocationType() {
return $this->geolocationType;
}
public function setGeolocationType($geolocationType) {
$this->geolocationType = $geolocationType;
return $this;
}
public function getViewportSouthWest() {
return $this->viewportSouthWest;
}
public function setViewportSouthWest($viewportSouthWest) {
$this->viewportSouthWest = $viewportSouthWest;
return $this;
}
public function getViewportNorthEast() {
return $this->viewportNorthEast;
}
public function setViewportNorthEast($viewportNorthEast) {
$this->viewportNorthEast = $viewportNorthEast;
return $this;
}
public function getChangeRequest() {
return $this->changeRequest;
}
public function setChangeRequest($changeRequest) {
$this->changeRequest = $changeRequest;
return $this;
}
public function setFormattedAddress($formattedAddress) {
$this->formattedAddress = $formattedAddress;
return $this;
}
public function getPostalCode() {
return $this->postalCode;
}
public function setPostalCode($postalCode) {
$this->postalCode = $postalCode;
return $this;
}
public function getValid() {
return $this->valid;
}
public function setValid($valid) {
$this->valid = $valid;
return $this;
}
public function getSlug() {
return $this->slug;
}
public function setSlug($slug) {
$this->slug = $slug;
return $this;
}
}

I answered my own question
I just needed to add
#Expose
before the Groups annotation.
/**
* #ORM\Column(type="string", length=32, nullable=true)
* #Expose
* #Groups({"details"})
*/
protected $number;

Related

How to save Foreign Key OneToMany Relationship in Symfony 5 with Doctrine

I am new to Symfony and I have a problem with saving a foreign key in the table. I try to explain it as well as possible.
I am making a ToDo application.
- Every user has one profile
- Every profile has many items
- Any User can add new items to the list
- When the user creates a new item, the profile_id should be saved in the Item Table. But I get an Error. I have tried diferent ways to solve that but I can not find a soloution. I hope you can help me with that.
This is my Profile Entity
<?php
namespace App\Entity;
use DateTime;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\ProfileRepository")
*/
class Profile
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $firstName;
/**
* #ORM\Column(type="string", length=255)
*/
private $lastName;
/**
* #ORM\OneToOne(targetEntity="App\Entity\User", inversedBy="profile", cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #ORM\Column(type="string", length=255)
*/
private $gender;
/**
* #ORM\Column(type="string", length=255)
*/
private $initials;
/**
* #ORM\Column(type="string", length=255)
*/
private $country;
/**
* #ORM\Column(type="string", length=255)
*/
private $city;
/**
* #ORM\Column(type="string", length=255)
*/
private $postalCode;
/**
* #ORM\Column(type="string", length=255)
*/
private $street;
/**
* #ORM\Column(type="string", length=255)
*/
private $houseNumber;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $houseNumberAddition;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $phoneNumber;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $mobileNumber;
/**
* #ORM\Column(type="boolean")
*/
private $accepted;
/**
* #ORM\Column(type="boolean")
*/
private $visible;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Items", mappedBy="profile")
*/
private $items;
public function __construct()
{
$this->items = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(User $user): self
{
$this->user = $user;
return $this;
}
public function getGender(): ?string
{
return $this->gender;
}
public function setGender(string $gender): self
{
$this->gender = $gender;
return $this;
}
public function getInitials(): ?string
{
return $this->initials;
}
public function setInitials(string $initials): self
{
$this->initials = $initials;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country): self
{
$this->country = $country;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(string $city): self
{
$this->city = $city;
return $this;
}
public function getPostalCode(): ?string
{
return $this->postalCode;
}
public function setPostalCode(string $postalCode): self
{
$this->postalCode = $postalCode;
return $this;
}
public function getStreet(): ?string
{
return $this->street;
}
public function setStreet(string $street): self
{
$this->street = $street;
return $this;
}
public function getHouseNumber(): ?string
{
return $this->houseNumber;
}
public function setHouseNumber(string $houseNumber): self
{
$this->houseNumber = $houseNumber;
return $this;
}
public function getHouseNumberAddition(): ?string
{
return $this->houseNumberAddition;
}
public function setHouseNumberAddition(?string $houseNumberAddition): self
{
$this->houseNumberAddition = $houseNumberAddition;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phoneNumber;
}
public function setPhoneNumber(?string $phoneNumber): self
{
$this->phoneNumber = $phoneNumber;
return $this;
}
public function getMobileNumber(): ?string
{
return $this->mobileNumber;
}
public function setMobileNumber(?string $mobileNumber): self
{
$this->mobileNumber = $mobileNumber;
return $this;
}
public function getAccepted(): ?bool
{
return $this->accepted;
}
public function setAccepted(bool $accepted): self
{
$this->accepted = $accepted;
return $this;
}
public function getVisible(): ?bool
{
return $this->visible;
}
public function setVisible(bool $visible): self
{
$this->visible = $visible;
return $this;
}
/**
* #return DateTimeInterface|null
*/
public function getCreatedAt(): ?DateTimeInterface
{
return $this->createdAt;
}
/**
* #param DateTimeInterface $createdAt
* #return $this
*/
public function setCreatedAt(DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return DateTimeInterface|null
*/
public function getUpdatedAt(): ?DateTimeInterface
{
return $this->updatedAt;
}
/**
* #param DateTimeInterface|null $updatedAt
* #return $this
*/
public function setUpdatedAt(?DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* #ORM\PrePersist()
*/
public function onPrePersist()
{
$this->createdAt = new DateTime("now");
}
/**
* #ORM\PreUpdate()
*/
public function onPreUpdate()
{
$this->updatedAt = new DateTime("now");
}
/**
* #return Collection|Items[]
*/
public function getItems(): Collection
{
return $this->items;
}
public function addItem(Items $item): self
{
if (!$this->items->contains($item)) {
$this->items[] = $item;
$item->setProfile($this);
}
return $this;
}
public function removeItem(Items $item): self
{
if ($this->items->contains($item)) {
$this->items->removeElement($item);
// set the owning side to null (unless already changed)
if ($item->getProfile() === $this) {
$item->setProfile(null);
}
}
return $this;
}
}
This is my Item Entity
<?php
namespace App\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\ItemsRepository")
* #ORM\HasLifecycleCallbacks
*/
class Items
{
/**
* #var int
*
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Profile", inversedBy="items")
* #ORM\JoinColumn(nullable=false)
*/
private $profile;
/**
* #var string
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $title;
/**
* #var string
*
* #ORM\Column(type="text", nullable=false)
*/
private $description;
/**
* #var datetime $createdAt
*
* #ORM\Column(type="datetime", nullable=false)
*/
private $createdAt;
/**
* #var datetime $updatedAt
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
* #return Items
*/
public function setId(int $id): Items
{
$this->id = $id;
return $this;
}
public function getProfile(): ?Profile
{
return $this->profile;
}
public function setProfile(?Profile $profile): self
{
$this->profile = $profile;
return $this;
}
/**
* #return string
*/
public function getTitle(): ?string
{
return $this->title;
}
/**
* #param string $title
* #return Items
*/
public function setTitle(string $title): Items
{
$this->title = $title;
return $this;
}
/**
* #return string
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* #param string $description
* #return Items
*/
public function setDescription(string $description): Items
{
$this->description = $description;
return $this;
}
/**
* #return DateTime
*/
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
/**
* #param DateTime $createdAt
* #return Items
*/
public function setCreatedAt(DateTime $createdAt): Items
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return DateTime
*/
public function getUpdatedAt(): DateTime
{
return $this->updatedAt;
}
/**
* #param DateTime $updatedAt
* #return Items
*/
public function setUpdatedAt(DateTime $updatedAt): Items
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* #ORM\PrePersist()
*/
public function onPrePersist()
{
$this->createdAt = new DateTime("now");
}
/**
* #ORM\PreUpdate()
*/
public function onPreUpdate()
{
$this->updatedAt = new DateTime("now");
}
}
This is my Item Controller where a new Item gets stored
/**
* #Route("/item/create", name="create_item")
* #return Response
*/
public function create()
{
$form = $this->createForm(CreateTodoFormType::class, null, ['action' => $this->generateUrl('store_item')]);
return $this->render('item/create.html.twig', [
'todoForm' => $form->createView(),
]);
}
/**
* #Route("/item/store", name="store_item", methods={"POST"})
* #param EntityManagerInterface $em
* #param Request $request
* #param TranslatorInterface $translator
* #return RedirectResponse
*/
public function store(EntityManagerInterface $em, Request $request, TranslatorInterface $translator)
{
$form = $this->createForm(CreateTodoFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$profile = $em->getRepository(Profile::class)->findBy(['user' => $this->getUser()->getId()]);
$item = new Items();
$item->setTitle($data->getTitle());
$item->setDescription($data->getDescription());
$item->setProfile($profile);
$em->persist($item);
$em->flush();
return $this->redirectToRoute('item');
}
return $this->redirectToRoute('create_item', [
'todoForm' => $form->createView(),
]);
}
When I do it in this way, I get an error!
Argument 1 passed to App\Entity\Items::setProfile() must be an instance of App\Entity\Profile or null, array given, called in C:\xampp\htdocs\projects\SymfonyProjects\symfony_to_do\src\Controller\ItemController.php on line 79
$profile = $em->getRepository(Profile::class)->findBy(['user' => $this->getUser()->getId()]);
This request returns an array, even if it contain just one element. You can use $profile[0] for the first element or better: use the findOneBy method!

Doctrine QueryBuilder COUNT and Voters

I have some entities, for example Device entity with a voter allowing the current user to access or not some Devices.
When searching for Devices, in order to filter, I user an array_filter function which is working well.
But, I want to make some stats on my Device entity, for example the number of Devices by Brand.
My Query is OK :
$query = $this->createQueryBuilder('d')
->select('COUNT(d.id), b.name')
->join('d.model', 'm')
->join('m.Brand', 'b')
->groupBy('b.name')
;
return $query->getQuery()->getResult();
I have an array with my datas.
But the voter doesn't apply.
If I switch the user to one who may not have access to all Devices, I still see the same numbers.
So, how can I filter my COUNT request with the voters ?
The Device Entity :
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity(repositoryClass="App\Repository\DeviceRepository")
*/
class Device
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=15)
*/
private $reference;
/**
* #ORM\Column(type="string", length=20)
*/
private $imei;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $buyDate;
/**
* #ORM\Column(type="float", nullable=true)
*/
private $buyPrice;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\DeviceGrade")
*/
private $grade;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\CustomerGroup")
* #ORM\JoinColumn(nullable=false)
*/
private $customerGroup;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\CustomerEntity")
*/
private $customerEntity;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\CustomerSite")
*/
private $customerSite;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Model")
* #ORM\JoinColumn(nullable=false)
*/
private $model;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $sellDate;
/**
* #ORM\Column(type="float", nullable=true)
*/
private $sellPrice;
/**
* #ORM\Column(type="datetime", nullable=true)
* #Gedmo\Timestampable(on="create")
*/
private $dateAdd;
/**
* #ORM\Column(type="datetime", nullable=true)
* #Gedmo\Timestampable(on="update")
*/
private $dateUpd;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #Gedmo\Blameable(on="create")
*/
private $createdBy;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #Gedmo\Blameable(on="update")
*/
private $modifiedBy;
/**
* #ORM\OneToMany(targetEntity="App\Entity\DeviceStatusHistory", mappedBy="device")
*/
private $deviceStatusHistories;
public function __construct()
{
$this->deviceStatusHistories = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getReference(): ?string
{
return $this->reference;
}
public function setReference(string $reference): self
{
$this->reference = $reference;
return $this;
}
public function getImei(): ?string
{
return $this->imei;
}
public function setImei(string $imei): self
{
$this->imei = $imei;
return $this;
}
public function getBuyDate(): ?\DateTimeInterface
{
return $this->buyDate;
}
public function setBuyDate(?\DateTimeInterface $buyDate): self
{
$this->buyDate = $buyDate;
return $this;
}
public function getBuyPrice(): ?float
{
return $this->buyPrice;
}
public function setBuyPrice(?float $buyPrice): self
{
$this->buyPrice = $buyPrice;
return $this;
}
public function getGrade(): ?DeviceGrade
{
return $this->grade;
}
public function setGrade(?DeviceGrade $grade): self
{
$this->grade = $grade;
return $this;
}
public function getCustomerGroup(): ?CustomerGroup
{
return $this->customerGroup;
}
public function setCustomerGroup(?CustomerGroup $customerGroup): self
{
$this->customerGroup = $customerGroup;
return $this;
}
public function getCustomerEntity(): ?CustomerEntity
{
return $this->customerEntity;
}
public function setCustomerEntity(?CustomerEntity $customerEntity): self
{
$this->customerEntity = $customerEntity;
return $this;
}
public function getCustomerSite(): ?CustomerSite
{
return $this->customerSite;
}
public function setCustomerSite(?CustomerSite $customerSite): self
{
$this->customerSite = $customerSite;
return $this;
}
public function getModel(): ?Model
{
return $this->model;
}
public function setModel(?Model $model): self
{
$this->model = $model;
return $this;
}
public function getSellDate(): ?\DateTimeInterface
{
return $this->sellDate;
}
public function setSellDate(?\DateTimeInterface $sellDate): self
{
$this->sellDate = $sellDate;
return $this;
}
public function getSellPrice(): ?float
{
return $this->sellPrice;
}
public function setSellPrice(?float $sellPrice): self
{
$this->sellPrice = $sellPrice;
return $this;
}
public function getDateAdd(): ?\DateTimeInterface
{
return $this->dateAdd;
}
public function setDateAdd(\DateTimeInterface $dateAdd): self
{
$this->dateAdd = $dateAdd;
return $this;
}
public function getDateUpd(): ?\DateTimeInterface
{
return $this->dateUpd;
}
public function setDateUpd(\DateTimeInterface $dateUpd): self
{
$this->dateUpd = $dateUpd;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function getModifiedBy(): ?User
{
return $this->modifiedBy;
}
public function setModifiedBy(?User $modifiedBy): self
{
$this->modifiedBy = $modifiedBy;
return $this;
}
/**
* #return Collection|DeviceStatusHistory[]
*/
public function getDeviceStatusHistories(): Collection
{
return $this->deviceStatusHistories;
}
public function addDeviceStatusHistory(DeviceStatusHistory $deviceStatusHistory): self
{
if (!$this->deviceStatusHistories->contains($deviceStatusHistory)) {
$this->deviceStatusHistories[] = $deviceStatusHistory;
$deviceStatusHistory->setDevice($this);
}
return $this;
}
public function removeDeviceStatusHistory(DeviceStatusHistory $deviceStatusHistory): self
{
if ($this->deviceStatusHistories->contains($deviceStatusHistory)) {
$this->deviceStatusHistories->removeElement($deviceStatusHistory);
// set the owning side to null (unless already changed)
if ($deviceStatusHistory->getDevice() === $this) {
$deviceStatusHistory->setDevice(null);
}
}
return $this;
}
public function __toString(): string
{
return $this->reference.' / '.$this->imei.' / '.$this->getModel()->getName().' - '.
$this->getModel()->getBrand()->getName().' - '.$this->getModel()->getColor()->getName().
' - '.$this->getModel()->getStorage()->getCapacity();
}
}
The Model Entity :
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
/**
* #ORM\Entity(repositoryClass="App\Repository\ModelRepository")
* #Vich\Uploadable
*/
class Model
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="boolean")
*/
private $isActive;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $dateStartSell;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $dateEndSell;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $dateEndSupport;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Brand", inversedBy="models")
* #ORM\JoinColumn(nullable=false)
*/
private $Brand;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Color")
* #ORM\JoinColumn(nullable=false)
*/
private $color;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Storage")
*/
private $storage;
/**
* #ORM\Column(type="datetime", nullable=true)
* #Gedmo\Timestampable(on="create")
*/
private $dateAdd;
/**
* #ORM\Column(type="datetime", nullable=true)
* #Gedmo\Timestampable(on="update")
*/
private $dateUpd;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #Gedmo\Blameable(on="create")
*/
private $createdBy;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #Gedmo\Blameable(on="update")
*/
private $modifiedBy;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\CustomerGroup", inversedBy="models")
*/
private $customerGroup;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="model_image", fileNameProperty="imageName", size="imageSize")
*
* #var File
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*
* #var string
*/
private $imageName;
/**
* #ORM\Column(type="integer", nullable=true)
*
* #var integer
*/
private $imageSize;
public function __construct(?File $imageFile = null)
{
$this->customerGroup = new ArrayCollection();
$this->imageFile = $imageFile;
if (null !== $imageFile) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->dateUpd = new \DateTimeImmutable();
}
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getIsActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
public function getDateStartSell(): ?\DateTimeInterface
{
return $this->dateStartSell;
}
public function setDateStartSell(?\DateTimeInterface $dateStartSell): self
{
$this->dateStartSell = $dateStartSell;
return $this;
}
public function getDateEndSell(): ?\DateTimeInterface
{
return $this->dateEndSell;
}
public function setDateEndSell(?\DateTimeInterface $dateEndSell): self
{
$this->dateEndSell = $dateEndSell;
return $this;
}
public function getDateEndSupport(): ?\DateTimeInterface
{
return $this->dateEndSupport;
}
public function setDateEndSupport(?\DateTimeInterface $dateEndSupport): self
{
$this->dateEndSupport = $dateEndSupport;
return $this;
}
public function getBrand(): ?Brand
{
return $this->Brand;
}
public function setBrand(?Brand $Brand): self
{
$this->Brand = $Brand;
return $this;
}
public function getColor(): ?Color
{
return $this->color;
}
public function setColor(?Color $color): self
{
$this->color = $color;
return $this;
}
public function getStorage(): ?Storage
{
return $this->storage;
}
public function setStorage(?Storage $storage): self
{
$this->storage = $storage;
return $this;
}
public function getDateAdd(): ?\DateTimeInterface
{
return $this->dateAdd;
}
public function setDateAdd(\DateTimeInterface $dateAdd): self
{
$this->dateAdd = $dateAdd;
return $this;
}
public function getDateUpd(): ?\DateTimeInterface
{
return $this->dateUpd;
}
public function setDateUpd(\DateTimeInterface $dateUpd): self
{
$this->dateUpd = $dateUpd;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function getModifiedBy(): ?User
{
return $this->modifiedBy;
}
public function setModifiedBy(?User $modifiedBy): self
{
$this->modifiedBy = $modifiedBy;
return $this;
}
public function __toString(): string
{
return $this->getBrand()->getName().' '.$this->getName().' '.$this->getColor()->getName().' '.$this->getStorage()->getCapacity();
}
/**
* #return Collection|CustomerGroup[]
*/
public function getCustomerGroup(): Collection
{
return $this->customerGroup;
}
public function addCustomerGroup(CustomerGroup $customerGroup): self
{
if (!$this->customerGroup->contains($customerGroup)) {
$this->customerGroup[] = $customerGroup;
}
return $this;
}
public function removeCustomerGroup(CustomerGroup $customerGroup): self
{
if ($this->customerGroup->contains($customerGroup)) {
$this->customerGroup->removeElement($customerGroup);
}
return $this;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $imageFile
*/
public function setImageFile(?File $imageFile = null): void
{
$this->imageFile = $imageFile;
if (null !== $imageFile) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->dateUpd = new \DateTimeImmutable();
}
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageName(?string $imageName): void
{
$this->imageName = $imageName;
}
public function getImageName(): ?string
{
return $this->imageName;
}
public function setImageSize(?int $imageSize): void
{
$this->imageSize = $imageSize;
}
public function getImageSize(): ?int
{
return $this->imageSize;
}
}
And the Brand Entity :
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity(repositoryClass="App\Repository\BrandRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Brand
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="create")
*/
private $dateAdd;
/**
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="create")
*/
private $dateUpd;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #ORM\JoinColumn(nullable=false)
* #Gedmo\Blameable(on="create")
*/
private $createdBy;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #ORM\JoinColumn(nullable=false)
* #Gedmo\Blameable(on="update")
*/
private $modifiedBy;
/**
* #ORM\Column(type="boolean")
*/
private $isDeleted;
/**
* #ORM\Column(type="boolean")
*/
private $isActive;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Model", mappedBy="Brand")
*/
private $models;
public function __construct()
{
$this->models = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDateAdd(): ?\DateTimeInterface
{
return $this->dateAdd;
}
public function setDateAdd(\DateTimeInterface $dateAdd): self
{
$this->dateAdd = $dateAdd;
return $this;
}
public function getDateUpd(): ?\DateTimeInterface
{
return $this->dateUpd;
}
public function setDateUpd(\DateTimeInterface $dateUpd): self
{
$this->dateUpd = $dateUpd;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function getModifiedBy(): ?User
{
return $this->modifiedBy;
}
public function setModifiedBy(?User $modifiedBy): self
{
$this->modifiedBy = $modifiedBy;
return $this;
}
public function getIsDeleted(): ?bool
{
return $this->isDeleted;
}
public function setIsDeleted(bool $isDeleted): self
{
$this->isDeleted = $isDeleted;
return $this;
}
public function getIsActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
/**
* #return Collection|Model[]
*/
public function getModels(): Collection
{
return $this->models;
}
public function addModel(Model $model): self
{
if (!$this->models->contains($model)) {
$this->models[] = $model;
$model->setBrand($this);
}
return $this;
}
public function removeModel(Model $model): self
{
if ($this->models->contains($model)) {
$this->models->removeElement($model);
// set the owning side to null (unless already changed)
if ($model->getBrand() === $this) {
$model->setBrand(null);
}
}
return $this;
}
}
Thanks for your help !
Best,
Julien
The voter won't update your query. It is used to check if a user is authorized to access some part of your code.
If you want to have your Devices according to your Voter, you'll need to write the correct query based on you need !
Thanks for your messages
#Alexandre : I'm going to search this way.
What I've done to achieve my goal :
- Add a bidirectionnal relation with inversedby in model and brand entities.
This way, I can make that :
$brands = $this->getDoctrine()->getRepository(Brand::class)->findAll();
$arrayBrands = array();
$arrayDevicesCount = array();
foreach($brands as $brand)
{
$devicesCount = 0;
$models = $brand->getModels();
foreach ($models as $model)
{
$devices = $model->getDevices()->getValues();
$devices = array_filter($devices, function (Device $device){
return $this->isGranted('view', $device);
});
$devicesCount+= count($devices);
}
if($devicesCount > 0)
{
array_push($arrayBrands, $brand->getName());
array_push($arrayDevicesCount, $devicesCount);
}
}
And this is working well !

Definition of association cause Entity gets invalid

I'm working on a project but all the time I'm seeing this mappings problems:
The association PL\OrderBundle\Entity\Order#company refers to the
inverse side field PL\CompanyBundle\Entity\Company#id which is not
defined as association.
The association PL\OrderBundle\Entity\Order#company refers to the inverse side field
PL\CompanyBundle\Entity\Company#id which does not exist.
The association PL\OrderBundle\Entity\Order#medias refers to the owning
side field Application\Sonata\MediaBundle\Entity\Media#orders which
does not exist.
For more than I read and read Doctrine Docs I don't know how to fix them, what is wrong? any help? Here are the related entities:
PL\OrderBundle\Entity\Order.php
<?php
namespace PL\OrderBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="tb_order")
*/
class Order {
/**
* #ORM\Id
* #ORM\Column(type="string", length=15, unique=true, nullable=false)
*/
protected $no_order;
/**
* #ORM\ManyToOne(targetEntity="PL\CompanyBundle\Entity\Company", inversedBy="id")
*/
protected $company;
/**
* #ORM\Column(type="string", length=15, unique=true)
*/
protected $business_case;
/**
* #ORM\Column(type="integer", length=1)
*/
protected $charge_status;
/**
* #ORM\Column(type="datetime")
*/
protected $eta;
/**
* #ORM\Column(type="datetime")
*/
protected $etd;
/**
* #ORM\Column(type="integer", length=1)
*/
protected $transport_media;
/**
* #ORM\Column(type="integer", length=1)
*/
protected $incoterm;
/**
* #ORM\Column(type="string", length=250)
*/
protected $comments;
/**
* #ORM\ManyToMany(targetEntity="Application\Sonata\MediaBundle\Entity\Media", mappedBy="orders")
*/
protected $medias;
public function __construct() {
$this->medias = new \Doctrine\Common\Collections\ArrayCollection();
}
public function setNoOrder($no_order) {
$this->no_order = $no_order;
}
public function getNoOrder() {
return $this->no_order;
}
public function setCompany(\PL\CompanyBundle\Entity\Company $company) {
$this->company = $company;
}
public function getCompany() {
return $this->company;
}
public function setBusinessCase($business_case) {
$this->business_case = $business_case;
}
public function getBusinessCase() {
return $this->business_case;
}
public function setChargeStatus($charge_status) {
$this->charge_status = $charge_status;
}
public function getChargeStatus() {
return $this->charge_status;
}
public function setETA($eta) {
$this->eta = $eta;
}
public function getETA() {
return $this->eta;
}
public function setETD($etd) {
$this->etd = $etd;
}
public function getETD() {
return $this->etd;
}
public function setTransportMedia($transport_media) {
$this->transport_media = $transport_media;
}
public function getTransportMedia() {
return $this->transport_media;
}
public function setIncoterm($incoterm) {
$this->incoterm = $incoterm;
}
public function getIncoterm() {
return $this->incoterm;
}
public function setComments($comments) {
$this->comments = $comments;
}
public function getComments() {
return $this->comments;
}
public function setMedias(\Application\Sonata\MediaBundle\Entity\Media $media) {
$this->medias[] = $media;
}
public function addMedia(\Application\Sonata\MediaBundle\Entity\Media $media) {
$this->medias[] = $media;
}
public function getMedias() {
return $this->medias;
}
}
\PL\CompanyBundle\Entity\Company.php
<?php
namespace PL\CompanyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity
* #ORM\Table(name="company")
*/
class Company {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=30, unique=true, nullable=false)
*/
protected $name;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="register_date", type="datetime")
*/
protected $created_on;
/**
* #ORM\Column(type="string", length=45)
*/
protected $country;
/**
* #ORM\ManyToMany(targetEntity="Application\Sonata\UserBundle\Entity\User", mappedBy="companies")
*/
protected $users;
public function __construct() {
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setCountry($country) {
$this->country = $country;
}
public function getCountry() {
return $this->country;
}
public function setCreatedOn($created_on) {
$this->created_on = $created_on;
}
public function getCreatedOn() {
return $this->created_on;
}
public function __toString() {
return $this->name;
}
}
\Application\Sonata\MediaBundle\Entity\Media.php
<?php
namespace Application\Sonata\MediaBundle\Entity;
use Sonata\MediaBundle\Entity\BaseMedia as BaseMedia;
use Doctrine\ORM\Mapping as ORM;
class Media extends BaseMedia {
/**
* #var integer $id
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="PL\OrderBundle\Entity\Order", inversedBy="medias")
* #ORM\JoinTable(name="order_has_media__media",
* joinColumns={#ORM\JoinColumn(name="media__media_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="order_no_order", referencedColumnName="no_order")}
* )
*/
protected $orders;
public function __construct() {
$this->orders = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer $id
*/
public function getId() {
return $this->id;
}
public function setOrders(\PL\OrderBundle\Entity\Order $order) {
$this->orders[] = $order;
}
public function getOrders() {
return $this->orders;
}
}
for starters, When using bi-directional ManyToOnes and OneToManys you must have inversedBy and a matching mappedBy. in your example:
/**
* #ORM\ManyToOne(targetEntity="PL\CompanyBundle\Entity\Company", inversedBy="id")
*/
protected $company;
the inversedBy you have is basically telling doctrine that the id field (which is your primary key) of your company is a foreign key to your order entity, which is incorrect. you need to have in orders:
/**
* #ORM\ManyToOne(targetEntity="PL\CompanyBundle\Entity\Company", inversedBy="orders")
*/
protected $company;
in company:
/**
* #ORM\OneToMany(targetEntity="PL\OrderBundle\Entity\Order", mappedBy="company")
*/
private $orders;
just follow the docs:
http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html

Symfony2 or Doctrine2 isn't unserializing values

I serialize some values when I send to DB, now I need to unserialize them in order to iterate over them. In my entity I have this:
public function getValuesText() {
return $this->values_text;
}
and then in the template I show as:
{{ element.getValuesText }}
But I get this raw result:
a:3:{i:1;s:7:"Value 1";i:2;s:7:"Value 2";i:3;s:7:"Value 3";}
And I don't know how to iterate over it to get key, values, what is failing?
UPDATE: Include mapping information
Here is:
<?php
namespace ProductBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use ProductBundle\DBAL\Types\StatusType;
use ProductBundle\DBAL\Types\FieldType;
use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
/**
* #ORM\Entity
* #ORM\Table(name="product_detail")
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class ProductDetail {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="ProductDetail")
* #ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
protected $parent;
/**
* #ORM\Column(type="string", length=255)
*/
protected $description;
/**
* #ORM\Column(type="string", length=255)
*/
protected $label;
/**
* #var string $field_type
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\FieldType")
* #ORM\Column(name="field_type", type="FieldType", nullable=false)
*/
protected $field_type;
/**
* #ORM\Column(name="values_text", type="array")
*/
protected $values_text;
/**
* #ORM\Column(type="string", length=255)
*/
protected $measure_unit;
/**
* #var string $status
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\StatusType")
* #ORM\Column(name="status", type="StatusType", nullable=false)
*/
protected $status;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
protected $created;
/**
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="modified", type="datetime")
*/
protected $modified;
/**
* #ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
protected $deletedAt;
/**
* #ORM\ManyToMany(targetEntity="CategoryBundle\Entity\Category", inversedBy="pd_category", cascade={"persist"})
* #ORM\JoinTable(name="product_detail_has_category",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="category", referencedColumnName="id")}
* )
*/
protected $category;
/**
* #ORM\ManyToMany(targetEntity="ProductBundle\Entity\DetailGroup", inversedBy="productDetail", cascade={"persist"})
* #ORM\JoinTable(name="detail_group_has_product_detail",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="kgroup", referencedColumnName="id")}
* )
*/
protected $detail_group;
/**
* #ORM\Column(name="to_product", type="boolean")
*/
protected $to_product;
public function __construct() {
$this->detail_group = new \Doctrine\Common\Collections\ArrayCollection();
$this->category = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setParent(ProductDetail $parent = null) {
$this->parent = $parent;
}
public function getParent() {
return $this->parent;
}
public function setDescription($description) {
$this->description = $description;
}
public function getDescription() {
return $this->description;
}
public function setLabel($label) {
$this->label = $label;
}
public function getLabel() {
return $this->label;
}
public function setFieldType($field_type) {
$this->field_type = $field_type;
}
public function getFieldType() {
return $this->field_type;
}
public function setValuesText($values_text) {
$this->values_text = $values_text;
}
public function getValuesText() {
return $this->values_text;
}
public function setMeasureUnit($measure_unit) {
$this->measure_unit = $measure_unit;
}
public function getMeasureUnit() {
return $this->measure_unit;
}
public function setStatus($status) {
$this->status = $status;
}
public function getStatus() {
return $this->status;
}
public function setCreated($param) {
$this->created = $param;
return true;
}
public function getCreated() {
return $this->created;
}
public function setModified($param) {
$this->modified = $param;
return true;
}
public function getModified() {
return $this->modified;
}
public function setCategory(\CategoryBundle\Entity\Category $category) {
$this->category[] = $category;
}
public function getCategory() {
return $this->category;
}
public function setDetailGroup(\ProductBundle\Entity\DetailGroup $detailGroup) {
$this->detail_group[] = $detailGroup;
}
public function getDetailGroup() {
return $this->detail_group;
}
public function getDeletedAt() {
return $this->deletedAt;
}
public function setDeletedAt($deletedAt) {
$this->deletedAt = $deletedAt;
}
public function setToProduct($to_product) {
$this->to_product = $to_product;
}
public function getToProduct() {
return $this->to_product;
}
}
Ok, after read and check my code I realize where the problem was:
Doctrine DBAL takes care for serialize/unserialize by using type="array" check here for more info
I made a mistake when I insert values since I was doing a unwanted serialize since as I said before Doctrine take care of this. See below:
Incorrect:
$entity->setValuesText(serialize($form->get('values_text')->getData()));
Correct:
$entity->setValuesText($form->get('values_text')->getData());
That's all, hope is helpful for someone else
Doctrine 2 DBAL ArrayType doesn't check for an array and serialize every type of parameter.
Control your database, that value should be a serialized string starting with s:
Ref: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Types/ArrayType.php

Cannot find a field on 'StockBundle\Entity\KStock' that is mapped to column 'id'

I have this to tables with 1:m relationship so one stock can have one or many stock_details. This is how I build the entities:
KStock.php
/**
* #ORM\Table(name="stock")
* #ORM\Entity(repositoryClass="StockBundle\Entity\Repository\KStockRepository")
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class KStock {
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ProductBundle\Entity\Product", inversedBy="stocks" )
* #ORM\JoinColumn(name="product", referencedColumnName="upc")
*/
protected $product;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="CompanyBundle\Entity\Company", inversedBy="companyHasStock" )
* #ORM\JoinColumn(name="company", referencedColumnName="id")
*/
protected $company;
/**
*
* #ORM\ManyToOne(targetEntity="ProductBundle\Entity\NCondition", inversedBy="stocks" )
* #ORM\JoinColumn(name="kcondition", referencedColumnName="id")
*/
protected $condition;
/**
*
* #ORM\ManyToOne(targetEntity="StockBundle\Entity\NStockStatus", inversedBy="stocks" )
* #ORM\JoinColumn(name="status", referencedColumnName="id")
*/
protected $status;
/**
* #ORM\Column(type="string", length=255, name="sku")
*/
protected $sku;
/**
* #ORM\Column(type="string", length=255)
*/
protected $description;
/**
* #ORM\ManyToOne(targetEntity="StockBundle\Entity\NUnit")
* #ORM\JoinColumn(name="unit", referencedColumnName="id")
*/
protected $unit;
/**
*
* #ORM\Column(type="decimal", precision=4, scale=2)
*/
protected $width;
/**
*
* #ORM\Column(type="decimal", precision=4, scale=2)
*/
protected $height;
/**
*
* #ORM\Column(type="decimal", precision=4, scale=2)
*/
protected $weight;
/**
*
* #ORM\Column(type="decimal", precision=4, scale=2)
*/
protected $length;
/**
* #ORM\ManyToOne(targetEntity="ProductBundle\Entity\NWeight")
* #ORM\JoinColumn(name="nweight", referencedColumnName="id")
*/
protected $nweight;
/**
* #ORM\ManyToOne(targetEntity="ProductBundle\Entity\NLength")
* #ORM\JoinColumn(name="nlength", referencedColumnName="id")
*/
protected $nlength;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
protected $created;
/**
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="modified", type="datetime")
*/
protected $modified;
/**
* #ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
protected $deletedAt;
/**
* #ORM\OneToMany(targetEntity="StockBundle\Entity\StockDetail", mappedBy="stockd")
*/
protected $sdetail;
public function setStockDetail(\StockBundle\Entity\StockDetail $stockDetail) {
$this->sdetail[] = $stockDetail;
}
public function getStockDetail() {
return $this->sdetail;
}
public function setProduct(\ProductBundle\Entity\Product $param) {
$this->product = $param;
}
public function getProduct() {
return $this->product;
}
public function setCompany(\CompanyBundle\Entity\Company $param) {
$this->company = $param;
}
public function getCompany() {
return $this->company;
}
public function setCondition(\ProductBundle\Entity\NCondition $condition) {
$this->condition = $condition;
}
public function getCondition() {
return $this->condition;
}
public function setStatus(\StockBundle\Entity\NStockStatus $param) {
$this->status = $param;
}
public function getStatus() {
return $this->status;
}
public function setSku($param) {
$this->sku = $param;
}
public function getSku() {
return $this->sku;
}
public function setDescription($description) {
$this->description = $description;
}
public function getDescription() {
return $this->description;
}
public function setUnit(\StockBundle\Entity\NUnit $unit) {
$this->unit = $unit;
}
public function getUnit() {
return $this->unit;
}
public function setWidth($width) {
$this->width = $width;
}
public function getWidth() {
return $this->width;
}
public function setHeight($height) {
$this->height = $height;
}
public function getHeight() {
return $this->height;
}
public function setWeight($weight) {
$this->weight = $weight;
}
public function getWeight() {
return $this->weight;
}
public function setLength($length) {
$this->length = $length;
}
public function getLength() {
return $this->length;
}
public function setCreated($created) {
$this->created = $created;
}
public function getCreated() {
return $this->created;
}
public function setModified($modified) {
$this->modified = $modified;
}
public function getModified() {
return $this->modified;
}
public function getDeletedAt() {
return $this->deletedAt;
}
public function setDeletedAt($deletedAt) {
$this->deletedAt = $deletedAt;
}
public function setNWeight(\ProductBundle\Entity\NWeight $nweight) {
$this->nweight = $nweight;
}
public function getNWeight() {
return $this->nweight;
}
public function setNLength(\ProductBundle\Entity\NLength $nlength) {
$this->nlength = $nlength;
}
public function getNLength() {
return $this->nlength;
}
public function __toString() {
return $this->company . ' -- ' . $this->product;
}
}
StockDetail.php
/**
* #ORM\Table(name="stock_detail")
* #ORM\Entity
* #ORM\Entity(repositoryClass="StockBundle\Entity\Repository\StockDetailRepository")
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class StockDetail {
/**
* #ORM\Id
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="CompanyBundle\Entity\Company")
* #ORM\JoinColumn(name="company", referencedColumnName="id")
*/
protected $company;
/**
*
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ProductBundle\Entity\NCondition")
* #ORM\JoinColumn(name="kcondition", referencedColumnName="id")
*/
protected $condition;
/**
*
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ProductBundle\Entity\Product")
* #ORM\JoinColumn(name="product", referencedColumnName="upc")
*/
protected $product;
/**
*
* #ORM\Column(type="decimal", precision=19, scale=4)
*/
protected $price;
/**
* #ORM\Column(type="integer")
*/
protected $amount;
/**
*
* #ORM\Column(type="integer")
*/
protected $availability;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
protected $created;
/**
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="modified", type="datetime")
*/
protected $modified;
/**
* #ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
protected $deletedAt;
/**
* #ORM\ManyToOne(targetEntity="StockBundle\Entity\KStock", inversedBy = "sdetail")
* #ORM\JoinColumn(name="stockd", referencedColumnName="id")
*/
protected $stockd;
public function setDetail(\StockBundle\Entity\KStock $detail) {
$this->stockd = $detail;
}
public function getDetail() {
return $this->stockd;
}
public function setProduct(\ProductBundle\Entity\Product $product) {
$this->product = $product;
}
public function getProduct() {
return $this->product;
}
public function setCompany(\CompanyBundle\Entity\Company $company) {
$this->company = $company;
}
public function getCompany() {
return $this->company;
}
public function setCondition(\ProductBundle\Entity\NCondition $condition) {
$this->condition = $condition;
}
public function getCondition() {
return $this->condition;
}
public function setAvailability($param) {
$this->availability = $param;
}
public function getAvailability() {
return $this->availability;
}
public function setPrice($param) {
$this->price = $param;
}
public function getPrice() {
return $this->price;
}
public function setAmount($amount) {
$this->amount = $amount;
}
public function getAmount() {
return $this->amount;
}
public function setCreated($created) {
$this->created = $created;
}
public function getCreated() {
return $this->created;
}
public function setModified($modified) {
$this->modified = $modified;
}
public function getModified() {
return $this->modified;
}
public function getDeletedAt() {
return $this->deletedAt;
}
public function setDeletedAt($deletedAt) {
$this->deletedAt = $deletedAt;
}
}
In my view I'm trying to access this values:
{{ entity.getStockDetail.getAmount }}
{{ entity.getStockDetail.getPrice|number_format(2, '.', '') }}
But I got this error:
An exception has been thrown during the rendering of a template
("Cannot find a field on 'StockBundle\Entity\KStock' that is mapped to
column 'id'. Either the field does not exist or an association exists
but it has multiple join columns.") in
ProductBundle:Default:index.html.twig at line 52.
What is wrong in the relations?
Try removing the following line from $stockd in StockDetail
#ORM\JoinColumn(name="stockd", referencedColumnName="id")

Resources