How to access one to one embedded form symfony2 - symfony

I used symfony 2 only few days.
I got two entities and i want to create one form and save data from this form into database.
UserDetails and Contract have relations OneToOne.
I embed a form of Contract into UserDetails form (form apper on web) but when i set some data into form and click button "save" i get a error. as i notice a "try" to assign an array instead of Contract i don't know how to access this new contract entite in Controler.
example ERRORS:
ContextErrorException: Catchable Fatal Error: Argument 1 passed to Leave\DatabaseBundle\Entity\UserDetails::setContract() must be an instance of Leave\DatabaseBundle\Entity\Contract, array given, called in /var/www/nowyUrlop/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 360 and defined in /var/www/nowyUrlop/src/Leave/DatabaseBundle/Entity/UserDetails.php line 165
at UserDetails->setContract(array('start_contr' => object(DateTime), 'end_contr' => object(DateTime), 'hours_per_week' => '6')) in /var/www/nowyUrlop/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php line 360
UserDetails entity:
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Annotations\AnnotationReader;
use Leave\DatabaseBundle\Entity\User;
/**
* #ORM\Entity
* #ORM\Table(name="userDetails")
*/
class UserDetails {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToOne(targetEntity="Contract", mappedBy="user_details", cascade={"persist"})
*/
protected $contract;
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="userDetails")
* #ORM\JoinColumn(name="user_id", nullable = true, referencedColumnName="id")
* */
protected $user;
Contract Entity:
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="contract")
*/
class Contract {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="date")
*/
protected $start_contr;
/**
* #ORM\Column(type="date")
*/
protected $end_contr;
/**
* #ORM\Column(type="integer")
*/
protected $type ;
/**
* #ORM\Column(type="integer")
*/
protected $hours_per_week;
/**
* #ORM\OneToOne(targetEntity="UserDetails", inversedBy="contract")
* #ORM\JoinColumn(name="user_details_id", nullable = true, referencedColumnName="id")
* */
protected $user_details;
public function setUserDetails(\Leave\DatabaseBundle\Entity\UserDetails $userDetails = null)
{
$this->user_details = $userDetails;
return $this;
}
/**
* Get user_details
*
* #return \Leave\DatabaseBundle\Entity\UserDetails
*/
public function getUserDetails()
{
return $this->user_details;
}
UserDetals Form:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Leave\DatabaseBundle\Form\Type\ContractFormType;
class UserDetailsFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('exp', 'text')
->add('total_leave', 'text')
->add('days_left', 'text')
->add('contract', new contractFormType())
->add('save', 'submit');
}
public function getName()
{
return 'userDetails';
}
}
Contract Form:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ContractFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('start_contr', 'date', array('widget' => 'single_text'))
->add('end_contr', 'date', array('widget' => 'single_text'))
->add('hours_per_week', 'text');
}
public function getName()
{
return 'contractForm';
}
}
Controller:
public function editUserAction(Request $request) {
$user = $this->get('security.context')->getToken()->getUser();
$userDetails = new UserDetails();
$form = $this->createForm(new UserDetailsFormType(), $userDetails);
$userDetails->setUser($user);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($userDetails);
$em->flush();
return $this->render('LeaveEmployeeBundle:Employee:editUser.html.twig', array(
'formEditUser' => $form->createView(),
'userDetails' => $userDetails,
'user' => $user
));
}
return $this->render('LeaveEmployeeBundle:Employee:editUser.html.twig', array(
'formEditUser' => $form->createView()
));
}

You have to pass data_class as second parameter.
In your UserDetals Form: do the following
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Leave\DatabaseBundle\Form\Type\ContractFormType;
class UserDetailsFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('exp', 'text')
->add('total_leave', 'text')
->add('days_left', 'text')
->add('contract', new contractFormType(), array(
'data_class' => 'Leave\DatabaseBundle\Entity\Contract')
)
->add('save', 'submit');
}
public function getName()
{
return 'userDetails';
}
}

Related

Symfony 5.0.8 weird issue when updating a simple entity

Here is my entity:
<?php
namespace App\Entity\Contact;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="contact_contact")
*/
class Contact
{
/**
* #ORM\Id
* #ORM\Column(type="integer", options={"unsigned":true})
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #Assert\NotBlank
* #ORM\Column(type="string", length=40, nullable=true)
*/
private $fname;
/**
* #ORM\Column(type="string", length=40, nullable=true)
*/
private $lname;
public function getId(): ?int
{
return $this->id;
}
public function getFname(): ?string
{
return $this->fname;
}
public function setFname(string $fname): self
{
$this->fname = $fname;
return $this;
}
public function getLname(): ?string
{
return $this->lname;
}
public function setLname(?string $lname): self
{
$this->lname = $lname;
return $this;
}
}
Here is the edit controller action code:
/**
* #Route("/{id}/edit", name="contact_contact_edit", methods={"GET","POST"})
*/
public function edit(Request $request, Contact $contact): Response
{
$form = $this->createForm(ContactType::class, $contact);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$this->getDoctrine()->getManager()->flush();
}
}
return $this->render('contact/contact/edit.html.twig', [
'contact' => $contact,
'form' => $form->createView(),
]);
}
When I post the form but leave the fname (first name) field empty...I get this error (Symfony\Component\PropertyAccess\Exception\InvalidArgumentException)
Expected argument of type "string", "null" given at property path
"fname".
When creating the entity, the #Assert works as expected and the message says so...but if I leave it blank and update post...bzzzt error.
What am I missing?
EDIT | Here is the form class incase thats doing something?
<?php
namespace App\Form\Contact;
use App\Entity\Contact\Contact;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('fname', TextType::class, ['label' => 'First Name'])
->add('lname', TextType::class, ['label' => 'Last Name']);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Contact::class,
'min_entry' => false,
// NOTE: Must be added to every form class to disable HTML5 validation
'attr' => ['novalidate' => 'novalidate']
]);
$resolver->setAllowedTypes('min_entry', 'bool');
}
}
That's one of the reasons you should avoid allowing the form component changing your entities directly. It will set the data, and then validate it. So it's totally possible for the entity to be in an invalid state after the form has been submitted.
Anyway, you can specify what an empty value should be:
->add('fname', TextType::class, ['label' => 'First Name', 'empty_data' => ''])

Render a filtered checkbox collection in a form

I want to render a filtered collection as a checkbox list.
But i have trouble to get the collection shown. i get "Catchable Fatal Error: Object of class Doctrine\ORM\PersistentCollection could not be converted to string".
Below is my formtype:
class PropertyfilterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('view', EntityType::class, [
'class' => Propsearch::class,
'choice_label' => 'propsearchviews',
'expanded' => true,
'multiple' => true
]);
}
This is my many-to-many entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
*/
class Propsearch
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var Propsearchview[]|ArrayCollection
*
* #ORM\ManyToMany(targetEntity="App\Entity\Propview", cascade={"persist"})
* #ORM\JoinTable(name="propsearch_propview")
* #ORM\OrderBy({"title": "ASC"})
* #Assert\Count(max="4", maxMessage="Can only select 4 views")
*/
private $propsearchviews;
/**
* #var Propsearchfacility[]|ArrayCollection
*
* #ORM\ManyToMany(targetEntity="App\Entity\Propfacility", cascade={"persist"})
* #ORM\JoinTable(name="propsearch_propfacility")
* #ORM\OrderBy({"title": "ASC"})
* #Assert\Count(max="4", maxMessage="Can only select 4 facilities")
*/
private $propsearchfacilities;
public function getId(): ?int
{
return $this->id;
}
public function __construct()
{
$this->propsearchviews = new ArrayCollection();
$this->propsearchfacilities = new ArrayCollection();
}
/**
* #return Collection|Propsearchview[]
*/
public function getPropsearchviews(): Collection
{
return $this->propsearchviews;
}
public function addPropsearchview(Propsearchview $propsearchview): self
{
if (!$this->propsearchviews->contains($propsearchview)) {
$this->propsearchviews[] = $propsearchview;
}
return $this;
}
public function removePropsearchview(Propsearchview $propsearchview): self
{
if ($this->propsearchviews->contains($propsearchview)) {
$this->propsearchviews->removeElement($propsearchview);
}
return $this;
}
/**
* #return Collection|Propsearchfacility[]
*/
public function getPropsearchfacilities(): Collection
{
return $this->propsearchfacilities;
}
public function addPropsearchfacility(Propsearchfacility $propsearchfacility): self
{
if (!$this->propsearchfacilities->contains($propsearchfacility)) {
$this->propsearchfacilities[] = $propsearchacility;
}
return $this;
}
public function removePropsearchfacility(Propsearchfacility $propsearchfacility): self
{
if ($this->propsearchfacilities->contains($propsearchfacility)) {
$this->propsearchfacilities->removeElement($propsearchfacility);
}
return $this;
}
}
This is my original view entity.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
* #ORM\Table(name="propview")
*
* Defines the properties of the Tag entity to represent the post tags.
*
* See https://symfony.com/doc/current/book/doctrine.html#creating-an-entity-class
*
* #author Yonel Ceruto <yonelceruto#gmail.com>
*/
class Propview
{
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string", length=191)
*/
private $title;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function __toString(): string
{
return $this->title;
}
}
So i want to show the collection of views as a checkbox list that has been added to the propsearch table in the form.
Thanks in advance!
Edit 2
Okay so i have the propsearchviews which has an colleciton from propviewtype. including the dataclass from propsearch.
I changed my propertyfiltertype to the following:
<?php
namespace App\Form;
use App\Entity\Propsearch;
class PropertyfilterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('propsearchviews', CollectionType::class, [
'entry_type' => PropviewType::class,
'by_reference' => false,
]);
}
the propviewtype itself
namespace App\Form\Type;
use App\Entity\Propview;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class PropviewType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('propview', EntityType::class, [
'class' => Propview::class,
'choice_label' => 'title',
]);
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Propview::class,
));
}
}
and my html.twig file
<div class="col-12 col-md-4 mb-2">
{% for field in propertybuyform.propsearchviews %}
<div class="col-xs-4">
{{ form_widget(field) }}
{{ form_label(field) }}
</div>
{% endfor %}
</div>
You should use embedded form functionality to achieve this. Please refer to https://symfony.com/doc/current/form/form_collections.html to get idea of how it could be implemented.
Briefly describing your case - you should create PropsearchType which would render propsearchviews property as CollectionType, where 'entry_type' would be another custom form type that you should create - PropviewType, that should render your Propviews as checboxes.

Symfony - Group sequence defined part in entity and in form type

It looks like there's something I can't understand. It will be a long post, so I'll try to be concise.
I try to use GroupSequence in Symfony 4.2, but I'm facing an issue. Goal I want to achieve is adding an unmapped field and define GroupSequence in FormType (because I want to use another FormType on this entity without this unmapped field). I want this unmapped field "verified" to be check before other constraints on the form.
Problem is I can't manage to enable part of the validation using Group Sequence in this particular case.
Sample code : https://github.com/sarramegnag/groupsequence-issue
Here's my entity code :
<?php // src/Entity/Product.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Product
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*
* #Assert\NotBlank()
*/
private $name;
/**
* #ORM\Column(type="text")
*
* #Assert\NotBlank()
*/
private $description;
/**
* #ORM\Column(type="integer")
*
* #Assert\NotBlank()
*/
private $price;
...
And my form type code :
<?php // src/Form/ProductType.php
namespace App\Form;
use App\Entity\Product;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\Constraints\NotBlank;
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('description')
->add('price')
->add('verified', CheckboxType::class, [
'mapped' => false,
'constraints' => [
new NotBlank(['groups' => ['Strict']]),
]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Product::class,
'validation_groups' => new GroupSequence(['Strict', 'Product']),
]);
}
}
It works if I set attribute and the assertion in the entity and map it as a normal field.
// src/Entity/Product.php
/**
* #Assert\NotBlank(groups={"Strict"})
*/
private $verified = false;
...
public function isVerified(): ?bool
{
return $this->verified;
}
public function setVerified(bool $verified): self
{
$this->verified = $verified;
return $this;
}
// src/Form/ProductType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('description')
->add('price')
->add('verified', CheckboxType::class)
;
}
In fact, it works as soon I set a group on an assertion in the entity.
Thank you for your time and let me know if I'm not being very clear.
Guillaume

symfony object could not be converted to string

i'm newbie in symfony and I'm trying to implement a Data Transformer. I followed the documentation and looked different solutions posted in here. But I haven't found what is wrong with my code.
I'm getting this error:
Catchable Fatal Error: Object of class AppBundle\Entity\Todo could not be converted to string
If someone knows another post with the solution, please tell me know where I could look for it.
Thank you in advance.
So, these are my Entities. Todo class
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Todo
*
* #ORM\Table(name="todo")
* #ORM\Entity(repositoryClass="AppBundle\Repository\TodoRepository")
*/
class Todo
{
/**
* #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=20)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="category", type="string", length=20)
*/
private $category;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=10)
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="priority", type="string", length=10)
*/
private $priority;
/**
*
* #ORM\ManyToOne(
* targetEntity="AppBundle\Entity\User",
* inversedBy="todos"
* )
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $creatorId;
//... getters and setters
User class:
<?php
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
/**
* #ORM\OneToMany(
* targetEntity="AppBundle\Entity\Todo",
* mappedBy="creatorId"
* )
*/
private $todos;
}
In the User class, I don't have getter/setters
My TodoType
class TodoType extends AbstractType{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, array(
'label' => 'Name',
'required' => true
)
)
->add('category', TextType::class, array(
'label' => 'Category'
)
)
->add('priority', EntityType::class, array(
'class' => 'AppBundle:Todo',
'choice_label' => 'priority',
)
)
->add('creatorId', TextType::class, array(
'label' => 'creator Id:',
));
$builder->get('creatorId')
->addModelTransformer(new IssueToNumberTransformer($this->manager));
}
public function getName()
{
return 'todo';
}
}
Transformer
<?php
namespace FOS\UserBundle\Form\DataTransformer;
use AppBundle\Entity\User;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class IssueToNumberTransformer implements DataTransformerInterface
{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
/**
* Transforms an object (creatorId) to a string (number).
*
* #param creatorId|null $creatorId
* #return string
*/
public function transform($creatorId)
{
if (null === $creatorId) {
return '';
}
return $creatorId->getId();
}
/**
* Transforms a string (number) to an object (creatorId).
*
* #param string $creatorId
* #return creatorId|null
* #throws TransformationFailedException if object (creatorId) is not found.
*/
public function reverseTransform($creatorId)
{
// no issue number? It's optional, so that's ok
if (!$creatorId) {
return;
}
$creatorId = $this->manager
->getRepository('AppBundle:User')
// query for the issue with this id
->find($creatorId);
if (null === $creatorId) {
throw new TransformationFailedException(sprintf(
'A user with number "%s" does not exist!',
$creatorId
));
}
return $creatorId;
}
}
Controller (function)
public function createAction(Request $request){
$em = $this->getDoctrine()->getManager();
// 1) build the form
$todo = new Todo();
$form = $this->createForm(new TodoType($em), $todo);
// 2) handle the submit (will only happen on POST)
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// 3) save the Todo!
$em->persist($todo);
$em->flush();
return $this->redirectToRoute('todo_create');
}
return $this->render('todo/create.html.twig', array(
'todo'=>$todo,
'form'=>$form->createView()
));
}
It's at this part:
return $this->render('todo/create.html.twig', array(
'todo'=>$todo,
'form'=>$form->createView()
));
Because you are trying to pass the $todo object to your Twig template. You can't do that. What do you need? If you just need the Todo name and you have created getters/setter, you could instead do like this:
return $this->render('todo/create.html.twig', array(
'todo_name' => $todo->getName(),
'form' => $form->createView()
));
Hopefully that makes sense.
EDIT #2 based on comments.
Also this line is wrong in your controller:
$form = $this->createForm(new TodoType($em), $todo);
Should be like this:
$form = $this->createForm(TodoType::class, $todo);

Symfony2: Inserting collection form data

There is a one-to-one relationship between User and Company entity.
When initializing (creating) the user's company, userID should be bind to Company user field as a foreign key. But instead of that, i get this error message:
Property "id" is not public in class
"Website\CompanyBundle\Entity\User". Maybe you should create the
method "setId()"?
Why Symfony wants to create new User when this form is about Company entity, and User entity is just a collection that should provide user's ID.
Here is my code:
Company.php entity:
namespace Website\CompanyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity(repositoryClass="Website\CompanyBundle\Entity\Repository\CompanyRepository")
* #ORM\Table(name="company")
*/
class Company
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="company")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
/**
* #ORM\Column(type="string")
*/
protected $name;
}
CompanyType.php
class CompanyType extends AbstractType
{
private $security;
public function __construct(SecurityContext $security)
{
$this->security= $security;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$user = $this->securityContext->getToken()->getUser();
$builder
->add('user', new UserType($security))
->add('company_name')
->add('company_address')
...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Website\CompanyBundle\Entity\Company'
));
}
public function getName()
{
return 'user';
}
}
UserRelationType.php
class UserRelationType extends AbstractType
{
private $user;
public function __construct(SecurityContext $security){
$this->user = $security->getToken()->getUser();
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', 'hidden', array('data' => $this->user->getId()))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Website\CompanyBundle\Entity\User'
));
}
public function getName()
{
return 'user';
}
}
User.php entity
namespace Website\CompanyBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
*/
protected $name;
/**
* #ORM\OneToOne(targetEntity="Company", mappedBy="user")
*/
protected $company;
}
You map entity to form in UserRelationType. On save it try to set id on user entity. You must specify data transformer or use entity type if you need to select existed user.
If you want to set current user, better do it in event listener like pre_persist
your properties in your entities are protected but you have not created getters/setters for them. ( or you have not pasted your full code )
Therefore the form-builder is not able to access your user's properties.
At least the public function setId($id) in User.php is definitely missing!
That's why the exception is thrown saying:
Maybe you should create the method "setId()"?
Create getters and settes for every property using ...
app/console doctrine:generate:entities
or create them by hand...
User.php
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
return $this;
}
// ...
I solved this problem without adding collections and just using Doctrine transitive persistence like described in this page: https://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations
CompanyController.php
public function createIndex(Request $request){
$user = $this->getId();
$company = new Company();
if($user instanceof User){
$company->setUser($user);
}
$request = $this->getRequest();
$createForm = $this->createForm(new CompanyType(), $company);
if('POST' === $request->getMethod())
{
$createForm->bindRequest($request);
if($createForm->isValid())
{
$em = $this->getDoctrine()->getManager();
$em->persist($company);
$em->flush();
}
}
}
Thank you all for your help

Resources