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.
Related
how can i get doctrine in entity to get permission list?
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\Role\Role;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
* #ORM\HasLifecycleCallbacks()
* #ORM\Table(name="`user`")
*/
class User implements UserInterface
{
private $entityManager;
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=180, unique=true)
*/
private $discordId;
/**
* #ORM\Column(type="string", length=180)
*/
private $username;
/**
* #ORM\Column(type="string", length=255, unique=true)
*/
private $email;
/**
* #ORM\Column(type="json")
*/
private $roles = [];
/**
* #ORM\OneToMany(targetEntity=Sites::class, mappedBy="owner", orphanRemoval=true)
*/
private $sites;
/**
* #ORM\PostLoad
* #ORM\PostPersist
*/
public function fetchEntityManager(LifecycleEventArgs $args)
{
$this->entityManager = $args->getEntityManager();
}
public function __construct()
{
$this->sites = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getdiscordId(): ?int
{
return $this->discordId;
}
public function setdiscordId(string $discordId): self
{
$this->discordId = $discordId;
return $this;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
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->username;
}
public function getRoles() :array
{
// get permissions from group
$groupPermissionsRepo = $this->entityManager->getRepository(GroupPermissions::class);
$groupAccessList = $groupPermissionsRepo->getPermissionsForGroup($this->getGroupId());
// create access
$accessList = [];
foreach ($groupAccessList as $access) {
$accessList[] = new Role('ROLE_'.$access);
}
// set default role when group didn't have any access granted
if(count($groupAccessList) == 0)
$accessList[] = new Role('ROLE_USER');
// return access
return $accessList;
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
/**
* #return Collection<int, Sites>
*/
public function getSites(): Collection
{
return $this->sites;
}
public function addSite(Sites $site): self
{
if (!$this->sites->contains($site)) {
$this->sites[] = $site;
$site->setOwner($this);
}
return $this;
}
public function removeSite(Sites $site): self
{
if ($this->sites->removeElement($site)) {
// set the owning side to null (unless already changed)
if ($site->getOwner() === $this) {
$site->setOwner(null);
}
}
return $this;
}
}
While using this code i get only error:
App\Entity\User::fetchEntityManager(): Argument #1 ($args) must be of type Doctrine\Common\Persistence\Event\LifecycleEventArgs, Doctrine\ORM\Event\LifecycleEventArgs given, called in C:\xampp\htdocs\dbshop2\vendor\doctrine\orm\lib\Doctrine\ORM\Event\ListenersInvoker.php on line 84
beginner here i'm trying to do an API with Api-platform and Symfony. Actually i want to create my database schema and start testing it but when using php bin/console doctrine:schema:validate, i got this error and i cant figure out how to fix it : The table with name 'mydb.appartment_user' already exists
Unfortunately i didnt found an answer on google to my problem :'(
Here is my appartement entity :
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\AppartmentRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ApiResource()
* #ORM\Entity(repositoryClass=AppartmentRepository::class)
*/
class Appartment
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $adress;
/**
* #ORM\Column(type="string", length=255)
*/
private $latitude;
/**
* #ORM\Column(type="string", length=255)
*/
private $longitude;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="occupied_appartments")
*/
private $current_tenant;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="rented_appartments")
*/
private $landlord;
/**
* #ORM\OneToOne(targetEntity=Lock::class, cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $lock_id;
public function __construct()
{
$this->current_tenant = new ArrayCollection();
$this->landlord = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getAdress(): ?string
{
return $this->adress;
}
public function setAdress(string $adress): self
{
$this->adress = $adress;
return $this;
}
public function getLatitude(): ?string
{
return $this->latitude;
}
public function setLatitude(string $latitude): self
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?string
{
return $this->longitude;
}
public function setLongitude(string $longitude): self
{
$this->longitude = $longitude;
return $this;
}
/**
* #return Collection|User[]
*/
public function getCurrentTenant(): Collection
{
return $this->current_tenant;
}
public function addCurrentTenant(User $currentTenant): self
{
if (!$this->current_tenant->contains($currentTenant)) {
$this->current_tenant[] = $currentTenant;
}
return $this;
}
public function removeCurrentTenant(User $currentTenant): self
{
$this->current_tenant->removeElement($currentTenant);
return $this;
}
/**
* #return Collection|User[]
*/
public function getLandlord(): Collection
{
return $this->landlord;
}
public function addLandlord(User $landlord): self
{
if (!$this->landlord->contains($landlord)) {
$this->landlord[] = $landlord;
}
return $this;
}
public function removeLandlord(User $landlord): self
{
$this->landlord->removeElement($landlord);
return $this;
}
public function getLockId(): ?Lock
{
return $this->lock_id;
}
public function setLockId(Lock $lock_id): self
{
$this->lock_id = $lock_id;
return $this;
}
}
and 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;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
* #ORM\Table(name="`user`")
*/
class User implements UserInterface
{
/**
* #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 = [];
/**
* #var string The hashed password
* #ORM\Column(type="string")
*/
private $password;
/**
* #ORM\Column(type="string", length=255)
*/
private $firstname;
/**
* #ORM\Column(type="string", length=255)
*/
private $lastname;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $profile_picture;
/**
* #ORM\ManyToMany(targetEntity=Appartment::class, mappedBy="current_tenant")
*/
private $occupied_appartments;
/**
* #ORM\ManyToMany(targetEntity=Appartment::class, mappedBy="landlord")
*/
private $rented_appartments;
/**
* #ORM\ManyToMany(targetEntity=Rental::class, mappedBy="tenant_id")
*/
private $tenant_rentals;
/**
* #ORM\ManyToMany(targetEntity=Rental::class, mappedBy="landlord_id")
*/
private $landlord_rentals;
public function __construct()
{
$this->occupied_appartments = new ArrayCollection();
$this->rented_appartments = new ArrayCollection();
$this->tenant_rentals = new ArrayCollection();
$this->landlord_rentals = 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->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 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 getProfilePicture(): ?string
{
return $this->profile_picture;
}
public function setProfilePicture(?string $profile_picture): self
{
$this->profile_picture = $profile_picture;
return $this;
}
/**
* #return Collection|Appartment[]
*/
public function getOccupiedAppartments(): Collection
{
return $this->occupied_appartments;
}
public function addOccupiedAppartment(Appartment $occupied_appartments): self
{
if (!$this->occupied_appartments->contains($occupied_appartments)) {
$this->occupied_appartments[] = $occupied_appartments;
$occupied_appartments->addCurrentTenant($this);
}
return $this;
}
public function removeOccupiedAppartment(Appartment $occupied_appartments): self
{
if ($this->occupied_appartments->removeElement($occupied_appartments)) {
$occupied_appartments->removeCurrentTenant($this);
}
return $this;
}
/**
* #return Collection|Appartment[]
*/
public function getRentedAppartments(): Collection
{
return $this->rented_appartments;
}
public function addRentedAppartment(Appartment $rentedAppartment): self
{
if (!$this->rented_appartments->contains($rentedAppartment)) {
$this->rented_appartments[] = $rentedAppartment;
$rentedAppartment->addLandlord($this);
}
return $this;
}
public function removeRentedAppartment(Appartment $rentedAppartment): self
{
if ($this->rented_appartments->removeElement($rentedAppartment)) {
$rentedAppartment->removeLandlord($this);
}
return $this;
}
/**
* #return Collection|Rental[]
*/
public function getTenantRentals(): Collection
{
return $this->tenant_rentals;
}
public function addTenantRental(Rental $tenantRental): self
{
if (!$this->tenant_rentals->contains($tenantRental)) {
$this->tenant_rentals[] = $tenantRental;
$tenantRental->addTenantId($this);
}
return $this;
}
public function removeTenantRental(Rental $tenantRental): self
{
if ($this->tenant_rentals->removeElement($tenantRental)) {
$tenantRental->removeTenantId($this);
}
return $this;
}
/**
* #return Collection|Rental[]
*/
public function getLandlordRentals(): Collection
{
return $this->landlord_rentals;
}
public function addLandlordRental(Rental $landlordRental): self
{
if (!$this->landlord_rentals->contains($landlordRental)) {
$this->landlord_rentals[] = $landlordRental;
$landlordRental->addLandlordId($this);
}
return $this;
}
public function removeLandlordRental(Rental $landlordRental): self
{
if ($this->landlord_rentals->removeElement($landlordRental)) {
$landlordRental->removeLandlordId($this);
}
return $this;
}
}
I tried to clear-cache and to force but it didnt work.
Thank's in advance for help and ask me if I forget any details !
add a JoinTable annotation for properties which have ManyToMany relation in Appartment entity
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="occupied_appartments")
* #ORM\JoinTable(name="appartment_current_tenant")
*/
private $current_tenant;
/**
* #ORM\ManyToMany(targetEntity=User::class, inversedBy="rented_appartments")
* #ORM\JoinTable(name="appartment_landlord")
*/
private $landlord;
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
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;
}
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.