Set default role for User Entity - php

When new user register, if there is no role set, automatically to set default role (the lowest in hierarchy). I already created relation "Many to Many" via migrations and have three tables: users, roles, user_roles. So the main goal is to have at least one relation in user_roles for every user.
Below are listed both entities of Users and Roles
Users Entity
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ApiResource(
* normalizationContext={
* "groups"={"read"}
* }
* )
* #ORM\Entity(repositoryClass=UserRepository::class)
* #UniqueEntity("username")
* #UniqueEntity("email")
*/
class User implements UserInterface
{
public function __construct()
{
$this->roles = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"read"})
*/
private $id;
/**
* #ORM\Column(type="string", length=100)
* #Groups({"read"})
* #Assert\NotBlank()
* #Assert\Length(min=3, max=100)
*/
private $username;
/**
* #ORM\Column(type="string", length=150)
* #Assert\NotBlank()
* #Assert\Length(min=3, max=100)
*/
private $password;
/**
* #ORM\Column(type="string", length=150)
* #Groups({"read"})
* #Assert\NotBlank()
* #Assert\Email()
*/
private $email;
/**
* #ORM\Column(type="string", length=150)
* #Groups({"read"})
* #Assert\NotBlank()
* #Assert\Length(min=3, max=100)
*/
private $firstname;
/**
* #ORM\Column(type="string", length=150)
* #Groups({"read"})
* #Assert\NotBlank()
* #Assert\Length(min=3, max=100)
*/
private $lastname;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Roles", inversedBy="users")
* #Groups({"read"})
*/
private $roles;
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
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;
}
/**
* #return array
*/
public function getRoles(): array
{
return $this->roles->toArray();
}
/**
* #param Roles $role
* #return $this
*/
public function addRole(Roles $role) : self
{
if(!$this->roles->contains($role)) {
$this->roles[] = $role;
}
return $this;
}
/**
* #param Roles $role
* #return $this
*/
public function deleteRole(Roles $role) : self
{
if($this->roles->contains($role)) {
$this->roles->removeElement($role);
}
return $this;
}
}
Roles Entity:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\RolesRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ApiResource(
* normalizationContext={
* "groups"={"read"}
* }
* )
* #ORM\Entity(repositoryClass=RolesRepository::class)
*/
class Roles
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=50)
* #Groups({"read"})
*/
private $sysName;
/**
* #ORM\Column(type="string", length=50)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\User", mappedBy="roles")
*/
private $users;
public function getId(): ?int
{
return $this->id;
}
public function getSysName(): ?string
{
return $this->sysName;
}
public function setSysName(string $sysName): self
{
$this->sysName = $sysName;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}

If you don't want to have a relation for every default user<->role you could extend the getRoles() method by adding your default role.
I did something similar in one of my projects, it looked like this:
public function getRoles()
{
if (count($this->getRole())) {
foreach ($this->getRole() as $role) {
$roles[] = $role->getRole();
}
} else {
$roles = ['ROLE_USER'];
}
return $roles;
}

Related

Symfony Maybe you forget to persist it in the entity manager?

i need select username of entity " user "on my form, but i get this fail:
Entity of type "Doctrine\ORM\PersistentCollection" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?
i try add public function __toString() on my entity user, but dont work
form
class AsignarEventoFormType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder->add('users', EntityType::class, [
'class' => User::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.nombre', 'ASC');
},
'choice_label' => 'nombre',
]);
}
}
entity of user :
<?php
declare(strict_types=1);
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\PersistentCollection;
/**
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="nombre", type="string", length=255, nullable=false)
*/
private $nombre;
/**
* #ORM\Column(name="apellido", type="string", length=255, nullable=false)
*/
private $apellido;
/**
* #var string|null
*
* #ORM\Column(name="email", type="string", length=255, nullable=true)
* #Assert\NotBlank
* #Assert\Email(
* message = "El email '{{ value }}' no es valido"
*
* )
*/
private $email;
/**
* #ORM\Column(name="password", type="string", length=255, nullable=false)
*/
private $password;
/**
* #ORM\Column(name="role", type="string", length=255, nullable=false)
*/
private $role;
/**
* #var \DateTime|null
*
* #ORM\Column(name="fecha", type="datetime", nullable=true)
*/
private $fecha;
/**
* #ORM\Column(name="foto", type="string", length=255, nullable=false)
*/
private $foto;
/**
* #ORM\ManyToMany(targetEntity="Evento", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(
* name="user_evento",
* joinColumns={
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="evento_id", referencedColumnName="id")
* }
* )
*/
private $eventos;
/**
* #ORM\ManyToMany(targetEntity="Sala", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(
* name="user_sala",
* joinColumns={
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="sala_id", referencedColumnName="id")
* }
* )
*/
private $salas;
public function __construct()
{
$this->eventos = new ArrayCollection();
$this->salas = new ArrayCollection();
}
public function getId(): int
{
return $this->id;
}
public function setNombre(string $nombre): self
{
$this->nombre = $nombre;
return $this;
}
public function getNombre(): string
{
return $this->nombre;
}
public function setApellido(string $apellido): self
{
$this->apellido = $apellido;
return $this;
}
public function getApellido(): string
{
return $this->apellido;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getEmail(): string
{
return $this->email;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getPassword(): string
{
return $this->password;
}
public function setRole(string $role): self
{
$this->role = $role;
return $this;
}
public function getRole(): string
{
return $this->role;
}
public function setFoto(string $foto): self
{
$this->foto = $foto;
return $this;
}
public function getFoto(): string
{
return $this->foto;
}
public function getFecha()
{
return $this->fecha;
}
public function setFecha($fecha): self
{
$this->fecha = $fecha;
return $this;
}
public function addEvento(Evento $evento): self
{
$this->eventos[] = $evento;
return $this;
}
public function removeEvento(Evento $evento): bool
{
return $this->eventos->removeElement($evento);
}
public function getEventos(): Collection
{
return $this->eventos;
}
public function addSala(Sala $sala): self
{
$this->salas[] = $salas;
return $this;
}
public function removeSala(Sala $sala): bool
{
return $this->salas->removeElement($sala);
}
public function getSalas(): Collection
{
return $this->salas;
}
public function getUsername(){
return $this->email;
}
public function getSalt(){
return null;
}
public function getRoles(){
return array('ROLE_USER');
}
public function eraseCredentials(){}
public function __toString() {
return $this->id;
}
}
capture 1
capture2
You should add multiple => true to your users form field options.

Symfony - Api-Platform - subresource error

I have a problem on Symfony5 - apiPlatform, when I request a subresource I have an answer in Json but with an error.
Symfony \ Component \ VarDumper \ Cloner \ Data objects are immutable
my code:
entity\Customer
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM; use
App\Repository\CustomerRepository; use
ApiPlatform\Core\Annotation\ApiFilter; use
Doctrine\Common\Collections\Collection; use
ApiPlatform\Core\Annotation\ApiResource; use
ApiPlatform\Core\Annotation\ApiSubresource; use
Doctrine\Common\Collections\ArrayCollection; use
Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter; use
ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
/** * #ORM\Entity(repositoryClass=CustomerRepository::class) *
#ApiResource( * normalizationContext={ *
"groups"={"customers_read"} * }, * collectionOperations={"GET",
"POST"}, * itemOperations={"GET","PUT","DELETE","PATCH"}, *
subresourceOperations={ *
"invoices_get_subresource"={"path"="/customers/{id}/invoices"} * }
* ) * #ApiFilter(SearchFilter::class, properties={"firstName":"partial","lastName","company"}) *
#ApiFilter(OrderFilter::class) */ class Customer {
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"customers_read","invoices_read"})
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"customers_read","invoices_read"})
*/
private $firstName;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"customers_read","invoices_read"})
*/
private $lastName;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"customers_read","invoices_read"})
*/
private $email;
/**
* #ORM\Column(type="string", length=255, nullable=true)
* #Groups({"customers_read","invoices_read"})
*/
private $company;
/**
* #ORM\OneToMany(targetEntity=Invoice::class, mappedBy="customer")
* #Groups({"customers_read"})
* #ApiSubresource
*/
private $invoices;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="customers")
* #ORM\JoinColumn(nullable=false)
* #Groups({"customers_read"})
*/
private $user;
public function __construct()
{
$this->invoices = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* #Groups({"customers_read"})
*
* #return float|null
*/
public function getTotalAmount(): ?float
{
return array_reduce($this->invoices->toArray(), function($total,$invoice){
return $total + $invoice->getAmount();
}, 0);
}
/**
* #Groups({"customers_read"})
*
* #return float|null
*/
public function getUnpaidAmount(): ?float
{
return array_reduce($this->invoices->toArray(), function($total,$invoice){
return $total + ($invoice->getStatus() === "PAID" || $invoice->getStatus() === "CANCELLED" ? 0 : $invoice->getAmount());
} , 0);
}
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 getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getCompany(): ?string
{
return $this->company;
}
public function setCompany(?string $company): self
{
$this->company = $company;
return $this;
}
/**
* #return Collection|Invoice[]
*/
public function getInvoices(): Collection
{
return $this->invoices;
}
public function addInvoice(Invoice $invoice): self
{
if (!$this->invoices->contains($invoice)) {
$this->invoices[] = $invoice;
$invoice->setCustomer($this);
}
return $this;
}
public function removeInvoice(Invoice $invoice): self
{
if ($this->invoices->removeElement($invoice)) {
// set the owning side to null (unless already changed)
if ($invoice->getCustomer() === $this) {
$invoice->setCustomer(null);
}
}
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
} }
entity\invoice
<?php
namespace App\Entity;
use App\Entity\User; use Doctrine\ORM\Mapping as ORM; use
App\Repository\InvoiceRepository; use
ApiPlatform\Core\Annotation\ApiFilter; use
ApiPlatform\Core\Annotation\ApiResource; use
Symfony\Component\Serializer\Annotation\Groups; use
ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
/** * #ORM\Entity(repositoryClass=InvoiceRepository::class) *
#ApiResource( * subresourceOperations={ *
"api_customers_invoices_get_subresource"={ *
"normalization_context"={"groups"={"invoices_subresource"}} * }
* }, * itemOperations={"GET","PUT","DELETE","increment"={ * "method"="post", * "path"="/invoices/{id}/increment", *
"controller"="App\Controller\InvoiceIncrementationController", *
"openapi_context"={ * "summary"="Incrémente une
facture", * "description"="Incrémente le chrono d'une
facture donnée" * } * }}, * attributes={ *
"pagination_enabled"=true, * "pagination_items_per_page"=20, *
"order": {"sentAt":"desc"} * }, *
normalizationContext={"groups"={"invoices_read"}} * ) *
#ApiFilter(OrderFilter::class, properties={"amount","sentAt"}) */
class Invoice {
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"invoices_read","customers_read","invoices_subresource"})
*/
private $id;
/**
* #ORM\Column(type="float")
* #Groups({"invoices_read","customers_read","invoices_subresource"})
*/
private $amount;
/**
* #ORM\Column(type="datetime")
* #Groups({"invoices_read","customers_read","invoices_subresource"})
*/
private $sentAt;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"invoices_read","customers_read","invoices_subresource"})
*/
private $status;
/**
* #ORM\ManyToOne(targetEntity=Customer::class, inversedBy="invoices")
* #ORM\JoinColumn(nullable=false)
* #Groups({"invoices_read"})
*/
private $customer;
/**
* #ORM\Column(type="integer")
* #Groups({"invoices_read"})
* #Groups({"invoices_read","customers_read","invoices_subresource"})
*/
private $chrono;
public function getId(): ?int
{
return $this->id;
}
/**
* Permet de récupérer le User à qui appartient finalement la facture
* #Groups({"invoices_read","invoices_subresource"})
*
* #return User
*/
public function getUser(): ?User
{
return $this->customer->getUser();
}
public function getAmount(): ?float
{
return $this->amount;
}
public function setAmount(float $amount): self
{
$this->amount = $amount;
return $this;
}
public function getSentAt(): ?\DateTimeInterface
{
return $this->sentAt;
}
public function setSentAt(\DateTimeInterface $sentAt): self
{
$this->sentAt = $sentAt;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getCustomer(): ?Customer
{
return $this->customer;
}
public function setCustomer(?Customer $customer): self
{
$this->customer = $customer;
return $this;
}
public function getChrono(): ?int
{
return $this->chrono;
}
public function setChrono(int $chrono): self
{
$this->chrono = $chrono;
return $this;
} }
Thank you for your help

SQLSTATE[42S22]: Column not found: 1054 Champ 't0.id' inconnu dans where clause ( Symfony 5 , API Platform )

I have 2 classes , Class Child "Livreur" inherite from Class Parent "Users" .
Problem in return data after insert by API Plateform . (it inserted by success but data deosn't returned + doesn't insert in table Users, before that it inserted in Users+Livreur but now no ).
Class "Users" (parent) :
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\UsersRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping ;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass=UsersRepository::class)
* #ApiResource(
* normalizationContext={"groups"={"read"}},
* collectionOperations={"post"={},"get"={}},
* itemOperations={"get","put"={"denormalization_Context"={"groups"={"put"}}}}
* )
*/
class Users implements UserInterface
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=180)
* #Groups({"read"})
*/
private $email;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=255)
* #Groups({"read"})
* #Groups({"put"})
*/
private $password;
/**
* #Assert\NotBlank()
* #Assert\Expression("this.getPassword() == this.getRepassword()",message="Mot de pass doit etre le meme dans les 2 deux champs")
*/
private $repassword;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=30)
* #Groups({"read"})
* #Groups({"put"})
*/
private $username;
/**
* #Assert\NotBlank()
* #ORM\Column(type="text")
* #Groups({"read"})
* #Groups({"put"})
*/
private $roles;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=20)
* #Groups({"read"})
*/
private $cin;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=20)
* #Groups({"read"})
*/
private $nom;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=20)
* #Groups({"read"})
*/
private $prenom;
/**
* #Assert\NotBlank()
* #ORM\Column(type="date")
* #Groups({"read"})
*/
private $dtn;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=255, nullable=true)
* #Groups({"read"})
*/
private $dtype;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=255, nullable=true)
* #Groups({"read"})
*/
private $img;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=30, nullable=true)
* #Groups({"read"})
* #Groups({"put"})
*/
private $rib;
/**
* #ORM\Column(type="string", length=255, nullable=true)
* #Groups({"read"})
* #Groups({"put"})
*/
private $adresse;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string", length=20)
* #Groups({"read"})
* #Groups({"put"})
*/
private $tel;
protected function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getRoles(): array
{
return array('ROLE_USER');
}
public function setRoles(string $roles): self
{
$this->roles = $roles;
return $this;
}
public function getCin(): ?string
{
return $this->cin;
}
public function setCin(string $cin): self
{
$this->cin = $cin;
return $this;
}
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 getDtn(): ?\DateTimeInterface
{
return $this->dtn;
}
public function setDtn(\DateTimeInterface $dtn): self
{
$this->dtn = $dtn;
return $this;
}
public function getDtype(): ?string
{
return $this->dtype;
}
public function setDtype(?string $dtype): self
{
$this->dtype = $dtype;
return $this;
}
public function getImg(): ?string
{
return $this->img;
}
public function setImg(?string $img): self
{
$this->img = $img;
return $this;
}
public function getRib(): ?string
{
return $this->rib;
}
public function setRib(?string $rib): self
{
$this->rib = $rib;
return $this;
}
public function getAdresse(): ?string
{
return $this->adresse;
}
public function setAdresse(?string $adresse): self
{
$this->adresse = $adresse;
return $this;
}
public function getTel(): ?string
{
return $this->tel;
}
public function setTel(string $tel): self
{
$this->tel = $tel;
return $this;
}
public function getSalt()
{
// TODO: Implement getSalt() method.
}
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
public function getRepassword()
{
return $this->repassword;
}
public function setRepassword($repassword): void
{
$this->repassword = $repassword;
}
}
Class Livreur (child) :
<?php
namespace App\Entity;
use App\Repository\LivreurRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiResource;
/**
* #ORM\Entity(repositoryClass=LivreurRepository::class)
* #ApiResource()
*/
class Livreur extends Users
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=20)
*/
private $type_vehicule;
/**
* #ORM\Column(type="string", length=20)
*/
private $permis;
/**
* #ORM\Column(type="boolean")
*/
private $disponibilite;
/**
* #ORM\Column(type="float")
*/
private $coffre;
/**
* #ORM\Column(type="text", nullable=true)
*/
private $log;
/**
* #ORM\OneToMany(targetEntity=Commande::class, mappedBy="livreur")
*/
private $commandes;
/**
* #ORM\OneToMany(targetEntity=Conge::class, mappedBy="livreur")
*/
private $conges;
/**
* #ORM\ManyToOne(targetEntity=Agence::class, inversedBy="livreurs")
* #ORM\JoinColumn(nullable=false)
*/
private $agence;
/**
* #ORM\OneToOne(targetEntity=SalaireEmp::class, inversedBy="livreur", cascade={"persist", "remove"})
*/
private $salaire_emp;
/**
* #ORM\ManyToOne(targetEntity=Ville::class, inversedBy="livreurs")
* #ORM\JoinColumn(nullable=false)
*/
private $ville;
public function __construct()
{
$this->commandes = new ArrayCollection();
$this->conges = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTypeVehicule(): ?string
{
return $this->type_vehicule;
}
public function setTypeVehicule(string $type_vehicule): self
{
$this->type_vehicule = $type_vehicule;
return $this;
}
public function getPermis(): ?string
{
return $this->permis;
}
public function setPermis(string $permis): self
{
$this->permis = $permis;
return $this;
}
public function getDisponibilite(): ?int
{
return $this->disponibilite;
}
public function setDisponibilite(int $disponibilite): self
{
$this->disponibilite = $disponibilite;
return $this;
}
public function getCoffre(): ?float
{
return $this->coffre;
}
public function setCoffre(float $coffre): self
{
$this->coffre = $coffre;
return $this;
}
public function getLog(): ?string
{
return $this->log;
}
public function setLog(?string $log): self
{
$this->log = $log;
return $this;
}
/**
* #return Collection|Commande[]
*/
public function getCommandes(): Collection
{
return $this->commandes;
}
public function addCommande(Commande $commande): self
{
if (!$this->commandes->contains($commande)) {
$this->commandes[] = $commande;
$commande->setLivreur($this);
}
return $this;
}
public function removeCommande(Commande $commande): self
{
if ($this->commandes->removeElement($commande)) {
// set the owning side to null (unless already changed)
if ($commande->getLivreur() === $this) {
$commande->setLivreur(null);
}
}
return $this;
}
/**
* #return Collection|Conge[]
*/
public function getConges(): Collection
{
return $this->conges;
}
public function addConge(Conge $conge): self
{
if (!$this->conges->contains($conge)) {
$this->conges[] = $conge;
$conge->setLivreur($this);
}
return $this;
}
public function removeConge(Conge $conge): self
{
if ($this->conges->removeElement($conge)) {
// set the owning side to null (unless already changed)
if ($conge->getLivreur() === $this) {
$conge->setLivreur(null);
}
}
return $this;
}
public function getAgence(): ?Agence
{
return $this->agence;
}
public function setAgence(?Agence $agence): self
{
$this->agence = $agence;
return $this;
}
public function getSalaireEmp(): ?SalaireEmp
{
return $this->salaire_emp;
}
public function setSalaireEmp(?SalaireEmp $salaire_emp): self
{
$this->salaire_emp = $salaire_emp;
return $this;
}
public function getVille(): ?Ville
{
return $this->ville;
}
public function setVille(?Ville $ville): self
{
$this->ville = $ville;
return $this;
}
}
Looks like you forgot to set an inheritance mapping strategy. Here is an example:
// (..)
/**
* #ORM\Entity(repositoryClass=UsersRepository::class)
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({"users" = "Users", "livreur" = "Livreur"})
* #ApiResource(
* normalizationContext={"groups"={"read"}},
* collectionOperations={"post"={},"get"={}},
* itemOperations={"get","put"={"denormalization_Context"={"groups"={"put"}}}}
* )
*/
class Users implements UserInterface
{
// (..)
This will add an extra field "discr" to the tables of both your classes so you will have to update their table configurations, for example with:
bin/console doctrine:schema:update --force
or if you use migrations:
bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate
For explanation of Mapping Strategies and their alternatives see the Inheritance Mapping page on doctrine-project.org

API-PLATFORM User Update Password Or user profile

I need help :-D, I'm a beginner on Symfony and Api Platform. I have an entity User, I want create an items Operation for update my user with an object { email: string; firstname: string; lastname: string } without password, and a second itemsOperation just for my password.
I have testing, but I can't do it.
this is my entity user and annotation api.
/**
* #ApiResource(
* itemOperations={
* "get",
* "update_password"={"method"="PUT", "path"="user/{id}/update-password",
* "validation_groups"={"updatePassword"}},
* "update_user"={"method"="PUT", "path"="user/{id}/update-user",
* "validation_groups"={"updateUser"}}
* }
* )
* #ORM\Table(name="users")
* #ORM\Entity
*/
class User implements UserInterface
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* #ORM\Column(type="string", length=255)
* #Assert\Length(min="8", max="22")
* #Assert\NotNull(groups={"updatePassword"})
* #Assert\IsNull(groups={"updateUser"})
*/
private $password;
/**
* #ORM\Column(type="string", length=45)
* #Groups({"updateUser"})
*/
private $email;
/**
* #ORM\Column(type="array")
*/
private $roles = [];
/**
* #ORM\Column(type="string", length=255, nullable=true)
* #Groups({"updateUser"})
*/
private $firstname;
/**
* #ORM\Column(type="string", length=255, nullable=true)
* #Groups({"updateUser"})
*/
private $lastname;
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getSalt()
{
return null;
}
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getRoles(): array
{
$roles = $this->roles;
return $roles;
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
$this->password = null;
}
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;
}
}
If I used update-user endpoint, failed error because i not send my password.
Can you help me?
Thanx all.
The "Symfony way" to handle this, is using 2 fields: password and plainPassword. This is Symfony best practice in general.
<?php
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ApiResource(
* normalizationContext={"groups"={"user"}},
* denormalizationContext={"groups"={"user"}}
* )
* #ORM\EntityListeners({"App\Listener\Entity\UserEntityListener"})
*/
class User
{
/**
* #ORM\Column(type="string", length=255)
*/
private $password; // This field should NEVER be exposed.
/**
* #Assert\Length(min="8", max="22") // Apply validation here, not on $password
* #Groups({"user"}) // Expose using groups
*/
private $plainPassword;
Next, create an entity listener (or any api platform event listener) to change password if plainPassword is not empty.
<?php
namespace App\Listener\Entity;
use App\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface
class UserEntityListener
{
private UserPasswordEncoderInterface $passwordEncoder;
public function __construct(
UserPasswordEncoderInterface $passwordEncoder
) {
$this->passwordEncoder = $passwordEncoder;
}
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function preUpdateHandler(User $user): void
{
if ($user->getPlainPassword() !== null) {
$password = $this->passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
}
}
}
If you want different itemOperations to change password, you can still do so by changing the groups.

#Doctrine\ORM\Mapping\ "Annotation was never imported"

so i'm new to Doctrine and PHP in general and i have a small issue that i don't know how to fix...
I need to create a PHP app (using Doctrine) and to make communication with the DB my predecessor used Doctrine ORM; so i tried to use one of his files as a templates to make my part of the app but it does not seem to work...
First, his file used as template:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #UniqueEntity("email")
*/
class User implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
* #Groups({"campaign_get", "user_logged"})
*/
private $id;
/**
* #ORM\Column(type="string", length=180, unique=true)
* #Assert\NotBlank
* #Assert\Email
* #Groups({"campaign_get", "user_logged"})
*/
private $email;
/**
* #var string The hashed password
* #ORM\Column(type="string")
* #Assert\NotBlank
* #Assert\Regex(
* pattern="/^(?=.{8,}$)(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$/",
* message="Votre mot de passe doit contenir au moins 1 chiffre, 1 majuscule, 1 minuscule et avoir une longueur d'au moins 8 caractères."
* )
*/
private $password;
/**
* #ORM\Column(type="string", length=100)
* #Assert\NotBlank
* #Groups("campaign_get")
*/
private $firstname;
/**
* #ORM\Column(type="string", length=100)
* #Assert\NotBlank
* #Groups("campaign_get")
*/
private $lastname;
/**
* #ORM\Column(type="boolean")
*/
private $status;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $idInstagram;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $idFacebook;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $idYoutube;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $idSnapchat;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $idTiktok;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Role")
* #Groups("campaign_get")
*/
private $userRoles;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Article", mappedBy="users")
*/
private $articles;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $companyName;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Campaign", mappedBy="users")
*/
private $campaigns;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $resetToken;
public function __construct()
{
$this->userRoles = new ArrayCollection();
$this->articles = new ArrayCollection();
$this->status = 1;
$this->createdAt = new \DateTime();
$this->campaigns = new ArrayCollection();
}
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 getUsername(): string
{
return (string) $this->email;
}
/**
* #see UserInterface
*/
public function getRoles(): array
{
$roles = $this->userRoles;
$userRoles = [];
foreach ($roles as $role) {
$userRoles[] = $role->getName();
}
return $userRoles;
}
/**
* #see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* #see UserInterface
*/
public function getSalt()
{
// not needed when using the "bcrypt" algorithm in security.yaml
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
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 getStatus(): ?bool
{
return $this->status;
}
public function setStatus(bool $status): self
{
$this->status = $status;
return $this;
}
public function getIdInstagram(): ?string
{
return $this->idInstagram;
}
public function setIdInstagram(?string $idInstagram): self
{
$this->idInstagram = $idInstagram;
return $this;
}
public function getIdFacebook(): ?string
{
return $this->idFacebook;
}
public function setIdFacebook(?string $idFacebook): self
{
$this->idFacebook = $idFacebook;
return $this;
}
public function getIdYoutube(): ?string
{
return $this->idYoutube;
}
public function setIdYoutube(?string $idYoutube): self
{
$this->idYoutube = $idYoutube;
return $this;
}
public function getIdSnapchat(): ?string
{
return $this->idSnapchat;
}
public function setIdSnapchat(?string $idSnapchat): self
{
$this->idSnapchat = $idSnapchat;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(?\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getIdTiktok(): ?string
{
return $this->idTiktok;
}
public function setIdTiktok(?string $idTiktok): self
{
$this->idTiktok = $idTiktok;
return $this;
}
/**
* #return Collection|Role[]
*/
public function getUserRoles(): Collection
{
return $this->userRoles;
}
public function addUserRole(Role $userRole): self
{
if (!$this->userRoles->contains($userRole)) {
$this->userRoles[] = $userRole;
}
return $this;
}
public function removeUserRole(Role $userRole): self
{
if ($this->userRoles->contains($userRole)) {
$this->userRoles->removeElement($userRole);
}
return $this;
}
/**
* #return Collection|Article[]
*/
public function getArticles(): Collection
{
return $this->articles;
}
public function addArticle(Article $article): self
{
if (!$this->articles->contains($article)) {
$this->articles[] = $article;
$article->addUser($this);
}
return $this;
}
public function removeArticle(Article $article): self
{
if ($this->articles->contains($article)) {
$this->articles->removeElement($article);
$article->removeUser($this);
}
return $this;
}
public function getCompanyName(): ?string
{
return $this->companyName;
}
public function setCompanyName(?string $companyName): self
{
$this->companyName = $companyName;
return $this;
}
/**
* #return Collection|Campaign[]
*/
public function getCampaigns(): Collection
{
return $this->campaigns;
}
public function addCampaign(Campaign $campaign): self
{
if (!$this->campaigns->contains($campaign)) {
$this->campaigns[] = $campaign;
$campaign->addUser($this);
}
return $this;
}
public function removeCampaign(Campaign $campaign): self
{
if ($this->campaigns->contains($campaign)) {
$this->campaigns->removeElement($campaign);
$campaign->removeUser($this);
}
return $this;
}
public function getResetToken(): ?string
{
return $this->resetToken;
}
public function setResetToken(?string $resetToken): self
{
$this->resetToken = $resetToken;
return $this;
}
}
Then, mine using the same philosophy:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ORM\Entity(repositoryClass="App\Repository\AgencyRepository")
*/
class Agency
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\nameAgency()
* #ORM\Column(type"string")
*/
private $nameAgency;
/**
* #ORM\nameContact
* #ORM\Column(type="string")
* #Assert\NotBlank
*/
private $nameContact;
}
Then i try to run this:
php bin/console doctrine:migrations:diff
into a terminal to update the DB, it works fine with the previous file (User Class) but mine (Agency Class) throw a error:
[Semantical Error] The annotation "#Doctrine\ORM\Mapping\nameAgency" in property App\Entity\Agency::$nameAgency was never imported. Did you maybe forget to add
a "use" statement for this annotation?
At first i thought it was an issue with import, so i made exactly the sames imports as in User Class but the error is still present.
Googling the error lead me to a github issue that leeds to this as a fix; but it doesn't seems to work's for me...
What should i do to fix this issue?
You are using
#ORM\nameAgency()
obviously this annotation does not exist, why do you have it there?
Remove #ORM\nameAgency() and #ORM\nameContact, it doesn't make any sense.
Explanation: by #ORM\nameAgency() you actually mean Doctrine\ORM\Mapping\nameAgency and this annotation naturally doesn't exist in Doctrine.

Categories