Related
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?
So in my Symfony application I have an Entity called Post.
My Post Entity has the following properties:
post_start,post_end and many more.
ENTITY:
/**
* #ORM\Entity
* #ORM\Table(name="post")
*/
class Post
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var DateType
* #ORM\Column(type="date")
*/
private $post_start;
/**
* #var DateType
* #ORM\Column(type="date")
* #Assert\GreaterThanOrEqual(propertyPath="post_start")
*/
private $post_end;
.....
}
FORMTYPE:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'post_start',
DateType::class,
[
'widget' => 'single_text',
'format' => 'dd.MM.yyyy',
'required' => true,
'attr' => [
'class' => 'form-control input-inline datepicker',
'data-provide' => 'datepicker',
'data-date-format' => 'dd.mm.yyyy',
]
]
);
$builder->add(
'post_end',
DateType::class,
[
'widget' => 'single_text',
'format' => 'dd.MM.yyyy',
'required' => true,
'attr' => [
'class' => 'form-control input-inline datepicker',
'data-provide' => 'datepicker',
'data-date-format' => 'dd.mm.yyyy'
]
]
);
$builder->add('submit', SubmitType::class, [
'label' => 'save post',
'attr' => array('class' => 'btn btn-success')
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Post::class
]);
}
When I submit the form, I want to check if the database already has an entry with the same startdate and enddate and of cource from the same user.
1. If YES -> Show error message
2. If NO -> Create post request.
When the entry already exists, but it's from a different user, just go ahead and create the post.
I wanted to do that with a custom validator constraint. But what happens next I have to somehow compare the data with each other
ContainsEqualDate:
/**
* #Annotation
*/
class ContainsEqualDate extends Constraint
{
public $message = 'Post request is already exists.';
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
ContainsEqualDateValidator:
class ContainsEqualDateValidator extends ConstraintValidator
{
/**
* #var ORMUserRepository
*/
private $userRepository;
/**
* #var ORMPostRepository
*/
private $postRepository;
/**
* #param ORMUserRepository $userRepository
* #param ORMPostRepository $postRepository
*/
public function __construct(ORMUserRepository $userRepository, ORMPostRepository $postRepository)
{
$this->userRepository = $userRepository;
$this->postRepository = $postRepository;
}
/**
* Checks if the passed value is valid.
*
* #param mixed $value The value that should be validated
* #param Constraint $constraint The constraint for the validation
*/
public function validate($value, Constraint $constraint)
{
$userId = $this->getUser();
$postExists = $this->postRepository->findBy(array(
'post_start' => $value,
'app_user_id' => $userId
));
}
/**
* #return User
*/
private function getUser(): User
{
return $this->storage->getToken()->getUser();
}
}
}
#Max Trui, you have not mentioned how are the User and Post entities are related in your database.
If you have UserId in Post Entity, you can do Following.
$userId = $this->userRepository->getUser()->getId();
$entryExists = ($this->postRepository->findBy(array('post_start' => $value, 'user_id' => $userId)) == null) ? true : false;
you can replace 'post_start' with the dynamic fieldname value(post_start or post_end), which you can provide from where you call validator.
If you want to check for both dates at the same time, provide both values in validator.
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.
I am using zendframework 2 and doctrine 2. My addAction doesn't work i don't have any error but when i valid my form no row created in my database !!
i think that i have problem in populating foreign key !
this is my Form:
<?php
// filename : module/Users/src/Users/Form/addForm.php
namespace Vehicules\Form;
use Zend\Form\Form;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;
class VehiculeForm extends form implements ObjectManagerAwareInterface
{
protected $objectManager;
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
public function getObjectManager()
{
return $this->objectManager;
}
//public function init()
public function __construct(ObjectManager $objectManager)
{
parent::__construct('add');
$this->objectManager = $objectManager;
$this->init();
}
public function init(){
$this->setAttribute('method', 'post');
$this->setAttribute('enctype','multipart/formdata');
$this->add(array(
'name' => 'matricule',
'attributes' => array(
'type' => 'text',
'required' => true
),
'options' => array(
'label' => 'Matricule',
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'carburant',
'options' => array(
'label' => 'Carburant',
'value_options' => array(
'0' => 'Essence',
'1' => 'Gasoil',
'2' => 'Hybride',
),
)
));
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectMultiCheckbox',
'name' => 'option',
'options' => array(
'label' => 'Options Véhicule',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Vehicules\Entity\optionsvehicule',
'property' => 'libellee',
)));
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'categorie',
'options' => array(
'label' => 'categorie',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Vehicules\Entity\categorie',
'property' => 'idcat',
)
));
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'modele',
'options' => array(
'label' => 'Modèle',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Vehicules\Entity\modele',
'property' => 'nom',
)
));
/*$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'modele',
'options' => array(
'label' => 'Modèle',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Vehicules\Entity\modele',
'property' => 'nom',
'is_method' => true,
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array('active' => 1),
// Use key 'orderBy' if using ORM
'orderBy' => array('lastname' => 'ASC'),
// Use key 'sort' if using ODM
'sort' => array('lastname' => 'ASC')
),
),
),
));*/
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'marque',
'options' => array(
'label' => 'Marque',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Vehicules\Entity\marque',
'property' => 'nom',
)
));
$this->add(array(
'name' => 'dateMiseCirculation',
'attributes' => array(
'type' => 'Zend\Form\Element\Date',
),
'options' => array(
'label' => 'Date de Mise en Circulation',
),
));
$this->add(array(
'name' => 'numChasis',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Numero de Chasis',
),
));
$this->add(array(
'name' => "Prix d'achat",
'attributes' => array(
'type' => 'int',
),
'options' => array(
'label' => "Prix d'achat",
),
));
$this->add(array(
'name' => 'concessionnaire',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'concessionnaire',
),
));
$this->add(array(
'name' => 'souslocation',
'attributes' => array(
'type' => 'string',
),
'options' => array(
'label' => 'Sous-location',
),
));
$this->add(array(
'name' => 'remarque',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'remarque',
),
));
$this->add(array(
'name' => 'puisfiscal',
'attributes' => array(
'type' => 'int',
),
'options' => array(
'label' => "puissance fiscale",
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'nbreport',
'options' => array(
'label' => 'Nombre de portes',
'value_options' => array(
'0' => '4',
'1' => '2',
'2' => '5',
'3' => '6',
'4' => '7',
'5' => '7',
),
)
));
$this->add(array(
'name' => 'dernierKm',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Dernier kilométrage',
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Valider'
),
));
}}
and this is my Entity Vehicule:
<?php
namespace Vehicules\Entity;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\Factory as InputFactory;
use Doctrine\ORM\Mapping as ORM;
/**
* Vehicule
*
* #ORM\Table(name="vehicule", uniqueConstraints={#ORM\UniqueConstraint(name="VEHICULE_PK", columns={"idVeh"})}, indexes={#ORM\Index(name="ASSOCIATION11_FK", columns={"idCat"}), #ORM\Index(name="ASSOCIATION13_FK", columns={"idMod"})})
* #ORM\Entity
*/
class Vehicule
{ protected $inputFilter;
/**
* #var integer
*
* #ORM\Column(name="idVeh", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idveh;
/**
* #var string
*
* #ORM\Column(name="matricule", type="string", length=254, nullable=false)
*/
private $matricule;
/**
* #var string
*
* #ORM\Column(name="dateMiseCirculation", type="string", length=254, nullable=true)
*/
private $datemisecirculation;
/**
* #var string
*
* #ORM\Column(name="numChasis", type="string", length=254, nullable=false)
*/
private $numchasis;
/**
* #var string
*
* #ORM\Column(name="carburant", type="string", length=254, nullable=true)
*/
private $carburant;
/**
* #var string
*
* #ORM\Column(name="dernierKm", type="decimal", precision=10, scale=0, nullable=false)
*/
private $dernierkm;
/**
* #var integer
*
* #ORM\Column(name="prixachat", type="integer", precision=10, scale=0, nullable=false)
*/
private $prixachat;
/**
* #var string
*
* #ORM\Column(name="concessionnaire", type="string", length=254, nullable=true)
*/
private $concessionnaire;
/**
* #var integer
*
* #ORM\Column(name="sousLocation", type="smallint", nullable=true)
*/
private $souslocation;
/**
* #var string
*
* #ORM\Column(name="remarque", type="string", length=254, nullable=true)
*/
private $remarque;
/**
* #var integer
*
* #ORM\Column(name="puisFiscal", type="integer", nullable=true)
*/
private $puisfiscal;
/**
* #var integer
*
* #ORM\Column(name="nbrePort", type="integer", nullable=true)
*/
private $nbreport;
/**
* #var \Vehicules\Entity\Categorie
*
* #ORM\ManyToOne(targetEntity="Vehicules\Entity\Categorie")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="idCat", referencedColumnName="idCat")
* })
*/
private $idcat;
/**
* #var \Vehicules\Entity\Modele
*
* #ORM\ManyToOne(targetEntity="Vehicules\Entity\Modele")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="idMod", referencedColumnName="idMod")
* })
*/
private $idmod;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Vehicules\Entity\Optionsvehicule", inversedBy="idveh")
* #ORM\JoinTable(name="veh_option",
* joinColumns={
* #ORM\JoinColumn(name="idVeh", referencedColumnName="idVeh")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="idOptVeh", referencedColumnName="idOptVeh")
* }
* )
*/
private $idoptveh;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Vehicules\Entity\Vehiculestatut", inversedBy="idveh")
* #ORM\JoinTable(name="veh_status",
* joinColumns={
* #ORM\JoinColumn(name="idVeh", referencedColumnName="idVeh")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="idStatut", referencedColumnName="idStatut")
* }
* )
*/
private $idstatut;
/**
* Constructor
*/
public function __construct()
{
$this->idoptveh = new \Doctrine\Common\Collections\ArrayCollection();
$this->idstatut = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get idveh
*
* #return integer
*/
public function getIdveh()
{
return $this->idveh;
}
/**
* Set matricule
*
* #param string $matricule
* #return Vehicule
*/
public function setMatricule($matricule)
{
$this->matricule = $matricule;
return $this;
}
/**
* Get matricule
*
* #return string
*/
public function getMatricule()
{
return $this->matricule;
}
/**
* Set datemisecirculation
*
* #param string $datemisecirculation
* #return Vehicule
*/
public function setDatemisecirculation($datemisecirculation)
{
$this->datemisecirculation = $datemisecirculation;
return $this;
}
/**
* Get datemisecirculation
*
* #return string
*/
public function getDatemisecirculation()
{
return $this->datemisecirculation;
}
/**
* Set numchasis
*
* #param string $numchasis
* #return Vehicule
*/
public function setNumchasis($numchasis)
{
$this->numchasis = $numchasis;
return $this;
}
/**
* Get numchasis
*
* #return string
*/
public function getNumchasis()
{
return $this->numchasis;
}
/**
* Set carburant
*
* #param string $carburant
* #return Vehicule
*/
public function setCarburant($carburant)
{
$this->carburant = $carburant;
return $this;
}
/**
* Get carburant
*
* #return string
*/
public function getCarburant()
{
return $this->carburant;
}
/**
* Set dernierkm
*
* #param string $dernierkm
* #return Vehicule
*/
public function setDernierkm($dernierkm)
{
$this->dernierkm = $dernierkm;
return $this;
}
/**
* Get dernierkm
*
* #return string
*/
public function getDernierkm()
{
return $this->dernierkm;
}
/**
* Set prixachat
*
* #param integer $prixachat
* #return Vehicule
*/
public function setPrixachat($prixachat)
{
$this->prixachat = $prixachat;
return $this;
}
/**
* Get prixachat
*
* #return integer
*/
public function getPrixachat()
{
return $this->prixachat;
}
/**
* Set concessionnaire
*
* #param string $concessionnaire
* #return Vehicule
*/
public function setConcessionnaire($concessionnaire)
{
$this->concessionnaire = $concessionnaire;
return $this;
}
/**
* Get concessionnaire
*
* #return string
*/
public function getConcessionnaire()
{
return $this->concessionnaire;
}
/**
* Set souslocation
*
* #param integer $souslocation
* #return Vehicule
*/
public function setSouslocation($souslocation)
{
$this->souslocation = $souslocation;
return $this;
}
/**
* Get souslocation
*
* #return integer
*/
public function getSouslocation()
{
return $this->souslocation;
}
/**
* Set remarque
*
* #param string $remarque
* #return Vehicule
*/
public function setRemarque($remarque)
{
$this->remarque = $remarque;
return $this;
}
/**
* Get remarque
*
* #return string
*/
public function getRemarque()
{
return $this->remarque;
}
/**
* Set puisfiscal
*
* #param integer $puisfiscal
* #return Vehicule
*/
public function setPuisfiscal($puisfiscal)
{
$this->puisfiscal = $puisfiscal;
return $this;
}
/**
* Get puisfiscal
*
* #return integer
*/
public function getPuisfiscal()
{
return $this->puisfiscal;
}
/**
* Set nbreport
*
* #param integer $nbreport
* #return Vehicule
*/
public function setNbreport($nbreport)
{
$this->nbreport = $nbreport;
return $this;
}
/**
* Get nbreport
*
* #return integer
*/
public function getNbreport()
{
return $this->nbreport;
}
/**
* Set idcat
*
* #param \Vehicules\Entity\Categorie $idcat
* #return Vehicule
*/
public function setIdcat(\Vehicules\Entity\Categorie $idcat = null)
{
$this->idcat = $idcat;
return $this;
}
/**
* Get idcat
*
* #return \Vehicules\Entity\Categorie
*/
public function getIdcat()
{
return $this->idcat;
}
/**
* Set idmod
*
* #param \Vehicules\Entity\Modele $idmod
* #return Vehicule
*/
public function setIdmod(\Vehicules\Entity\Modele $idmod = null)
{
$this->idmod = $idmod;
return $this;
}
/**
* Get idmod
*
* #return \Vehicules\Entity\Modele
*/
public function getIdmod()
{
return $this->idmod;
}
/**
* Add idoptveh
*
* #param \Vehicules\Entity\Optionsvehicule $idoptveh
* #return Vehicule
*/
public function addIdoptveh(\Vehicules\Entity\Optionsvehicule $idoptveh)
{
$this->idoptveh[] = $idoptveh;
return $this;
}
/**
* Remove idoptveh
*
* #param \Vehicules\Entity\Optionsvehicule $idoptveh
*/
public function removeIdoptveh(\Vehicules\Entity\Optionsvehicule $idoptveh)
{
$this->idoptveh->removeElement($idoptveh);
}
/**
* Get idoptveh
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getIdoptveh()
{
return $this->idoptveh;
}
/**
* Add idstatut
*
* #param \Vehicules\Entity\Vehiculestatut $idstatut
* #return Vehicule
*/
public function addIdstatut(\Vehicules\Entity\Vehiculestatut $idstatut)
{
$this->idstatut[] = $idstatut;
return $this;
}
/**
* Remove idstatut
*
* #param \Vehicules\Entity\Vehiculestatut $idstatut
*/
public function removeIdstatut(\Vehicules\Entity\Vehiculestatut $idstatut)
{
$this->idstatut->removeElement($idstatut);
}
/**
* Get idstatut
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getIdstatut()
{
return $this->idstatut;
}
public function populate($data) {
$this->setMatricule($data['matricule']) ;
$this->setDatemisecirculation($data['dateMiseCirculation']) ;
$this->setNumchasis($data['numChasis']) ;
$this->setCarburant($data['carburant']) ;
$this->setDernierkm($data['dernierKm']) ;
$this->setPrixachat($data["Prix d'achat"]) ;
$this->setConcessionnaire($data['concessionnaire']) ;
$this->setSouslocation($data['souslocation']) ;
$this->setRemarque($data['remarque']) ;
$this->setPuisfiscal($data['puisfiscal']) ;
$this->setNbreport($data['nbreport']) ;
//$this->addIdoptveh($data['option']) ; /* select................*/
//$this->setIdmod() ; /* select................*/
//$this->addIdstatut() ; /*ghanakhd l option dyal libre */
}
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'matricule',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 4,
'max' => 14,
),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'option',
'required' => false,
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
public function getArrayCopy()
{
return get_object_vars($this);
}
}
this is my controller VehiculeController:
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* #link http://github.com/zendframework/Vehicules for the canonical source repository
* #copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* #license http://framework.zend.com/license/new-bsd New BSD License
*
*/
namespace Vehicules\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Vehicules\Form\VehiculeForm;
use Vehicules\Entity\Vehicule;
class VehiculesController extends AbstractActionController
{
/**
* #var Doctrine\ORM\EntityManager
*/
protected $_objectManager;
protected function getObjectManager()
{
if (!$this->_objectManager) {
$this->_objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
}
return $this->_objectManager;
}
public function indexAction()
{
$vehicules = $this->getObjectManager()->getRepository('Vehicules\Entity\Vehicule')->findAll();
return new ViewModel(array('vehicules' => $vehicules));
}
public function addAction()
{ $_objectManager=$this->getObjectManager();
$form = new VehiculeForm($_objectManager);
$request = $this->getRequest();
$post = $this->request->getPost();
if ($this->request->isPost()) {
$Vehicule= new Vehicule();
$form->setData($post);
$form->setInputFilter($Vehicule->getInputFilter());
if ($form->isValid()) {
$f=$form->getData();
$Vehicule->populate($f);
$cat = $this->getObjectManager()->getRepository('Vehicules\Entity\categorie')->findAll();
foreach ($cat as $c){
if($c->getIdcat()==$f['categorie'] ){
$Vehicule->setIdcat($c) ;
exit;
}
}
$mod = $this->getObjectManager()->getRepository('Vehicules\Entity\modele')->findAll();
foreach ($mod as $m){
if($m->getNom()==$f['modele'] ){
$Vehicule->setIdmod($m->getIdmod()) ;
exit;
}
}
$objectManager = $this->getObjectManager();
$objectManager->persist($Vehicule);
$objectManager->flush();
$id=$Vehicule->getIdveh();
var_dump($id);
$viewModel = new ViewModel(array('form' =>$form,'donne'=>$id));
return $viewModel;
}
}
$viewModel = new ViewModel(array('form' =>$form));
return $viewModel;
}
public function editAction()
{
$id = (int) $this->getEvent()->getRouteMatch()->getParam('id');
if (!$id) {
return $this->redirect()->toRoute('vehicules/default', array('controller'=>'vehicules','action'=>'add'));
}
$vehicule = $this->getObjectManager()->find('Vehicules\Entity\vehicule', $id);
$objectManager= $this->getObjectManager();
$form = new VehiculeForm($objectManager);
$form->setBindOnValidate(false);
$form->bind($vehicule);
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->post());
if ($form->isValid()) {
$form->bindValues();
$this->getEntityManager()->flush();
// Redirect to list of vehicules
return $this->redirect()->toRoute('vehicules/default', array('controller'=>'vehicules','action'=>'index'));
}
}
return array(
'id' => $id,
'form' => $form,
);
}
public function deleteAction()
{
$id = (int)$this->getEvent()->getRouteMatch()->getParam('idVeh');
if (!$id) {
return $this->redirect()->toRoute('vehicules');
}
$request = $this->getRequest();
if ($request->isPost()) {
$del = $request->post()->get('del', 'No');
if ($del == 'Yes') {
$id = (int)$request->post()->get('id');
$vehicule = $this->getEntityManager()->find('Vehicules\Entity\vehicule', $id);
if ($vehicule) {
$this->getEntityManager()->remove($vehicule);
$this->getEntityManager()->flush();
}
}
// Redirect to list of albums
return $this->redirect()->toRoute('default', array(
'controller' => 'vehicules',
'action' => 'index',
));
}
return array(
'id' => $id,
'vehicule' => $this->getEntityManager()->find('Vehicules\Entity\vehicule', $id)->getArrayCopy()
);
}
}
to populate forgnein key idMod and idCat i tried with this:
$mod = $this->getObjectManager()->getRepository('Vehicules\Entity\modele')->findAll();
foreach ($mod as $m){
if($m->getNom()==$f['modele'] ){
$Vehicule->setIdmod($m->getIdmod()) ;
exit;
}
}
but id doesn't work :/
Your issue is the form/entity hydration. You don't need to reinvent the wheel here as Zend\Form already takes care of getting the data in and out of a form.
Currently your form uses the default ArraySerializable hydrator, so when the form is validated and you fetch the data (using $form->getData()) you are given an array. What you want is a already populated Vehicule entity.
The DoctrineModule\Stdlib\Hydrator\DoctrineObject is a hydrator specifically for Doctrine. If you attach it as the hydrator to your form it will return hydrated entity.
To solve this you need to STOP creating the form using new
$form = new VehiculeForm($_objectManager);
Instead create it via the ServiceManager
$form = $this->getServiceLocator()->get('MyModule\Form\VehiculeForm');
Now create the form from a service factory; allowing the injection of the form dependencies, including the hydrator.
MyModule/Factory/Form/VehiculeFormFactory.php
namespace MyModule\Factory\Form;
use MyModule\Entity;
use MyModule\Form;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
use DoctrineModule\Stdlib\Hydrator;
class VehiculeFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $sl)
{
$objectManager = $sl->get('Doctrine\ORM\EntityManager');
$form = new Form\VehiculeForm($objectManager);
$vehicule = new Entity\Vehicule();
// create the hydrator; this could also be done via the
// hydrator manager but create here for the example
$hydrator = new DoctrineObject($objectManager);
$form->setHydrator($hydrator);
$form->setObject($vehicule);
// We can also take care of the input filter here too!
// meaning less code in the controller and only
// one place to modify should it change
$form->setInputFilter($Vehicule->getInputFilter());
return $form;
}
}
Module.php
public function getFormElementConfig()
{
return array(
'factories' => array(
'MyModule\Form\VehiculeForm' => 'MyModule\Factory\Form\VehiculeForm' // path to our new factory
),
);
}
You can now get rid of your populate() method and allot of the controller code.
FooController.php
//...
protected function getVehiculeForm()
{
return $this->getServiceLocator()->get('MyModule\Form\VehiculeForm');
}
public function addAction()
{
$request = $this->getRequest();
$form = $this->getVehiculeForm();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$vehicule = $form->getData(); // returns the entity!
if ($vehicule instanceof Vehicule) {
/// Fully hydrated entity!
var_dump($vehicule);
}
}
}
//...
}
//...
I have a category table and product table. The categories are listed in product form in a drop down select box. When i edit a product then category saved in product table should be auto selected in category drop down at product edit form (selected="selected").
I have already tried empty_data and empty_value but they does not work.
I am searching for the solution since 2 days but could not find any tutorial or such example. I will be really thankful if someone can refer me a tutorial or can see below code to sort out the problem:
Controller
<?php
// src/Scsp/CmsBundle/Controller/ProductController.php
namespace Scsp\CmsBundle\Controller;
use Scsp\CmsBundle\Entity\CategoryEntity;
use Scsp\CmsBundle\Entity\ProductEntity;
use Scsp\CmsBundle\Form\ProductForm;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\HttpFoundation\Session\Session;
class ProductController extends Controller {
public function editAction($id, $request) {
$em = $this->getDoctrine()->getManager();
$product = $em->getRepository('ScspCmsBundle:ProductEntity')->find($id);
if (!$product){
throw $this->createNotFoundException('No product found for id ' . $id);
}
$productForm=new ProductForm($id);
$form = $this->createForm($productForm, $product, array(
'attr' => array('class' => 'form-horizontal')
));
$form->handleRequest($request);
if ($request->isMethod('POST') && $form->isValid()) {
$product->setCategoryid(3);
$em->persist($product);
$em->flush();
$this->session->getFlashBag()->add('success', $product->getProducts() . ' successfully edited!');
return $this->redirect($this->generateUrl('scsp_cms_products', array('action' => 'list', 'id' => 0)));
}
return $this->render('ScspCmsBundle:Default:form.html.twig', array(
'form' => $form->createView(),
'page_title' => 'Edit product',
'type' => 'products',
'id' => $id
));
}
}
Product Entity:
<?php
// src/Scsp/CmsBundle/Entity/ProductEntity.php
namespace Scsp\CmsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="Scsp\CmsBundle\Repository\ProductRepository")
* #ORM\Table(name="products")
*/
class ProductEntity {
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
*/
protected $products;
/**
* #ORM\Column(type="integer")
* #ORM\ManyToOne(targetEntity="CategoryEntity", inversedBy="products")
* #ORM\JoinColumn(name="categoryid", referencedColumnName="id")
*/
protected $categoryid;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set id
*
* #param string $id
* #return Id
*/
public function setId($id) {
$this->id = $id;
return $this;
}
/**
* Set products
*
* #param string $products
* #return ProductEntity
*/
public function setProducts($products)
{
$this->products = $products;
return $this;
}
/**
* Get products
*
* #return string
*/
public function getProducts()
{
return $this->products;
}
/**
* Set categoryid
*
* #param integer $categoryid
* #return ProductEntity
*/
public function setCategoryid($categoryid)
{
$this->categoryid = $categoryid;
return $this;
}
/**
* Get categoryid
*
* #return integer
*/
public function getCategoryid()
{
return $this->categoryid;
}
}
Category Entity:
<?php
// src/Scsp/CmsBundle/Entity/CategoryEntity.php
namespace Scsp\CmsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity(repositoryClass="Scsp\CmsBundle\Repository\CategoryRepository")
* #ORM\Table(name="categories")
*/
class CategoryEntity {
/**
* #ORM\OneToMany(targetEntity="ProductEntity", mappedBy="categorid")
*/
protected $products;
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
*/
protected $categories;
public function __construct(){
$this->products = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set id
*
* #param string $id
* #return Id
*/
public function setId($id) {
$this->id = $id;
return $this;
}
/**
* Set categories
*
* #param string $categories
* #return Categories
*/
public function setCategories($categories) {
$this->categories = $categories;
return $this;
}
/**
* Get categories
*
* #return string
*/
public function getCategories() {
return $this->categories;
}
public function __toString() {
return $this->getCategories();
}
/**
* Add products
*
* #param \Scsp\CmsBundle\Entity\ProductEntity $products
* #return CategoryEntity
*/
public function addProduct(\Scsp\CmsBundle\Entity\ProductEntity $products)
{
$this->products[] = $products;
return $this;
}
/**
* Remove products
*
* #param \Scsp\CmsBundle\Entity\ProductEntity $products
*/
public function removeProduct(\Scsp\CmsBundle\Entity\ProductEntity $products)
{
$this->products->removeElement($products);
}
/**
* Get products
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
}
Product Form:
<?php
// src/Scsp/CmsBundle/Form/ProductForm.php
namespace Scsp\CmsBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use \Scsp\CmsBundle\Entity\ProductEntity;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormInterface;
class ProductForm extends AbstractType
{
private $id;
public function __construct($id) {
$this->id=$id;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
if($this->id>0){
$builder->add('id', 'text',
array(
'label' => false,
'attr' => array(
'class' => 'form-control',
'readonly' => 'readonly'
)
)
);
}
$builder
->add('products', 'text',
array(
'label' => false,
'max_length' => 100,
'attr' => array(
'class' => 'form-control',
'autocomplete' => 'off'
)
)
)
->add('categoryid', 'entity', array(
'label' => false,
'class' => 'ScspCmsBundle:CategoryEntity',
'property' => 'categories',
'data'=>$builder->getData()->getCategoryId(),
'attr' => array(
)
)
)
->add('save', 'submit',array(
'attr' => array(
'formnovalidate' => 'formnovalidate',
'class' => 'btn btn-primary',
'label' => 'Save Changes'
)
)
)
->getForm();
}
public function getName()
{
return 'products';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'empty_data' => 'Scsp\CmsBundle\Entity\CategoryEntity'
));
}
}
categoryid
is not an entity, so you must to add a property called category in ProductEntity and stablish the relation ManyToOne there, the code:
/**
* #ORM\Column(type="integer")
* #ORM\ManyToOne(targetEntity="CategoryEntity", inversedBy="products")
* #ORM\JoinColumn(name="categoryid", referencedColumnName="id")
*/
protected $categoryid;
must be replaced by:
/**
* #ORM\Column(name="categoryid", type="integer")
*/
protected $categoryid;
/**
* #var CategoryEntity
* #ORM\ManyToOne(targetEntity="CategoryEntity", inversedBy="products")
* #ORM\JoinColumn(name="categoryid", referencedColumnName="id")
*/
protected $category;
//Here generate the get and the set customized
/**
* #return CategoryEntity
*/
public function getCategory()
{
return $this->category;
}
/**
* #param CategoryEntity $category
* #return $this
*/
public function setCategory($category)
{
//this is the owning side
//all changes will be detected
//in this side by doctrine
$category->addProduct($this);
$this->category= $category;
//The line below is important to set the categoryid
//field in the product table
$this->setCategoryid($category->getId());
return $this;
}
Now in the Product Form replace:
->add('categoryid', 'entity', array(
'label' => false,
'class' => 'ScspCmsBundle:CategoryEntity',
'property' => 'categories',
'data'=>$builder->getData()->getCategoryId(),
'attr' => array(
)
)
)
by:
->add('category', 'entity', array(
'label' => false,
'class' => 'ScspCmsBundle:CategoryEntity',
'property' => 'categories',
'attr' => array(
)
)
)
That's all, enjoy it!
I see many things wrong in your form type, nonetheless, what are you looking for is the data option in the field definition:
->add('categoryid', 'entity',
array(
'label' => false,
'class' => 'ScspCmsBundle:CategoryEntity',
'property' => 'categories',
'data' => $builder->getData()->getCategoryId()
)
)
This data field must contain the select value property, which is the categoryId, at least when using an entity field type as normal. I don't know if this will work with you current setup!
I have a solution for Symfony 1.4.18.
The key is use jQuery.
You can view a detail explanation (including images) in my blog (in Spanish) here: http://symfonyandme.com/2013/10/09/como-usar-select-dependientes-en-symfony-1-4-con-tres-tablas/
And the same solution here: Symfony 1.4 with AJAX jQuery. How can I improve the AJAX's function that contains a select box which depends on another select box?
Then you would work for adjust this example for Symfony 2