Symfony 6 - How to access properties of object of specific ID - php

I have two entities - one is Product, second - Order. I've created controllers to navigate between page of ProductController that lists the whole ProductRepository to the page of OrderController, which should:
take a Product ID to show its properties on the Order page (name and price)
have a form with quantity and "customer's" email to be added to the Order
calculate the price x quantity and add to the Order
I can't figure how to access the passed project's properties. I am able to access it via addProduct method of the Order entity, but cannot reach them to show them in twig nor manipulate them on variables as described above.
I'm sure it's a simple stuff but I am not sure even how to ask google the right way on this.
we click on a product from ProductRepository with
<a href="{{ path('app_order', {id: product.id}) }}">
and we go to OrderController
OrderController:
<?php
namespace App\Controller;
class OrderController extends AbstractController
{
#[Route('/order', name: 'app_order')]
public function addToOrder(ManagerRegistry $doctrine, Request $request, EntityManagerInterface $em): Response
{
$orderedProductId = (int) ($request->query->get('id'));
$pPrice = 1;
$order = new Order();
$order->addProduct($doctrine->getRepository(Product::class)->find($orderedProductId));
$form = $this->createFormBuilder($order)
->add('clientEmail', TextType::class)
->add('quantity', IntegerType::class)
->add('makeOrder', SubmitType::class, ['label' => 'Make Order'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//$data = $form->getData();
$order->setStatus("Pending");
$order->setTotalSum(1);
$em->persist($order);
$em->flush();
}
return $this->render('order/index.html.twig', [
'form'=> $form->createView(),
'order'=> $order
]);
}
}
The entities look like this:
Product
<?php
namespace App\Entity;
use App\Repository\ProductRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ProductRepository::class)]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string')]
private $name;
#[ORM\Column(type: 'integer')]
private $price;
#[ORM\Column(type: 'boolean')]
private $visible;
#[ORM\ManyToOne(targetEntity: Order::class, inversedBy: 'product')]
private $orderIds;
public function getId(): ?int
{
return $this->id;
}
public function getPrice(): ?int
{
return $this->price;
}
public function setPrice(int $price): self
{
$this->price = $price;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function isVisible(): ?bool
{
return $this->visible;
}
public function setVisible(bool $visible): self
{
$this->visible = $visible;
return $this;
}
public function getOrderIds(): ?Order
{
return $this->orderIds;
}
public function setOrderIds(?Order $orderIds): self
{
$this->orderIds = $orderIds;
return $this;
}
}
Order:
<?php
namespace App\Entity;
use App\Repository\OrderRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: OrderRepository::class)]
#[ORM\Table(name: '`order`')]
class Order
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'integer')]
private $totalSum;
#[ORM\Column(type: 'string', length: 255)]
private $status;
#[ORM\Column(type: 'integer')]
private $quantity;
#[ORM\OneToMany(mappedBy: 'orderIds', targetEntity: Product::class)]
private $product;
#[ORM\Column(type: 'string', length: 255)]
private $clientEmail;
public function __construct()
{
$this->product = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTotalSum(): ?int
{
return $this->totalSum;
}
public function setTotalSum(int $totalSum): self
{
$this->totalSum = $totalSum;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getQuantity(): ?int
{
return $this->quantity;
}
public function setQuantity(int $quantity): self
{
$this->quantity = $quantity;
return $this;
}
/**
* #return Collection<int, Product>
*/
public function getProduct(): Collection
{
return $this->product;
}
public function addProduct(Product $product): self
{
if (!$this->product->contains($product)) {
$this->product[] = $product;
$product->setOrderIds($this);
}
return $this;
}
public function removeProduct(Product $product): self
{
if ($this->product->removeElement($product)) {
// set the owning side to null (unless already changed)
if ($product->getOrderIds() === $this) {
$product->setOrderIds(null);
}
}
return $this;
}
public function getClientEmail(): ?string
{
return $this->clientEmail;
}
public function setClientEmail(string $clientEmail): self
{
$this->clientEmail = $clientEmail;
return $this;
}
}

OK I got this.
Changed a property taken by OrderController from EntityManager to ProductRepository, then
$product= $productRepository->find($orderedProductId);
also: this is helpful: Getting only ID from entity relations without fetching whole object in Doctrine
solved!

Related

Symfony api cannot post data to database

i want to create a user, but the user entity is connected to the entities role, address and personInfo, but i get the error that personInfo_id cannot be null? how do i pass in the id
i tried a value where i would manually pass the id, but that didn't work
This is my User entity
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 30)]
private ?string $password = null;
#[ORM\OneToOne(inversedBy: 'User', cascade: ['persist', 'remove'])]
#[ORM\JoinColumn(nullable: false)]
private ?Role $roleId = null;
#[ORM\OneToMany(mappedBy: 'UserId', targetEntity: PersonInfo::class, orphanRemoval: true, cascade:['persist'])]
private Collection $PersonInfoId;
#[ORM\ManyToOne(cascade: ['persist', 'remove'])]
#[ORM\JoinColumn(nullable: false)]
private ?PersonInfo $personInfoId = null;
#[ORM\ManyToOne(inversedBy: 'UserId')]
#[ORM\JoinColumn(nullable: false)]
private ?Address $AddressId = null;
#[ORM\OneToMany(mappedBy: 'UserId', targetEntity: Address::class, orphanRemoval: true)]
private Collection $UserId;
public function __construct()
{
$this->PersonInfoId = new ArrayCollection();
$this->UserId = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getRoleId(): ?Role
{
return $this->roleId;
}
public function setRoleId(Role $roleId): self
{
$this->roleId = $roleId;
return $this;
}
/**
* #return Collection<int, PersonInfo>
*/
public function getPersonInfoId(): Collection
{
return $this->PersonInfoId;
}
public function addPersonInfoId(PersonInfo $personInfoId): self
{
if (!$this->PersonInfoId->contains($personInfoId)) {
$this->PersonInfoId->add($personInfoId);
$personInfoId->setUserId($this);
}
return $this;
}
public function removePersonInfoId(PersonInfo $personInfoId): self
{
if ($this->PersonInfoId->removeElement($personInfoId)) {
// set the owning side to null (unless already changed)
if ($personInfoId->getUserId() === $this) {
$personInfoId->setUserId(null);
}
}
return $this;
}
public function setPersonInfoId(?PersonInfo $personInfoId): self
{
$this->personInfoId = $personInfoId;
return $this;
}
public function getAddressId(): ?Address
{
return $this->AddressId;
}
public function setAddressId(?Address $AddressId): self
{
$this->AddressId = $AddressId;
return $this;
}
/**
* #return Collection<int, Address>
*/
public function getUserId(): Collection
{
return $this->UserId;
}
public function addUserId(Address $userId): self
{
if (!$this->UserId->contains($userId)) {
$this->UserId->add($userId);
$userId->setUserId($this);
}
return $this;
}
public function removeUserId(Address $userId): self
{
if ($this->UserId->removeElement($userId)) {
// set the owning side to null (unless already changed)
if ($userId->getUserId() === $this) {
$userId->setUserId(null);
}
}
return $this;
}
}
Role Entity
<?php
namespace App\Entity;
use App\Repository\RoleRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: RoleRepository::class)]
class Role
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 30)]
private ?string $name = null;
#[ORM\OneToOne(mappedBy: 'roleId', cascade: ['persist', 'remove'])]
private ?User $User = null;
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 getUser(): ?User
{
return $this->User;
}
public function setUser(User $User): self
{
// set the owning side of the relation if necessary
if ($User->getRoleId() !== $this) {
$User->setRoleId($this);
}
$this->User = $User;
return $this;
}
}
PersonInfo Entity :
<?php
namespace App\Entity;
use App\Repository\PersonInfoRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: PersonInfoRepository::class)]
class PersonInfo
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 30)]
private ?string $name = null;
#[ORM\Column(length: 30)]
private ?string $email = null;
#[ORM\Column]
private ?int $phone_number = null;
#[ORM\ManyToOne(inversedBy: 'PersonInfoId', cascade: ['persist'])]
#[ORM\JoinColumn(nullable: false)]
private ?User $UserId = null;
#[ORM\ManyToOne(inversedBy: 'addressId')]
#[ORM\JoinColumn(nullable: false)]
private ?Address $addressId = null;
#[ORM\OneToMany(mappedBy: 'personInfoId', targetEntity: ContactPersoon::class, orphanRemoval: true)]
private Collection $personInfoId;
public function __construct()
{
$this->personInfoId = 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 getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getPhoneNumber(): ?int
{
return $this->phone_number;
}
public function setPhoneNumber(int $phone_number): self
{
$this->phone_number = $phone_number;
return $this;
}
public function getUserId(): ?User
{
return $this->UserId;
}
public function setUserId(?User $UserId): self
{
$this->UserId = $UserId;
return $this;
}
public function getAddressId(): ?Address
{
return $this->addressId;
}
public function setAddressId(?Address $addressId): self
{
$this->addressId = $addressId;
return $this;
}
/**
* #return Collection<int, ContactPersoon>
*/
public function getPersonInfoId(): Collection
{
return $this->personInfoId;
}
public function addPersonInfoId(ContactPersoon $personInfoId): self
{
if (!$this->personInfoId->contains($personInfoId)) {
$this->personInfoId->add($personInfoId);
$personInfoId->setPersonInfoId($this);
}
return $this;
}
public function removePersonInfoId(ContactPersoon $personInfoId): self
{
if ($this->personInfoId->removeElement($personInfoId)) {
// set the owning side to null (unless already changed)
if ($personInfoId->getPersonInfoId() === $this) {
$personInfoId->setPersonInfoId(null);
}
}
return $this;
}
}
This is the erd that i designed if that may help with building the pictureThe ERD
please help
In class User and class PersonInfo both entity has nullable=false field mapping so you must need to pass object when you are creating user. For example:
$user = new User();
$personInfo = new PersonInfo();
$user->addPersonInfoId($personInfo); // Here argument must be object of PersonInfo instead of Id.
$em->persist($user);
$em->flush();

The mappings App\Entity\xx and App\Entity\are inconsistent with each other

I'm new on Symfony 6 and i've got problem with 2 of my entities.
App\Entity\Mission :
The mappings App\Entity\Mission#idtagmissionassign and App\Entity\Tag#missionstag are inconsistent with each other.
App\Entity\Tag :
The association App\Entity\Tag#missionstag refers to the inverse side field App\Entity\Mission#tags which does not exist.
This is the relation betewen the 2 entities :
DB
This is Mission entity
<?php
namespace App\Entity;
use App\Repository\MissionRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: MissionRepository::class)]
#[ORM\Table(name: 'mission')]
class Mission
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $titlemission = null;
#[ORM\Column(length: 255)]
private ?string $descriptionmission = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $onsetdate = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $deadline = null;
#[ORM\Column]
private ?int $budgetmission = null;
/*#[ORM\Column(length: 255)]
private ?string $codeapemission = null;*/
#[ORM\Column(length: 255)]
private ?string $prioritymission = null;
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'missionstag',cascade: ['persist'])]
#[ORM\JoinTable(name:'mission_tag')]
private Collection $idtagmissionassign;
#[ORM\ManyToOne(inversedBy: 'missions')]
#[ORM\JoinColumn(nullable: false)]
private ?User $iduser = null;
#[ORM\ManyToMany(targetEntity: User::class, inversedBy: 'missionsassign')]
private Collection $idmissionassign;
#[ORM\Column(length: 100)]
private ?string $remote = null;
public function __construct()
{
$this->idtagmissionassign = new ArrayCollection();
$this->idmissionassign = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitlemission(): ?string
{
return $this->titlemission;
}
public function setTitlemission(string $titlemission): self
{
$this->titlemission = $titlemission;
return $this;
}
public function getDescriptionmission(): ?string
{
return $this->descriptionmission;
}
public function setDescriptionmission(string $descriptionmission): self
{
$this->descriptionmission = $descriptionmission;
return $this;
}
public function getOnsetdate(): ?\DateTimeInterface
{
return $this->onsetdate;
}
public function setOnsetdate(\DateTimeInterface $onsetdate): self
{
$this->onsetdate = $onsetdate;
return $this;
}
public function getDeadline(): ?\DateTimeInterface
{
return $this->deadline;
}
public function setDeadline(\DateTimeInterface $deadline): self
{
$this->deadline = $deadline;
return $this;
}
public function getBudgetmission(): ?int
{
return $this->budgetmission;
}
public function setBudgetmission(int $budgetmission): self
{
$this->budgetmission = $budgetmission;
return $this;
}
/*public function getCodeapemission(): ?string
{
return $this->codeapemission;
}
public function setCodeapemission(string $codeapemission): self
{
$this->codeapemission = $codeapemission;
return $this;
}*/
public function getPrioritymission(): ?string
{
return $this->prioritymission;
}
public function setPrioritymission(string $prioritymission): self
{
$this->prioritymission = $prioritymission;
return $this;
}
/**
* #return Collection<int, tag>
*/
public function getIdtagmissionassign(): Collection
{
return $this->idtagmissionassign;
}
public function addIdtagmissionassign(tag $idtagmissionassign): self
{
if (!$this->idtagmissionassign->contains($idtagmissionassign)) {
$this->idtagmissionassign->add($idtagmissionassign);
}
return $this;
}
public function removeIdtagmissionassign(tag $idtagmissionassign): self
{
$this->idtagmissionassign->removeElement($idtagmissionassign);
return $this;
}
public function getIduser(): ?user
{
return $this->iduser;
}
public function setIduser(?user $iduser): self
{
$this->iduser = $iduser;
return $this;
}
/**
* #return Collection<int, user>
*/
public function getIdmissionassign(): Collection
{
return $this->idmissionassign;
}
public function addIdmissionassign(user $idmissionassign): self
{
if (!$this->idmissionassign->contains($idmissionassign)) {
$this->idmissionassign->add($idmissionassign);
}
return $this;
}
public function removeIdmissionassign(user $idmissionassign): self
{
$this->idmissionassign->removeElement($idmissionassign);
return $this;
}
public function getRemote(): ?string
{
return $this->remote;
}
public function setRemote(string $remote): self
{
$this->remote = $remote;
return $this;
}
public function __toString(){
return $this->titlemission;
}
}
This is Tag entity :
<?php
namespace App\Entity;
use App\Repository\TagRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: TagRepository::class)]
class Tag
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 100)]
#[Assert\NotBlank]
#[Assert\Length(min:2)]
#[Assert\Valid]
private ?string $nomtag = null;
#[ORM\ManyToMany(targetEntity: Mission::class, mappedBy: 'tags')]
#[ORM\JoinTable(name:'mission_tag')]
private Collection $missionstag;
public function __construct()
{
$this->missionstag = new ArrayCollection();
}
// #[ORM\ManyToMany(targetEntity: Mission::class, inversedBy:"$idtagmissionassign")]
// private $genusScientists;
public function getId(): ?int
{
return $this->id;
}
public function getNomtag(): ?string
{
return $this->nomtag;
}
public function setNomtag(string $nomtag): self
{
$this->nomtag = $nomtag;
return $this;
}
/**
* #return Collection<int, Mission>
*/
public function getMissions(): Collection
{
return $this->missionstag;
}
public function addMission(Mission $mission): self
{
if (!$this->missionstag->contains($mission)) {
$this->missionstag->add($mission);
$mission->addTag($this);
}
return $this;
}
public function removeMission(Mission $mission): self
{
if ($this->missionstag->removeElement($mission)) {
$mission->removeTag($this);
}
return $this;
}
public function __toString(): string
{
return $this->nomtag;
}
}
Do you have an idea to help me to solve this problem ?
Many thanks
Change the mappedby and inversedby with no effect.
Trying some stuff follow internet guideline with no success.
Tag's property missionstag claims, that it is mapped by Missions's property "tags", but there is no such property, instead you have idtagmissionassign. (Side note: Your property names are bad, because they look like database columns, but you're using an ORM.
The first question you would have to ask yourself: will you need additional columns on your many-to-many table. If the answer is yes, ORM\ManyToMany isn't even the right fit. If the answer is no, it fits.
The case where it fits:
Mission should have the following property + attributes:
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'missions', cascade: ['persist'])]
#[ORM\JoinTable(name: 'mission_tag')]
private Collection $tags;
and the Tag should have the following property + attributes:
#[ORM\ManyToMany(targetEntity: Mission::class, mappedBy: 'tags', cascade: ['persist'])]
#[ORM\JoinTable(name: 'mission_tag')] // <- is this the actual table name?
private Collection $missions;
the mappedBy and inversedBy must match the property name on the other entity, respectively.
If your mission_tag table doesn't have columns mission_id and tag_id, you might have to explicitly name the columns via the JoinColumn and InverseJoinColumn Attibutes.
For the case, where it doesn't fit, you would have to have an actual entity MissionTags with OneToMany on Mission/Tag that both reference it, and reversed ManyToOnes on MissionTags. But that wasn't what you asked.
BC\InventoryBundle\Entity\ProductRecipe:
type: entity
table: ProductRecipe
repositoryClass: BC\InventoryBundle\Entity\ProductRecipeRepository
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
amount: // Previously "ammount"
type: decimal
presision: 10
scale: 2
manyToOne:
products:
targetEntity: Product
// "Products" is named correctly but recipe is singular
// so for the sake of uniformity
inversedBy: recipes
joinColumn:
name: product_id
referencedColumnName: id
recipes:
targetEntity: Recipe
// Previously "Recipes", incorrect entity name
inversedBy: products
joinColumn:
name: recipe_id
referencedColumnName: id

How to get a single column from a Doctrine Array Collection?

i have a entity called "AreasProfesionales"
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\InverseJoinColumn;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use App\Repository\AreasProfesionalesRepository;
use Doctrine\Common\Collections\ArrayCollection;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
#[ORM\Entity(repositoryClass: AreasProfesionalesRepository::class)]
#[UniqueEntity(fields: ['Codigo'], message: 'Ya existe un area profesional registrada con ese mismo código')]
#[ApiFilter(SearchFilter::class, properties: ['Denominacion' => 'partial', 'Codigo' => 'partial', 'familiasProfesionales'=> 'exact'])]
#[ApiFilter(OrderFilter::class, properties: ['id'], arguments: ['orderParameterName' => 'order'])]
#[ApiResource(paginationEnabled: false,formats: ['json' => ['application/json']],
normalizationContext: ['groups' => ['read']],
denormalizationContext: ['groups' => ['write']])]
class AreasProfesionales
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['read','write'])]
#[ApiProperty(writable:true)]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['read','write'])]
private ?string $Denominacion = null;
#[ORM\Column(length: 20, unique:true)]
#[Groups(['read', 'write'])]
private ?string $Codigo = null;
#[ORM\ManyToOne(inversedBy: 'Familiasprofesionales_areasprofesionales')]
#[Groups(['read','write'])]
#[InverseJoinColumn(name: "familias_profesionales_id", referencedColumnName: "id")]
#[ApiProperty(readableLink: true, writableLink: true)]
private ?FamiliasProfesionales $familiasProfesionales = null;
#[ORM\OneToMany(mappedBy: 'areasProfesionales', targetEntity: CertificadosProfesionalidad::class)]
private Collection $Areasprofesionales_certificadosprofesionalidad;
#[ORM\OneToMany(mappedBy: 'areasProfesionales', targetEntity: AreasProfesionalesDocentes::class)]
private Collection $Areasprofesionales_areasprofesionalesdocentes;
#[ORM\OneToMany(mappedBy: 'areasProfesionales', targetEntity: AreasProfesionalesItinerariosFormativos::class)]
private Collection $Areasprofesionales_areasprofesionalesitinerariosformativos;
public function __construct()
{
$this->Areasprofesionales_certificadosprofesionalidad = new ArrayCollection();
$this->Areasprofesionales_areasprofesionalesdocentes = new ArrayCollection();
$this->Areasprofesionales_areasprofesionalesitinerariosformativos = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getDenominacion(): ?string
{
return $this->Denominacion;
}
public function setDenominacion(string $Denominacion): self
{
$this->Denominacion = $Denominacion;
return $this;
}
public function getCodigo(): ?string
{
return $this->Codigo;
}
public function setCodigo(string $Codigo): self
{
$this->Codigo = $Codigo;
return $this;
}
public function getFamiliasProfesionales(): ?FamiliasProfesionales
{
return $this->familiasProfesionales;
}
public function setFamiliasProfesionales(?FamiliasProfesionales $familiasProfesionales): self
{
$this->familiasProfesionales = $familiasProfesionales;
return $this;
}
/**
* #return Collection<int, CertificadosProfesionalidad>
*/
/*public function getAreasprofesionalesCertificadosprofesionalidad(): Collection
{
return $this->Areasprofesionales_certificadosprofesionalidad;
}
public function addAreasprofesionalesCertificadosprofesionalidad(CertificadosProfesionalidad $areasprofesionalesCertificadosprofesionalidad): self
{
if (!$this->Areasprofesionales_certificadosprofesionalidad->contains($areasprofesionalesCertificadosprofesionalidad)) {
$this->Areasprofesionales_certificadosprofesionalidad->add($areasprofesionalesCertificadosprofesionalidad);
$areasprofesionalesCertificadosprofesionalidad->setAreasProfesionales($this);
}
return $this;
}
public function removeAreasprofesionalesCertificadosprofesionalidad(CertificadosProfesionalidad $areasprofesionalesCertificadosprofesionalidad): self
{
if ($this->Areasprofesionales_certificadosprofesionalidad->removeElement($areasprofesionalesCertificadosprofesionalidad)) {
// set the owning side to null (unless already changed)
if ($areasprofesionalesCertificadosprofesionalidad->getAreasProfesionales() === $this) {
$areasprofesionalesCertificadosprofesionalidad->setAreasProfesionales(null);
}
}
return $this;
}*/
/**
* #return Collection<int, AreasProfesionalesDocentes>
*/
/public function getAreasprofesionalesAreasprofesionalesdocentes(): Collection
{
return $this->Areasprofesionales_areasprofesionalesdocentes;
}
public function addAreasprofesionalesAreasprofesionalesdocente(AreasProfesionalesDocentes $areasprofesionalesAreasprofesionalesdocente): self
{
if (!$this->Areasprofesionales_areasprofesionalesdocentes->contains($areasprofesionalesAreasprofesionalesdocente)) {
$this->Areasprofesionales_areasprofesionalesdocentes->add($areasprofesionalesAreasprofesionalesdocente);
$areasprofesionalesAreasprofesionalesdocente->setAreasProfesionales($this);
}
return $this;
}
public function removeAreasprofesionalesAreasprofesionalesdocente(AreasProfesionalesDocentes $areasprofesionalesAreasprofesionalesdocente): self
{
if ($this->Areasprofesionales_areasprofesionalesdocentes->removeElement($areasprofesionalesAreasprofesionalesdocente)) {
// set the owning side to null (unless already changed)
if ($areasprofesionalesAreasprofesionalesdocente->getAreasProfesionales() === $this) {
$areasprofesionalesAreasprofesionalesdocente->setAreasProfesionales(null);
}
}
return $this;
}*/
/**
* #return Collection<int, AreasProfesionalesItinerariosFormativos>
*/
public function getAreasprofesionalesAreasprofesionalesitinerariosformativos(): Collection
{
return $this->Areasprofesionales_areasprofesionalesitinerariosformativos;
}
public function addAreasprofesionalesAreasprofesionalesitinerariosformativo(AreasProfesionalesItinerariosFormativos $areasprofesionalesAreasprofesionalesitinerariosformativo): self
{
if (!$this->Areasprofesionales_areasprofesionalesitinerariosformativos->contains($areasprofesionalesAreasprofesionalesitinerariosformativo)) {
$this->Areasprofesionales_areasprofesionalesitinerariosformativos->add($areasprofesionalesAreasprofesionalesitinerariosformativo);
$areasprofesionalesAreasprofesionalesitinerariosformativo->setAreasProfesionales($this);
}
return $this;
}
public function removeAreasprofesionalesAreasprofesionalesitinerariosformativo(AreasProfesionalesItinerariosFormativos $areasprofesionalesAreasprofesionalesitinerariosformativo): self
{
if ($this->Areasprofesionales_areasprofesionalesitinerariosformativos->removeElement($areasprofesionalesAreasprofesionalesitinerariosformativo)) {
// set the owning side to null (unless already changed)
if ($areasprofesionalesAreasprofesionalesitinerariosformativo->getAreasProfesionales() === $this) {
$areasprofesionalesAreasprofesionalesitinerariosformativo->setAreasProfesionales(null);
}
}
return $this;
}
public function __toString()
{
return $this->id;
}
I have another entity called "FamiliasProfesionales"
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\Common\Collections\Collection;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use Doctrine\Common\Collections\ArrayCollection;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use App\Repository\FamiliasProfesionalesRepository;
use Symfony\Component\Serializer\Annotation\Groups;
#[ORM\Entity(repositoryClass: FamiliasProfesionalesRepository::class)]
#[ApiFilter(SearchFilter::class, properties: ['Denominacion' => 'partial'])]
#[ApiFilter(OrderFilter::class, properties: ['id', 'Denominacion'], arguments: ['orderParameterName' => 'order'])]
#[ApiResource(paginationEnabled: false,formats: ['json' => ['application/json']],
normalizationContext: ['groups' => ['read']],
denormalizationContext: ['groups' => ['write']])]
class FamiliasProfesionales
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['read','write'])]
#[ApiProperty(writable:true)]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['read','write'])]
private ?string $Denominacion = null;
#[ORM\OneToMany(mappedBy: 'familiasProfesionales', targetEntity: AreasProfesionales::class)]
#[ORM\JoinColumn()]
private Collection $Familiasprofesionales_areasprofesionales;
public function __construct()
{
$this->Familiasprofesionales_areasprofesionales = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getDenominacion(): ?string
{
return $this->Denominacion;
}
public function setDenominacion(string $Denominacion): self
{
$this->Denominacion = $Denominacion;
return $this;
}
/**
* #return Collection<int, AreasProfesionales>
*/
public function getFamiliasprofesionalesAreasprofesionales(): Collection
{
return $this->Familiasprofesionales_areasprofesionales;
}
public function addFamiliasprofesionalesAreasprofesionale(AreasProfesionales $familiasprofesionalesAreasprofesionale): self
{
if (!$this->Familiasprofesionales_areasprofesionales->contains($familiasprofesionalesAreasprofesionale)) {
$this->Familiasprofesionales_areasprofesionales->add($familiasprofesionalesAreasprofesionale);
$familiasprofesionalesAreasprofesionale->setFamiliasProfesionales($this);
}
return $this;
}
public function removeFamiliasprofesionalesAreasprofesionale(AreasProfesionales $familiasprofesionalesAreasprofesionale): self
{
if ($this->Familiasprofesionales_areasprofesionales->removeElement($familiasprofesionalesAreasprofesionale)) {
// set the owning side to null (unless already changed)
if ($familiasprofesionalesAreasprofesionale->getFamiliasProfesionales() === $this) {
$familiasprofesionalesAreasprofesionale->setFamiliasProfesionales(null);
}
}
return $this;
}
public function __toString()
{
return $this->id;
}
}
I´m using API PLATFORM in my proyect to show all the operations and services.
Is there a way to get only a single field from the Collection? I want the entity "AreasProfesionales" to only appear, for example, the id from "FamiliasProfesionales"
if I need to create a new professional area in the POST method, I only have to enter the id of the professional family to which it belongs and not have to enter all the other data, however, it returns all its fields.Thank you in advance.
I have been trying using the read and write methods of API Platform, but I don't get the result I want, I think the problem is that Api Platform works with IRI and not with id (but i need work with this one).
Yes you can :
<?php
// api/src/Entity/Book.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
#[ApiResource(normalizationContext: ['groups' => ['book']])]
class Book
{
#[Groups('book')]
public $name;
#[Groups('book')]
public $author;
// ...
}
you can follow this documentation : https://api-platform.com/docs/core/serialization/
Regards,

Call to a member function get...() on null

Hello guys I need help.
I'm trying to build a forum for my website in symfony.
I have an entity Theme who regroup the entity Slug who regroup the entity Post.
When I navigate to the slug route to see the posts, I have the error "Call to a member function getSlug() on null".
But this function is called in another route.
Here is my different entity.
Theme
<?php
namespace App\Entity;
use App\Repository\ThemeRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ThemeRepository::class)]
class Theme
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string', length: 255)]
private $name;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $imageName;
#[ORM\OneToMany(mappedBy: 'theme', targetEntity: Slug::class, orphanRemoval: true)]
private $slug;
public function __construct()
{
$this->slug = 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 getImageName(): ?string
{
return $this->imageName;
}
public function setImageName(?string $imageName): self
{
$this->imageName = $imageName;
return $this;
}
/**
* #return Collection<int, Slug>
*/
public function getSlug(): Collection
{
return $this->slug;
}
public function addSlug(Slug $slug): self
{
if (!$this->slug->contains($slug)) {
$this->slug[] = $slug;
$slug->setTheme($this);
}
return $this;
}
public function removeSlug(Slug $slug): self
{
if ($this->slug->removeElement($slug)) {
// set the owning side to null (unless already changed)
if ($slug->getTheme() === $this) {
$slug->setTheme(null);
}
}
return $this;
}
}
Slug
<?php
namespace App\Entity;
use App\Repository\SlugRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: SlugRepository::class)]
class Slug
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string', length: 255)]
private $slugName;
#[ORM\OneToMany(mappedBy: 'slug', targetEntity: Post::class, orphanRemoval: true)]
private $posts;
#[ORM\ManyToOne(targetEntity: Theme::class, inversedBy: 'slug')]
#[ORM\JoinColumn(nullable: false)]
private $theme;
public function __construct()
{
$this->posts = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getSlugName(): ?string
{
return $this->slugName;
}
public function setSlugName(string $slugName): self
{
$this->slugName = $slugName;
return $this;
}
/**
* #return Collection<int, Post>
*/
public function getPosts(): Collection
{
return $this->posts;
}
public function addPost(Post $post): self
{
if (!$this->posts->contains($post)) {
$this->posts[] = $post;
$post->setSlug($this);
}
return $this;
}
public function removePost(Post $post): self
{
if ($this->posts->removeElement($post)) {
// set the owning side to null (unless already changed)
if ($post->getSlug() === $this) {
$post->setSlug(null);
}
}
return $this;
}
public function getTheme(): ?Theme
{
return $this->theme;
}
public function setTheme(?Theme $theme): self
{
$this->theme = $theme;
return $this;
}
}
Post
<?php
namespace App\Entity;
use App\Repository\PostRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: PostRepository::class)]
class Post
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'text')]
private $content;
#[ORM\Column(type: 'datetime_immutable')]
private $createdAt;
#[ORM\Column(type: 'datetime_immutable', nullable: true)]
private $updatedAt;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'posts')]
#[ORM\JoinColumn(nullable: false)]
private $user;
#[ORM\ManyToOne(targetEntity: Slug::class, inversedBy: 'posts')]
#[ORM\JoinColumn(nullable: false)]
private $slug;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $imageName;
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;
}
public function getContent(): ?string
{
return $this->content;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeImmutable $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(?\DateTimeImmutable $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getSlug(): ?Slug
{
return $this->slug;
}
public function setSlug(?Slug $slug): self
{
$this->slug = $slug;
return $this;
}
public function getImageName(): ?string
{
return $this->imageName;
}
public function setImageName(?string $imageName): self
{
$this->imageName = $imageName;
return $this;
}
}
And here is my controller
<?php
namespace App\Controller;
use App\Repository\SlugRepository;
use App\Repository\ThemeRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ForumController extends AbstractController
{
#[Route('/forum', name: 'forum')]
public function index(SlugRepository $slugRepository, ThemeRepository $themeRepository ): Response
{
$themes = $themeRepository->findAll();
return $this->render('forum/index.html.twig', [
'themes' => $themes,
]);
}
#[Route('/forum/{name}/{id}', name: 'theme')]
public function theme(string $name, $id, ThemeRepository $themeRepository ): Response
{
$themesId = $themeRepository->find($id);
$themes = $themeRepository->find($name);
$slugs = $themesId->getSlug();
$allThemes = $themeRepository->findAll();
return $this->render('forum/theme.html.twig', [
'themes' => $themesId,
'slugs' => $slugs,
'allThemes' => $allThemes,
]);
}
#[Route('/forum/{name}/{slugName}', name: 'slug')]
public function slug(string $name, string $slugName, $id,SlugRepository $slugRepository, ThemeRepository $themeRepository ): Response
{
$slugName = $slugRepository->find($slugName);
$slugsId = $slugRepository->find($id);
$themesId = $slugsId->getTheme()->getName($name);
$allThemes = $themeRepository->findAll();
return $this->render('forum/slug.html.twig', [
'themes' => $themesId,
'slugs' => $slugsId,
'allThemes' => $allThemes,
]);
}
}
I'm working on symfony 5.0.8
Thanks for your help.
In your method ForumController::theme the method $themeRepository->find() does not return a Theme object but null and $themes is unused.
$themesId = $themeRepository->find($id); // <- returns null
Solution: query by id and name explicitly.
$theme = $themeRepository->findOneBy([
'id' => $id,
'name' => $name
]);
if (!$theme) {
// log id and name, return a 404
}
$slug = $theme->getSlug();

Symfony 6 data access and transmission between multiple tables with format error [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 12 months ago.
Improve this question
The project is a website written in symfony. The problem there is that
there is a user and a consultant which is a separate table, but a user
becomes the consultant, and when this consultant wants to give up his
free time and I want to store it in a third table that listens for
the interval name I have to fill in the consultant ID.
user_table:
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #UniqueEntity(fields={"email"}, message="There is already an account with this email")
*/
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string', length: 180, unique: true)]
private $email;
#[ORM\Column(type: 'json')]
private $roles = [];
#[ORM\Column(type: 'string')]
private $password;
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* #see UserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->email;
}
/**
* #see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* #see PasswordAuthenticatedUserInterface
*/
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
}
cons table:
<?php
namespace App\Entity;
use App\Repository\ConsRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ConsRepository::class)]
class Cons
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\OneToOne(targetEntity: User::class, cascade: ['persist', 'remove'])]
private $user;
#[ORM\OneToMany(mappedBy: 'cons_id', targetEntity: Intervall::class)]
private $intervalls;
public function __construct()
{
$this->intervalls = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getUserId(): ?User
{
return $this->user;
}
public function setUserId(?User $user): self
{
$this->user = $user;
return $this;
}
/**
* #return Collection|Intervall[]
*/
public function getIntervalls(): Collection
{
return $this->intervalls;
}
public function addIntervall(Intervall $intervall): self
{
if (!$this->intervalls->contains($intervall)) {
$this->intervalls[] = $intervall;
$intervall->setConsId($this);
}
return $this;
}
public function removeIntervall(Intervall $intervall): self
{
if ($this->intervalls->removeElement($intervall)) {
// set the owning side to null (unless already changed)
if ($intervall->getConsId() === $this) {
$intervall->setConsId(null);
}
}
return $this;
}
}
intervall table:
<?php
namespace App\Entity;
use App\Repository\IntervallRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: IntervallRepository::class)]
class Intervall
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'datetime')]
private $start;
#[ORM\Column(type: 'datetime')]
private $end;
#[ORM\Column(type: 'boolean')]
private $more;
#[ORM\Column(type: 'time')]
private $cons_time;
#[ORM\Column(type: 'time')]
private $free_time;
#[ORM\ManyToOne(targetEntity: Cons::class, inversedBy: 'intervalls')]
private $cons;
public function __construct()
{
$this->cons = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getStart(): ?\DateTimeInterface
{
return $this->start;
}
public function setStart(\DateTimeInterface $start): self
{
$this->start = $start;
return $this;
}
public function getEnd(): ?\DateTimeInterface
{
return $this->end;
}
public function setEnd(\DateTimeInterface $end): self
{
$this->end = $end;
return $this;
}
public function getMore(): ?bool
{
return $this->more;
}
public function setMore(bool $more): self
{
$this->more = $more;
return $this;
}
public function getConsTime(): ?\DateTimeInterface
{
return $this->cons_time;
}
public function setConsTime(\DateTimeInterface $cons_time): self
{
$this->cons_time = $cons_time;
return $this;
}
public function getFreeTime(): ?\DateTimeInterface
{
return $this->free_time;
}
public function setFreeTime(\DateTimeInterface $free_time): self
{
$this->free_time = $free_time;
return $this;
}
public function getConsId(): ?Cons
{
return $this->cons;
}
public function setConsId(?Cons $cons): self
{
$this->cons = $cons;
return $this;
}
}
intervall wrong code slise:
#[Route('/new', name: 'intervall_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response
{
$user_id = $this->getUser()->getId();
$cnsuseridrepo = $entityManager->getRepository(Cons::class);
$cnsuserid = $cnsuseridrepo->findOneBy(["user"=>$user_id]);
$intervall = new Intervall();
$intervall->setConsId(($cnsuserid->getId());
$form = $this->createForm(IntervallType::class, $intervall);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($intervall);
$entityManager->flush();
return $this->redirectToRoute('intervall_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('intervall/new.html.twig', [
'intervall' => $intervall,
'form' => $form,
]);
}
that would be the mistake I see:
Seems like setter method allows only object of Cons or null value, so you have to set it as object.
$intervall = new Intervall();
$intervall->setConsId($cnsuserid);
$form = $this->createForm(IntervallType::class, $intervall);
$form->handleRequest($request);

Categories