Insert into junction table with relationship many to many in symfony 4 - symfony

I have a next tables: quiz, question and junction table question_quiz. I have a many-to-many relationship.
Insert is working for the tables quiz and questions but I don't understand how insert in junction table.
Entity quiz.
class Quiz
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=191)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Question", mappedBy="quiz", cascade={"persist"})
*/
private $questions;
public function __construct()
{
$this->questions = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* #return string|null
*/
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* #return Collection|Question[]
*/
public function getQuestions(): Collection
{
return $this->questions;
}
public function addQuestion(Question $question): self
{
if (!$this->questions->contains($question)) {
$this->questions[] = $question;
$question->addQuiz($this);
}
return $this;
}
public function removeQuestion(Question $question): self
{
if ($this->questions->contains($question)) {
$this->questions->removeElement($question);
$question->removeQuiz($this);
}
return $this;
}
}
Entity question.
class Question
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $title;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Quiz", inversedBy="questions")
*/
private $quiz;
public function __construct()
{
$this->quiz = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
/**
* #return Collection|Quiz[]
*/
public function getQuiz(): Collection
{
return $this->quiz;
}
public function addQuiz(Quiz $quiz): self
{
if (!$this->quiz->contains($quiz)) {
$this->quiz[] = $quiz;
}
return $this;
}
public function removeQuiz(Quiz $quiz): self
{
if ($this->quiz->contains($quiz)) {
$this->quiz->removeElement($quiz);
}
return $this;
}
}
Controller code:
$quiz = new Quiz();
$form = $this->get('form.factory')->createNamed('quiz', QuizType::class, $quiz);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($quiz);
$em->flush();
return $this->redirectToRoute('admin');
}
Code in controller is correct and working, but not working for a table of junction. Maybe need doing with join table, but I not sure it that is working for symfony 4. Could you help me, please?

Related

Semantical Error line 0, col 97 near 'prix WHERE prix': Error: Class App\Entity\Produit has no association named prix

I try to join two entities with Symfony QueryBuilder. I've created a function findAllQuery in order to filter a research, but I get the error that my entity doesn't have any association. I saw already some similar questions but I can't resolve the problem.
Thanks for help !
Publication entity
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=PublicationRepository::class)
*/
class Publication
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $datePublication;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="publications")
*/
private $user;
/**
* #ORM\ManyToOne(targetEntity=Produit::class, inversedBy="publications")
*/
private $produit;
public function getId(): ?int
{
return $this->id;
}
public function getDatePublication(): ?\DateTimeInterface
{
return $this->datePublication;
}
public function setDatePublication(?\DateTimeInterface $datePublication): self
{
$this->datePublication = $datePublication;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getProduit(): ?Produit
{
return $this->produit;
}
public function setProduit(?Produit $produit): self
{
$this->produit = $produit;
return $this;
}
}
Produit Entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=ProduitRepository::class)
*/
class Produit
{
public function hydrate(array $init)
{
foreach ($init as $key => $value) {
$method = "set" . ucfirst($key);
if (method_exists($this, $method)) {
$this->$method($value);
}
}
}
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $nom;
/**
* #ORM\Column(type="string", length=255)
*/
private $description;
/**
* #ORM\Column(type="boolean", nullable=true)
*/
private $vendu;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $photo;
/**
* #ORM\ManyToOne(targetEntity=Commande::class, inversedBy="produits")
*/
private $commande;
/**
* #ORM\ManyToOne(targetEntity=Type::class, inversedBy="produit")
*/
private $type;
/**
* #ORM\OneToOne(targetEntity=Publication::class, mappedBy="produit", cascade={"persist", "remove"})
*/
private $publication;
/**
* #ORM\Column(type="float")
*/
private $prix;
/**
* #ORM\OneToMany(targetEntity=Publication::class, mappedBy="produit")
*/
private $publications;
public function __construct()
{
$this->publications = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getVendu(): ?bool
{
return $this->vendu;
}
public function setVendu(?bool $vendu): self
{
$this->vendu = $vendu;
return $this;
}
public function getPhoto(): ?string
{
return $this->photo;
}
public function setPhoto(?string $photo): self
{
$this->photo = $photo;
return $this;
}
public function getCommande(): ?Commande
{
return $this->commande;
}
public function setCommande(?Commande $commande): self
{
$this->commande = $commande;
return $this;
}
public function getType(): ?Type
{
return $this->type;
}
public function setType(?Type $type): self
{
$this->type = $type;
return $this;
}
public function getPrix(): ?float
{
return $this->prix;
}
public function setPrix(float $prix): self
{
$this->prix = $prix;
return $this;
}
/**
* #return Collection|Publication[]
*/
public function getPublications(): Collection
{
return $this->publications;
}
public function addPublication(Publication $publication): self
{
if (!$this->publications->contains($publication)) {
$this->publications[] = $publication;
$publication->setProduit($this);
}
return $this;
}
public function removePublication(Publication $publication): self
{
if ($this->publications->removeElement($publication)) {
// set the owning side to null (unless already changed)
if ($publication->getProduit() === $this) {
$publication->setProduit(null);
}
}
return $this;
}
}
Publication Repository
<?php
namespace App\Repository;
use App\Entity\Publication;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use App\Entity\ProduitSearch;
use App\Entity\Produit;
/**
* #method Publication|null find($id, $lockMode = null, $lockVersion = null)
* #method Publication|null findOneBy(array $criteria, array $orderBy = null)
* #method Publication[] findAll()
* #method Publication[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PublicationRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Publication::class);
}
public function findAllQuery (ProduitSearch $search){
if ($search->getMaxPrix()){
return $this
->createQueryBuilder('publication')
->select('produit')
->from('App\Entity\Produit','produit')
->join('produit.prix','prix')
->andWhere('prix <= :maxPrix')
->setParameter('maxPrix', $search->getMaxPrix())
->getQuery()
->getResult();
}
return $this->findAll();
}
Your query is not right. You can only join on relations and not on fields. I guess you try to get publications where the price of any produit is lower than maxPrix.
return $this
->createQueryBuilder('publication')
->join('publication.produit','produit')
->andWhere('produit.prix <= :maxPrix')
->setParameter('maxPrix', $search->getMaxPrix())
->getQuery()
->getResult();

How to fetch data from many to many relation ship third table in symfony doctrine

I have an intermediate table that acts as a pivot between two others: user, punto_suministro and table pivot user_punto_suministro:
How to fetch data from table user to table punto_suministro?
Entity User:
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
*/
class User implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
.....
/**
* #ORM\OneToMany(targetEntity=UserPuntoSuministro::class, mappedBy="user")
*/
private $userPuntoSuministros;
/**
* #throws \Exception
*/
public function __construct()
{
$this->puntoSuministros = new ArrayCollection();
$this->userPuntoSuministros = new ArrayCollection();
}
/**
* #return Collection|UserPuntoSuministro[]
*/
public function getUserPuntoSuministros(): Collection
{
return $this->userPuntoSuministros;
}
public function addUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if (!$this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros[] = $userPuntoSuministro;
$userPuntoSuministro->setUser($this);
}
return $this;
}
public function removeUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if ($this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros->removeElement($userPuntoSuministro);
// set the owning side to null (unless already changed)
if ($userPuntoSuministro->getUser() === $this) {
$userPuntoSuministro->setUser(null);
}
}
return $this;
}
Entity PuntoSuministro:
/**
* #ORM\Entity(repositoryClass=PuntoSuministroRepository::class)
*/
class PuntoSuministro
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
...
/**
* #ORM\OneToMany(targetEntity=UserPuntoSuministro::class, mappedBy="punto_suministro")
*/
private $userPuntoSuministros;
public function __construct()
{
$this->userPuntoSuministros = new ArrayCollection();
}
/**
* #return Collection|UserPuntoSuministro[]
*/
public function getUserPuntoSuministros(): Collection
{
return $this->userPuntoSuministros;
}
public function addUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if (!$this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros[] = $userPuntoSuministro;
$userPuntoSuministro->setPuntoSuministro($this);
}
return $this;
}
public function removeUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if ($this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros->removeElement($userPuntoSuministro);
// set the owning side to null (unless already changed)
if ($userPuntoSuministro->getPuntoSuministro() === $this) {
$userPuntoSuministro->setPuntoSuministro(null);
}
}
return $this;
}
Entity UserPuntoSuministro (table pivot):
/**
* #ORM\Entity(repositoryClass=UserPuntoSuministroRepository::class)
*/
class UserPuntoSuministro
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="userPuntoSuministros")
*/
private $user;
/**
* #ORM\ManyToOne(targetEntity=PuntoSuministro::class, inversedBy="userPuntoSuministros")
*/
private $punto_suministro;
public function getId(): ?int
{
return $this->id;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getPuntoSuministro(): ?PuntoSuministro
{
return $this->punto_suministro;
}
public function setPuntoSuministro(?PuntoSuministro $punto_suministro): self
{
$this->punto_suministro = $punto_suministro;
return $this;
}
I try and access as follows:
$user = $userRepository->find($this->security->getUser());
$pivote = $user->getUserPuntoSuministros();
but from here I don't know how to recover the punto_suministro of a user to show it on twig.
Thanks in advance.
In simple case you could iterate over $user->getUserPuntoSuministros() and fetch concrete punto_suministro's
$user = $userRepository->find($this->security->getUser());
$puntoSuministros = []; // contains PuntoSuministro's of User
foreach ($user->getUserPuntoSuministros() as $userPuntoSuministro) {
$puntoSuministros[] = $userPuntoSuministro->getPuntoSuministro();
}

ManyToMany error : Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, object given

I have a problem with type ManyToMany relations entities.
I learn symfony i make maybe something wrong.
I tried many ways (Without foreach ...) but i fall always on errors.
These entities were created whit the CLI.
Thanks for your replys and sorry for my bad english
My entities :
Clients
<?php
namespace App\Entity;
use App\Repository\ClientsRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=ClientsRepository::class)
*/
class Clients
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $nom;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $prenom;
/**
* #ORM\Column(type="string", length=255)
*/
private $mail;
/**
* #ORM\Column(type="datetime")
*/
private $created_at;
/**
* #ORM\Column(type="boolean")
*/
private $actif;
/**
* #ORM\ManyToMany(targetEntity=Services::class, mappedBy="clients")
*/
private $services;
public function __construct()
{
$this->services = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getPrenom(): ?string
{
return $this->prenom;
}
public function setPrenom(?string $prenom): self
{
$this->prenom = $prenom;
return $this;
}
public function getMail(): ?string
{
return $this->mail;
}
public function setMail(string $mail): self
{
$this->mail = $mail;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getActif(): ?bool
{
return $this->actif;
}
public function setActif(bool $actif): self
{
$this->actif = $actif;
return $this;
}
/**
* #return Collection|Services[]
*/
public function getServices(): Collection
{
return $this->services;
}
public function addService(Services $service): self
{
if (!$this->services->contains($service)) {
$this->services[] = $service;
$service->setClients($this);
}
return $this;
}
public function removeService(Services $service): self
{
if ($this->services->contains($service)) {
$this->services->removeElement($service);
// set the owning side to null (unless already changed)
if ($service->getClients() === $this) {
$service->setClients(null);
}
}
return $this;
}
}
Services
<?php
namespace App\Entity;
use App\Repository\ServicesRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=ServicesRepository::class)
*/
class Services
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $nom;
/**
* #ORM\Column(type="float")
*/
private $prix;
/**
* #ORM\ManyToMany(targetEntity=Clients::class, inversedBy="services")
*/
private $clients;
public function getId(): ?int
{
return $this->id;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getPrix(): ?float
{
return $this->prix;
}
public function setPrix(float $prix): self
{
$this->prix = $prix;
return $this;
}
public function getClients(): ?Clients
{
return $this->clients;
}
public function setClients(?Clients $clients): self
{
$this->clients = $clients;
return $this;
}
}
Controller
[...]
$entityManager = $this->getDoctrine()->getManager();
foreach($servicesClient as $srv){
$service = $this->getDoctrine()->getRepository(Services::class)->find($srv);
$service->setClients($client);
$client->addService($service);
$entityManager->persist($client);
$entityManager->persist($service);
$entityManager->flush();
}
[...]
Your Service::clients property is marked with #ManyToMany annotation, which means it should be typed #var Collection|Clients[] but both getter and setter returns/set a nullable object ?Clients $clients.
No way the bin/console make:entity did that.
You should use the same system as your Clients::services property, i.e using three methods getClients(), addClients() and removeClients() without setClients(). Besides, you need a constructor starting the $clients property: $this->clients = new ArrayCollection();.
Or maybe you want to use #OneToMany and #ManyToOne annotations.
Note that an entity classname should be singular.

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 !

showing only current user's relations

I have 2 entities, User and courses, each student can have many courses and each course can have many students. Anyway, I'm trying to make it so that when a user connects to his account, it shows him all the courses he's related to. I know I have to do it from my controller but how do I get only the ones he's related to.
my entities
<?php
/**
* #ORM\Entity
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
public function getId()
{
return $this->id;
}
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Courses", mappedBy="Users")
*/
private $courses;
public function __construct()
{
$this->courses = new ArrayCollection();
}
/**
* #return Collection|course[]
*/
public function getCourses(): Collection
{
return $this->courses;
}
public function addCourse(Course $course): self
{
if (!$this->courses->contains($course)) {
$this->courses[] = $course;
$course->addUser($this);
return $this;
}
return $this;
}
public function removeCourse(Course $course): self
{
if ($this->courses->contains($course)) {
$this->courses->removeElement($course);
$course->removeUser($this);
}
return $this;
}
}
<?php
/**
* #ORM\Entity(repositoryClass="App\Repository\CourseRepository")
*/
class Course
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=55)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\user", inversedBy="courses")
*/
private $users;
public function __construct()
{
$this->users = 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;
}
/**
* #return Collection|user[]
*/
public function getUser(): Collection
{
return $this->user;
}
public function addUser(user $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}
return $this;
}
public function removeUser(user $user): self
{
if ($this->users->contains($user)) {
$this->users->removeElement($user);
}
return $this;
}
}
Well, because you apparently have a bi-directional relationship (inversedBy and mappedBy) you dont need to do anything special. Doctrine has already done this. Just grab the user in the controller:
// Once you have a protected controller route,
// you can use $this->getUser() from inside the
// controller action to access the current authenticated user.
$user = $this->getUser();
And iterate as you'd like through their related courses:
foreach ($user->getCourses() as $course) {
}
Because getCourses also returns a Collection instance, you can also use the ->map and ->filter functions that ship with the Collection class...

Resources