Property not found Symfony - php

I'm receiving this error on Symfony 2.7.9:
Neither the property "puestos" nor one of the methods "addPuesto()"/"removePuesto()", "setPuestos()", "puestos()", "__set()" or "__call()" exist and have public access in class "UserBundle\Entity\UsuarioTrabajador".
<?php
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use PUGX\MultiUserBundle\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity
* #ORM\Table(name="usuario_trabajador")
* #UniqueEntity(fields = "username", targetClass = "UserBundle\Entity\Usuario", message="fos_user.username.already_used")
* #UniqueEntity(fields = "email", targetClass = "UserBundle\Entity\Usuario", message="fos_user.email.already_used")
*
* #UniqueEntity(fields = {"nit","dpi"}, targetClass = "UserBundle\Entity\UsuarioTrabajador", message="El dpi o nit debe ser único")
* Esta entidad cubre los tipos de Asistente, Supervisor y Gerente.
*
* #author Pablo Díaz soporte#newtonlabs.com.gt
*/
class UsuarioTrabajador extends Usuario
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="direccion",type="string",length=255)
*/
private $direccion;
/**
* #var date fecha de egreso de la empresa.
* #ORM\Column(name="fechaEgreso", type="date",nullable=true)
*/
private $fechaEgreso;
/**
* #var string DPI del trabajador
* #ORM\Column(name="dpi",type="string",length=20, unique=true)
*/
private $dpi;
/**
* Número de identificación tributaria.
*
* #var string
* #ORM\Column(name="nit", type="string",length=20,unique=true)
*/
private $nit;
/**
* #var int
* #ORM\Column(name="telefono", type="string",length=15,nullable=true)
*/
private $telefono;
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="DatosPrestaciones", mappedBy="usuario")
*/
private $datosPrestaciones;
/**
* #var string Tipo de Usuarios(Asistente, Supervisor, Gerente)
* #ORM\OneToMany(targetEntity="UserBundle\Entity\Puesto", mappedBy="usuarioPuesto")
*/
private $puestos;
/**
* Constructor.
*/
public function __construct()
{
$this->datosPrestaciones = new \Doctrine\Common\Collections\ArrayCollection();
$this->puestos = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set direccion
*
* #param string $direccion
*
* #return UsuarioTrabajador
*/
public function setDireccion($direccion)
{
$this->direccion = $direccion;
return $this;
}
/**
* Get direccion
*
* #return string
*/
public function getDireccion()
{
return $this->direccion;
}
/**
* Set fechaEgreso
*
* #param \DateTime $fechaEgreso
*
* #return UsuarioTrabajador
*/
public function setFechaEgreso($fechaEgreso)
{
$this->fechaEgreso = $fechaEgreso;
return $this;
}
/**
* Get fechaEgreso
*
* #return \DateTime
*/
public function getFechaEgreso()
{
return $this->fechaEgreso;
}
/**
* Set dpi
*
* #param string $dpi
*
* #return UsuarioTrabajador
*/
public function setDpi($dpi)
{
$this->dpi = $dpi;
return $this;
}
/**
* Get dpi
*
* #return string
*/
public function getDpi()
{
return $this->dpi;
}
/**
* Set nit
*
* #param string $nit
*
* #return UsuarioTrabajador
*/
public function setNit($nit)
{
$this->nit = $nit;
return $this;
}
/**
* Get nit
*
* #return string
*/
public function getNit()
{
return $this->nit;
}
/**
* Set telefono
*
* #param string $telefono
*
* #return UsuarioTrabajador
*/
public function setTelefono($telefono)
{
$this->telefono = $telefono;
return $this;
}
/**
* Get telefono
*
* #return string
*/
public function getTelefono()
{
return $this->telefono;
}
/**
* Add datosPrestacione
*
* #param \UserBundle\Entity\DatosPrestaciones $datosPrestacione
*
* #return UsuarioTrabajador
*/
public function addDatosPrestacione(\UserBundle\Entity\DatosPrestaciones $datosPrestacione)
{
$this->datosPrestaciones[] = $datosPrestacione;
return $this;
}
/**
* Remove datosPrestacione
*
* #param \UserBundle\Entity\DatosPrestaciones $datosPrestacione
*/
public function removeDatosPrestacione(\UserBundle\Entity\DatosPrestaciones $datosPrestacione)
{
$this->datosPrestaciones->removeElement($datosPrestacione);
}
/**
* Get datosPrestaciones
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDatosPrestaciones()
{
return $this->datosPrestaciones;
}
/**
* Add puesto
*
* #param \UserBundle\Entity\Puesto $puesto
*
* #return UsuarioTrabajador
*/
public function addPuesto(\UserBundle\Entity\Puesto $puesto)
{
$this->puestos[] = $puesto;
return $this;
}
/**
* Remove puesto
*
* #param \UserBundle\Entity\Puesto $puesto
*/
public function removePuesto(\UserBundle\Entity\Puesto $puesto)
{
$this->puestos->removeElement($puesto);
}
/**
* Get puestos
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPuestos()
{
return $this->puestos;
}
public function __toString()
{
return $this->nombre.' '.$this->apellidos;
}
}
This is the other Entity
<?php
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Puesto
*
* #ORM\Table()
* #ORM\Entity
*/
class Puesto
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="tipoPuesto",type="string",length=100)
*/
private $tipoPuesto;
/**
* #var string
*
* #ORM\Column(name="nombrePuesto", type="string", length=255)
*/
private $nombrePuesto;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #ORM\ManyToOne(targetEntity="UserBundle\Entity\UsuarioTrabajador", inversedBy="puestos")
* #var [type]
*/
private $usuarioPuesto;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nombrePuesto
*
* #param string $nombrePuesto
*
* #return Puesto
*/
public function setNombrePuesto($nombrePuesto)
{
$this->nombrePuesto = $nombrePuesto;
return $this;
}
/**
* Get nombrePuesto
*
* #return string
*/
public function getNombrePuesto()
{
return $this->nombrePuesto;
}
/**
* Set date
*
* #param \DateTime $date
*
* #return Puesto
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set usuario
*
* #param \UserBundle\Entity\UsuarioTrabajdor $usuario
*
* #return Puesto
*/
public function setUsuario(\UserBundle\Entity\UsuarioTrabajdor $usuario = null)
{
$this->usuario = $usuario;
return $this;
}
/**
* Get usuario
*
* #return \UserBundle\Entity\UsuarioTrabajdor
*/
public function getUsuario()
{
return $this->usuario;
}
/**
* Set tipoPuesto
*
* #param string $tipoPuesto
*
* #return Puesto
*/
public function setTipoPuesto($tipoPuesto)
{
$this->tipoPuesto = $tipoPuesto;
return $this;
}
/**
* Get tipoPuesto
*
* #return string
*/
public function getTipoPuesto()
{
return $this->tipoPuesto;
}
/**
* Mostrar el noombre del puesto
* #return string
*/
public function __toString()
{
return $this->tipoPuesto.': '.$this->nombrePuesto.' '.$this->getUsuarioPuesto();
}
/**
* Set usuarioPuesto
*
* #param \UserBundle\Entity\UsuarioTrabajador $usuarioPuesto
*
* #return Puesto
*/
public function setUsuarioPuesto(\UserBundle\Entity\UsuarioTrabajador $usuarioPuesto = null)
{
$this->usuarioPuesto = $usuarioPuesto;
return $this;
}
/**
* Get usuarioPuesto
*
* #return \UserBundle\Entity\UsuarioTrabajador
*/
public function getUsuarioPuesto()
{
return $this->usuarioPuesto;
}
}
This is the Form
<?php
namespace UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
class RegistrationTrabajadorFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// agregar campos personalizados
$builder->add('nombre', null, [
'label' => 'Nombre/s',
'attr' => [
'placeholder' => 'Nombre/s',
'class' => 'form-control input-lg',
],
])
->add('apellidos', null, [
'label' => 'Apellidos/s',
'attr' => [
'placeholder' => 'Apellidos',
'class' => 'form-control input-lg',
],
])
->add('username', null, [
'label' => 'Usuario',
'translation_domain' => 'FOSUserBundle',
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Nombre de Usuario',
],
])
->add('email', 'email', [
'label' => 'Correo',
'translation_domain' => 'FOSUserBundle',
'required' => true,
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Correo electrónico',
],
])
->add('plainPassword', 'repeated', [
'label' => 'Contraseña',
'type' => 'password',
'options' => ['translation_domain' => 'FOSUserBundle'],
'first_options' => [
'label' => 'Contraseña',
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Contraseña',
],
],
'second_options' => [
'label' => 'Repetir Contraseña',
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Repetir Contraseña',
],
],
'invalid_message' => 'fos_user.password.mismatch',
])
->add('direccion',null,[
'label' => 'Dirección',
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Dirección',
],
'required' => true,
])
->add('dpi', null, [
'label' => 'DPI',
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Documento Personal de Identificación',
],
'required' => true,
])
->add('nit', null, [
'label' => 'NIT',
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Número de Identificación Tributaria',
],
'required' => true,
])
->add('telefono', null, [
'label' => 'Teléfono',
'translation_domain' => 'FOSUserBundle',
'attr' => [
'class' => 'form-control input-lg',
'placeholder' => 'Teléfono',
],
'required' => false,
])
->add('submit', 'submit', [
'label' => 'Guardar',
'attr' => [
'class' => 'btn btn-primary',
],
])
->add('puestos', 'entity', [
'label' => false,
'empty_value' => 'Aquí aparecerá su puesto',
'class' => 'UserBundle:Puesto',
'attr' => [
'class' => 'select2',
],
])
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'validation' => ['registration'],
]);
}
public function getParent()
{
return 'fos_user_registration';
}
public function getName()
{
return 'user_registration';
}
}

Related

Symfony 5 using the validation to validate a new entity

I'm using Symfony 5.3.7, and using the #Assert annotations, attempting to validate a new user upon registering. Trying to understand the docs however not getting anywhere. Ideally I'd like to be able to understand how to validate an entity using these annotations. I've tried using a separate class, and got nowhere with understanding, although I do want to go down this route in case i reuse the component elsewhere. (I'd rather not validate in the form, but if i have to I can)
Entity
class User implements UserInterface
{
use TimestampableEntity;
/**
* #var int
*
* #ORM\Id()
* #ORM\GeneratedValue(strategy="IDENTITY")
* #ORM\Column(name="intUserId", type="integer", nullable=false)
*/
private int $id;
/**
* #var string
*
* #ORM\Column(name="strFirstName", type="string", nullable=false)
*
* #Assert\NotBlank
* #Assert\Length(
* min = 2,
* max = 50,
* minMessage = "Your first name must be at least {{ limit}} characters long",
* maxMessage = "Your first name cannot be longer than {{ limit }} characters"
* )
*/
private string $firstName;
/**
* #var string
*
* #ORM\Column(name="strLastName", type="string", nullable=false)
*
* #Assert\NotBlank
* #Assert\Length(
* min = 2,
* max = 50,
* minMessage = "Your first name must be at least {{ limit}} characters long",
* maxMessage = "Your first name cannot be longer than {{ limit }} characters"
* )
*/
private string $lastName;
/**
* #var string
*
* #ORM\Column(name="strUsername", type="string", nullable=false)
*
* #Assert\Unique()
* #Assert\Length(
* min = 2,
* max = 15,
* minMessage = "Your first name must be at least {{ limit}} characters long",
* maxMessage = "Your first name cannot be longer than {{ limit }} characters"
* )
*/
private string $username;
/**
* #var string
*
* #ORM\Column(name="strPassword", type="string", nullable=false)
*
* #Assert\NotNull()
* #Assert\Regex(pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!#$%^&*-]).{8,}$")
*
* #SecurityAssert\UserPassword(message = "Password is incorrect, please try again")
*/
private string $password;
/**
* #var string
*
* #ORM\Column(name="strEmail", type="string", nullable=false)
*
* #Assert\Unique()
* #Assert\Regex(pattern = "\b[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,}\b")
*/
private string $email;
/**
* #var boolean
*
* #ORM\Column(name="bolAcceptTermsConditions", type="bool", nullable=false)
*
* #Assert\NotNull()
*/
private bool $acceptTermsAndConditions;
/**
* #var boolean
*
* #ORM\Column(name="bolAcceptPrivacyPolicy", type="bool", nullable=false)
*
* #Assert\NotNull()
*/
private bool $acceptPrivacyPolicy;
/**
* #var boolean
*
* #ORM\Column(name="bolEmailOptIn", type="bool", nullable=false)
*
* #Assert\NotNull()
*/
private bool $emailOptIn;
/**
* User constructor.
*
* #param string $firstName
* #param string $lastName
* #param string $username
* #param string $email
* #param string $password
*/
public function __construct(
string $firstName,
string $lastName,
string $username,
string $email,
string $password,
bool $acceptTermsAndConditions = false,
bool $acceptPrivacyPolicy = false,
bool $emailOptIn = false
) {
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->username = $username;
$this->email = $email;
$this->password = $password;
$this->acceptTermsAndConditions = $acceptTermsAndConditions;
$this->acceptPrivacyPolicy = $acceptPrivacyPolicy;
$this->emailOptIn = $emailOptIn;
$this->dtmAdded = Carbon::now();
}
Ideally I'd pass in the new entity or the array, either create the entity in the validator or similar
Controller
public function register(Request $request): Response
{
$registrationForm = $this->createForm(RegistrationFormType::class);
$registrationForm->handleRequest($request);
if ($registrationForm->isSubmitted() && $registrationForm->isValid()) {
$newUserData = $registrationForm->getData();
$user = new User(
$newUserData['firstName'],
$newUserData['lastName'],
$newUserData['email'],
$newUserData['username'],
$newUserData['password'],
$newUserData['termsConditions'],
$newUserData['privacyPolicy'],
$newUserData['emailFrequency']
);
return new RedirectResponse($request->headers->get('referer'));
}
return new RedirectResponse($request->headers->get('referer'));
}
Form
<?php
declare(strict_types=1);
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RegistrationFormType extends AbstractType
{
public const FORM_NAME = 'registrationForm';
/**
* Form Builder for Registration Form
*
* #param FormBuilderInterface $builder
* #param array $options
*
* #return void
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('firstName', TextType::class, [
'label' => 'Firstname:',
'required' => true,
'attr' => [
'class' => 'form-input input-type-text',
'placeholder' => 'John',
],
]);
$builder->add('lastName', TextType::class, [
'label' => 'Lastname:',
'required' => true,
'attr' => [
'class' => 'form-input input-type-text',
'placeholder' => 'Doe'
],
]);
$builder->add('email', EmailType::class, [
'label' => 'Email:',
'required' => true,
'attr' => [
'class' => 'form-input input-type-email',
'placeholder' => 'example#example.com'
]
]);
$builder->add('username', TextType::class, [
'label' => 'Username:',
'required' => true,
'attr' => [
'class' => 'form-input input-type-text',
]
]);
$builder->add('password', PasswordType::class, [
'label' => 'Password:',
'required' => true,
'attr' => [
'class' => 'form-input input-type-email',
]
]);
$builder->add('termsConditions', CheckboxType::class, [
'label' => 'I accept the terms & conditions',
'required' => true,
]);
$builder->add('privacyPolicy', CheckboxType::class, [
'label' => 'I have read and understood the privacy policy',
'required' => true,
]);
$builder->add('emailFrequency', ChoiceType::class, [
'label' => 'Opt in to emails:',
'multiple' => false,
'expanded' => true,
'choices' => [
'Yes' => true,
'No' => false,
],
]);
}
/**
* #param OptionsResolver $resolver
*
* #return void
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([]);
}
/**
* #return string
*/
public function getBlockPrefix(): string
{
return self::FORM_NAME;
}
}
so the issue is that you are not passing the new User object to the form, so the validation will not happen in this case.
What you can do to fix this is, declare the data_class for the form to be User in this case
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
And when you create the form in the action you need to pass a new User object to it like:
$user = new User();
$registrationForm = $this->createForm(RegistrationFormType::class, $user);
And you can remove the part where you instantiate and send data to the user entity
$user = new User(
$newUserData['firstName'],
$newUserData['lastName'],
$newUserData['email'],
$newUserData['username'],
$newUserData['password'],
$newUserData['termsConditions'],
$newUserData['privacyPolicy'],
$newUserData['emailFrequency']
);
instead of that, you should just use the entity manager to save the new user
, for that, you need to inject the entity manager, like so:
public function register(Request $request, EntityManagerInterface $entityManager): Response
and just use it to save the user object into the database
if ($registrationForm->isSubmitted() && $registrationForm->isValid()) {
$entityManager->persist($user);
$entityManager->flush();
}

Symfony CollectionType many to many relation in edit form

I have crud with 3 entities. Meal, Product and ProductsQuantity. Between Meal and ProductQuantity is relation many to many. Adding data is working fine, all data are saving to entities but problem is when in want to edit form. Then I got error:
The form's view data is expected to be an instance of class MealBundle\Entity\ProductsQuantity, but is an instance of class Doctrine\ORM\PersistentCollection. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms an instance of class Doctrine\ORM\PersistentCollection to an instance of MealBundle\Entity\ProductsQuantity.
I tried with data_class option to null, and setting fetch="EAGER" on the relation but it doesn't solved the problem.
Meal:
/**
* #Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="name", type="string", length=255)
*/
protected $name = "";
/**
* #var ProductsQuantity[]|Collection
* #ORM\ManyToMany(targetEntity="ProductsQuantity", inversedBy="meal", cascade={"persist"}, fetch="EAGER")
* #ORM\JoinTable(name="meal_products_quantity_relations",
* joinColumns={#ORM\JoinColumn(name="meal_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="products_quantity_id", referencedColumnName="id")}
* )
*/
protected $productsQuantity;
/**
* Meal constructor.
*/
public function __construct()
{
$this->productsQuantity = new ArrayCollection();
}
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
* #return Meal
*/
public function setId(int $id): Meal
{
$this->id = $id;
return $this;
}
/**
* #return string
*/
public function getName(): string
{
return $this->name;
}
/**
* #param string $name
* #return Meal
*/
public function setName(string $name): Meal
{
$this->name = $name;
return $this;
}
/**
* #return Collection|ProductsQuantity[]
*/
public function getProductsQuantity()
{
return $this->productsQuantity;
}
/**
* #param Collection|ProductsQuantity[] $productsQuantity
* #return Meal
*/
public function setProductsQuantity($productsQuantity)
{
$this->productsQuantity = $productsQuantity;
return $this;
}
ProductQuantity:
/**
* #Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #var Product
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* #ORM\ManyToOne(targetEntity="Product", inversedBy="productsQuantity")
*/
protected $product;
/**
* #var integer
* #ORM\Column(name="amount", type="integer")
*/
protected $amount;
/**
* #var $meal
* #ORM\ManyToMany(targetEntity="MealBundle\Entity\Meal", mappedBy="productsQuantity")
*/
protected $meal;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
* #return ProductsQuantity
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return Product
*/
public function getProduct(): ?Product
{
return $this->product;
}
/**
* #param Product $product
* #return ProductsQuantity
*/
public function setProduct(Product $product): ProductsQuantity
{
$this->product = $product;
return $this;
}
/**
* #return int
*/
public function getAmount(): ?int
{
return $this->amount;
}
/**
* #param int $amount
*/
public function setAmount(int $amount): void
{
$this->amount = $amount;
}
/**
* #return mixed
*/
public function getMeal()
{
return $this->meal;
}
/**
* #param mixed $meal
* #return ProductsQuantity
*/
public function setMeal($meal)
{
$this->meal = $meal;
return $this;
}
Meal form:
class MealType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options = [])
{
parent::buildForm($builder, $options);
/** #var Meal $meal */
$meal = $options['data'];
$data = null;
if(!empty($meal)) {
$data = $meal->getProductsQuantity();
} else {
$data = new ProductsQuantity();
}
$builder
->add('name', TextType::class,[
'label' => 'Nazwa Dania',
'required' => true
])->add('productsQuantity', CollectionType::class, [
'data_class' => null,
'label' => 'Produkty',
'entry_type' => ProductsQuantityType::class,
'allow_add' => true,
'data' => ['productsQuantity' => $data],
'prototype_name' => '__product__',
'entry_options' => [
'allow_extra_fields' => true,
'label' => false
],
'prototype' => true
])->add('addProduct', ButtonType::class, [
'label' => 'Dodaj kolejny produkt',
'attr' => [
'class' => 'btn-default addProductEntry'
]
])->add('submit', SubmitType::class, [
'label' => 'Dodaj'
]);
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('productsQuantity');
$resolver->setDefaults([
'data_class' => Meal::class
]);
}
}
ProductsQuantity form:
class ProductsQuantityType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('product', EntityType::class,[
'class' => Product::class,
'label' => 'Nazwa produktu',
])
->add('amount', NumberType::class, [
'label' => 'Ilość',
'required' => true,
'attr' => [
'placeholder' => 'ilość'
]
])
->add('removeProduct', ButtonType::class, [
'label' => 'X',
'attr' => [
'class' => 'btn-danger removeProductEntry'
]
]);
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ProductsQuantity::class,
]);
}
}
If I change 'data' => ['productsQuantity' => $data] to 'data' => ['productsQuantity' => new ProductsQuantity()] there is no error but have empty ProductsQuantity part of MealType form. Can anyone tell me how to fix this?

Symfony 3 - Form with OneToMany association in database

I work on a OneToMany association in my database. This association work perfectly when I try to add data from fixtures and when I try to return data from database.
The problem is with my FormType CommandType which does'nt work. Symfony and Doctrine return this error message :
An exception occurred while executing 'INSERT INTO command_product (quantity, command_id, product_id) VALUES (?, ?, ?)' with params [3, null, 1]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1048 Column 'command_id' cannot be null
CommandType's code :
class CommandType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('establishment', EntityType::class, array(
'class' => Company::class,
'required' => true
))
->add('dateCreation', DateTimeType::class, array(
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',
'required' => true
))
->add('contains', CollectionType::class, array(
'entry_type' => CommandProductType::class,
'required' => true,
'allow_add' => true
))
->add('state',TextType::class, array(
'required' => true
))
->add('totalAmount', MoneyType::class, array(
'required' => true
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Command::class
));
}
public function getBlockPrefix()
{
return 'appbundle_command';
}
}
CommandProductType's code :
class CommandProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('quantity', NumberType::class, array(
'required' => true
))
->add('product', EntityType::class, array(
'class' => Product::class,
'required' => true
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => CommandProduct::class
));
}
public function getBlockPrefix()
{
return 'appbundle_commandproduct';
}
}
Command's code class :
class Command
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Company $establishment
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Company")
* #ORM\JoinColumn(name="establishment_id", referencedColumnName="id", nullable=false)
*/
private $establishment;
/**
* #var DateTime $dateCreation
*
* #ORM\Column(name="dateCreation", type="datetime", nullable=false)
* #Assert\Type("datetime")
*/
private $dateCreation;
/**
* #var string $state
*
* #ORM\Column(name="state", type="string", length=255, nullable=false)
* #Assert\Type("string")
*/
private $state;
/**
* #var float $totalAmount
*
* #ORM\Column(name="totalAmount", type="float", precision=10, scale=2, nullable=false)
* #Assert\NotBlank()
* #Assert\Type(type="float")
*/
private $totalAmount;
/**
* #var mixed $contains
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\CommandProduct", mappedBy="contain", cascade={"persist", "remove"})
*/
private $contains;
public function __construct()
{
$this->contains = new ArrayCollection();
}
/**
* #var CommandProduct $commandProduct
*/
public function addContain(CommandProduct $commandProduct = null)
{
$commandProduct->setContain($this);
$this->contains->add($commandProduct);
}
/**
* #param CommandProduct $commandProduct
*/
public function removeContain(CommandProduct $commandProduct)
{
if ($this->contains->contains($commandProduct)) {
$this->contains->removeElement($commandProduct);
}
}
}
CommandOrder's code class :
class CommandProduct
{
/**
* #var int $id
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var Command $contain
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Command", inversedBy="contains")
* #ORM\JoinColumn(name="command_id", referencedColumnName="id", nullable=false)
*/
private $contain;
/**
* #var int $quantity
*
* #ORM\Column(name="quantity", type="integer", nullable=true, options={"default": 1})
* #Assert\NotBlank()
* #Assert\Type(type="int")
*/
private $quantity;
/**
* #var Product $product
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Product")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
private $product;
}

How to hide system fields (oro platform 2.1.0 & symfony 2.8)

I am using Oro Platform and AccountBundle (OroCRM).
I want to remove (hide) social fields, and customize the address for my location (hide unnecessary fields). How can I do this? What to edit in code? Custom fields (created in ui) can be freely edited. The problem is with system fields.
Can I edit views (twig.html)? Is there another way? What is good practice?
UserBundle/Form/Type/UserType.php
<?php
namespace Oro\Bundle\UserBundle\Form\Type;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Oro\Bundle\FormBundle\Form\Type\OroBirthdayType;
use Oro\Bundle\SecurityBundle\SecurityFacade;
use Oro\Bundle\UserBundle\Entity\User;
use Oro\Bundle\UserBundle\Form\EventListener\UserSubscriber;
use Oro\Bundle\UserBundle\Form\Provider\PasswordFieldOptionsProvider;
class UserType extends AbstractType
{
/** #var SecurityContextInterface */
protected $security;
/** #var SecurityFacade */
protected $securityFacade;
/** #var bool */
protected $isMyProfilePage;
/** #var PasswordFieldOptionsProvider */
protected $optionsProvider;
/**
* #param SecurityContextInterface $security Security context
* #param SecurityFacade $securityFacade
* #param Request $request Request
* #param PasswordFieldOptionsProvider $optionsProvider
*/
public function __construct(
SecurityContextInterface $security,
SecurityFacade $securityFacade,
Request $request,
PasswordFieldOptionsProvider $optionsProvider
) {
$this->security = $security;
$this->securityFacade = $securityFacade;
$this->isMyProfilePage = $request->attributes->get('_route') === 'oro_user_profile_update';
$this->optionsProvider = $optionsProvider;
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->addEntityFields($builder);
}
/**
* {#inheritdoc}
*/
public function addEntityFields(FormBuilderInterface $builder)
{
// user fields
$builder->addEventSubscriber(new UserSubscriber($builder->getFormFactory(), $this->security));
$this->setDefaultUserFields($builder);
if ($this->securityFacade->isGranted('oro_user_role_view')) {
$builder->add(
'roles',
'entity',
[
'property_path' => 'rolesCollection',
'label' => 'oro.user.roles.label',
'class' => 'OroUserBundle:Role',
'property' => 'label',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('r')
->where('r.role <> :anon')
->setParameter('anon', User::ROLE_ANONYMOUS)
->orderBy('r.label');
},
'multiple' => true,
'expanded' => true,
'required' => !$this->isMyProfilePage,
'read_only' => $this->isMyProfilePage,
'disabled' => $this->isMyProfilePage,
'translatable_options' => false
]
);
}
if ($this->securityFacade->isGranted('oro_user_group_view')) {
$builder->add(
'groups',
'entity',
[
'label' => 'oro.user.groups.label',
'class' => 'OroUserBundle:Group',
'property' => 'name',
'multiple' => true,
'expanded' => true,
'required' => false,
'read_only' => $this->isMyProfilePage,
'disabled' => $this->isMyProfilePage,
'translatable_options' => false
]
);
}
$this->addOrganizationField($builder);
$builder
->add(
'plainPassword',
'repeated',
[
'invalid_message' => 'oro.user.message.password_mismatch',
'type' => 'password',
'required' => true,
'first_options' => [
'label' => 'oro.user.password.label',
'tooltip' => $this->optionsProvider->getTooltip(),
'attr' => [
'data-validation' => $this->optionsProvider->getDataValidationOption()
]
],
'second_options' => [
'label' => 'oro.user.password_re.label',
],
]
)
->add(
'emails',
'collection',
[
'label' => 'oro.user.emails.label',
'type' => 'oro_user_email',
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'prototype' => true,
'prototype_name' => 'tag__name__'
]
)
->add('change_password', ChangePasswordType::NAME)
->add('avatar', 'oro_image', ['label' => 'oro.user.avatar.label', 'required' => false]);
$this->addInviteUserField($builder);
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => 'Oro\Bundle\UserBundle\Entity\User',
'intention' => 'user',
'validation_groups' => function ($form) {
if ($form instanceof FormInterface) {
$user = $form->getData();
} elseif ($form instanceof FormView) {
$user = $form->vars['value'];
} else {
$user = null;
}
return $user && $user->getId()
? ['Roles', 'Default']
: ['Registration', 'Roles', 'Default'];
},
'ownership_disabled' => $this->isMyProfilePage
]
);
}
/**
* {#inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'oro_user_user';
}
/**
* Set user fields
*
* #param FormBuilderInterface $builder
*/
protected function setDefaultUserFields(FormBuilderInterface $builder)
{
$builder
->add('username', 'text', ['label' => 'oro.user.username.label', 'required' => true])
->add('email', 'email', ['label' => 'oro.user.email.label', 'required' => true])
->add('phone', 'text', ['label' => 'oro.user.phone.label', 'required' => false])
->add('namePrefix', 'text', ['label' => 'oro.user.name_prefix.label', 'required' => false])
->add('firstName', 'text', ['label' => 'oro.user.first_name.label', 'required' => true])
->add('middleName', 'text', ['label' => 'oro.user.middle_name.label', 'required' => false])
->add('lastName', 'text', ['label' => 'oro.user.last_name.label', 'required' => true])
->add('nameSuffix', 'text', ['label' => 'oro.user.name_suffix.label', 'required' => false])
->add('birthday', OroBirthdayType::class, ['label' => 'oro.user.birthday.label', 'required' => false]);
}
/**
* Add Invite user fields
*
* #param FormBuilderInterface $builder
*/
protected function addInviteUserField(FormBuilderInterface $builder)
{
$builder->add(
'inviteUser',
'checkbox',
[
'label' => 'oro.user.invite.label',
'mapped' => false,
'required' => false,
'tooltip' => 'oro.user.invite.tooltip',
'data' => true
]
);
}
/**
* #param FormBuilderInterface $builder
*/
protected function addOrganizationField(FormBuilderInterface $builder)
{
if ($this->securityFacade->isGranted('oro_organization_view')
&& $this->securityFacade->isGranted('oro_business_unit_view')
) {
$builder->add(
'organizations',
'oro_organizations_select',
[
'required' => false,
]
);
}
}
... /Entity/User.php
<?php
namespace Oro\Bundle\UserBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use Oro\Bundle\EmailBundle\Entity\EmailOrigin;
use Oro\Bundle\EmailBundle\Entity\EmailOwnerInterface;
use Oro\Bundle\EmailBundle\Model\EmailHolderInterface;
use Oro\Bundle\EntityConfigBundle\Metadata\Annotation\Config;
use Oro\Bundle\EntityConfigBundle\Metadata\Annotation\ConfigField;
use Oro\Bundle\ImapBundle\Entity\UserEmailOrigin;
use Oro\Bundle\ImapBundle\Form\Model\AccountTypeModel;
use Oro\Bundle\LocaleBundle\Model\FullNameInterface;
use Oro\Bundle\NotificationBundle\Entity\NotificationEmailInterface;
use Oro\Bundle\OrganizationBundle\Entity\BusinessUnit;
use Oro\Bundle\OrganizationBundle\Entity\Organization;
use Oro\Bundle\OrganizationBundle\Entity\OrganizationInterface;
use Oro\Bundle\UserBundle\Model\ExtendUser;
use Oro\Bundle\UserBundle\Security\AdvancedApiUserInterface;
/**
* #SuppressWarnings(PHPMD.ExcessivePublicCount)
* #SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* #SuppressWarnings(PHPMD.ExcessiveClassLength)
*
* #ORM\Entity(repositoryClass="Oro\Bundle\UserBundle\Entity\Repository\UserRepository")
* #ORM\Table(name="oro_user", indexes = {
* #ORM\Index("user_first_name_last_name_idx", columns = {"first_name", "last_name"})
* })
* #ORM\HasLifecycleCallbacks()
* #Config(
* routeName="oro_user_index",
* routeView="oro_user_view",
* defaultValues={
* "entity"={
* "icon"="fa-user"
* },
* "grouping"={
* "groups"={"dictionary"}
* },
* "dictionary"={
* "virtual_fields"={"id"},
* "search_fields"={"firstName", "lastName"},
* "representation_field"="fullName",
* "activity_support"="true"
* },
* "ownership"={
* "owner_type"="BUSINESS_UNIT",
* "owner_field_name"="owner",
* "owner_column_name"="business_unit_owner_id",
* "organization_field_name"="organization",
* "organization_column_name"="organization_id"
* },
* "dataaudit"={"auditable"=true},
* "security"={
* "type"="ACL",
* "group_name"="",
* "category"="account_management"
* },
* "form"={
* "form_type"="oro_user_select",
* "grid_name"="users-select-grid"
* },
* "grid"={
* "default"="users-grid",
* "context"="users-for-context-grid"
* },
* "tag"={
* "enabled"=true
* }
* }
* )
* #JMS\ExclusionPolicy("ALL")
*/
class User extends ExtendUser implements
EmailOwnerInterface,
EmailHolderInterface,
FullNameInterface,
NotificationEmailInterface,
OrganizationAwareUserInterface,
AdvancedApiUserInterface
{
const ROLE_DEFAULT = 'ROLE_USER';
const ROLE_ADMINISTRATOR = 'ROLE_ADMINISTRATOR';
const ROLE_ANONYMOUS = 'IS_AUTHENTICATED_ANONYMOUSLY';
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Type("integer")
* #JMS\Expose
*/
protected $id;
/**
* #var string
*
* #ORM\Column(type="string", length=255, unique=true)
* #JMS\Type("string")
* #JMS\Expose
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* },
* "importexport"={
* "identity"=true
* }
* }
* )
*/
protected $username;
/**
* #var string
*
* #ORM\Column(type="string", length=255, unique=true)
* #JMS\Type("string")
* #JMS\Expose
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* }
* }
* )
*/
protected $email;
/**
* Name prefix
*
* #var string
*
* #ORM\Column(name="name_prefix", type="string", length=255, nullable=true)
* #JMS\Type("string")
* #JMS\Expose
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* }
* }
* )
*/
protected $namePrefix;
/**
* First name
*
* #var string
*
* #ORM\Column(name="first_name", type="string", length=255, nullable=true)
* #JMS\Type("string")
* #JMS\Expose
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* }
* }
* )
*/
protected $firstName;
/**
* Middle name
*
* #var string
*
* #ORM\Column(name="middle_name", type="string", length=255, nullable=true)
* #JMS\Type("string")
* #JMS\Expose
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* }
* }
* )
*/
protected $middleName;
/**
* Last name
*
* #var string
*
* #ORM\Column(name="last_name", type="string", length=255, nullable=true)
* #JMS\Type("string")
* #JMS\Expose
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* }
* }
* )
*/
protected $lastName;
/**
* Name suffix
*
* #var string
*
* #ORM\Column(name="name_suffix", type="string", length=255, nullable=true)
* #JMS\Type("string")
* #JMS\Expose
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* }
* }
* )
*/
protected $nameSuffix;
/**
* #var Group[]|Collection
*
* #ORM\ManyToMany(targetEntity="Oro\Bundle\UserBundle\Entity\Group")
* #ORM\JoinTable(name="oro_user_access_group",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id", onDelete="CASCADE")}
* )
* #ConfigField(
* defaultValues={
* "dataaudit"={
* "auditable"=true
* }
* }
* )
*/
(...)
You can inherit the UserBundle and override the parts you need.
Symfony docs for bundle inheritance.

New fields not persisted in database after overriding FormType when register a new user

I am overriding the form type to register a user. All looks ok, but when I submit my form the new fields are not persisted in database.
I followed the documentation.
My ProfileType:
<?php
namespace Application\Sonata\UserBundle\Form\Type;
//use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
//use Sonata\UserBundle\Model\UserInterface;
use Sonata\UserBundle\Form\Type\ProfileType as BaseType;
class ProfileType extends BaseType
{
private $class;
/**
* #param string $class The User class name
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('username', null, array(
'label' => 'Pseudo',
'required' => false
))
->add('firstname', null, array(
'label' => 'Prénom'
))
->add('lastname', null, array(
'label' => 'Nom'
))
->add('email', 'email', array(
'label' => 'Email'
))
->add('dateOfBirth', 'birthday', array(
'label' => 'Date d\'anniversaire',
'required' => false,
'data' => new \DateTime("01/01/1980")
))
->add('plainPassword', 'password', array(
'label' => 'Password'
))
->add('phone', null, array(
'label' => 'Téléphone',
'required' => false
))
->add('adress', null, array(
'label' => 'Adresse',
'required' => false
))
->add('zip', null, array(
'label' => 'Code postale',
'required' => false
))
->add('city', null, array(
'label' => 'Ville',
'required' => false
))
->add('newsletter', 'checkbox', array(
'label' => 'newsletter',
'required' => false
))
#hidden
->add('website', 'hidden', array(
'label' => 'website',
'required' => false
))
->add('biography', 'hidden', array(
'label' => 'biography',
'required' => false
))
->add('locale', 'hidden', array(
'label' => 'locale',
'required' => false
))
->add('timezone', 'hidden', array(
'label' => 'Timezone',
'required' => false
))
->add('gender', 'hidden', array(
'label' => 'Civilité',
'required' => false
))
;
// var_dump($builder);
}
/**
* {#inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Application\Sonata\UserBundle\Entity\User',
'intention' => 'profile',
'label' => 'Edit Profile'
));
}
// public function getParent()
// {
// return 'fos_user_registration';
// }
/**
* {#inheritdoc}
*/
public function getName()
{
return 'application_sonata_user_profile';
}
}
My user class:
<?php
namespace Application\Sonata\UserBundle\Entity;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;
/**
* Application\Sonata\UserBundle\Entity\User
*
* #ORM\Table(name="fos_user_user", indexes={#ORM\Index(name="search_idx", columns={"username", "email"})}))
* #ORM\Entity()
* #DoctrineAssert\UniqueEntity(fields={"username"}, message="username.already.exist" )
* #DoctrineAssert\UniqueEntity(fields={"email"}, message="email.already.exist" )
*/
class User extends BaseUser
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="zip", type="string", length=255, nullable=true)
*/
protected $zip;
/**
* #var string
*
* #ORM\Column(name="adress", type="text", nullable=true)
*/
protected $adress;
/**
* #var string
*
* #ORM\Column(name="city", type="string", length=255, nullable=true)
*/
protected $city;
/**
* #var boolean
*
* #ORM\Column(name="newsletter", type="boolean", nullable=true)
*/
private $newsletter;
/**
* Get id
*
* #return integer $id
*/
public function getId()
{
return $this->id;
}
/**
* Set zip
*
* #param string $zip
* #return FosUserUser
*/
public function setZip($zip)
{
$this->zip = $zip;
return $this;
}
/**
* Get zip
*
* #return string
*/
public function getZip()
{
return $this->zip;
}
/**
* Set adress
*
* #param string $adress
* #return FosUserUser
*/
public function setAdress($adress)
{
$this->adress = $adress;
return $this;
}
/**
* Get adress
*
* #return string
*/
public function getAdress()
{
return $this->adress;
}
/**
* Set city
*
* #param string $city
* #return FosUserUser
*/
public function setCity($city)
{
$this->city = $city;
return $this;
}
/**
* Get city
*
* #return string
*/
public function getCity()
{
return $this->city;
}
/**
* Set Newsletter
*
* #param boolean $newsletter
* #return FosUserUser
*/
public function setNewsletter($newsletter)
{
$this->newsletter = $newsletter;
return $this;
}
/**
* Get Newsletter
*
* #return boolean
*/
public function getNewsletter()
{
return $this->newsletter;
}
}
Thank you for your help.
If you have a just created properties of the entity and you are using the metadata cache, the doctrine still doesn't aware about these new properties. Just try to clear the metadata cache.

Categories