I'm following the Documentation About Authentication. Now I want implement Role
This is my entities
User.php
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users", cascade={"all"})
* #ORM\JoinTable(name="user_role",
* joinColumns={
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="role_id", referencedColumnName="id")
* }
* )
*/
private $roles;
public function __construct () {
$this->roles = new ArrayCollection();
}
public function getRoles () {
return $this->roles->toArray();
}
public function getRoles2 () {
return $this->roles;
}
Than i Have three tables
users user_role role
roles
<?php
namespace ADV\UserBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Role
*
* #ORM\Table(name="role")
* #ORM\Entity(repositoryClass="ADV\UserBundle\Entity\RoleRepository")
*/
class Role
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=30)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="role", type="string", length=20)
*/
private $role;
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="roles")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Role
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set role
*
* #param string $role
* #return Role
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Get role
*
* #return string
*/
public function getRole()
{
return $this->role;
}
/**
* Add users
*
* #param \ADV\UserBundle\Entity\User $users
* #return Role
*/
public function addUser(\ADV\UserBundle\Entity\User $users)
{
$this->users[] = $users;
return $this;
}
/**
* Remove users
*
* #param \ADV\UserBundle\Entity\User $users
*/
public function removeUser(\ADV\UserBundle\Entity\User $users)
{
$this->users->removeElement($users);
}
/**
* Get users
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
}
I create two form, userType and Roletype, and UserType "embed" the roleType
->add('roles', 'collection', array(
'type' => new RoleType()
))
My Controller:
public function registrationAction (Request $request) {
$user = new User();
$role = new Role();
$user->getRoles2()->add($role);
$form = $this->createForm(new UserType(), $user);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getEm();
try {
$em->beginTransaction();
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$user->setSalt(md5(time()));
$password = $encoder->encodePassword($user->getPassword(), $user->getSalt());
$user->setPassword($password);
$em->persist($user);
$em->flush();
$em->commit();
} catch (\Exception $e) {
$em->rollback();
}
}
return array(
'form' => $form->createView()
);
}
I have the Right Form
A new entity was found through the relationship
'ADV\UserBundle\Entity\User#roles' that was not configured to cascade
persist operations for entity: ROLE_WRITER. To solve this issue:
Either explicitly call EntityManager#persist() on this unknown entity
or configure cascade persist this association in the mapping for
example #ManyToOne(..,cascade={"persist"}).
But I want to use ManyToMay, and if I add cascade, each time that I create a new User, create also a new Role related
Related
I need your help on my problem for saving my data in table.
I use fosUserBundle and have different user types (Admin, Pro, Client) that are classes extending a base User entity.
I also have a Language entity linked to the User with a one-to-many association.
To subscribe, a userClient needs to check by checkbox the language(s) that he speaks.
The form page is ok, it displays the UserClient form (+ the parent User form) with the list of languages as checkboxes.
The problem is the data saved in table.
I have the same values in the language column:
O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:2:{i:0;O:32:"LanguagesBundle\Entity\Languages":10:{s:36:"LanguagesBundle\Entity\Languagesid";i:2;s:38:"LanguagesBundle\Entity\Languagesname";s:7:"English";s:44:"LanguagesBundle\Entity\Languagesshort_slug";s:2:"en";s:43:"LanguagesBundle\Entity\Languageslong_slug";s:5:"en_EN";s:43:"LanguagesBundle\Entity\LanguagesisDefault";b:0;s:43:"LanguagesBundle\Entity\LanguagesupdatedAt";O:8:"DateTime":3:{s:4:"date";s:26:"2018-04-20 22:46:48.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";}s:43:"LanguagesBundle\Entity\LanguagesimageFile";N;s:39:"LanguagesBundle\Entity\Languagesimage";s:39:"Flag_of_United_Kingdom_-_Circle-512.png";s:43:"LanguagesBundle\Entity\LanguagesimageSize";i:37621;s:44:"LanguagesBundle\Entity\LanguagesuserClient";N;}i:1;O:32:"LanguagesBundle\Entity\Languages":10:{s:36:"LanguagesBundle\Entity\Languagesid";i:1;s:38:"LanguagesBundle\Entity\Languagesname";s:9:"Français";s:44:"LanguagesBundle\Entity\Languagesshort_slug";s:2:"fr";s:43:"LanguagesBundle\Entity\Languageslong_slug";s:5:"fr_FR";s:43:"LanguagesBundle\Entity\LanguagesisDefault";b:1;s:43:"LanguagesBundle\Entity\LanguagesupdatedAt";O:8:"DateTime":3:{s:4:"date";s:26:"2018-04-20 22:45:50.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";}s:43:"LanguagesBundle\Entity\LanguagesimageFile";N;s:39:"LanguagesBundle\Entity\Languagesimage";s:31:"Flag_of_France_-_Circle-512.png";s:43:"LanguagesBundle\Entity\LanguagesimageSize";i:23352;s:44:"LanguagesBundle\Entity\LanguagesuserClient";N;}}}
Here's my code:
User.php
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use UserBundle\Entity\UserAdmin;
use UserBundle\Entity\UserProfessional;
use UserBundle\Entity\UserClient;
use UserBundle\Entity\Adress;
/**
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({"client" = "UserClient", "professional"="UserProfessional", "admin"="UserAdmin"})
*/
abstract class User extends BaseUser {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
*/
protected $firstname;
//[...] getters and setters
Entity: UserClient.php
<?php
// src/UserBundle/Entity/UserGuest.php
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
*/
class UserClient extends User {
/**
* #ORM\Column(type="array")
* #ORM\OneToMany(targetEntity="LanguagesBundle\Entity\Languages", mappedBy="userClient")
*/
private $languages;
public function __construct() {
parent::__construct();
$this->languages = new ArrayCollection();
}
/**
* Set languages
*
* #param array $languages
*
* #return UserClient
*/
public function setLanguages($languages)
{
$this->languages = $languages;
}
/**
* Get languages
*
* #return array
*/
public function getLanguages()
{
return $this->languages;
}
/**
* Add language
*
* #param \LanguagesBundle\Entity\Languages $language
*
* #return UserClient
*/
public function addLanguage(LanguagesBundle\Entity\Languages $language)
{
$this->languages[] = $language;
return $this;
}
/**
* Remove language
*
* #param \LanguagesBundle\Entity\Languages $language
*/
public function removeLanguage(\LanguagesBundle\Entity\Languages $language)
{
$this->languages->removeElement($language);
}
}
Entity Languages.php
<?php
namespace LanguagesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
*
* #Vich\Uploadable
*/
class Languages
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string")
* #Assert\NotBlank()
*/
private $name;
/**
* #ORM\Column(type="string", length=2, unique=true)
*/
private $short_slug;
/**
* #var string
*
* #ORM\Column(type="string", length=5, unique=true)
* #Assert\NotBlank()
*/
private $long_slug;
/**
* #var string
*
* #ORM\Column(type="boolean", nullable=true)
*/
private $isDefault;
/**
* #ORM\Column(type="datetime")
* #var \DateTime
*/
private $updatedAt;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Assert\File(
* maxSize="1M",
* mimeTypes={"image/png", "image/jpeg", "image/pjpeg"}
* )
* #Vich\UploadableField(mapping="language_images", fileNameProperty="image", size="imageSize")
* #var File
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255, nullable = true)
* #var string
*/
private $image;
/**
* #ORM\Column(type="integer")
*
* #var integer
*/
private $imageSize;
/**
* #ORM\ManyToOne(targetEntity="UserBundle\Entity\UserClient", inversedBy="languages")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $userClient;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*/
public function setImageFile(?File $image = null): void
{
$this->imageFile = $image;
if (null !== $image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getImageFile()
{
return $this->imageFile;
}
/**
* Constructor
*/
public function __construct()
{
$this->updatedAt = new \DateTime();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Languages
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set shortSlug
*
* #param string $shortSlug
*
* #return Languages
*/
public function setShortSlug($shortSlug)
{
$this->short_slug = $shortSlug;
return $this;
}
/**
* Get shortSlug
*
* #return string
*/
public function getShortSlug()
{
return $this->short_slug;
}
/**
* Set longSlug
*
* #param string $longSlug
*
* #return Languages
*/
public function setLongSlug($longSlug)
{
$this->long_slug = $longSlug;
return $this;
}
/**
* Get longSlug
*
* #return string
*/
public function getLongSlug()
{
return $this->long_slug;
}
/**
* Set isDefault
*
* #param boolean $isDefault
*
* #return Languages
*/
public function setIsDefault($isDefault)
{
$this->isDefault = $isDefault;
return $this;
}
/**
* Get isDefault
*
* #return boolean
*/
public function getIsDefault()
{
return $this->isDefault;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
* #return Languages
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set image
*
* #param string $image
*
* #return Languages
*/
public function setImage($image)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* #return string
*/
public function getImage()
{
return $this->image;
}
/**
* Set imageSize
*
* #param integer $imageSize
*
* #return Languages
*/
public function setImageSize($imageSize)
{
$this->imageSize = $imageSize;
return $this;
}
/**
* Get imageSize
*
* #return integer
*/
public function getImageSize()
{
return $this->imageSize;
}
/**
* Set userClient
*
* #param \UserBundle\Entity\UserClient $userClient
*
* #return Languages
*/
public function setUserClient(\UserBundle\Entity\UserClient $userClient = null)
{
$this->userClient = $userClient;
return $this;
}
/**
* Get userClient
*
* #return \UserBundle\Entity\UserClient
*/
public function getUserClient()
{
return $this->userClient;
}
/**
* {#inheritdoc}
*/
public function __toString()
{
return $this->getName() ?: '-';
}
}
My FormType: RegistrationTypeClient.php
<?php
// src/UserBundle/Form/UserContactFormType.php
namespace UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use LanguagesBundle\Services\LanguagesService;
use LanguagesBundle\Entity\Languages ;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
class RegistrationClientType extends AbstractType {
protected $service;
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
$builder
->add('languages', EntityType::class, [
'class' => 'LanguagesBundle:Languages',
'choice_label' => 'name',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.name', 'ASC');
},
'label' => 'Langues',
'expanded' => true,
'multiple' => true,
])
;
}
public function getParent() {
// on inclut le formulaire de base d'inscription utilisateur
return 'UserBundle\Form\RegistrationType';
}
public function getBlockPrefix() {
return 'app_user_registration_client';
}
// For Symfony 2.x
public function getName() {
return $this->getBlockPrefix();
}
public function configureOptions(OptionsResolver $resolver) {
$resolver
->setDefaults(array(
'data_class' => \UserBundle\Entity\UserClient::class,
))
//->setRequired('service_languages');
;
}
}
And my Controller:
public function registerClientAction(Request $request) {
/** #var $formFactory FactoryInterface */
//$formFactory = $this->get('fos_user.registration_pro.form.factory');
/** #var $userManager UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
/** #var $dispatcher EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$user = new UserClient();
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->createForm(RegistrationClientType::class, $user);
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);
if (null !== $response = $event->getResponse()) {
return $response;
}
}
return $this->render('UserBundle\Registration\register_client.html.twig', array(
'form' => $form->createView(),
));
}
Here's a picture showing the data saved in the table
I need the languages to be stored in the database as an array for userClient.
Could you help me please.
Thank's for re-edit my question Philip-B-
Thank's for your reading also.
I have resolve my problem by adding a foreach to transform my object to array:
The code is in my controller:
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
foreach ($user->getLanguages() as $value) {
$langue[] = $value->getShortSlug();
}
$user->setLanguages($langue);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
I am using Symfony and Doctrine.
I have two Entities, User and Pots.
Every logged User can create as many Post he want to.
Every Post is associated to one User.
Thats the Workflow: I log in with an User, this user create a Post. A New Post is saved in the Database with a foreigkey on the User wo create it.
Problem: when the User create the Post, the post ist create, but a new User is created too. The new Post is asssociate to the new Users and not to the logged User.
USER ENTITY:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Post;
/**
* #ORM\Entity
* #ORM\Table(name= "User")
*/
class User
{
/**
* #ORM\Column(type = "integer")
* #ORM\Id
* #ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* #ORM\Column(type = "string", length = 50)
*/
private $account;
/**
* #ORM\Column(type = "string", length = 22)
*/
private $password;
/**
* #ORM\Column(type = "string", length = 100)
*/
private $email;
/**
* #ORM\Column(type = "integer", length = 1)
*/
private $type;
/**
*
* #ORM\OneToMany(targetEntity="Post", mappedBy="user")
*/
private $posts;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set account
*
* #param string $account
*
* #return User
*/
public function setAccount($account)
{
$this->account = $account;
return $this;
}
/**
* Get account
*
* #return string
*/
public function getAccount()
{
return $this->account;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set mail
*
* #param string $mail
*
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get mail
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set type
*
* #param integer $type
*
* #return User
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return integer
*/
public function getType()
{
return $this->type;
}
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* #param \AppBundle\Entity\Post $post
*
* #return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
return $this;
}
/**
* Remove post
*
* #param \AppBundle\Entity\Post $post
*/
public function removePost(\AppBundle\Entity\Post $post)
{
$this->posts->removeElement($post);
}
/**
* Get posts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPosts()
{
return $this->posts;
}
}
POST ENTITY:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
* #ORM\Table(name = "Post")
* #Vich\Uploadable
*/
class Post
{
/**
* #ORM\Column(type = "integer")
* #ORM\Id
* #ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* #ORM\Column(type = "string", length = 25)
*/
private $title;
/**
* #ORM\Column(type = "string", length = 255)
*/
private $text;
/**
* #ORM\Column(type= "string", length = 250)
*/
private $pic;
/**
* #Vich\UploadableField(mapping="post_file", fileNameProperty="pic")
*
*/
private $picFile;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="posts", cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
public function getPicFile(){
return $this->picFile;
}
public function setPicFile(File $picFile = null){
$this->picFile = $picFile;
return $this;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return Coach
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* 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 text
*
* #param string $text
*
* #return Post
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* #return string
*/
public function getText()
{
return $this->text;
}
/**
* Set pic
*
* #param string $pic
*
* #return Post
*/
public function setPic($pic)
{
$this->pic = $pic;
return $this;
}
/**
* Get pic
*
* #return string
*/
public function getPic()
{
return $this->pic;
}
/**
* Set id
*
* #param integer $id
*
* #return Post
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
CONTROLLER:
NOTE: Here is take the logged User from the SESSION. This works, i output the id from the User i use and it was the correct id.
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$user = $session->get('user');
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$post = $form->getData();
$post->setUser($user);
$doct = $this->getDoctrine()->getManager();
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
I left the Entity like you said, but i changed the Controller to. The Session User Object dind't work to associate it to the Post. So I just toke the ID from the Session and then search the user object again throw that id in the database and used this instade.
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$users = $session->get('user');
$repo = $this->getDoctrine()->getRepository(User::class);
$user = $repo->find($users->getId());
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$doct = $this->getDoctrine()->getManager();
$post = $form->getData();
$post->setUser($user);
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
The user is the strong side so you should move the cascade={"persist"} option to user, then the user can save the post not the other way. It seems the cascade={"persist"} option is rewriting the setUser method. When you use the cascade={"persist"} option that entity would create the targetEntity.
In addition to #Juan I. Morales Pestana
class User
{
// ...
/**
*
* #ORM\OneToMany(
* targetEntity="Post",
* mappedBy="user",
* cascade={"persist"}
* )
*/
private $posts;
// ...
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* #param \AppBundle\Entity\Post $post
*
* #return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
$post->setUser($this);
return $this;
}
Hi i got this error while data insert in database please let me know where is the problem i am new in symfony
"Expected value of type \"AppBundle\Entity\Class_cat\" for
association field \"AppBundle\Entity\User#$class_cat\", got
\"integer\" instead.",
"class": "Doctrine\ORM\ORMInvalidArgumentException"
this is User entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User
{
/**
* Constructor
*/
public function __construct()
{
$this->class_cat = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="role", type="string", length=255)
*/
private $role;
/**
* #ORM\ManyToOne(targetEntity="Class_cat", inversedBy="users")
* #ORM\JoinColumn(name="class_id", referencedColumnName="id")
*/
private $class_cat;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set role
*
* #param string $role
*
* #return User
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Get role
*
* #return string
*/
public function getRole()
{
return $this->role;
}
/**
* #return mixed
*/
public function getClassCat()
{
return $this->class_cat;
}
/**
* #param mixed $class_cat
*/
public function setClassCat($class_cat)
{
$this->class_cat = $class_cat;
}
this is class_cat enity
class Class_cat {
/**
* Constructor
*/
public function __construct()
{
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="class_name", type="string", length=255)
*/
private $className;
/**
* #ORM\OneToMany(targetEntity="User", mappedBy="class_cat")
*/
protected $users;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set className
*
* #param string $className
*
* #return Class_cat
*/
public function setClassName($className)
{
$this->className = $className;
return $this;
}
/**
* Get className
*
* #return string
*/
public function getClassName()
{
return $this->className;
}
public function getUsers()
{
return $this->users;
}
/**
* #param mixed $users
*/
public function setUsers($users)
{
$this->users = $users;
}
this is controller code
> public function postAction(Request $request)
> {
> $data = new User;
> $name = $request->get('name');
> $role = $request->get('role');
> $class = $request->get('class_id');
> if (empty($name) || empty($role) || empty($class)) {
> return new View("NULL VALUES ARE NOT ALLOWED", Response::HTTP_NOT_ACCEPTABLE);
> }
> $data->setName($name);
> $data->setRole($role);
> $data->setClassId(1);
> $em = $this->getDoctrine()->getManager();
> $em->persist($data);
> $em->flush();
> return new View("User Added Successfully", Response::HTTP_OK);
> }
You need to pass the entity not the id for example:
$em = $this->getDoctrine()->getManager();
$classCat = $em->getRepository('AppBundle:ClassCat')->find(1);
$data->setClassCat($classCat);
Hi instead of passing integer value you need to pass an object of class Class_cat.
When you mapped any entity field to any other entity symfony need object to set.
So your solution is simple to try something like this:
public function postAction(Request $request){
$em = $this->getDoctrine()->getManager();
$data = new User;
$name = $request->get('name');
$role = $request->get('role');
$class = $request->get('class_id');
if (empty($name) || empty($role) || empty($class)) {
return new View("NULL VALUES ARE NOT ALLOWED",
Response::HTTP_NOT_ACCEPTABLE);
}
$classCat = $em->getRepository('AppBundle:ClassCat')->find($class);
$data->setName($name);
$data->setRole($role);
$data->setClassId($classCat);
$em->persist($data);
$em->flush();
return new View("User Added Successfully", Response::HTTP_OK);
}
Instead of integer value in
use object like this:
$data->setClassId(1);
$em = $this->getDoctrine()->getManager();
$classCat = $em->getRepository('AppBundle:ClassCat')->find(1);
$data->setClassCat($classCat);
curl -v -H "Content-Type: application/json" -d "{\"user\":1,\"userapikey\":\"aaaaaaaaaaaaaaaaaa\",\"title\":\"test tile\"}" http://localhost/us/serenify/web/app_dev.php/userapi/create
I am passing data for creating a apikey record for a specific user.
In above expression user is forign key from user master table.
public function processform(ApiKey $apikey,Request $request)
{
$apiuser = new ApiUser();
$apiform = $this->createForm(new ApiKeyType(), $apikey);
$apiform->submit($request);
if($apiform->isValid())
{
// $page = $apiform->getData();
$content = json_decode($request->getContent());
$apikey->setUserApikey($content->userapikey);
$apikey->setTitle($content->title);
$em = $this->getDoctrine()->getManager();
$em->persist($apikey);
$em->flush();
$data=array(
"success"=>'true',
"msg"=>'Record inserted!'
);
$response = new Response(json_encode($data));
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'application/json');
}
else
{
$out=array(
"success"=>'true',
"msg"=>'invalid form data!'
);
$response = new Response(json_encode($out));
$response->setStatusCode(204);
$response->headers->set('Content-Type', 'application/json');
}
return $response;
}
This is my controller.
class ApiKey
{
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="ApiUser", inversedBy="apikey",cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="userapikey", type="string", length=255)
*/
private $userapikey;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set apikey
*
* #param string $userapikey
* #return userapi
*/
public function setUserApikey($userapikey)
{
$this->userapikey = $userapikey;
return $this;
}
/**
* Get apikey
*
* #return string
*/
public function getUserApikey()
{
return $this->userapikey;
}
/**
* Set title
*
* #param string $title
* #return userapi
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Get user
*
* #return integer
*/
public function getUser()
{
return $this->user;
}
/**
* Set User
*
* #param integer $user
* #return userapi
*/
public function setUser(ApiUser $value = null)
{
$this->user = $value;
return $this;
}
}
And the class ApiUser
class ApiUser
{
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="ApiKey", mappedBy="apiuser")
*/
private $apikeys;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=255)
* #Assert\NotBlank()
*/
private $username;
/**
* #var string
* #Assert\NotBlank()
*
* #ORM\Column(name="userpassword", type="string", length=255)
*/
private $userpassword;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return user
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set userpassword
*
* #param string $userpassword
* #return user
*/
public function setUserpassword($userpassword)
{
$this->userpassword = $userpassword;
return $this;
}
/**
* Get userpassword
*
* #return string
*/
public function getUserpassword()
{
return $this->userpassword;
}
}
& this are entity classes.
Please help to insert record, right now NULL value is getting inserted in userid column.
You need a DataTransformer: http://symfony.com/doc/current/cookbook/form/data_transformers.html
class UserToIdTransformer implements DataTransformerInterface
{
/**
* #var ObjectManager
*/
private $om;
/**
* #param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* Transforms an object (user) to an int (id).
*
* #param User|null $user
* #return integer
*/
public function transform($user)
{
if (null === $user) {
return "";
}
return $user->getId();
}
/**
* Transforms an integer (id) to an object (User).
*
* #param integer $number
*
* #return User|null
*
* #throws TransformationFailedException if object (user) is not found.
*/
public function reverseTransform($id)
{
if (!$id) {
return null;
}
$user = $this->om
->getRepository('YourBundle:User')
->find($id);
if (null === $user) {
throw new TransformationFailedException(sprintf(
'An user with id "%s" does not exist!',
$id
));
}
return $user;
}
}
Then in your formtype, while adding the field:
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
// this assumes that the entity manager was passed in as an option
$entityManager = $options['em'];
$transformer = new UserToIdTransformer($entityManager);
// add a normal text field, but add your transformer to it
$builder->add(
$builder->create('user', 'text')
->addModelTransformer($transformer)
);
Note that with a few changes you can get it to work by providing the username rather than the id.
Old Query in symfony 1.4 and doctrine 1.2
$user = Doctrine_Query::create()
->from('User.u')
->innerJoin('u.State s')
->where('u.id = ?', $id)
->andWhere('u.state_id = ?', $state_id)
->fetchOne();
Now my Query in symfony2:
$repository = $this->getDoctrine()
->getRepository('FrontendAccountBundle:User');
$user = $repository->findBy(array(
'activationId' => $activation_id),
array('state' => 3));
My error is comming up:
Unrecognized field: state
What is the problem?
Edit: reformatted code
Update
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User implements UserInterface, \Serializable
{
/**
* #var string
*
* #ORM\Column(name="activation_id", type="string", length=255, nullable=true)
*/
private $activationId;
/**
* #var \State
*
* #ORM\ManyToOne(targetEntity="State")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="state_id", referencedColumnName="id")
* })
*/
private $state;
/**
* Set activationId
*
* #param string $activationId
* #return User
*/
public function setActivationId($activationId)
{
$this->activationId = $activationId;
return $this;
}
/**
* Get activationId
*
* #return string
*/
public function getActivationId()
{
return $this->activationId;
}
/**
* Set state
*
* #param \Frontend\AccountBundle\Entity\State $state
* #return User
*/
public function setState(\Frontend\AccountBundle\Entity\State $state = null)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return \Frontend\AccountBundle\Entity\State
*/
public function getState()
{
return $this->state;
}
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* #inheritDoc
*/
public function getUsername()
{
return $this->email;
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
}
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* State
*
* #ORM\Table(name="state")
* #ORM\Entity
*/
class State
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="state", type="string", length=255, nullable=false)
*/
private $state;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set state
*
* #param string $state
* #return State
*/
public function setState($state)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return string
*/
public function getState()
{
return $this->state;
}
/**
* Set description
*
* #param string $description
* #return State
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
}
The problem is that the variable in the User entity is "state" not "stateId". You must always use the names from the entity, not the database. The join from User to State also needs to be done since the stateId is in the State entity.
When joins are needed you are probably better off using queryBuilder or DQL.
Here's a post about joins in Doctrine 2 queryBuilder: doctrine 2 query builder and join tables
Here's the documentation from the Symfony Book for Doctrine: http://symfony.com/doc/current/book/doctrine.html#entity-relationships-associations
Here's an example from my project that is very similar to your problem:
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->select ('a.activityId, a.startTime, a.endTime, u.username')
->join('a.login','u')
->where('u.id = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
If I didn't need anything from the user table the query could be written as
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->where('a.login = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
This is your query reworked in the same way:
$rep = $this->getDoctrine()->getRepository('FrontendAccountBundle:User');
$q = $rep->createQueryBuilder('u')
->join('u.state','s')
->where ('u.id = :uid')
->andWhere ('s.stateId = :sid')
->setParameters(array('uid' => $id, 'sid' => $state_id))
->getQuery();
$user = $q->getSingleResult();
Thanks to Peter to light me up a little bit!!!
If you don't want again a the stupid solution from symfony2(-docs) and doctrine2, because you need much more code than in symfony1.4, like that way http://symfony.com/doc/current/book/doctrine.html#joining-to-related-records. Try my solution.
Here is the result.
$em = $this->getDoctrine()->getEntityManager();
$user = $em->createQuery('SELECT u FROM FrontendAccountBundle:User u
INNER JOIN FrontendAccountBundle:State s
WHERE
u.activation_id=:activation_id
and
u.state=:state_id
')
->setParameter('activation_id', $activation_id)
->setParameter('state_id', 3)
->getSingleResult();