Symfony3 Trying to add record in join table - php

A User has many Games.
A Game can Belong to many Users.
I have a form with a list of games, I want the list of Games to be added to the current logged User.
When I submit the form nothing happens, I want at least 1 record to be added to users_games:
Update:
Added User entity
FormType addGameToUserType:
namespace AppBundle\Form;
use AppBundle\Entity\Game;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class addGameToUserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('game', EntityType::class, [
'class' => 'AppBundle:Game',
'choice_label' => function ($game) {
return $game->getName();
},
'multiple' => true,
'expanded' => false,
]);
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getBlockPrefix()
{
return 'app_bundleadd_game_to_user';
}
}
UserController addGameAction:
/**
* Adds game(s) to current user.
*
* #Route("user/game/add", name="game_add")
* #Method({"GET", "POST"})
*/
public function addGameAction(Request $request)
{
/** #var $form */
$form = $this->createForm('AppBundle\Form\addGameToUserType');
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
echo $form->get('game')->getData();
$em = $this->getDoctrine()->getManager();
/** #var $game */
$game = new Game();
$game->getId();
/** #var User $userObject */
$userObject = $this->getUser();
$user = $em->getRepository('AppBundle:User')
->find(['id' => $userObject->getId()]);
$game->addGameUser($user);
$em->persist($user);
$em->flush();
}
return $this->render('user/addGame.html.twig', array(
'form' => $form->createView()
));
}
Game entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Game
*
* #ORM\Table(name="game")
* #ORM\Entity(repositoryClass="AppBundle\Repository\GameRepository")
*/
class Game
{
/**
* #ORM\OneToMany(targetEntity="PlayLog", mappedBy="game")
* #ORM\OrderBy({"date" = "DESC"})
*
*/
private $playlogs;
private $users;
/**
* #return ArrayCollection
*/
public function getUsers()
{
return $this->users;
}
/**
* #param ArrayCollection $users
*/
public function setUsers($users)
{
$this->users = $users;
}
// private $categories;
public function __construct()
{
$this->playlogs = new ArrayCollection();
$this->users = new ArrayCollection();
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Assert\NotBlank()
* #Assert\Length(
* min = "3",
* max = "100"
* )
* #ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Game
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #return mixed
*/
public function getPlaylogs()
{
return $this->playlogs;
}
/**
* #param mixed $playlogs
*/
public function setPlaylogs($playlogs)
{
$this->playlogs = $playlogs;
}
public function addPlayLog(PlayLog $playlog)
{
$this->playlog->add($playlog);
$playlog->setPlayLogs($this);
}
public function addGameUser(User $user){
$this->users[] = $user;
}
}
User entity:
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\ManyToMany(targetEntity="Game")
*
* #ORM\JoinTable(name="users_games",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="game_id", referencedColumnName="id")}
* )
*/
private $games;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\PlayLog", mappedBy="user")
*
*/
private $playlogs;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
public function __construct()
{
$this->games = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #return mixed
*/
public function getGames()
{
return $this->games;
}
/**
* #param mixed $games
*/
public function setGames($games)
{
$this->games = $games;
}
public function addGame(Game $game)
{
// $this->games->add($game);
$this->games[] = $game;
return $this;
}
public function removeGame(Game $game)
{
$this->games->removeElement($game);
}
/**
* #return mixed
*/
public function getPlaylogs()
{
return $this->playlogs;
}
/**
* #param mixed $playlogs
*/
public function setPlaylogs($playlogs)
{
$this->playlogs = $playlogs;
}
public function addPlayLog(PlayLog $playlog)
{
$this->playlog->add($playlog);
$playlog->setPlayLogs($this);
}
}

Related

Symfony Forms embedded forms

Following the symfony documentation I am trying to embed a collection to a form. But when sending a post request to my endpoint the embedded form with the People collection stays empty.
My entities:
user.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Entity
* #UniqueEntity(fields="email", message="Email already taken")
* #ORM\HasLifecycleCallbacks()
*/
class User implements UserInterface
{
use Mapping\UserTrait;
/**
* #param Person $person
*/
public function addPeople(Person $person)
{
$this->people->add($person);
$person->setOwner($this);
}
/**
* #param Person $person
*/
public function removePeople(Person $person)
{
$this->people->removeElement($person);
}
}
UserTrait.php
<?php
namespace App\Entity\Mapping;
use App\Entity\Person;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* User
*
* #ORM\Table()
*/
trait UserTrait
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="hash", type="string")
*/
private $hash;
/**
* #var bool
*
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* #var \DateTime
*
* #ORM\Column(name="updated_at", type="datetime")
*/
private $updatedAt;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
/**
* #var string
* #ORM\Column(name="email", type="string")
* #Assert\NotBlank
* #Assert\Email
*/
private $email;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\OneToMany(targetEntity="App\Entity\Person", mappedBy="owner", cascade={"persist"})
*/
private $people;
/**
* #var string
* #Assert\NotBlank
* #Assert\Length(max=4096)
*/
private $plainPassword;
/**
* Constructor
*/
public function __construct()
{
$this->people = new ArrayCollection();
$this->roles = ['ROLE_USER'];
$this->isActive = 1;
}
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* #return bool
*/
public function isActive(): bool
{
return $this->isActive;
}
/**
* #param bool $isActive
*/
public function setIsActive(bool $isActive): void
{
$this->isActive = $isActive;
}
/**
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* #param string $email
*/
public function setEmail(string $email): void
{
$this->email = $email;
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getPeople(): \Doctrine\Common\Collections\Collection
{
return $this->people;
}
/**
* #param \Doctrine\Common\Collections\Collection $people
*/
public function setPeople(\Doctrine\Common\Collections\Collection $people): void
{
$this->people = $people;
}
/**
* #return string
*/
public function getPlainPassword()
{
return $this->plainPassword;
}
/**
* #param string $plainPassword
*/
public function setPlainPassword(string $plainPassword): void
{
$this->plainPassword = $plainPassword;
}
/**
* Implementation of UserInterface: Get password hash.
* #return string
*/
public function getPassword()
{
return $this->hash;
}
/**
* Implementation of UserInterface
*/
public function eraseCredentials()
{
$this->plainPassword = null;
}
/**
* Implementation of UserInterface
*/
public function getUsername()
{
return $this->email;
}
public function getSalt()
{
return null;
}
public function getRoles()
{
return ["User"];
}
/**
* #return string
*/
public function getHash(): string
{
return $this->hash;
}
/**
* #param string $hash
*/
public function setHash(string $hash): void
{
$this->hash = $hash;
}
/**
* #ORM\PrePersist
* #ORM\PreUpdate
*/
public function updatedTimestamps(): void
{
$dateTimeNow = new \DateTime('now');
$this->setUpdatedAt($dateTimeNow);
if ($this->getCreatedAt() === null) {
$this->setCreatedAt($dateTimeNow);
}
}
/**
* #return \DateTime
*/
public function getUpdatedAt(): \DateTime
{
return $this->updatedAt;
}
/**
* #param \DateTime $updatedAt
*/
public function setUpdatedAt(\DateTime $updatedAt): void
{
$this->updatedAt = $updatedAt;
}
/**
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #param \DateTime $createdAt
*/
public function setCreatedAt(\DateTime $createdAt): void
{
$this->createdAt = $createdAt;
}
}
Person.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Person
*
* #ORM\Entity
*/
class Person
{
use Mapping\PersonTrait;
}
PersonTrait.php
<?php
namespace App\Entity\Mapping;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Person
*
* #ORM\Table()
*/
trait PersonTrait
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="family_name", type="string")
* #Assert\NotBlank
*/
private $familyName;
/**
* #var string
*
* #ORM\Column(name="given_name", type="string")
* #Assert\NotBlank
*/
private $givenName;
/**
* #var string
*
* #ORM\Column(name="title", type="string")
*/
private $title;
/**
* #var \DateTime
*
* #ORM\Column(name="birth_date", type="datetime")
*/
private $birthDate;
/**
* #var string
*
* #ORM\Column(name="salutation", type="string")
*/
private $salutation;
/**
* #var string
*
* #ORM\Column(name="gender", type="string")
*/
private $gender;
/**
* #var \App\Entity\User
*
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="people")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="owner_id", referencedColumnName="id")
* })
*/
private $owner;
/**
* #return string
*/
public function getFamilyName()
{
return $this->familyName;
}
/**
* #param string $familyName
*/
public function setFamilyName($familyName)
{
var_dump($familyName);
$this->familyName = $familyName;
}
/**
* #return string
*/
public function getGivenName()
{
return $this->givenName;
}
/**
* #param string $givenName
*/
public function setGivenName($givenName)
{
$this->givenName = $givenName;
}
/**
* #return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* #param string $title
*/
public function setTitle(string $title): void
{
$this->title = $title;
}
/**
* #return \DateTime
*/
public function getBirthDate(): \DateTime
{
return $this->birthDate;
}
/**
* #param \DateTime $birthDate
*/
public function setBirthDate(\DateTime $birthDate): void
{
$this->birthDate = $birthDate;
}
/**
* #return string
*/
public function getSalutation(): string
{
return $this->salutation;
}
/**
* #param string $salutation
*/
public function setSalutation(string $salutation): void
{
$this->salutation = $salutation;
}
/**
* #return string
*/
public function getGender(): string
{
return $this->gender;
}
/**
* #param string $gender
*/
public function setGender(string $gender): void
{
$this->gender = $gender;
}
/**
* #return \App\Entity\User
*/
public function getOwner(): \App\Entity\User
{
return $this->owner;
}
/**
* #param \App\Entity\User $owner
*/
public function setOwner(\App\Entity\User $owner): void
{
$this->owner = $owner;
}
}
Now to my form types:
UserType.php
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class)
->add('plainPassword', PasswordType::class)
->add(
"people",
CollectionType::class,
[
'entry_type' => PersonType::class,
'allow_add' => true,
'by_reference' => false,
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => User::class,
'csrf_protection' => false
]
);
}
}
PersonType.php
<?php
namespace App\Form;
use App\Entity\Person;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PersonType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('familyName', TextType::class)
->add('givenName', TextType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => Person::class,
'csrf_protection' => false,
]
);
}
}
Using this Types I am now trying to register a user and create a Person and add it to the user using this code:
/**
* #Route("/register")
* #param Request $request
* #param UserPasswordEncoderInterface $passwordEncoder
*/
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->submit($request->request->all());
if ($form->isSubmitted() && $form->isValid()) {
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setHash($password);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return new Response("ok", 300);
}
return new Response("not ok", 500);
}
My problem now is that when I send a post request with postman with following parameters and content:
email: test#test.de
plainPassword: test1234
people.familyName: testLastname
people.givenName: testFirstname
I get the following error which means that it does not recognize the data for the person entity
"This form should not contain extra fields."
How do I make symfony forms to recognize that people.givenName and people.familyName are meant to create a instance of Person
Edit: comment by u_mulder suggested to change the post body to person[0].givenName and now I am getting the error message
This value is not valid.
I had two problems which had to be fixed. First hint from u_mulder was that I have to use the index for people since its a collection. So instead of
people["givenName"]
I had to use
people[0]["givenName"]
Second mistake was that the structure of the postman body was wrong. Instead of
people[0]["givenName"]
I had to remove the quotes.
people[0][givenName]
After fixing both problems the forms work as expected.

I can't upload multiple files in Symfony 3

I don't find solutions for several days to resolve my issue. I want to upload multiple images when I create a Post. My Post entity has a OneToMany relation with Image Entity. I use an embedded form in my PostType. It is a CollectionType of ImageType::class. To manage my upload functionality, I wrote an event listener called ImageUploadListener which injects my custom service called FileUploader.
This listener call a uploadFile function when a preUpdate and a prePersist event is handled. This function call my upload function from my FileUploader to move the image/file... to a target directory and to return a filename.
After that, I try to instantiate an Image Entity and to set the appropriate datas. But it doesn't work, only a file seems to be stored properly but with an additional entry unwanted in my db. (In my Image Table, for one image uploaded, I've got an entry with id 1 for example, a post_id set to NULL and file field set to /tmp/random number).
Please, could you help me ?
Post Entity
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Post
*
* #ORM\Table(name="post")
* #ORM\Entity(repositoryClass="UserBundle\Repository\PostRepository")
*/
class Post
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="Title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="Content", type="text")
*/
private $content;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="posts")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* #ORM\OneToMany(targetEntity="Image", mappedBy="post", cascade={"persist", "remove"})
*/
private $images;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
*
* #return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set content
*
* #param string $content
*
* #return Post
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set post
*
* #param \
*
* #return Post
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get post
*
* #return \?
*/
public function getUser()
{
return $this->user;
}
/**
* Constructor
*/
public function __construct()
{
$this->images = new ArrayCollection();
}
/**
* Add image
*
* #param \UserBundle\Entity\Image $image
*
* #return Post
*/
public function addImage(\UserBundle\Entity\Image $image)
{
$this->images[] = $image;
return $this;
}
/**
* Remove image
*
* #param \UserBundle\Entity\Image $image
*/
public function removeImage(\UserBundle\Entity\Image $image)
{
$this->images->removeElement($image);
}
/**
* Get images
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getImages()
{
return $this->images;
}
}
Image Entity
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity(repositoryClass="UserBundle\Entity\ImageRepository")
*/
class Image
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $file;
public function setFile($file)
{
$this->file = $file;
return $this;
}
public function getFile()
{
return $this->file;
}
/**
* #ORM\ManyToOne(targetEntity="Post", inversedBy="images")
* #ORM\JoinColumn(name="post_id", referencedColumnName="id")
*/
private $post;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set post
*
* #param \UserBundle\Entity\Post $post
*
* #return Image
*/
public function setPost(\UserBundle\Entity\Post $post = null)
{
$this->post = $post;
return $this;
}
/**
* Get post
*
* #return \UserBundle\Entity\Post
*/
public function getPost()
{
return $this->post;
}
}
PostType
namespace UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
//use Ivory\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use UserBundle\Entity\Post;
class PostType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('content')
->add('images', CollectionType::class, array (
'entry_type' => ImageType::class,
'entry_options' => array('label' => false),
'allow_add' => true,
'allow_delete' => true
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
//'data_class' => 'UserBundle\Entity\Post',
'data_class' => Post::class,
//'csrf_protection' => false
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'userbundle_post';
}
}
ImageType
namespace UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use UserBundle\Entity\Image;
class ImageType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, [
'required' => false,
'data_class' => null,
])
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Image::class,
//'csrf_protection' => false
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'userbundle_image';
}
}
EDIT: ImageUploadListener
//src/UserBundle/EventListener/ImageUploadListener.php
namespace UserBundle\EventListener;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\File;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use UserBundle\Entity\User;
use UserBundle\Entity\Post;
use UserBundle\Entity\Image;
use UserBundle\Service\FileUploader;
class ImageUploadListener
{
private $uploader;
public function __construct(FileUploader $uploader)
{
$this->uploader = $uploader;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
private function uploadFile($entity)
{
if ($entity instanceof Post) {
$post = $entity;
$images = $post->getImages();
foreach ($images as $image) {
if ($image->getFile() instanceof UploadedFile) {
$imageName = $this->uploader->upload($image->getFile());
// to avoid persisting FileObject in DB
$post->removeImage($image);
$postImage = new Image();
$postImage->setFile($imageName);
$postImage->setPost($post);
$post->addImage($postImage);
}
}
}
return;
}
}
FileUploader
namespace UserBundle\Service;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUploader
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getTargetDir(), $fileName);
return $fileName;
}
public function getTargetDir()
{
return $this->targetDir;
}
}

Symfony 3: FileType multiple and Many-to-Many database relation

I got entity called SupportMessage which contains messages from my support (ticket) system. I want to implement feature which allows users and support agents attach files to their posts.
I also got an entity called Files where all files from my project are listed: file ID, file name, user and uploading date.
When user writes a message in my support system, he can attach multiple files. I think using multiple=true is more elegant way than creating CollectionType of FileType buttons, but I don't really know how to implement this feature and make it works. Didn't find any information in official docs and Google about this case.
When I send the form, I got an array of UploadedFile object, but not ArrayCollection, so everything fails:
Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\SupportMessage#$attachments", got "Symfony\Component\HttpFoundation\File\UploadedFile" instead.
Controller:
/**
* #Security("is_granted('ALLOWED_TO_VIEW_SUPPORT_TICKET', supportTicket)")
* #Route("/support/ticket-{supportTicket}", name="view_ticket")
*
* #param Request $request
* #param SupportTicket $supportTicket
* #return Response
*/
public function viewTicket(Request $request, SupportTicket $supportTicket)
{
$translator = $this->get('translator');
$breadcrumbs = $this->get('white_october_breadcrumbs');
$breadcrumbs->addRouteItem('app.name', 'homepage');
$breadcrumbs->addRouteItem('page_title.support', 'my_support_tickets');
$breadcrumbs->addItem($supportTicket->getTitle());
$supportMessage = new SupportMessage();
$supportMessage->setSupportTicket($supportTicket);
$supportMessage->setUser($this->getUser());
$form = $this->createForm(SupportMessageType::class, $supportMessage);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
foreach ($supportMessage->getAttachments() as $attachment) {
$fileName = $this->get('app.file_uploader')->upload($attachment);
$file = new File();
$file->setFilename($fileName);
$file->setUser($this->getUser());
//$supportMessage->addAttachment($file);
}
//dump($supportMessage);die;
$em = $this->getDoctrine()->getManager();
$em->persist($supportMessage);
$em->flush();
$this->addFlash('notice', $translator->trans('support.flash_message.sent'));
return $this->redirect($request->getUri());
}
return $this->render('support/view-ticket.html.twig', [
'title' => $supportTicket->getTitle(),
'supportTicket' => $supportTicket,
'form' => $form->createView()
]);
}
Service:
namespace AppBundle\Service;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUploader
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->targetDir, $fileName);
return $fileName;
}
}
SupportMessage entity:
namespace AppBundle\Entity;
use Carbon\Carbon;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
*/
class SupportMessage
{
public function __construct()
{
$this->postedAt = new \DateTime();
$this->attachments = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*
* #var int
*/
private $id;
/**
* #ORM\Column(type="text")
*
* #Assert\NotBlank
* #Assert\Length(max=65535)
*
* #var string
*/
private $message;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
private $postedAt;
/**
* #return int
*/
public function getId(): ?int
{
return $this->id;
}
/**
* #return string
*/
public function getMessage(): ?string
{
return $this->message;
}
/**
* #param string $message
*/
public function setMessage(?string $message)
{
$this->message = $message;
}
/**
* #return \DateTime
*/
public function getPostedAt()
{
return $this->postedAt;
}
/**
* #return string
*/
public function getPostedAgo()
{
Carbon::setLocale('ru');
return Carbon::instance($this->postedAt)->diffForHumans();
}
/**
* #param \DateTime $postedAt
*/
public function setPostedAt($postedAt)
{
$this->postedAt = $postedAt;
}
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(nullable=false)
*
* #var User
*/
private $user;
/**
* #return User
*/
public function getUser()
{
return $this->user;
}
/**
* #param User $user
*/
public function setUser($user)
{
$this->user = $user;
}
/**
* #ORM\ManyToOne(targetEntity="SupportTicket", inversedBy="supportMessages")
*
* #var SupportTicket
*/
private $supportTicket;
/**
* #return SupportTicket
*/
public function getSupportTicket()
{
return $this->supportTicket;
}
/**
* #param SupportTicket $supportTicket
*/
public function setSupportTicket($supportTicket)
{
$this->supportTicket = $supportTicket;
}
/**
* #ORM\ManyToMany(targetEntity="File", inversedBy="supportMessages")
*
* #var File[]
*/
private $attachments;
/**
* #return File[]
*/
public function getAttachments()
{
return $this->attachments;
}
/**
* #param File[] $attachments
*/
public function setAttachments($attachments)
{
foreach ($attachments as $attachment) {
$this->attachments->add($attachment);
}
//dump($this->attachments);die;
}
/**
* #param File $attachment
*/
public function addAttachment($attachment)
{
$this->attachments->add($attachment);
}
}
File entity:
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
*/
class File
{
public function __construct()
{
$this->uploadedAt = new \DateTime();
$this->supportMessages = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*
* #var int
*/
private $id;
/**
* #ORM\Column(type="string")
*
* #Assert\File
*
* #var string
*/
private $filename;
/**
* #ORM\Column(type="string")
*
* #var User
*/
private $user;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
private $uploadedAt;
/**
* #return int
*/
public function getId(): ?int
{
return $this->id;
}
/**
* #return string
*/
public function getFilename(): ?string
{
return $this->filename;
}
/**
* #param string $filename
*/
public function setFilename(?string $filename)
{
$this->filename = $filename;
}
/**
* #return User
*/
public function getUser()
{
return $this->user;
}
/**
* #param mixed $user
*/
public function setUser($user)
{
$this->user = $user;
}
/**
* #return \DateTime
*/
public function getUploadedAt()
{
return $this->uploadedAt;
}
/**
* #param \DateTime $uploadedAt
*/
public function setUploadedAt($uploadedAt)
{
$this->uploadedAt = $uploadedAt;
}
/**
* #ORM\ManyToMany(targetEntity="SupportMessage", mappedBy="attachments")
*
* #var Collection|SupportMessage[]
*/
private $supportMessages;
/**
* #return Collection|SupportMessage[]
*/
public function getSupportMessages()
{
return $this->supportMessages;
}
/**
* #param Collection|SupportMessage[] $supportMessages
*/
public function setSupportMessages($supportMessages)
{
$this->supportMessages = $supportMessages;
}
/**
* #param SupportMessage $supportMessage
*/
public function addSupportMessage($supportMessage)
{
$supportMessage->addAttachment($this);
$this->supportMessages->add($supportMessage);
}
}
Much thanks for any help in advance.
Finally, my colleague found the problem. It was in my controller. I've attached UploadedFile objects there, but in the fact I needed to attach my entity File objects.
Fixed code snipped:
if ($form->isSubmitted() && $form->isValid()) {
$attachments = new ArrayCollection();
foreach ($supportMessage->getAttachments() as $attachment) {
$fileName = $this->get('app.file_uploader')->upload($attachment);
$file = new File();
$file->setFilename($fileName);
$file->setUser($this->getUser());
$attachments->add($file);
//$supportMessage->addAttachment($file);
}
$supportMessage->setAttachments($attachments);
// ... other code here ...
}

Symfony 3 form pre-populate collection field type

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.

Symfony2 dropdown form from database

So i want to display all the courses within my database in a drop down form. a user who is logged in then select one of the drop downs and it would store the users ID and the course ID into the database. How would i go about doing this?
Here's my course entity course.php
<?php
// src/Simple/SimpleBundle/Entity/Course.php
namespace Simple\ProfileBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="course")
*/
class Course
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="course", type="string", length=255)
*/
protected $course;
public function __construct()
{
$this->users = new ArrayCollection();
}
public function setCourse($course)
{
$this->course = $course;
}
public function getCourse()
{
return $this->course;
}
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
ChooseCourseType.php my form
<?php
// src/Simple/ProfileBundle/Controller/ChooseCourseType.php
namespace Simple\ProfileBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ChooseCourseType extends AbstractType
{
private $course;
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('course', 'choice', array(
'choices' => $this->course,
));
$builder->add('Choose Course', 'submit');
}
public function getName()
{
return 'name';
}
public function getCourse()
{
return 'course';
}
}
Coursecontroller.php
function chooseAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(new ChooseCourseType(), $CourseType);
$form->handleRequest($request);
if ($form->isValid()) {
$course = $form->getData();
$em->persist($course->getCourse());
$em->flush();
}
return $this->render(
'SimpleProfileBundle:Course:choosecourse.html.twig',
array('form' => $form->createView())
);
}
}
User.php
namespace Simple\ProfileBundle\Entity;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="users")
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="user", type="string", length=255)
*/
protected $username;
/**
* #ORM\Column(name="password", type="string", length=255)
*/
protected $password;
/**
* #ORM\Column(name="salt", type="string", length=255)
*/
protected $salt;
/**
* #ORM\ManyToMany(targetEntity="Role")
* #ORM\JoinTable(name="user_role",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
protected $roles;
/**
* #ORM\ManyToMany(targetEntity="Course")
* #ORM\JoinTable(name="user_course",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="course_id",
referencedColumnName="id")}
* )
*/
protected $courses;
/**
* #inheritDoc
*/
public function getUsername()
{
return $this->username;
}
/**
* #inheritDoc
*/
public function getSalt()
{
return '';
}
/**
* #inheritDoc
*/
public function getPassword()
{
return $this->password;
}
/**
* #inheritDoc
*/
public function getRoles()
{
return $this->roles->toArray();
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* Constructor
*/
public function __construct()
{
$this->roles = new \Doctrine\Common\Collections\ArrayCollection();
$this->salt = sha1(uniqid(null, true));
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* #param string $user
* #return User
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return string
*/
public function getUser()
{
return $this->user;
}
/**
* Set password
*
* #param string $password
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set salt
*
* #param string $salt
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Add roles
*
* #param \Simple\ProfileBundle\Entity\Role $roles
* #return User
*/
public function addRole(\Simple\ProfileBundle\Entity\Role $roles)
{
$this->roles[] = $roles;
return $this;
}
/**
* Remove roles
*
* #param \Simple\ProfileBundle\Entity\Role $roles
*/
public function removeRole(\Simple\ProfileBundle\Entity\Role $roles)
{
$this->roles->removeElement($roles);
}
/**
* Add roles
*
* #param \Simple\ProfileBundle\Entity\Course $courses
* #return User
*/
public function addCourse(\Simple\ProfileBundle\Entity\Course $courses)
{
$this->course[] = $courses;
return $this;
}
}
What else am i missing i am new to symfony2 and just need some direction.
Cheers
You need to use the entity form type.
Form type
<?php
// src/Simple/ProfileBundle/Controller/ChooseCourseType.php
namespace Simple\ProfileBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ChooseCourseType extends AbstractType {
$builder->add('courses', 'entity', array(
'label' => 'Courses',
'class' => 'SimpleSimpleBundle:Course',
'expanded' => false,
'multiple' => false
))
// ...
Controller
function chooseAction(Request $request) {
$em = $this->getDoctrine()->getManager();
// Replace this with whatever logic you use to find the user
$user = $em->getRepository('SimpleSimpleBundle:User')->findOneBy(
array('id' => 1)
);
$form = $this->createForm(new ChooseCourseType(), $user);
$form->handleRequest($request);
if ($form->isValid()) {
$user = $form->getData();
// Since you've bound this user object to the form and properly
// created a relationship between the course and user entities
// the relationship between course and user will persist here
$em->persist($user);
$em->flush();
}

Categories