Vichuploader Entity is not uploadable - php

I have an issue with my vichuplader it triggers and exception Not uploadable knowing that I've followed all the setup I'm using easyadmin3 to insert data for my News entity that have an image attachement to it.
I've reinstalled VichBundel, rewrote the entity, tried diffrent fieldtype in my easyadmin config
vich_uploader:
db_driver: orm
metadata:
type: attribute
mappings:
news_image:
uri_prefix: /images/news
upload_destination: "%kernel.project_dir%/public/images/news"
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
class NewsCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return News::class;
}
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id')->onlyOnIndex(),
TextField::new('title'),
TextEditorField::new('description'),
BooleanField::new('isActive', 'Actif'),
ImageField::new('imagename')->setBasePath('images/news')->onlyOnIndex(),
VichImageField::new('imageFile')->hideOnIndex()
];
}
}
<?php
namespace App\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use App\Repository\NewsRepository;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[ ORM\Entity( repositoryClass: NewsRepository::class ) ]
#[Vich\Uploadable]
class News {
#[ ORM\Id ]
#[ ORM\GeneratedValue ]
#[ ORM\Column ]
private ?int $id = null;
#[ ORM\Column( length: 255 ) ]
private ?string $title = null;
#[ ORM\Column( type: Types::TEXT ) ]
private ?string $description = null;
#[ ORM\Column ]
private ?bool $isActive = null;
#[ ORM\Column( length: 255 ) ]
private ?string $imageName = null;
#[ Vich\UploadableField( mapping: 'news_image', fileNameProperty: 'imageName' ) ]
private ?File $imageFile = null;
#[ ORM\Column ]
private ?\DateTimeImmutable $createdAt = null;
#[ ORM\Column ]
private ?\DateTimeImmutable $updatedAt = null;
#[ ORM\Column( nullable: true ) ]
private ?\DateTimeImmutable $publishedAt = null;
public function __construct() {
$this->createdAt = new \DateTimeImmutable();
$this->updatedAt = new \DateTimeImmutable();
}
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 getDescription(): ?string {
return $this->description;
}
public function setDescription( string $description ): self {
$this->description = $description;
return $this;
}
public function isIsActive(): ?bool {
return $this->isActive;
}
public function setIsActive( bool $isActive ): self {
$this->isActive = $isActive;
return $this;
}
public function getImageName(): ?string {
return $this->imageName;
}
public function setImageName( ?string $imageName ): self {
$this->imageName = $imageName;
return $this;
}
public function setImageFile( ?File $imageFile = null ): void {
$this->imageFile = $imageFile;
if ($imageFile) {
$this->updatedAt = new \DateTime( 'now' );
}
}
public function getImageFile() {
return $this->imageFile;
}
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 getPublishedAt(): ?\DateTimeImmutable {
return $this->publishedAt;
}
public function setPublishedAt( ?\DateTimeImmutable $publishedAt ): self {
$this->publishedAt = $publishedAt;
return $this;
}
}

Related

Object of class App\Entity\Fournisseurs could not be converted to string

I have the following error: Object of class App\Entity\Fournisseurs could not be converted to string I wish that in my order page we can choose a supplier to register in the db page and supplier page in order to associate an order with one or several suppliers I have however used the to_string command well so I do not see where the error is even if it must surely be stupid.
I have try add to_sting command in orders.php and in fournisseurs.php ( fournisseurs = suppliers in french)
I use Symfony and EasyAdmin
OrdersCrudController.php
<?php
namespace App\Controller\Admin;
use App\Entity\Orders;
use App\Entity\Fournisseurs;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use phpDocumentor\Reflection\Types\Boolean;
class OrdersCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Orders::class;
}
public function configureCrud(Crud $crud): Crud
{
return $crud
->setEntityLabelInPlural('Liste des Commandes');
}
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id')->hideOnForm(),
NumberField::new('numero_cmd'),
AssociationField::new('fournisseur','name_sct')
->setCrudController(FournisseursCrudController::class),
DateTimeField::new('date_cmd'),
DateTimeField::new('date_rcp'),
TextField::new('article'),
TextField::new('designation'),
NumberField::new('qte_cmd_uom'),
NumberField::new('unite_cmd'),
];
}
}
FournisseursCrudController.php
<?php
namespace App\Controller\Admin;
use App\Entity\Fournisseurs;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TelephoneField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
class FournisseursCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Fournisseurs::class;
}
public function configureCrud(Crud $crud): Crud
{
return $crud
->setEntityLabelInPlural('Liste des Fournisseurs');
}
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id')->hideOnForm(),
TextField::new('name_sct'),
TextField::new('rcs'),
EmailField::new('Email'),
TelephoneField::new('tel'),
TextField::new('adresse'),
TextField::new('cp'),
TextField::new('ville')->setRequired(true),
];
}
}
Orders.php
<?php
namespace App\Entity;
use App\Repository\OrdersRepository;
use App\Repository\FournisseurRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: OrdersRepository::class)]
class Orders
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $numero_cmd = null;
#[ORM\ManyToMany(targetEntity: Fournisseurs::class, inversedBy: 'fournisseurs_orders')]
private Collection $fournisseur;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $date_cmd = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $date_rcp = null;
#[ORM\Column(length: 255)]
private ?string $article = null;
#[ORM\Column(length: 255)]
private ?string $designation = null;
#[ORM\Column(length: 255)]
private ?string $qte_cmd_uom = null;
#[ORM\Column(length: 255)]
private ?string $unite_cmd = null;
public function __construct()
{
$this->fournisseur = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNumeroCmd(): ?string
{
return $this->numero_cmd;
}
public function setNumeroCmd(string $numero_cmd): self
{
$this->numero_cmd = $numero_cmd;
return $this;
}
/**
* #return Collection<int, Fournisseurs>
*/
public function getFournisseur(): Collection
{
return $this->fournisseur;
}
public function addFournisseur(Fournisseurs $fournisseur): self
{
if (!$this->fournisseur->contains($fournisseur)) {
$this->fournisseur->add($fournisseur);
}
return $this;
}
public function removeFournisseur(Fournisseurs $fournisseur): self
{
$this->fournisseur->removeElement($fournisseur);
return $this;
}
public function getDateCmd(): ?\DateTimeInterface
{
return $this->date_cmd;
}
public function setDateCmd(\DateTimeInterface $date_cmd): self
{
$this->date_cmd = $date_cmd;
return $this;
}
public function getDateRcp(): ?\DateTimeInterface
{
return $this->date_rcp;
}
public function setDateRcp(\DateTimeInterface $date_rcp): self
{
$this->date_rcp = $date_rcp;
return $this;
}
public function getArticle(): ?string
{
return $this->article;
}
public function setArticle(string $article): self
{
$this->article = $article;
return $this;
}
public function getDesignation(): ?string
{
return $this->designation;
}
public function setDesignation(string $designation): self
{
$this->designation = $designation;
return $this;
}
public function getQteCmdUom(): ?string
{
return $this->qte_cmd_uom;
}
public function setQteCmdUom(string $qte_cmd_uom): self
{
$this->qte_cmd_uom = $qte_cmd_uom;
return $this;
}
public function getUniteCmd(): ?string
{
return $this->unite_cmd;
}
public function setUniteCmd(string $unite_cmd): self
{
$this->unite_cmd = $unite_cmd;
return $this;
}
public function __toString()
{
return $this->sct_name;
}
}
Fournisseurs.php
<?php
namespace App\Entity;
use App\Repository\FournisseursRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: FournisseursRepository::class)]
class Fournisseurs
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name_sct = null;
#[ORM\Column(length: 255)]
private ?string $rcs = null;
#[ORM\Column(length: 255)]
private ?string $adresse = null;
#[ORM\Column(length: 255)]
private ?string $email = null;
#[ORM\Column(length: 8)]
private ?string $cp = null;
#[ORM\Column(length: 8)]
private ?string $tel = null;
#[ORM\OneToMany(mappedBy: 'fournisseur_name', targetEntity: Orders::class)]
private Collection $orders;
#[ORM\ManyToMany(targetEntity: Orders::class, mappedBy: 'fournisseur_name')]
private Collection $orders_obj;
#[ORM\ManyToMany(targetEntity: Orders::class, mappedBy: 'fournisseur')]
private Collection $fournisseurs_orders;
#[ORM\Column(length: 255)]
private ?string $Ville = null;
public function __construct()
{
$this->orders = new ArrayCollection();
$this->orders_obj = new ArrayCollection();
$this->fournisseurs_orders = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNameSct(): ?string
{
return $this->name_sct;
}
public function setNameSct(string $name_sct): self
{
$this->name_sct = $name_sct;
return $this;
}
public function getRcs(): ?string
{
return $this->rcs;
}
public function setRcs(string $rcs): self
{
$this->rcs = $rcs;
return $this;
}
public function getAdresse(): ?string
{
return $this->adresse;
}
public function setAdresse(string $adresse): self
{
$this->adresse = $adresse;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getCp(): ?string
{
return $this->cp;
}
public function setCp(string $cp): self
{
$this->cp = $cp;
return $this;
}
public function getTel(): ?string
{
return $this->tel;
}
public function setTel(string $tel): self
{
$this->tel = $tel;
return $this;
}
/**
* #return Collection<int, Orders>
*/
public function getOrders(): Collection
{
return $this->orders;
}
public function addOrder(Orders $order): self
{
if (!$this->orders->contains($order)) {
$this->orders->add($order);
$order->setFournisseurName($this);
}
return $this;
}
public function removeOrder(Orders $order): self
{
if ($this->orders->removeElement($order)) {
// set the owning side to null (unless already changed)
if ($order->getFournisseurName() === $this) {
$order->setFournisseurName(null);
}
}
return $this;
}
/**
* #return Collection<int, Orders>
*/
public function getOrdersObj(): Collection
{
return $this->orders_obj;
}
public function addOrdersObj(Orders $ordersObj): self
{
if (!$this->orders_obj->contains($ordersObj)) {
$this->orders_obj->add($ordersObj);
$ordersObj->addFournisseurName($this);
}
return $this;
}
public function removeOrdersObj(Orders $ordersObj): self
{
if ($this->orders_obj->removeElement($ordersObj)) {
$ordersObj->removeFournisseurName($this);
}
return $this;
}
/**
* #return Collection<int, Orders>
*/
public function getFournisseursOrders(): Collection
{
return $this->fournisseurs_orders;
}
public function addFournisseursOrder(Orders $fournisseursOrder): self
{
if (!$this->fournisseurs_orders->contains($fournisseursOrder)) {
$this->fournisseurs_orders->add($fournisseursOrder);
$fournisseursOrder->addFournisseur($this);
}
return $this;
}
public function removeFournisseursOrder(Orders $fournisseursOrder): self
{
if ($this->fournisseurs_orders->removeElement($fournisseursOrder)) {
$fournisseursOrder->removeFournisseur($this);
}
return $this;
}
public function getVille(): ?string
{
return $this->Ville;
}
public function setVille(string $Ville): self
{
$this->Ville = $Ville;
return $this;
}
}
Try to move your function
public function __toString()
{
return $this->sct_name;
}
in Fournisseurs.php instead of Orders.php and also rename
$this->sct_name
To
$this->name_sct
You have to add toString function on Fournisseur.
Your orders class has a relation with fournisseur, and symfony can't know what to display on your order form for the fournisseur input. So you have to explain in Fournisseur.php what is the string to show on the input.
public function __toString()
{
return $this->name;
}

Symfony roles doesn't save in database as array

The roles of my user entity aren't save well in database.
I have a basic question but I didn't find the solution so I'm asking it myself here.
When I create an user he he's register with the role ROLE_USER. But in my database he's save as a:0:{}
Do you have an idea of what I can do to store them as [] by default.
Ok here is my user entity:
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
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;
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`', options:["collate"=>"utf8mb4_unicode_ci", "charset"=>"utf8mb4"])]
#[UniqueEntity(fields: ['mail'], message: 'There is already an account with this mail.')]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(type: Types::ARRAY, nullable: true)]
private array $roles = [];
#[ORM\Column(length: 255)]
private ?string $username = null;
#[ORM\Column(length: 255)]
private ?string $password = null;
#[ORM\Column(length: 255)]
private ?string $group_role = null;
#[ORM\Column(length: 255)]
private ?string $mail = null;
#[ORM\Column(length: 255)]
private ?string $firstname = null;
#[ORM\Column(length: 255)]
private ?string $lastname = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, options: ['default' => 'CURRENT_TIMESTAMP'])]
private ?\DateTime $create_datetime = null;
#[ORM\Column(length: 255)]
private ?string $notif_rule = null;
#[ORM\OneToMany(mappedBy: 'his_user', targetEntity: Logs::class, orphanRemoval: true)]
private Collection $logs;
#[ORM\OneToMany(mappedBy: 'his_user', targetEntity: Session::class)]
private Collection $sessions;
#[ORM\OneToMany(mappedBy: 'his_user', targetEntity: Access::class, orphanRemoval: true)]
private Collection $accesses;
public function __construct()
{
$this->logs = new ArrayCollection();
$this->sessions = new ArrayCollection();
$this->accesses = new ArrayCollection();
$this->create_datetime = new \DateTime( );
}
public function getId(): ?int
{
return $this->id;
}
/**
* #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;
}
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 getGroupRole(): ?string
{
return $this->group_role;
}
public function setGroupRole(string $group_role): self
{
$this->group_role = $group_role;
return $this;
}
public function getMail(): ?string
{
return $this->mail;
}
public function setMail(string $mail): self
{
$this->mail = $mail;
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;
}
public function getCreateDatetime(): ?\DateTimeInterface
{
return $this->create_datetime;
}
public function setCreateDatetime(\DateTimeInterface $create_datetime): self
{
$this->create_datetime = $create_datetime;
return $this;
}
public function getNotifRule(): ?string
{
return $this->notif_rule;
}
public function setNotifRule(string $notif_rule): self
{
$this->notif_rule = $notif_rule;
return $this;
}
/**
* #return Collection<int, Logs>
*/
public function getLogs(): Collection
{
return $this->logs;
}
public function addLog(Logs $log): self
{
if (!$this->logs->contains($log)) {
$this->logs->add($log);
$log->setHisUser($this);
}
return $this;
}
public function removeLog(Logs $log): self
{
if ($this->logs->removeElement($log)) {
// set the owning side to null (unless already changed)
if ($log->getHisUser() === $this) {
$log->setHisUser(null);
}
}
return $this;
}
/**
* #return Collection<int, Session>
*/
public function getSessions(): Collection
{
return $this->sessions;
}
public function addSession(Session $session): self
{
if (!$this->sessions->contains($session)) {
$this->sessions->add($session);
$session->setHisUser($this);
}
return $this;
}
public function removeSession(Session $session): self
{
if ($this->sessions->removeElement($session)) {
// set the owning side to null (unless already changed)
if ($session->getHisUser() === $this) {
$session->setHisUser(null);
}
}
return $this;
}
/**
* #return Collection<int, Access>
*/
public function getAccesses(): Collection
{
return $this->accesses;
}
public function addAccess(Access $access): self
{
if (!$this->accesses->contains($access)) {
$this->accesses->add($access);
$access->setHisUser($this);
}
return $this;
}
public function removeAccess(Access $access): self
{
if ($this->accesses->removeElement($access)) {
// set the owning side to null (unless already changed)
if ($access->getHisUser() === $this) {
$access->setHisUser(null);
}
}
return $this;
}
/**
* A visual identifier that represents this user
*
* #see UserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->mail;
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
}
And here is my route:
#[Route('/register', name: 'app_register')]
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, UserAuthenticatorInterface $userAuthenticator, UserAuthenticator $authenticator, EntityManagerInterface $entityManager): Response
{
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
$entityManager->persist($user);
$entityManager->flush();
// do anything else you need here, like send an email
return $userAuthenticator->authenticateUser(
$user,
$authenticator,
$request
);
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
]);
}
Sorry the code is not properly formated I copy past it and it came that way.

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();

Create personalized validator for form by easyadmin with symfony

The problem
Hi everybody ! I'm new on stackoverflow and in symfony. Before I came here, i've tried some solutions like create validator or insert functions directly in my entity or repository and call them into my CrudController but I still block...
I've 7 entities : User, Hideout, Agent, Contact, Mission, Speciality and Target (it's for a dummy project for training myself) and I use easyadmin to have CRUD on all of them.
Everything works well but in my MissionCrudController, I need to specify error if contact's nationality is different of the mission's country for example. And I don't know how I can do that without make a form by myself. I even don't know how to use Validators to help me.
Or maybe the solution is to create filters ? When user enters the mission's country, contacts from this country will be display ?
Maybe someone can explain it to me ?
Thanks in advance !
(And sorry for my english !)
And this is my code :
MissionCrudController.php
<?php
namespace App\Controller\Admin;
use App\Entity\Mission;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\CountryField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class MissionCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Mission::class;
}
public function configureFields(string $pageName): iterable
{
return [
TextField::new('title'),
TextareaField::new('description')->hideOnIndex(),
ChoiceField::new('type')->setChoices([
'Murder' => 'Murder',
'Surveillance' => 'Surveillance',
'Infiltration' => 'Infiltration',
'Kidnapping' => 'Kidnapping',
'Extraction' => 'Extraction',
]),
CountryField::new('country'),
DateField::new('startDate')->hideOnIndex(),
DateField::new('endDate')->hideOnIndex(),
AssociationField::new('speciality')->hideOnIndex(),
AssociationField::new('agent')->setRequired(true),
AssociationField::new('target')->setRequired(true),
AssociationField::new('contact')->setRequired(true),
AssociationField::new('hideout'),
ChoiceField::new('status')->setChoices([
'Preparation' => 'Preparation',
'Started' => 'Started',
'Finished' => 'Finished',
'Failed' => 'Failed',
]),
];
}
public function configureCrud(Crud $crud): Crud
{
return $crud
->setPageTitle('index', 'Missions');
}
}
Contact.php
<?php
namespace App\Entity;
use App\Repository\ContactRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ContactRepository::class)]
class Contact
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column()]
private ?int $id = null;
#[ORM\Column(length: 100)]
private ?string $firstname = null;
#[ORM\Column(length: 100)]
private ?string $lastname = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $dateOfBirth = null;
#[ORM\Column(length: 100)]
private ?string $codeName = null;
#[ORM\Column(length: 100)]
private ?string $nationality = null;
#[ORM\ManyToMany(targetEntity: Mission::class, mappedBy: 'contact')]
private Collection $missions;
public function __construct()
{
$this->missions = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFirstname(): ?string
{
return $this->firstname;
}
public function setFirstname(string $firstname): self
{
$this->firstname = $firstname;
return $this;
}
public function getLastname(): ?string
{
return $this->lastname;
}
public function setLastname(string $lastname): self
{
$this->lastname = $lastname;
return $this;
}
public function getDateOfBirth(): ?\DateTimeInterface
{
return $this->dateOfBirth;
}
public function setDateOfBirth(\DateTimeInterface $dateOfBirth): self
{
$this->dateOfBirth = $dateOfBirth;
return $this;
}
public function getCodeName(): ?string
{
return $this->codeName;
}
public function setCodeName(string $codeName): self
{
$this->codeName = $codeName;
return $this;
}
public function getNationality(): ?string
{
return $this->nationality;
}
public function setNationality(string $nationality): self
{
$this->nationality = $nationality;
return $this;
}
/**
* #return Collection<int, Mission>
*/
public function getMissions(): Collection
{
return $this->missions;
}
public function addMission(Mission $mission): self
{
if (!$this->missions->contains($mission)) {
$this->missions[] = $mission;
$mission->addContact($this);
}
return $this;
}
public function removeMission(Mission $mission): self
{
if ($this->missions->removeElement($mission)) {
$mission->removeContact($this);
}
return $this;
}
public function __toString()
{
return $this->getCodeName();
}
}
Mission.php
<?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)]
class Mission
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column()]
private ?int $id = null;
#[ORM\Column(length: 100)]
private ?string $title = null;
#[ORM\Column(type: Types::TEXT)]
private ?string $description = null;
#[ORM\Column(length: 100)]
private ?string $country = null;
#[ORM\ManyToMany(targetEntity: Agent::class, inversedBy: 'missions')]
#[ORM\JoinColumn(nullable: false, onDelete: 'cascade')]
private Collection $agent;
#[ORM\ManyToMany(targetEntity: Contact::class, inversedBy: 'missions')]
#[ORM\JoinColumn(nullable: false, onDelete: 'cascade')]
private Collection $contact;
#[ORM\ManyToMany(targetEntity: Target::class, inversedBy: 'missions')]
#[ORM\JoinColumn(nullable: false, onDelete: 'cascade')]
private Collection $target;
#[ORM\ManyToMany(targetEntity: Hideout::class, inversedBy: 'missions')]
#[ORM\JoinColumn(nullable: false, onDelete: 'cascade')]
private Collection $hideout;
#[ORM\Column(length: 100)]
private ?string $type = null;
#[ORM\Column(length: 100)]
private ?string $status = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $startDate = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $endDate = null;
#[ORM\ManyToOne(inversedBy: 'missions')]
private ?Speciality $speciality = null;
public function __construct()
{
$this->agent = new ArrayCollection();
$this->contact = new ArrayCollection();
$this->target = new ArrayCollection();
$this->hideout = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country): self
{
$this->country = $country;
return $this;
}
/**
* #return Collection<int, Agent>
*/
public function getAgent(): Collection
{
return $this->agent;
}
public function addAgent(Agent $agent): self
{
if (!$this->agent->contains($agent)) {
$this->agent[] = $agent;
}
return $this;
}
public function removeAgent(Agent $agent): self
{
$this->agent->removeElement($agent);
return $this;
}
/**
* #return Collection<int, Contact>
*/
public function getContact(): Collection
{
return $this->contact;
}
public function addContact(Contact $contact): self
{
if (!$this->contact->contains($contact)) {
$this->contact[] = $contact;
}
return $this;
}
public function removeContact(Contact $contact): self
{
$this->contact->removeElement($contact);
return $this;
}
/**
* #return Collection<int, Target>
*/
public function getTarget(): Collection
{
return $this->target;
}
public function addTarget(Target $target): self
{
if (!$this->target->contains($target)) {
$this->target[] = $target;
}
return $this;
}
public function removeTarget(Target $target): self
{
$this->target->removeElement($target);
return $this;
}
/**
* #return Collection<int, Hideout>
*/
public function getHideout(): Collection
{
return $this->hideout;
}
public function addHideout(Hideout $hideout): self
{
if (!$this->hideout->contains($hideout)) {
$this->hideout[] = $hideout;
}
return $this;
}
public function removeHideout(Hideout $hideout): self
{
$this->hideout->removeElement($hideout);
return $this;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(string $type): self
{
$this->type = $type;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getStartDate(): ?\DateTimeInterface
{
return $this->startDate;
}
public function setStartDate(\DateTimeInterface $startDate): self
{
$this->startDate = $startDate;
return $this;
}
public function getEndDate(): ?\DateTimeInterface
{
return $this->endDate;
}
public function setEndDate(\DateTimeInterface $endDate): self
{
$this->endDate = $endDate;
return $this;
}
public function getSpeciality(): ?Speciality
{
return $this->speciality;
}
public function setSpeciality(?Speciality $speciality): self
{
$this->speciality = $speciality;
return $this;
}

$user->addTag() adding a doublon on my tag database on a many to many relation

I develop a site where an user can add a tag on his profile.
So to make this feature, I add this script on my controller:
if ($formTag->isSubmitted() && $formTag->isValid()) {
$dataFormTag = $formTag->getData();
$userTagsAssocied = $user->getTags();
$userTagsAssociedArray = $userTagsAssocied->toArray();
if (in_array($dataFormTag->getName(), $userTagsAssociedArray)) {
$this->addFlash('danger', 'Vous avez deja le tag ' . $dataFormTag->getName() . ' associé à votre profil');
return $this->redirectToRoute('app_user_profil');
}
$user->addTag($dataFormTag);
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->addFlash('success', 'Tag ' . $dataFormTag->getName() . ' bien lier à votre profil');
return $this->redirectToRoute('app_user_profil');
}
That work ! but the problem, is that duplicate the tag in my tag database.
An user who's add the tag FPS on his profil, the tag gonna be duplicate on bdd:
I add one of the 5 tag n my profil ( for exemple FPS)
The tag FPS is correctly added on my profil
But now, the Tag FPS is duplicate on my database and I show him to my select input..
here 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\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`')]
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;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $discord;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $twitter;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $instagram;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $tiktok;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $facebook;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $twitch;
#[ORM\Column(type: 'string', length:255)]
private $img;
#[ORM\Column(type: 'string', length: 255)]
private $pseudo;
#[ORM\Column(type:'text', nullable: true)]
private $description;
#[ORM\Column(type: 'datetime')]
private $created_time;
#[ORM\Column(type: 'datetime')]
private $updated_time;
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'users', cascade: ['persist'])]
private $tags;
#[ORM\ManyToMany(targetEntity: Games::class, inversedBy: 'users', cascade: ['persist'])]
private $games;
#[ORM\Column(type: 'boolean')]
private $isVerified = false;
public function __construct()
{
$this->tags = new ArrayCollection();
$this->games = new ArrayCollection();
$this->created_time = new \DateTime();
$this->updated_time = new \DateTime();
}
public function __toString()
{
return $this->pseudo;
}
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;
}
public function getDiscord(): ?string
{
return $this->discord;
}
public function setDiscord(?string $discord): self
{
$this->discord = $discord;
return $this;
}
public function getTwitter(): ?string
{
return $this->twitter;
}
public function setTwitter(?string $twitter): self
{
$this->twitter = $twitter;
return $this;
}
public function getInstagram(): ?string
{
return $this->instagram;
}
public function setInstagram(?string $instagram): self
{
$this->instagram = $instagram;
return $this;
}
public function getTiktok(): ?string
{
return $this->tiktok;
}
public function setTiktok(?string $tiktok): self
{
$this->tiktok = $tiktok;
return $this;
}
public function getFacebook(): ?string
{
return $this->facebook;
}
public function setFacebook(?string $facebook): self
{
$this->facebook = $facebook;
return $this;
}
public function getTwitch(): ?string
{
return $this->twitch;
}
public function setTwitch(?string $twitch): self
{
$this->twitch = $twitch;
return $this;
}
public function getImg(): ?string
{
return $this->img;
}
public function setImg(string $img): self
{
$this->img = $img;
return $this;
}
public function getPseudo(): ?string
{
return $this->pseudo;
}
public function setPseudo(string $pseudo): self
{
$this->pseudo = $pseudo;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getCreatedTime(): ?\DateTimeInterface
{
return $this->created_time;
}
public function setCreatedTime(\DateTimeInterface $created_time): self
{
$this->created_time = $created_time;
return $this;
}
public function getUpdatedTime(): ?\DateTimeInterface
{
return $this->updated_time;
}
public function setUpdatedTime(\DateTimeInterface $updated_time): self
{
$this->updated_time = $updated_time;
return $this;
}
/**
* #return Collection<int, Tag>
*/
public function getTags(): Collection
{
return $this->tags;
}
public function addTag(Tag $tag): self
{
if (!$this->tags->contains($tag)) {
$this->tags[] = $tag;
}
return $this;
}
public function removeTag(Tag $tag): self
{
$this->tags->removeElement($tag);
return $this;
}
/**
* #return Collection<int, Games>
*/
public function getGames(): Collection
{
return $this->games;
}
public function addGame(Games $game): self
{
if (!$this->games->contains($game)) {
$this->games[] = $game;
}
return $this;
}
public function removeGame(Games $game): self
{
$this->games->removeElement($game);
return $this;
}
public function getIsVerified(): ?bool
{
return $this->isVerified;
}
public function setIsVerified(bool $isVerified): self
{
$this->isVerified = $isVerified;
return $this;
}
}
And here my 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;
#[ORM\Entity(repositoryClass: TagRepository::class)]
class Tag
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string', length: 255)]
private $name;
#[ORM\Column(type: 'datetime')]
private $created_time;
#[ORM\Column(type: 'datetime')]
private $updated_time;
#[ORM\ManyToMany(targetEntity: User::class, mappedBy: 'tags',cascade: ['persist'])]
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
$this->created_time = new \DateTime();
$this->updated_time = new \DateTime();
}
public function __toString()
{
return $this->name;
}
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 getCreatedTime(): ?\DateTimeInterface
{
return $this->created_time;
}
public function setCreatedTime(\DateTimeInterface $created_time): self
{
$this->created_time = $created_time;
return $this;
}
public function getUpdatedTime(): ?\DateTimeInterface
{
return $this->updated_time;
}
public function setUpdatedTime(\DateTimeInterface $updated_time): self
{
$this->updated_time = $updated_time;
return $this;
}
/**
* #return Collection<int, User>
*/
public function getUsers(): Collection
{
return $this->users;
}
public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
$user->addTag($this);
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->users->removeElement($user)) {
$user->removeTag($this);
}
return $this;
}
}
You can check if the tag exists before persisting it:
if ($formTag->isSubmitted() && $formTag->isValid()) {
$dataFormTag = $formTag->getData();
$userTagsAssocied = $user->getTags();
$userTagsAssociedArray = $userTagsAssocied->toArray();
if (in_array($dataFormTag->getName(), $userTagsAssociedArray)) {
$this->addFlash('danger', 'Vous avez deja le tag ' . $dataFormTag->getName() . ' associé à votre profil');
return $this->redirectToRoute('app_user_profil');
}
$existingTag = $tagRepository->findOneByName($dataFormTag->getName());
if ($existingTag !== null) {
$user->addTag($existingTag);
} else {
$user->addTag($dataFormTag);
}
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->addFlash('success', 'Tag ' . $dataFormTag->getName() . ' bien lier à votre profil');
return $this->redirectToRoute('app_user_profil');
}
To prevent any duplicates because of case issue you could write your own findByName method in your repository
// TagRepository.php
public function findOneByName($name) {
return $this->createQueryBuilder('t')
->where('upper(t.name) = upper(:name)')
->setParameter('name', $name)
->getQuery()
->getOneOrNullResult();
}

Categories