Hello I'm trying to make a file upload with a oneToMany relation between an Annonce and some images; So an Annonce can contain 0 or more images and an image is still attached to an Annonce. I think everything is ok with my entities but I get this error when I submit the form.
> Annonce.php
<?php
namespace MDB\AnnonceBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Annonce
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="MDB\AnnonceBundle\Entity\AnnonceRepository")
*/
class Annonce {
public function __construct() {
$this->date = new \Datetime();
$this->categories = new ArrayCollection();
$this->images= new ArrayCollection();
}
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=255)
*/
private $titre;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #var float
*
* #ORM\Column(name="prix", type="float")
*/
private $prix;
/**
* #ORM\ManyToOne(targetEntity="MDB\AdresseBundle\Entity\Ville", inversedBy="annonces")
*/
private $ville;
/**
* #ORM\ManyToMany(targetEntity="MDB\AnnonceBundle\Entity\Category", cascade={"persist"})
*/
private $categories;
/**
* #ORM\ManyToMany(targetEntity="MDB\UserBundle\Entity\User")
*
*/
private $wishlist;
/**
* #var boolean
*
* #ORM\Column(name="telAppear", type="boolean")
*/
private $telAppear;
/**
* #ORM\ManyToOne(targetEntity="MDB\UserBundle\Entity\User", inversedBy="annonces")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #ORM\OneToMany(targetEntity="MDB\PlatformBundle\Entity\Image", mappedBy="annonce")
*/
private $images;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set titre
*
* #param string $titre
* #return Annonce
*/
public function setTitre($titre) {
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre() {
return $this->titre;
}
/**
* Set description
*
* #param string $description
* #return Annonce
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription() {
return $this->description;
}
/**
* Set prix
*
* #param float $prix
* #return Annonce
*/
public function setPrix($prix) {
$this->prix = $prix;
return $this;
}
/**
* Get prix
*
* #return float
*/
public function getPrix() {
return $this->prix;
}
public function addCategory(Category $category) {
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->categories[] = $category;
return $this;
}
public function removeCategory(Category $category) {
$this->categories->removeElement($category);
}
public function getCategories() {
return $this->categories;
}
public function getDate() {
return $this->date;
}
public function setDate($date) {
$this->date = $date;
}
public function getWishlist() {
return $this->wishlist;
}
public function setWishlist($wishlist) {
$this->wishlist = $wishlist;
}
public function getVille() {
return $this->ville;
}
public function setVille($ville) {
$this->ville = $ville;
}
public function getTelAppear() {
return $this->telAppear;
}
public function setTelAppear($telAppear) {
$this->telAppear = $telAppear;
}
public function getUser() {
return $this->user;
}
public function setUser($user) {
$this->user = $user;
}
public function addImage(Image $image) {
$this->images[] = $image;
$image->setUser($this);
return $this;
}
public function removeImage(Image $image) {
$this->images->removeElement($image);
}
public function getImages() {
return $this->images;
}
}
Image.php
<?php
namespace MDB\PlatformBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Image
*
* #ORM\Table()
* #ORM\Entity
*/
class Image {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $path;
/**
* #var string
*
* #ORM\Column(name="alt", type="string", length=255)
*/
private $alt;
/**
* #ORM\ManyToOne(targetEntity="MDB\AnnonceBundle\Entity\Annonce", inversedBy="images")
* #ORM\JoinColumn(nullable=true)
*/
private $annonce;
/**
* #Assert\File(maxSize="6000000")
*/
public $file;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set url
*
* #param string $url
* #return Image
*/
public function setUrl($url) {
$this->url = $url;
return $this;
}
/**
* Get url
*
* #return string
*/
public function getUrl() {
return $this->url;
}
/**
* Set alt
*
* #param string $alt
* #return Image
*/
public function setAlt($alt) {
$this->alt = $alt;
return $this;
}
/**
* Get alt
*
* #return string
*/
public function getAlt() {
return $this->alt;
}
public function getAnnonce() {
return $this->annonce;
}
public function setAnnonce($annonce) {
$this->annonce = $annonce;
}
public function getAbsolutePath() {
return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path;
}
public function getWebPath() {
return null === $this->path ? null : $this->getUploadDir() . '/' . $this->path;
}
protected function getUploadRootDir() {
// le chemin absolu du répertoire où les documents uploadés doivent être sauvegardés
return __DIR__ . '/../../../../web/' . $this->getUploadDir();
}
protected function getUploadDir() {
// on se débarrasse de « __DIR__ » afin de ne pas avoir de problème lorsqu'on affiche
// le document/image dans la vue.
return 'uploads/documents';
}
public function getFile() {
return $this->file;
}
public function setFile($file) {
$this->file = $file;
}
}
AnnonceType.php
<?php
namespace MDB\AnnonceBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class AnnonceType extends AbstractType {
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('titre')
->add('description')
->add('date')
->add('prix')
->add('telAppear', 'checkbox', array('required' => false))
->add('ville', new \MDB\AdresseBundle\Form\VilleType(), array('required' => true))
->add('categories')
->add('wishlist')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'MDB\AnnonceBundle\Entity\Annonce'
));
}
/**
* #return string
*/
public function getName() {
return 'mdb_annoncebundle_annonce';
}
}
AnnonceSellType.php (who herit of AnnonceType.php)
<?php
namespace MDB\AnnonceBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use \MDB\PlatformBundle\Form\ImageType;
class AnnonceSellType extends AbstractType {
private $arrayListCat;
public function __construct($arrayListCat) {
$this->arrayListCat = $arrayListCat;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->remove('wishlist')
->remove('date')
->remove('categories')
->add('titre')
->add('description', 'textarea')
->add('prix')
->add('categories', 'choice', array(
'choices' => $this->arrayListCat,
'multiple' => true,
'mapped' => false,
))
->add('images', new ImageType())
;
}
/**
* #return string
*/
public function getName() {
return 'mdb_annoncebundle_annonce_sell';
}
public function getParent() {
return new AnnonceType();
}
}
ImageType.php
<?php
namespace MDB\PlatformBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ImageType extends AbstractType {
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('file')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'MDB\PlatformBundle\Entity\Image'
));
}
/**
* #return string
*/
public function getName() {
return 'mdb_platformbundle_image';
}
}
And I have the following error at the form submit :
Neither the property "images" nor one of the methods
"addImag()"/"removeImag()", "addImage()"/"removeImage()",
"setImages()", "images()", "__set()" or "__call()" exist and have
public access in class "MDB\AnnonceBundle\Entity\Annonce".
I don't understand cause these getter exist in my entity. Anyone have an idea?
Thanks
This error was logic. Just use a collection field type solved the problem
Related
So here is my concern. I have a "Child" entity that contains $services and $users linked in ManyToMany.
The goal in my application is to be able to assign a child to a user of my service.
So, depending on the service I'm in, I won't have the same choice of users to assign.
In my ChildType, in my "users" field, I added a key ''query_builder'' that will retrieve only the users concerned.
My ChildType.php
<?php
namespace App\Form;
use App\Entity\Child;
use App\Entity\Service;
use App\Entity\Sexe;
use App\Entity\User;
use App\Repository\ServiceRepository;
use App\Repository\UserRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Security;
class ChildType extends AbstractType
{
/** #var User $user */
private $user;
private $serviceRepository;
private $authorization;
public function __construct(Security $security, AuthorizationCheckerInterface $authorization, ServiceRepository $serviceRepository)
{
$this->user = $security->getUser();
$this->authorization = $authorization;
$this->serviceRepository = $serviceRepository;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** #var Service $service */
$service = $this->user->getService();
$builder
->add('nom', TextType::class)
->add('prenom', TextType::class)
->add('sexe', EntityType::class, [
'class' => Sexe::class,
])
->add('dateDeNaissance', DateType::class, [
'widget' => 'single_text'
])
->add('lieuDeNaissance', TextType::class)
->add('nationalite', TextType::class)
->add('dateElaborationPpe', DateType::class, [
'widget' => 'single_text'
]);
if ($this->authorization->isGranted('ROLE_ADMIN')) {
$builder->add('users', EntityType::class, [
'class' => User::class,
'label' => 'Affecter à un utilisateur',
'query_builder' => function (UserRepository $userRepository) use ($service) {
return $userRepository->findByCurrentService($service);
},
'multiple' => true,
'expanded' => true,
]);
$builder->add('services', EntityType::class, [
'class' => Service::class,
'label' => 'Affecter à un service',
'choices' => $this->serviceRepository->findByDepartement($service->getDepartement()),
'choice_attr' => function($key, $val, $index) use ($service) {
return([]);
return $key->getCategorie()->getId() === $service->getCategorie()->getId() ?
['disabled' => 'disabled'] :
[];
},
'multiple' => true,
'expanded' => true,
]);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Child::class,
]);
}
}
The problem:
Let's assume that my Service #1 has several users from Service #1 to my child. When I assign in my Service #2 users from Service #2 to the child, I have my 2 new users from Service #2 in the database, but on the other hand, those from Service #1 have been deleted, which is not the desired behavior.
I've been looking for a topic for almost 2 hours, and I can't find an answer, so if it's a duplicate, really sorry.
edit method in my controller:
/**
* #Route("/{id}/edit", name="child_edit", methods={"GET","POST"})
*/
public function edit(Request $request, Child $child): Response
{
$this->denyAccessUnlessGranted("edit", $child);
$form = $this->createForm(ChildType::class, $child);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('child_show', ['id' => $child->getId()]);
}
return $this->render('child/edit.html.twig', [
'child' => $child,
'form' => $form->createView(),
]);
}
User.php:
<?php
namespace App\Entity;
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 App\Entity\Service;
use App\Traits\BlameableEntity;
use App\Traits\TimestampableEntity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
*
*/
class User implements UserInterface, \Serializable
{
use BlameableEntity;
use TimestampableEntity;
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string")
* #Assert\NotBlank()
*/
private $fullName;
/**
* #var string
*
* #ORM\Column(type="string", unique=true)
* #Assert\NotBlank()
* #Assert\Length(min=2, max=50)
*/
private $username;
/**
* #var string
*
* #ORM\Column(type="string", unique=true)
* #Assert\Email()
*/
private $email;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $password;
/**
* #var array
*
* #ORM\Column(type="json")
*/
private $roles = [];
/**
* #var \DateTime
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $lastLogin;
/**
* #var \DateTime
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $secondToLastLogin;
/**
* #ORM\ManyToOne(targetEntity="Service", inversedBy="users")
*/
private $service;
/**
* #ORM\ManyToMany(targetEntity="Child", mappedBy="users")
*/
private $children;
public function __construct()
{
$this->children = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFullName(): ?string
{
return $this->fullName;
}
public function setFullName(string $fullName): self
{
$this->fullName = $fullName;
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;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* Returns the roles or permissions granted to the user for security.
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantees that a user always has at least one role for security
if (empty($roles)) {
$roles[] = 'ROLE_USER';
}
return array_unique($roles);
}
public function setRoles(array $roles): void
{
$this->roles = $roles;
}
/**
* Get the value of lastLogin
*
* #return \DateTime
*/
public function getLastLogin()
{
return $this->lastLogin;
}
/**
* Set the value of lastLogin
*
* #param \DateTime $lastLogin
*
* #return self
*/
public function setLastLogin(\DateTime $lastLogin)
{
$this->lastLogin = $lastLogin;
return $this;
}
/**
* Get the value of secondToLastLogin
*
* #return \DateTime
*/
public function getSecondToLastLogin()
{
return $this->secondToLastLogin;
}
/**
* Set the value of secondToLastLogin
*
* #param \DateTime $secondToLastLogin
*
* #return self
*/
public function setSecondToLastLogin(\DateTime $secondToLastLogin)
{
$this->secondToLastLogin = $secondToLastLogin;
return $this;
}
/**
*
* {#inheritdoc}
*/
public function getSalt(): ?string
{
return null;
}
/**
* Removes sensitive data from the user.
*
* {#inheritdoc}
*/
public function eraseCredentials(): void
{
// if you had a plainPassword property, you'd nullify it here
// $this->plainPassword = null;
}
/**
* {#inheritdoc}
*/
public function serialize(): string
{
// add $this->salt too if you don't use Bcrypt or Argon2i
return serialize([$this->id, $this->username, $this->password]);
}
/**
* {#inheritdoc}
*/
public function unserialize($serialized): void
{
// add $this->salt too if you don't use Bcrypt or Argon2i
[$this->id, $this->username, $this->password] = unserialize($serialized, ['allowed_classes' => false]);
}
/**
* Get the value of service
*/
public function getService()
{
return $this->service;
}
/**
* Set the value of service
*
* #return self
*/
public function setService($service)
{
$this->service = $service;
return $this;
}
public function hasService(): bool
{
return !empty($this->getService());
}
/**
* #return Collection|Child[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function addChild(Child $child): self
{
if (!$this->children->contains($child)) {
$this->children[] = $child;
$child->addUser($this);
}
return $this;
}
public function removeChild(Child $child): self
{
if ($this->children->removeElement($child)) {
$child->removeUser($this);
}
return $this;
}
public function __toString()
{
return $this->getFullName();
}
}
Service.php :
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Repository\ServiceRepository;
use App\Entity\Categorie;
use App\Entity\Departement;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* #ORM\Entity(repositoryClass=ServiceRepository::class)
*/
class Service
{
public const ASE = 'ASE';
public const MDPH = 'MDPH';
public const E_N = 'Éducation Nationale';
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $nom;
/**
* #var Departement
*
* #ORM\ManyToOne(targetEntity="Departement")
* #ORM\JoinColumn(nullable=false)
*/
private $departement;
/**
* #var Categorie
*
* #ORM\ManyToOne(targetEntity="Categorie")
* #ORM\JoinColumn(nullable=false)
*/
private $categorie;
/**
* #ORM\OneToMany(targetEntity="User", mappedBy="service")
*/
private $users;
/**
* #ORM\ManyToMany(targetEntity="Child", mappedBy="services")
*/
private $children;
/**
* #ORM\ManyToMany(targetEntity="Element", mappedBy="services")
*/
private $elements;
public function __construct()
{
$this->users = new ArrayCollection();
$this->children = new ArrayCollection();
$this->elements = new ArrayCollection();
}
/**
* Get the value of id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set the value of id
*
* #param int $id
*
* #return self
*/
public function setId(int $id)
{
$this->id = $id;
return $this;
}
/**
* Get the value of nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set the value of nom
*
* #param string $nom
*
* #return self
*/
public function setNom(string $nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get the value of departement
*
* #return Departement
*/
public function getDepartement()
{
return $this->departement;
}
/**
* Set the value of departement
*
* #param Departement $departement
*
* #return self
*/
public function setDepartement(Departement $departement)
{
$this->departement = $departement;
return $this;
}
/**
* Get the value of categorie
*
* #return Categorie
*/
public function getCategorie()
{
return $this->categorie;
}
/**
* Set the value of categorie
*
* #param Categorie $categorie
*
* #return self
*/
public function setCategorie(Categorie $categorie)
{
$this->categorie = $categorie;
return $this;
}
/**
* #return Collection|Users[]
*/
public function getUsers(): Collection
{
return $this->users;
}
public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
$user->setService($this);
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->users->removeElement($user)) {
// set the owning side to null (unless already changed)
if ($user->getService() === $this) {
$user->setService(null);
}
}
return $this;
}
/**
* #return Collection|Children[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function addChild(Child $child): self
{
if (!$this->children->contains($child)) {
$this->children[] = $child;
$child->addService($this);
}
return $this;
}
public function removeChild(Child $child): self
{
if ($this->children->removeElement($child)) {
$child->removeService($this);
}
return $this;
}
/**
* #return Collection|Elements[]
*/
public function getElements(): Collection
{
return $this->elements;
}
public function addElements(Element $element): self
{
if (!$this->children->contains($element)) {
$this->elements[] = $element;
$element->addService($this);
}
return $this;
}
public function removeElement(Element $element): self
{
if ($this->elements->removeElement($element)) {
$element->removeService($this);
}
return $this;
}
public function __toString()
{
return $this->getNom();
}
}
Child.php :
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\Service;
use App\Entity\Sexe;
use App\Entity\User;
use DateTime;
use App\Repository\ChildRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use App\Traits\TimestampableEntity;
use App\Traits\BlameableEntity;
/**
* #ORM\Entity(repositoryClass=ChildRepository::class)
*/
class Child
{
use BlameableEntity;
use TimestampableEntity;
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $nom;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $prenom;
/**
* #var Sexe
*
* #ORM\ManyToOne(targetEntity="Sexe")
*/
private $sexe;
/**
* #var date
*
* #ORM\Column(type="date")
*/
private $dateDeNaissance;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $lieuDeNaissance;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $nationalite;
/**
* #var date
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $dateElaborationPpe;
/**
* #var Service[]|Collection
*
* #ORM\ManyToMany(targetEntity="Service", inversedBy="children")
*/
private $services;
/**
* #var User[]|Collection
*
* #ORM\ManyToMany(targetEntity="User", inversedBy="children")
*/
private $users;
/**
* #var Element[]|Collection
*
* #ORM\OneToMany(targetEntity="Element", mappedBy="child")
*/
private $elements;
public function __construct()
{
$this->services = new ArrayCollection();
$this->users = new ArrayCollection();
$this->elements = new ArrayCollection();
}
/**
* Get the value of id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set the value of id
*
* #param int $id
*
* #return self
*/
public function setId(int $id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return string
*/
public function getNumDossier()
{
return str_pad($this->id, 6, "0", STR_PAD_LEFT);
}
/**
* Get the value of nom
*/
public function getNom()
{
return $this->nom;
}
/**
* Set the value of nom
*
* #return self
*/
public function setNom(string $nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get the value of prenom
*/
public function getPrenom()
{
return $this->prenom;
}
/**
* Set the value of prenom
*
* #return self
*/
public function setPrenom(string $prenom)
{
$this->prenom = $prenom;
return $this;
}
/**
* Get the value of sexe
*
* #return Sexe
*/
public function getSexe()
{
return $this->sexe;
}
/**
* Set the value of sexe
*
* #param Sexe $sexe
*
* #return self
*/
public function setSexe(Sexe $sexe)
{
$this->sexe = $sexe;
return $this;
}
/**
* Get the value of dateDeNaissance
*/
public function getDateDeNaissance()
{
return $this->dateDeNaissance;
}
/**
* Set the value of dateDeNaissance
*
* #return self
*/
public function setDateDeNaissance(datetime $dateDeNaissance)
{
$this->dateDeNaissance = $dateDeNaissance;
return $this;
}
/**
* Get the value of lieuDeNaissance
*/
public function getLieuDeNaissance()
{
return $this->lieuDeNaissance;
}
/**
* Set the value of lieuDeNaissance
*
* #return self
*/
public function setLieuDeNaissance(string $lieuDeNaissance)
{
$this->lieuDeNaissance = $lieuDeNaissance;
return $this;
}
/**
* Get the value of nationalite
*/
public function getNationalite()
{
return $this->nationalite;
}
/**
* Set the value of nationalite
*
* #return self
*/
public function setNationalite(string $nationalite)
{
$this->nationalite = $nationalite;
return $this;
}
/**
* Get the value of dateElaborationPpe
*/
public function getDateElaborationPpe()
{
return $this->dateElaborationPpe;
}
/**
* Set the value of dateElaborationPpe
*
* #return self
*/
public function setDateElaborationPpe(datetime $dateElaborationPpe)
{
$this->dateElaborationPpe = $dateElaborationPpe;
return $this;
}
/**
* #return Collection|Service[]
*/
public function getServices(): Collection
{
return $this->services;
}
public function addService(Service $service): self
{
if (!$this->services->contains($service)) {
$this->services[] = $service;
}
return $this;
}
public function removeService(Service $service): self
{
$this->services->removeElement($service);
return $this;
}
/**
* #return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}
public function addUser(User $user): self
{
$test = 'test';
if (!$this->users->contains($user)) {
$this->users[] = $user;
}
return $this;
}
public function removeUser(User $user): self
{
$this->users->removeElement($user);
return $this;
}
public function getNbUsers()
{
return count($this->getUsers());
}
/**
* #return Collection|Element[]
*/
public function getElements(): Collection
{
return $this->elements;
}
public function addElement(Element $element): self
{
if (!$this->elements->contains($element)) {
$this->elements[] = $element;
}
return $this;
}
public function removeElement(Element $element): self
{
$this->elements->removeElement($element);
return $this;
}
public function isNotAssigned(): bool
{
return (!$this->getNbUsers());
}
public function __toString(): string
{
return $this->getNom() . ' ' . $this->getPrenom();
}
}
Thanks in advance for your help.
I am trying to upload a file with symfony. But I have an error when I send data formulaire to controller. Variable file is null and function move file don't working.
code entity (par uplaod):
<?php
namespace AppBundle\Entity;
use AppBundle\Model\CompanyInterface;
use AppBundle\Model\RecruiterInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Company.
*
* #ORM\Table(name="company")
* #ORM\Entity(repositoryClass="AppBundle\Repository\CompanyRepository")
*/
class Company implements CompanyInterface
{
/**
* #var string
*
* #ORM\Column(name="id", type="guid")
* #ORM\Id
* #ORM\GeneratedValue(strategy="UUID")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #var array
*
* #ORM\Column(name="activities", type="array")
*/
private $activities;
/**
* #var RecruiterInterface
*
* #ORM\OneToOne(targetEntity="AppBundle\Entity\Recruiter", cascade={"persist"})
*/
private $recruiter;
/**
* #var string
*
* #ORM\Column(name="path", type="string", length=255,nullable=true)
*/
private $logo;
/**
* #Assert\File(maxSize="6000000")
*/
private $file;
/**
* {#inheritdoc}
*/
public static function create(string $name, RecruiterInterface $recruiter, string $description = '', array $activities = []): CompanyInterface
{
return new self($name, $recruiter, $description, $activities);
}
/**
* {#inheritdoc}
*/
public function update(string $name, string $description, array $activities): CompanyInterface
{
$this->name = $name;
$this->description = $description;
$this->activities = $activities;
return $this;
}
/**
* {#inheritdoc}
*/
public function updateName(string $name): CompanyInterface
{
$this->name = $name;
return $this;
}
/**
* {#inheritdoc}
*/
public function getId(): string
{
return $this->id;
}
/**
* {#inheritdoc}
*/
public function getName(): ?string
{
return $this->name;
}
/**
* function setName.
*
* #param string $name
*
* #return string
*/
public function setName(string $name)
{
$this->name = $name;
return $this;
}
/**
* function setDescription.
*
* #param string $description
*
* #return string
*/
public function setDescription(string $description)
{
$this->description = $description;
return $this;
}
/**
* function setActivities.
*
* #param string $activities
*
* #return string
*/
public function setActivities(string $activities)
{
$this->activities = $activities;
return $this;
}
/**
* {#inheritdoc}
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* {#inheritdoc}
*/
public function getActivities()
{
return $this->activities;
}
/**
* {#inheritdoc}
*/
public function getRecruiter(): ?RecruiterInterface
{
return $this->recruiter;
}
/**
* #return string
*/
public function __toString()
{
return $this->name;
}
/**
* {#inheritdoc}
*/
public function updateLogo(string $logo): CompanyInterface
{
$this->logo = $logo;
return $this;
}
/**
* Get file.
*
* #return UploadedFile
*/
public function getFile()
{
return $this->file;
}
/**
* Sets file.
*
* #param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
}
/**
* Set logo.
*
* #param string $logo
*
* #return Company
*/
public function setLogo($logo)
{
$this->logo = $logo;
return $this;
}
/**
* Get logo.
*
* #return string
*/
public function getLogo()
{
return $this->logo;
}
/**
* function upload.
*/
public function upload()
{
// the file property can be empty if the field is not required
if (null === $this->getFile()) {
return;
}
$this->file->move($this->getUploadRootDir(),$this->path);
// set the path property to the filename where you've saved the file
$this->logo = $this->getFile()->getClientOriginalName();
// clean up the file property as you won't need it anymore
//$this->file = null;
}
/**
* function getUploadRootDir.
*/
protected function getUploadRootDir()
{
return __DIR__.'/../../../web/uploads';
}
}
code formType(content variable file):
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
/**
* Class CompanyType.
*/
class CompanyType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('description')
->add('activities', TextType::class)
->add('file', FileType::class)
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Company',
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return '';
}
}
code other FormTyp(I use form imbrique):
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Entity\Recruiter;
/**
* Class RecruiterType.
*/
class RecruiterType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->remove('username');
$builder->remove('plainPassword');
$builder
->add('email')
->add('lastname')
->add('firstname')
->add('phone')
->add('civility', ChoiceType::class, array(
'choices' => ['Mr' => 'Mr', 'Mrs' => 'Mrs'], 'expanded' => true, 'multiple' => false,
))
->add('company', CompanyType::class)
;
}
/**
* function get Parent Form.
*
* #return string
*/
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
/**
* name for this form.
*
* #return string
*/
public function getBlockPrefix()
{
return '';
}
/**
* name for this form.
*
* #return string
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Recruiter::class,
'allow_extra_fields' => true,
'csrf_protection' => false,
));
}
}
function post (persist object):
public function post(array $parameters, bool $submitted = true, array $options = [])
{
/** #var Recruiter $recruiter */
$recruiter = $this->formHandler->handle(
$this->userManager->createRecruiter(),
$parameters,
Request::METHOD_POST,
$submitted,
$options
);
if (false === $submitted) {
return $recruiter;
}
$recruiter->submit($parameters);
if ($recruiter->isSubmitted() && $recruiter->isValid()) {
$recruiter->getData()->setCompany($recruiter->getData()->getCompany());
$recruiter->getData()->getCompany()->upload();
$this->em->persist($recruiter->getData());
$this->em->flush();
$event = new FormEvent($recruiter, $this->request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
return $recruiter->getData();
}
return $recruiter;
}
code controller :
<?php
namespace AppBundle\Controller\Recruiter;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
use FOS\UserBundle\Event\GetResponseUserEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use AppBundle\Handler\RecruiterHandler;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use AppBundle\Entity\Recruiter;
use Symfony\Component\HttpFoundation\RedirectResponse;
use AppBundle\Util\UserManagerr;
/**
* Class RegistrationRecruiterController.
*/
class RegistrationRecruiterController extends BaseController
{
/**
* #Template()
* #Route("/register", name="register_recruiter")
*
* #param Request $request
*
* #return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function registerAction(Request $request)
{
try {
$user = new UserManagerr();
$dispatcher = $this->get('event_dispatcher');
$user = $user->createRecruiter();
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$recruiter = $this->getHandler()->post($request->request->all(), $request->isMethod(Request::METHOD_POST));
if ($recruiter instanceof Recruiter) {
$url = $this->generateUrl('fos_user_registration_check_email');
$response = new RedirectResponse($url);
return $response;
}
} catch (InvalidFormException $e) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);
return [
'form' => $e->getForm()->createView(),
'edit' => false,
'event' => $event->getResponse(),
];
}
return ['form' => $recruiter->createView()];
}
/**
* #return RecruiterHandler
*/
public function getHandler()
{
return $this->get(RecruiterHandler::class);
}
}
I use form imbriqu (form in other form) but when I send form I have all variable from object but variable file has null and function move doesn't work.
How to resolve this error please?
Thanks in advance for any help.
Change this
public function post(array $parameters, bool $submitted = true, array $options = [])
For
public function post(Request $request, bool $submitted = true, array $options = [])
[...]
$recruiter->submit($request);
[...]
Your issue is probably in the for tag, which you should declare it like:
{{ form_start(form, {'method': 'post', 'action': '', 'attr': {'class': '', 'novalidate': 'novalidate' }}) }}
Is it possible to populate collection with some default items
Say you have collection of prices, but each price can be of different type. And what I want is that collection always has some predefined (generated somehow) items?
Main entity
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\ManyToMany;
/**
* Class Stamp
* #package AppBundle\Entity
*
*
* #ORM\Entity(repositoryClass="AppBundle\Repository\StampRepository")
* #ORM\Table(name="stamp")
* #ORM\HasLifecycleCallbacks()
*/
class Stamp
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=512, nullable=true)
*/
private $title;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Price", cascade={"persist", "remove"})
* #ORM\JoinTable(name="stamps_prices",
* joinColumns={#ORM\JoinColumn(name="stamp_id", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={#ORM\JoinColumn(name="price_id", referencedColumnName="id", onDelete="CASCADE")}
* )
*/
private $prices;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #ORM\Column(type="datetime")
*/
private $updatedAt;
public function __construct()
{
$this->prices = new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* #param mixed $title
*
* #return Stamp
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* #return mixed
*/
public function getPrices()
{
return $this->prices;
}
public function addPrice(Price $price)
{
$this->prices->add($price);
}
/**
* #param mixed $prices
*
* #return Stamp
*/
public function setPrices(ArrayCollection $prices)
{
$this->prices = $prices;
return $this;
}
/**
* #return mixed
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #param mixed $createdAt
*
* #return Stamp
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return mixed
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* #param mixed $updatedAt
*
* #return Stamp
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* #ORM\PrePersist
* #ORM\PreUpdate
*/
public function updateTimestamps()
{
$this->setUpdatedAt(new \DateTime('now'));
if (null == $this->getCreatedAt()) {
$this->setCreatedAt(new \DateTime());
}
}
}
Main entity form
<?php
namespace AppBundle\Form;
use AppBundle\Entity\Stamp;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AdminStampForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', null, [
'label' => false,
'attr' => [
'id' => 'stamp-title',
'class' => 'form-control input-md',
'placeholder' => 'Enter title',
'autocomplete' => 'off'
]
])
->add('prices', CollectionType::class, [
'label' => false,
'entry_type' => AdminStampPriceForm::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Stamp::class,
]);
}
public function getName()
{
return 'app_bundle_admin_stamp_form';
}
}
Price entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Price
* #package AppBundle\Entity
*
* #ORM\Entity(repositoryClass="AppBundle\Repository\PriceRepository")
* #ORM\Table(name="price")
*/
class Price
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\PriceType")
* #ORM\JoinColumn(name="type_id", nullable=false, referencedColumnName="id")
*/
private $type;
/**
* #ORM\Column(type="string")
*/
private $value;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $city;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $issueDate;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getType()
{
return $this->type;
}
/**
* #param mixed $type
* #return Price
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* #return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* #param mixed $value
*
* #return Price
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* #return mixed
*/
public function getCity()
{
return $this->city;
}
/**
* #param mixed $city
*
* #return Price
*/
public function setCity($city)
{
$this->city = $city;
return $this;
}
/**
* #return mixed
*/
public function getIssueDate()
{
return $this->issueDate;
}
/**
* #param mixed $issueDate
*
* #return Price
*/
public function setIssueDate($issueDate)
{
$this->issueDate = $issueDate;
return $this;
}
}
PriceType Entity
<?php
namespace AppBundle\Entity;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\ORM\Mapping as ORM;
/**
* Class PriceType
* #package AppBundle\Entity
*
* #ORM\Entity(repositoryClass="AppBundle\Repository\PriceTypeRepository")
* #ORM\Table(name="price_type")
* #ORM\HasLifecycleCallbacks()
*/
class PriceType
{
const SECTION_UNUSED = 1;
const SECTION_USED = 2;
const SECTION_FDC = 3;
const SECTION_CUSTOM = 4;
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="integer")
*/
private $section;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\Column(type="boolean")
*/
private $hasCityName = false;
/**
* #ORM\Column(type="boolean")
*/
private $hasIssueDate = false;
/**
* #ORM\Column(type="boolean")
*/
private $isPredefined = false;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #ORM\Column(type="datetime")
*/
private $updatedAt;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getSection()
{
return $this->section;
}
/**
* #param mixed $section
*
* #return PriceType
*/
public function setSection($section)
{
$this->section = $section;
return $this;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*
* #return PriceType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* #return mixed
*/
public function getHasCityName()
{
return $this->hasCityName;
}
/**
* #param mixed $hasCityName
*
* #return PriceType
*/
public function setHasCityName($hasCityName)
{
$this->hasCityName = $hasCityName;
return $this;
}
/**
* #return mixed
*/
public function getHasIssueDate()
{
return $this->hasIssueDate;
}
/**
* #param mixed $hasIssueDate
*
* #return PriceType
*/
public function setHasIssueDate($hasIssueDate)
{
$this->hasIssueDate = $hasIssueDate;
return $this;
}
/**
* #return mixed
*/
public function getIsPredefined()
{
return $this->isPredefined;
}
/**
* #param mixed $isPredefined
*
* #return PriceType
*/
public function setIsPredefined($isPredefined)
{
$this->isPredefined = $isPredefined;
return $this;
}
/**
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #param \DateTime $createdAt
*
* #return PriceType
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* #param \DateTime $updatedAt
*
* #return PriceType
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* #ORM\PrePersist
* #ORM\PreUpdate
*/
public function updateTimestamps()
{
$this->setUpdatedAt(new \DateTime('now'));
if (null == $this->getCreatedAt()) {
$this->setCreatedAt(new \DateTime());
}
}
}
PriceType repository
<?php
namespace AppBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* Class PriceTypeRepository
* #package AppBundle\Entity
*/
class PriceTypeRepository extends EntityRepository
{
public function getPredefinedPriceTypes($section)
{
return $this
->createQueryBuilder('pt')
->andWhere('pt.section = :section')
->setParameter('section', $section)
->andWhere('pt.isPredefined = :isPredefined')
->setParameter('isPredefined', true)
->getQuery()
->getResult()
;
}
}
Priec form
<?php
namespace AppBundle\Form;
use AppBundle\Entity\Price;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AdminStampPriceForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('value', null, [
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Price::class,
]);
}
public function getBlockPrefix()
{
return 'app_bundle_admin_stamp_price_form';
}
}
Main entity controller newAction
/**
* #Route("/new", name="admin_stamps_new")
* #Template(engine="haml")
*/
public function newAction(Request $request)
{
$stamp = new Stamp();
$priceTypeRepo = $this->getDoctrine()->getManager()->getRepository('AppBundle:PriceType');
$priceTypes = $priceTypeRepo->getPredefinedPriceTypes(PriceType::SECTION_UNUSED);
/** #var PriceType $priceType */
foreach ($priceTypes as $priceType) {
$price = new Price();
$price->setType($priceType->getId());
$stamp->addPrice($price);
}
$form = $this->createForm(AdminStampForm::class, $stamp);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** #var Stamp $stamp */
$stamp = $form->getData();
$user = $this->getUser();
$stamp->setUser($user);
$stamp->setCountry($user->getAdminConfig()->getCountry());
$em = $this->getDoctrine()->getManager();
$em->persist($stamp);
$em->flush();
$this->addFlash('success', 'Successfully added a new stamp!');
return $this->redirectToRoute('admin_stamps_list');
}
return [
'form' => $form->createView(),
];
}
So I tried to populate Stamp entity itself. But what I actually need is to have 4 separate field sets of prices (each field set for a price type). And (and) to have some predefined $priceType->isPredefined() prices to be there. I'm not sure if you understand correctly what I'm trying to say. So I will answer all upcoming questions.
im new with symfony and i work with Symfony 2.7 and wamp server. I try to implement the upload method following the Symfony doc/cookbook.
Here is my entity:
<?php
namespace NoticiaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraint as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Imagem
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="NoticiaBundle\Repository\ImagemRepository")
* #ORM\HasLifecycleCallbacks
*/
class Imagem
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
public $path;
/**
* #ORM\OneToMany(targetEntity="Noticia", mappedBy="imagem")
*/
private $noticias = array();
public function __construct()
{
$this->noticias = new ArrayCollection();
}
public $file;
public function getUploadRootDir()
{
return __dir__.'/../../../../web/uploads';
}
public function getAbsolutePath()
{
return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path;
}
/**
* #ORM\Prepersist()
* #ORM\Preupdate()
*/
public function preUpload()
{
$this->tempFile = $this->getAbsolutePath();
$this->oldFile = $this->getPath();
if(null !== $this->file) $this->path = sha1(uniqid(mt_rand(),true)).'.'.$this->file->guessExtension();
}
/**
* #ORM\Postpersist()
* #ORM\Postupdate()
*/
public function upload()
{
if(null !==$this->file){
$this->file->move($this->getUploadRootDir(),$this->path);
unset($this->file);
if($this->oldFile !==null) unlink($this->tempFile);
}
}
/**
* #ORM\PreRemove()
*/
public function preRemoveUpload()
{
$this->tempFile = $this->getAbsolutePath();
}
/**
* #ORM\PostRemove()
*/
public function removeUpload()
{
if(file_exists($this->tempFile)) unlink($this->tempFile);
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function getPath()
{
return $this->path;
}
public function getName()
{
return $this->name;
}
}
My entity whith foreign key imagem
<?php
namespace NoticiaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Noticia
*
* #ORM\Table(name="NOTICIA")
* #ORM\Entity(repositoryClass="NoticiaBundle\Repository\NoticiaRepository")
* #ORM\HasLifecycleCallbacks
*/
class Noticia
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titulo", type="string", length=255)
*/
private $titulo;
/**
* #var string
*
* #ORM\Column(name="noticia", type="string", length=255)
*/
private $noticia;
/**
* #ORM\ManyToOne(targetEntity="Imagem", cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $imagem;
/**
* #ORM\ManyToOne(targetEntity="Categoria", inversedBy="noticias")
* #ORM\JoinColumn(name="categoria_id", referencedColumnName="id")
*/
private $categoria;
/**
* #ORM\OneToMany(targetEntity="Comentario", mappedBy="noticia")
*/
private $comentarios = array();
public function __construct()
{
$this->comentarios = new ArrayCollection();
$this->setDtCadastro(new \DateTime());
$this->setDtAtualizacao(new \DateTime());
}
/**
* #var \DateTime
*
* #ORM\Column(name="dt_cadastro", type="datetime")
*/
private $dtCadastro;
/**
* #var \DateTime
*
* #ORM\Column(name="dt_atualizacao", type="datetime")
*/
private $dtAtualizacao;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set titulo
*
* #param string $titulo
* #return Noticia
*/
public function setTitulo($titulo)
{
$this->titulo = $titulo;
return $this;
}
/**
* Get titulo
*
* #return string
*/
public function getTitulo()
{
return $this->titulo;
}
/**
* Set noticia
*
* #param string $noticia
* #return Noticia
*/
public function setNoticia($noticia)
{
$this->noticia = $noticia;
return $this;
}
/**
* Get noticia
*
* #return string
*/
public function getNoticia()
{
return $this->noticia;
}
/**
* Set imagem
*
* #param string $imagem
* #return Noticia
*/
public function setImagem($imagem)
{
$this->imagem = $imagem;
return $this;
}
/**
* Get imagem
*
* #return string
*/
public function getImagem()
{
return $this->imagem;
}
/**
* Set categoria
*
* #param string $categoria
* #return Noticia
*/
public function setCategoria($categoria)
{
$this->categoria = $categoria;
return $this;
}
/**
* Get categoria
*
* #return string
*/
public function getCategoria()
{
return $this->categoria;
}
public function addComentario(Comentario $comentario)
{
$this->comentarios[] = $comentario;
return $this;
}
public function getComentarios()
{
return $this->comentarios;
}
/**
* Set dtCadastro
*
* #param \DateTime $dtCadastro
* #return Noticia
*/
public function setDtCadastro($dtCadastro)
{
$this->dtCadastro = $dtCadastro;
return $this;
}
/**
* Get dtCadastro
*
* #return \DateTime
*/
public function getDtCadastro()
{
return $this->dtCadastro;
}
/**
* Set dtAtualizacao
*
* #param \DateTime $dtAtualizacao
* #return Noticia
*/
public function setDtAtualizacao($dtAtualizacao)
{
$this->dtAtualizacao = $dtAtualizacao;
return $this;
}
/**
* Get dtAtualizacao
*
* #return \DateTime
*/
public function getdtAtualizacao()
{
return $this->dtAtualizacao;
}
/**
* #ORM\PreUpdate
*/
public function setDtAtualizacaoValue()
{
$this->setDtAtualizacao(new \DateTime());
}
/**
* Remove comentarios
*
* #param \NoticiaBundle\Entity\Comentario $comentarios
*/
public function removeComentario(\NoticiaBundle\Entity\Comentario $comentarios)
{
$this->comentarios->removeElement($comentarios);
}
}
my imagem form type
<?php
namespace NoticiaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ImagemType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file','file',array('required' => false));
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'NoticiaBundle\Entity\Imagem'
));
}
/**
* #return string
*/
public function getName()
{
return 'noticiabundle_imagem';
}
}
Noticia FormType
<?php
namespace NoticiaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use NoticiaBundle\Form\ImagemType;
class NoticiaType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('titulo',null, array('attr' => array('class' => 'form-control'),
'label_attr' => array('class' => 'control-label col-lg-2')
))
->add('imagem', new ImagemType(),
array('label_attr' => array('class' => 'control-label col-lg-2')
))
->add('noticia','textarea', array('attr' => array('class' => 'form-control', 'rows' => 15),
'label_attr' => array('class' => 'control-label col-lg-2')
))
->add('categoria', 'entity', array('attr' => array('class' => 'form-control'),
'label_attr' => array('class' => 'control-label col-lg-2'),
'class' => 'NoticiaBundle:Categoria',
'property' => 'nome',
'placeholder' => 'Escolha...',
))
->add('salvar', 'submit', array('attr' => array('class' => 'btn btn-primary pull-right')));
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'NoticiaBundle\Entity\Noticia'
));
}
/**
* #return string
*/
public function getName()
{
return 'noticiabundle_noticia';
}
}
And the controler function to persist Noticias and imagens(upload files)
/**
* Add new Noticia.
*
* #Route("/noticia/novo", name="nova_noticia")
* #Template()
*/
public function novoAction(Request $request)
{
$form = $this->createForm(new NoticiaType(), new Noticia());
$form->handleRequest($request);
if ($form->isValid()) {
$noticia = $form->getData();
$noticia->setLogin($_SESSION['colaborador_login']);
$noticiaRepository = $this->getDoctrine()->getRepository('NoticiaBundle:Noticia');
try {
$noticiaRepository->novo($noticia);
$this->get('session')->getFlashBag()
->add('success', 'Iserido com sucesso!');
return $this->redirect($this->generateUrl('noticias_index'));
} catch (\Exception $e) {
$this->get('session')->getFlashBag()->add(
'danger', $e->getMessage()
);
}
}
return $this->render("NoticiaBundle:Noticia:formulario.html.twig",
array('form' => $form->createView()));
}
I change my entity upload file and now he is saving the right path, but the file is bot saving into the project directory
There is no easy way to test your code but just looking at it, the most obvious issue I see is that you don't call the function preUpload before saving the file.
You may need the following annotation for the preUpload function.
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
i'm trying to make a multiple upload file on an entity with the vlabsmediaBundle.
So i have an advert who can have many images but each can be linked with only one advert.
I followed the tutorial(tuto) of the bundle but get an error.
Here:
Entity Image.php
namespace MDB\PlatformBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Vlabs\MediaBundle\Entity\BaseFile as VlabsFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Image
*
* #ORM\Table()
* #ORM\Entity
*/
class Image extends VlabsFile {
/**
* #var string
*
* #ORM\Column(name="url", type="string", length=255)
*/
private $url;
/**
* #var string
*
* #ORM\Column(name="alt", type="string", length=255)
*/
private $alt;
/**
* #ORM\ManyToOne(targetEntity="MDB\AnnonceBundle\Entity\Annonce", inversedBy="images")
* #ORM\JoinColumn(nullable=true)
*/
private $annonce;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set url
*
* #param string $url
* #return Image
*/
public function setUrl($url) {
$this->url = $url;
return $this;
}
/**
* Get url
*
* #return string
*/
public function getUrl() {
return $this->url;
}
/**
* Set alt
*
* #param string $alt
* #return Image
*/
public function setAlt($alt) {
$this->alt = $alt;
return $this;
}
/**
* Get alt
*
* #return string
*/
public function getAlt() {
return $this->alt;
}
public function getAnnonce() {
return $this->annonce;
}
public function setAnnonce($annonce) {
$this->annonce = $annonce;
}
/**
* #var string $path
*
* #ORM\Column(name="path", type="string", length=255)
* #Assert\Image()
*/
private $path;
/**
* Set path
*
* #param string $path
* #return Image
*/
public function setPath($path) {
$this->path = $path;
return $this;
}
/**
/**
* Get path
*
* #return string
*/
public function getPath() {
return $this->path;
}
}
Annonce.php (advert enity)
<?php
namespace MDB\AnnonceBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Vlabs\MediaBundle\Annotation\Vlabs;
/**
* Annonce
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="MDB\AnnonceBundle\Entity\AnnonceRepository")
*/
class Annonce {
public function __construct() {
$this->date = new \Datetime();
$this->categories = new ArrayCollection();
$this->images = new ArrayCollection();
}
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=255)
*/
private $titre;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #var float
*
* #ORM\Column(name="prix", type="float")
*/
private $prix;
/**
* #ORM\ManyToOne(targetEntity="MDB\AdresseBundle\Entity\Ville", inversedBy="annonces")
*/
private $ville;
/**
* #ORM\ManyToMany(targetEntity="MDB\AnnonceBundle\Entity\Category", cascade={"persist"})
*/
private $categories;
/**
* #ORM\ManyToMany(targetEntity="MDB\UserBundle\Entity\User")
*
*/
private $wishlist;
/**
* #var boolean
*
* #ORM\Column(name="telAppear", type="boolean")
*/
private $telAppear;
/**
* #ORM\ManyToOne(targetEntity="MDB\UserBundle\Entity\User", inversedBy="annonces")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #var VlabsFile
* #ORM\OneToMany(targetEntity="MDB\PlatformBundle\Entity\Image", mappedBy="annonce")
* #Vlabs\Media(identifier="image_entity", upload_dir="files/images")
* #Assert\Valid()
*/
private $images;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set titre
*
* #param string $titre
* #return Annonce
*/
public function setTitre($titre) {
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre() {
return $this->titre;
}
/**
* Set description
*
* #param string $description
* #return Annonce
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription() {
return $this->description;
}
/**
* Set prix
*
* #param float $prix
* #return Annonce
*/
public function setPrix($prix) {
$this->prix = $prix;
return $this;
}
/**
* Get prix
*
* #return float
*/
public function getPrix() {
return $this->prix;
}
public function addCategory(Category $category) {
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->categories[] = $category;
return $this;
}
public function removeCategory(Category $category) {
$this->categories->removeElement($category);
}
public function getCategories() {
return $this->categories;
}
public function getDate() {
return $this->date;
}
public function setDate($date) {
$this->date = $date;
}
public function getWishlist() {
return $this->wishlist;
}
public function setWishlist($wishlist) {
$this->wishlist = $wishlist;
}
public function getVille() {
return $this->ville;
}
public function setVille($ville) {
$this->ville = $ville;
}
public function getTelAppear() {
return $this->telAppear;
}
public function setTelAppear($telAppear) {
$this->telAppear = $telAppear;
}
public function getUser() {
return $this->user;
}
public function setUser($user) {
$this->user = $user;
}
public function addImage(Image $image) {
$this->images[] = $image;
$image->setUser($this);
return $this;
}
public function removeImage(Image $image) {
$this->images->removeElement($image);
}
public function getImages() {
return $this->images;
}
}
config.yml
vlabs_media:
image_cache:
cache_dir: files/c
mapping:
image_entity:
class: MDB\PlatformBundle\Entity\Image
AnnonceSellType.php
<?php
namespace MDB\AnnonceBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use MDB\PlatformBundle\Form\ImageType;
class AnnonceSellType extends AbstractType {
private $arrayListCat;
public function __construct( $arrayListCat)
{
$this->arrayListCat = $arrayListCat;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->remove('wishlist')
->remove('date')
->remove('images')
->add('titre')
->add('description', 'textarea')
->add('prix')
->add('categories', 'choice', array(
'choices' => $this->arrayListCat,
'multiple' => true,
'mapped'=>false,
))
//->add('images', 'collection', array('type' => new ImageType()))
->add('image', 'vlabs_file', array(
'required' => false
))
;
}
/**
* #return string
*/
public function getName() {
return 'mdb_annoncebundle_annonce_sell';
}
public function getParent() {
return new AnnonceType();
}
}
And i have the following error : Catchable Fatal Error: Argument 1 passed to Vlabs\MediaBundle\EventListener\BaseFileListener::preSetData() must be an instance of Symfony\Component\Form\Event\DataEvent, instance of Symfony\Component\Form\FormEvent given in C:\wamp\www\Mdb\vendor\vlabs\media-bundle\Vlabs\MediaBundle\EventListener\BaseFileListener.php line 59
i tried to change this line :
->add('image', 'vlabs_file', array(
'required' => false
))
with :
->add('images', 'collection', array('type' => 'vlabs_file'))
but i just have the image label who appear in this case
if someone have an idea ?
I was a little bit investigating about your problem and Vlabs Media Bundle seems to be unmaintained. There is form listener on PRE_SET_DATA event (Vlabs\MediaBundle\EventListener\BaseFileListener::preSetData()) that is not compatible with new version of Symfony (it expects DataEvent as parametr instead FormEvent). They fixed it but after 1.1.1 release (you can compare dates from links). If really wanna give a try, change composer.json and run composer update. I can't guarantee there will not be another possible issues.
composer.json
"vlabs/media-bundle": "dev-master"
Library update
composer update vlabs/media-bundle