I'm trying to create a for with an entity.
My controller:
$questionnaire = $em->getRepository('questionnaireBundle:questionnaire')->findOneBy(array('id' => $id));
$form = $this->createForm(new questionnaireType(), $questionnaire);
QuestionnaireType:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('nom', 'text', array('label' => 'Nom:'));
$builder->add('nbreQuestions', 'text', array('label' => 'Nombre de questions:'));
$builder->add('type', 'entity', array('class' => 'questionnaireBundle:type', 'property' => 'type'));
$builder->add('envoyer', 'submit', array('label' => 'Enregistrer', 'attr' => array('class' => 'btn btn-success col-md-12')));
}
The entity: questionnaire
namespace questionnaireBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* questionnaire
*
* #ORM\Table()
* #ORM\Entity
*/
class questionnaire {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=255)
*/
private $type;
/**
* #var integer
*
* #ORM\Column(name="nbreQuestions", type="integer")
*
* #Assert\NotBlank(message="Veuillez entrer un nombre de questions.")
* #Assert\Type(type="integer")
*/
private $nbreQuestions;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set nom
*
* #param string $nom
* #return questionnaire
*/
public function setNom($nom) {
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom() {
return $this->nom;
}
/**
* Set type
*
* #param string $type
* #return type
*/
public function setType($type) {
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return string
*/
public function getType() {
return $this->type;
}
/**
* Set nbreQuestions
*
* #param integer $nbreQuestions
* #return questionnaire
*/
public function setNbreQuestions($nbreQuestions) {
$this->nbreQuestions = $nbreQuestions;
return $this;
}
/**
* Get nbreQuestions
*
* #return integer
*/
public function getNbreQuestions() {
return $this->nbreQuestions;
}
public function __toString() {
return (string) $this->getNom();
}
}
The field nom, nbreQuestions will automatically be fully with the entity questionnaire, but type is not update!
Anybody knows why?
Thanks
Best regards
that must do a second query behind the sense, but you can increase performance by dql & join:
use this code:
$questionnaire = $em->createQuery('select q from questionnaireBundle:questionnaire q join q.type t where q.id = :id')->setParameter('id', $id)->getSingleResult();
$form = $this->createForm(new questionnaireType(), $questionnaire);
The reason of not selecting the proper type in your for is that entity type builds choices as
entity_id => property_value
So it is comparing your values from questionnaire type to the ids from your type entity and it will not find a match. Moreover if you update your questionnaire object the type will be changed to the id of type entity.
I see here two solutions:
proposed by #ghanbari to make relation from questionnaire to type
make your form as a service and inject entityManager than build your choices like you want (type => type) and change the field from entity type to choice type
Related
I am using symfony2 and doctrine.
I have a list of contacts and they are classified in a number of groups.
These groups are stored in a table.
Then I have users in my application and for each users I want to specify their rights: no/read/write.
In order to achieve this I have created a userspermission table as such :
<?php
namespace Curuba\contactsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use APY\DataGridBundle\Grid\Mapping as GRID;
/**
* userspermissions
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Curuba\contactsBundle\Entity\userspermissionsRepository")
*/
class userspermissions
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="permission", type="string", length=10)
*
* #GRID\Column(title="Permission")
*
*/
private $permission;
/**
* #ORM\ManyToOne(targetEntity="groupes", inversedBy="permissions")
* #ORM\JoinColumn(nullable=false)
*
* #GRID\Column(title="Groupes")
*/
private $groupe;
/**
* #ORM\ManyToOne(targetEntity="users", inversedBy="permissions")
* #ORM\JoinColumn(nullable=false)
*
* #GRID\Column(title="Permission")
*/
private $user;
Now in my user form, I would need to show a table with all available groups and a drop-down list in front of them.
But I dont know how to achieve that without a collection and then asking the user to add a group permission, select a group and the according permission.
Thanks in advance.
You can use an ManyToOne relation.
For example with an User and Group
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="groups")
*/
class Group
{
const CLASS_NAME = __CLASS__;
/**
* #var integer
*
* #ORM\Id()
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id",type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="label",type="string",length=255)
*/
private $label;
/**
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param string $label
*/
public function setLabel($label)
{
$this->label = $label;
}
/**
* #return string
*/
public function getLabel()
{
return $this->label;
}
/**
* #return string
*/
public function __toString()
{
return $this->getLabel();
}
}
and the User entity
<?php
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
*
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User
{
const CLASS_NAME = __CLASS__;
/**
* #var integer
*
* #ORM\Id()
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id",type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string", name="label", length=255)
*/
private $label;
/**
* #ORM\ManyToMany(targetEntity="Group")
* #ORM\JoinTable(name="user_group",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
**/
private $groups;
public function __construct()
{
$this->groups = new ArrayCollection();
}
/**
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param string $label
*/
public function setLabel($label)
{
$this->label = $label;
}
/**
* #return string
*/
public function getLabel()
{
return $this->label;
}
/**
* #param Group $group
*
* #return bool
*/
public function hasGroup(Group $group)
{
return $this->groups->contains($group);
}
/**
* #param Group $group
*
* #return $this
*/
public function addGroup(Group $group)
{
if (false === $this->hasGroup($group)) {
$this->groups->add($group);
}
return $this;
}
/**
* #return \Doctrine\Common\Collections\ArrayCollection
*/
public function getGroups()
{
return $this->groups;
}
/**
* #return string
*/
public function __toString()
{
return $this->getLabel();
}
}
and finally create an form type like this :
class UserType extends AbstractType
{
const NAME = 'userType';
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('label', 'text');
$builder->add('groups', 'entity', array(
'class' => Group::CLASS_NAME,
'multiple' => true,
'expanded' => true,
));
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::CLASS_NAME,
));
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
public function getName()
{
return self::NAME;
}
}
I have found how to do this. This is in fact very simple and I was probably expecting something more complex...
I have added a function in my controller (could be in my entity...) and I cal this function when I create a new user entity or when I edit one (in case a groupe has been added in the mean time.
Here is the code:
private function autocompleteForm(users $user) {
$em = $this->getDoctrine()->getManager();
$groupes = $em->getRepository('contactsBundle:groupes')->findAll();
if ($user) {
foreach ($groupes as $groupe) {
$permission = $em->getRepository('contactsBundle:userspermissions')->findOneBy(array('groupe' => $groupe, 'user' => $user));
if(!$permission) {
$permission = new userspermissions();
$permission->setGroupe($groupe);
$user->addPermission($permission);
}
}
}
return $user;
}
I am happy to explain more if someone needs...
Client Entity
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Client
*
* #ORM\Table(name="client", uniqueConstraints={#ORM\UniqueConstraint(name="mail", columns=
* {"mail"}), #ORM\UniqueConstraint(name="pseudo", columns={"pseudo"})}, indexes=
* {#ORM\Index(name="FK_client_situation", columns={"situation"}),
*#ORM\Index(name="FK_client_city", columns={"ville"})})
* #ORM\Entity
*/
class Client
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="firstname", type="string", length=255, nullable=true)
*/
private $firstname;
/**
* #var string
*
* #ORM\Column(name="lastname", type="string", length=255, nullable=true)
*/
private $lastname;
/**
* #var \DateTime
*
* #ORM\Column(name="birthay", type="datetime", nullable=true)
*/
private $birthay;
/**
* #var string
*
* #ORM\Column(name="mail", type="string", length=255, nullable=true)
*/
private $mail;
/**
* #var string
*
* #ORM\Column(name="phone", type="text", nullable=true)
*/
private $phone;
/**
* #var string
*
* #ORM\Column(name="pseudo", type="string", length=255, nullable=true)
*/
private $pseudo;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255, nullable=true)
*/
private $password;
/**
* #var integer
*
* #ORM\Column(name="situation", type="integer", nullable=true)
*/
private $situation;
/**
* #var integer
*
* #ORM\Column(name="ville", type="integer", nullable=true)
*/
private $ville;
/**
* #var string
*
* #ORM\Column(name="facebook", type="string", length=255, nullable=true)
*/
private $facebook;
/**
* #var string
*
* #ORM\Column(name="picture", type="string", length=255, nullable=true)
*/
private $picture;
/**
* #var integer
*
* #ORM\Column(name="newseltter", type="integer", nullable=true)
*/
private $newseltter;
/**
* #var \DateTime
*
* #ORM\Column(name="dateinscription", type="datetime", nullable=true)
*/
private $dateinscription;
/**
* #var \DateTime
*
* #ORM\Column(name="datedelete", type="datetime", nullable=true)
*/
private $datedelete;
/**
* #var string
*
* #ORM\Column(name="statut", type="string", length=50, nullable=true)
*/
private $statut;
/**
* #var string
*
* #ORM\Column(name="contenu", type="text", nullable=true)
*/
private $contenu;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstname
*
* #param string $firstname
* #return Client
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return Client
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set birthay
*
* #param \DateTime $birthay
* #return Client
*/
public function setBirthay($birthay)
{
$this->birthay = $birthay;
return $this;
}
/**
* Get birthay
*
* #return \DateTime
*/
public function getBirthay()
{
return $this->birthay;
}
/**
* Set mail
*
* #param string $mail
* #return Client
*/
public function setMail($mail)
{
$this->mail = $mail;
return $this;
}
/**
* Get mail
*
* #return string
*/
public function getMail()
{
return $this->mail;
}
/**
* Set phone
*
* #param string $phone
* #return Client
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* #return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set pseudo
*
* #param string $pseudo
* #return Client
*/
public function setPseudo($pseudo)
{
$this->pseudo = $pseudo;
return $this;
}
/**
* Get pseudo
*
* #return string
*/
public function getPseudo()
{
return $this->pseudo;
}
/**
* Set password
*
* #param string $password
* #return Client
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set situation
*
* #param integer $situation
* #return Client
*/
public function setSituation($situation)
{
$this->situation = $situation;
return $this;
}
/**
* Get situation
*
* #return integer
*/
public function getSituation()
{
return $this->situation;
}
/**
* Set ville
*
* #param integer $ville
* #return Client
*/
public function setVille($ville)
{
$this->ville = $ville;
return $this;
}
/**
* Get ville
*
* #return integer
*/
public function getVille()
{
return $this->ville;
}
/**
* Set facebook
*
* #param string $facebook
* #return Client
*/
public function setFacebook($facebook)
{
$this->facebook = $facebook;
return $this;
}
/**
* Get facebook
*
* #return string
*/
public function getFacebook()
{
return $this->facebook;
}
/**
* Set picture
*
* #param string $picture
* #return Client
*/
public function setPicture($picture)
{
$this->picture = $picture;
return $this;
}
/**
* Get picture
*
* #return string
*/
public function getPicture()
{
return $this->picture;
}
/**
* Set newseltter
*
* #param integer $newseltter
* #return Client
*/
public function setNewseltter($newseltter)
{
$this->newseltter = $newseltter;
return $this;
}
/**
* Get newseltter
*
* #return integer
*/
public function getNewseltter()
{
return $this->newseltter;
}
/**
* Set dateinscription
*
* #param \DateTime $dateinscription
* #return Client
*/
public function setDateinscription($dateinscription)
{
$this->dateinscription = $dateinscription;
return $this;
}
/**
* Get dateinscription
*
* #return \DateTime
*/
public function getDateinscription()
{
return $this->dateinscription;
}
/**
* Set datedelete
*
* #param \DateTime $datedelete
* #return Client
*/
public function setDatedelete($datedelete)
{
$this->datedelete = $datedelete;
return $this;
}
/**
* Get datedelete
*
* #return \DateTime
*/
public function getDatedelete()
{
return $this->datedelete;
}
/**
* Set statut
*
* #param string $statut
* #return Client
*/
public function setStatut($statut)
{
$this->statut = $statut;
return $this;
}
/**
* Get statut
*
* #return string
*/
public function getStatut()
{
return $this->statut;
}
/**
* Set contenu
*
* #param string $contenu
* #return Client
*/
public function setContenu($contenu)
{
$this->contenu = $contenu;
return $this;
}
/**
* Get contenu
*
* #return string
*/
public function getContenu()
{
return $this->contenu;
}
}
?>
ClienFieldset
<?php
namespace Application\Form;
use Application\Entity\Client;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class ClientFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('post');
//$em = Registry::get('entityManager');
$this->setHydrator(new DoctrineHydrator($objectManager,'Application\Entity\Client'))
->setObject(new Client());
$this->setLabel('Post');
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden'
)
));
$this->add(array(
'name' => 'mail',
'options' => array(
'label' => 'Title for this Post'
),
'attributes' => array(
'type' => 'text'
)
));
$this->add(array(
'name' => 'password',
'options' => array(
'label' => 'Text-Content for this post'
),
'attributes' => array(
'type' => 'text'
)
));
}
/**
* Define InputFilterSpecifications
*
* #access public
* #return array
*/
public function getInputFilterSpecification()
{
return array(
'mail' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags')
),
'properties' => array(
'required' => true
)
),
'password' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags')
),
'properties' => array(
'required' => true
)
)
);
}
}
?>
Client Form
<?php
namespace Application\Form;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Form;
class ClientForm extends Form
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('post');
// The form will hydrate an object of type "BlogPost"
$this->setHydrator(new DoctrineHydrator($objectManager));
// Add the user fieldset, and set it as the base fieldset
$clientFieldset = new ClientFieldset($objectManager);
$clientFieldset->setUseAsBaseFieldset(true);
$this->add($clientFieldset);
$this->add(array(
'name' => 'security',
'type' => 'Zend\Form\Element\Csrf'
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Go',
'id' => 'submitbutton'
)
));
$this->setValidationGroup(array(
'security',
'post' => array(
'title',
'text'
)
));
}
}
?>
Index Action
<?php
public function indexAction()
{
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
// Create the form and inject the ObjectManager
$form = new ClientForm($objectManager);
// Create a new, empty entity and bind it to the form
$Client = new Client();
$form->bind($Client);
if ($this->request->isPost()) {
$form->setData($this->request->getPost());
if ($form->isValid()) {
$objectManager->persist($Client);
$objectManager->flush();
}
}
return array('form' => $form);
}
?>
#index View
<table class="table">
<?php
if($this->form){
echo $this->form()->openTag($form);
echo $this->formRow($form->get('id'));
echo $this->formRow($form->get('mail'));
echo $this->form()->closeTag();
}
</table> ?>
When i execute My Code i get this Error..
Warning:
include(/var/www/Colocation/Colocation/module/Visitor/config/../view/error/index.phtml):
failed to open stream: No such file or directory in
/var/www/Colocation/Colocation/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php
on line 506
Warning: include(): Failed opening '/var/www/Colocation/Colocation/module/Visitor/config/../view/error/index.phtml'
for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in
/var/www/Colocation/Colocation/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php
on line 506
Pleaz Help me!
The php warning says that it cannot find the file error/index.phtml.
It is looking for this file because somewhere in your code there is an error, which would lead to the error page.
Default error page files are located in the Application module (module/Application/view/error/), but in your case, it is trying to find these files in the 'Visitor' module.
Perhaps in the 'Visitor' module you overwritten the Application's module 'view_manager' configs, so you can try ONE of the follow:
Open the 'Visitor' module config file and comment or remove all error related configs, using this config for the 'view_manager' should be enough
'view_manager' => array(
'template_path_stack' => array(
'visitor' => __DIR__ . '/../view',
),
),
Create error page templates in your 'Visitor' module like the ones you can find in the Application module. Do this only if you want to customize your error page template, keeping unchanged the Application error template, otherwise use the first solution.
After you finish you should be able to see another error but this time related to your code!
I have a symfony2 Form CategoryType with a buildForm:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('language', 'entity', array(
'class' => 'Evr\HomeBundle\Entity\Language',
'property' => 'language'
)
)
->add('category', 'text', array('label' => 'category.category', 'required' => true));
}
As you can expect, I have two entities Category and Language, of which Category is a child of Language (One language can have many categories, and one category belongs to 1 or 0 language)
Category
<?php
namespace Evr\HomeBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Category
*
* #ORM\Table(name="ev_category")
* #ORM\Entity
*/
class Category
{
/**
* #var integer
*
* #ORM\Column(name="category_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ORM\ManyToOne(targetEntity="Language",inversedBy="categories")
* #ORM\JoinColumn(name="language_id",referencedColumnName="language_id")
*/
private $language;
/**
* #var string
*
* #ORM\Column(name="category", type="string", length=255)
*/
private $category;
/**
* #ORM\OneToMany(targetEntity="Subcategory", mappedBy="category")
*/
protected $subcategories;
public function __construct(){
$this->subcategories=new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set language
*
* #param integer $language
* #return Category
*/
public function setLanguage($language) {
$this->language = $language;
return $this;
}
/**
* Get language
*
* #return integer
*/
public function getLanguage() {
return $this->language;
}
/**
* Set category
*
* #param \string $category
* #return Category
*/
public function setCategory($category)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \string
*/
public function getCategory()
{
return $this->category;
}
}
Language
<?php
namespace Evr\HomeBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Language
*
* #ORM\Table(name="ev_language")
* #ORM\Entity
*/
class Language
{
/**
* #var integer
*
* #ORM\Column(name="language_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="language", type="string", length=128)
*/
private $language;
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=10)
*/
private $code;
/**
* #var boolean
*
* #ORM\Column(name="direction", type="boolean")
*/
private $direction;
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="language")
*/
protected $categories;
/**
* #ORM\OneToMany(targetEntity="Country", mappedBy="language")
*/
protected $countries;
public function __construct(){
$this->categories=new ArrayCollection();
$this->countries=new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set language
*
* #param string $language
* #return Language
*/
public function setLanguage($language)
{
$this->language = $language;
return $this;
}
/**
* Get language
*
* #return string
*/
public function getLanguage()
{
return $this->language;
}
/**
* Set code
*
* #param string $code
* #return Language
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set direction
*
* #param boolean $direction
* #return Language
*/
public function setDirection($direction)
{
$this->direction = $direction;
return $this;
}
/**
* Get direction
*
* #return boolean
*/
public function getDirection()
{
return $this->direction;
}
}
When editing a category, I need to display the current values in a form, so that the user can modify them and save.
Here I have a controller editAction(), whose mission is to display the edition form:
public function editAction($id) { //id of the category to modify
$category = $this->getDoctrine()->getRepository('EvrHomeBundle:Category')->find($id); //return the category with id
$categoryForm = $this->createForm(new CategoryType(),$category); //building the form
return $this->render('EvrAdminBundle:Categories:edit.html.twig', array('categoryForm' => $categoryForm->createView(), 'category' => $category));
}//render the form
Remember that the CategoryType has an element which type : entity, which loads the languages in A select box.
But when trying to populate the form CategoryType with the current data (Category and Language) , Symfony returns an Error : Entity Not Found
Symfony doesn't specify in which line the error occures, but I think it's around this line :
$categoryForm = $this->createForm(new CategoryType(),$category); //building the form
Because when I remove the second argument of createForm : $category, it displays an empty form (just like an add category form
Is there a solution for this issue? And how can I create a form with current data from the database, considering the fact that it contains an entity element.
Thank you
If you have a database without referential integrity enforced, then you can delete a record even though another record is pointing to it (they should be linked through a foreign key). Then when you try to grab the record it seem to work but when you want to access attributes of that entity (this is when the real access to the database occurs) it can't find the entity with that record_id and so "Entity not found".
Ex:
$user=new User();
$car=$user->getCar(); /*The user had a CAR record assigned with Id = 1 but the record was
deleted.
The record USER still has the id of 1.*/
/*No error up till here*/
$carName=$car->getName(); /*Error occurs because it tries to grab the record with id of 1
which was deleted*/
Try to use \ in front of entity namespace:
'class' => '\Evr\HomeBundle\Entity\Language',
I would like to create a form with a collection of self reference entity.
I need a form to create new Product ,this form will have a select field (child) with existing products.
I have a product entity and this entity include a child field (child is a product too).
Product entity :
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", length=20)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
protected $title;
/**
* #var string
*
* #ORM\Column(name="manufacturer_reference", type="string", length=255, nullable=true)
*/
protected $manufacturer_reference;
/**
* #var string
*
* #ORM\Column(name="resume", type="text", nullable=true)
*/
protected $resume;
/**
* #var boolean
*
* #ORM\Column(name="is_salable", type="boolean", options={"default" = 1})
*/
protected $is_salable = 1;
/**
* #var boolean
*
* #ORM\Column(name="is_active", type="boolean", options={"default" = 1})
*/
protected $is_active = 1;
/**
* #ORM\ManyToOne(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductCategory")
* #ORM\JoinColumn(name="product_category_id", referencedColumnName="id", nullable=true)
*/
protected $product_category;
/**
* #ORM\ManyToOne(targetEntity="\Hexanet\Common\CatalogBundle\Entity\Manufacturer")
* #ORM\JoinColumn(name="manufacturer_id", referencedColumnName="id", nullable=true)
*/
protected $manufacturer;
/**
* #ORM\ManyToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\Product", mappedBy="parents" )
*/
protected $children;
/**
* #ORM\ManyToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\Product")
* #ORM\JoinTable(name="product_to_product",
* joinColumns={#ORM\JoinColumn(name="child_product_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="parent_product_id", referencedColumnName="id")}
* )
*/
protected $parents;
/**
* #ORM\OneToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductPrice", mappedBy="product" )
*/
protected $product_prices;
/**
* #ORM\OneToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase", mappedBy="product")
*/
protected $product_prices_purchase;
/**
* #ORM\OneToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom", mappedBy="product")
*/
protected $product_prices_custom;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Product
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set product category
*
* #param \Hexanet\Common\CatalogBundle\Entity\ProductCategory $product_category
* #return Product
*/
public function setProductCategory(\Hexanet\Common\CatalogBundle\Entity\ProductCategory $product_category = null)
{
$this->product_category = $product_category;
return $this;
}
/**
* Get product category
*
* #return \Hexanet\Common\CatalogBundle\Entity\ProductCategory
*/
public function getProductCategory()
{
return $this->product_category;
}
/**
* Set resume
*
* #param string $resume
* #return Product
*/
public function setResume($resume)
{
$this->resume = $resume;
return $this;
}
/**
* Get resume
*
* #return string
*/
public function getResume()
{
return $this->resume;
}
/**
* Set manufacturer reference
*
* #param string $title
* #return Product
*/
public function setManufacturerReference($ref)
{
$this->manufacturer_reference = $ref;
return $this;
}
/**
* Get manufacturer reference
*
* #return string
*/
public function getManufacturerReference()
{
return $this->manufacturer_reference;
}
/**
* Set is salable
*
* #param boolean $active
* #return Product
*/
public function setIsSalable($salable)
{
$this->is_salable = $salable;
return $this;
}
/**
* Get is salable
*
* #return boolean
*/
public function getIsSalable()
{
return $this->is_salable;
}
/**
* Set is active
*
* #param boolean $active
* #return Product
*/
public function setIsActive($active)
{
$this->is_active = $active;
return $this;
}
/**
* Get is active
*
* #return boolean
*/
public function getIsActive()
{
return $this->is_active;
}
/**
* Set manufacturer
*
* #param $manufacturer
* #return Product
*/
public function setManufacturer($manufacturer)
{
$this->manufacturer = $manufacturer;
return $this;
}
/**
* Get manufacturer
*
*/
public function getManufacturer()
{
return $this->manufacturer;
}
/**
* Constructor
*/
public function __construct()
{
$this->parents = new \Doctrine\Common\Collections\ArrayCollection();
$this->children = new \Doctrine\Common\Collections\ArrayCollection();
$this->product_prices = new \Doctrine\Common\Collections\ArrayCollection();
$this->product_prices_purchase = new \Doctrine\Common\Collections\ArrayCollection();
$this->product_prices_custom = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add child
*
* #param \Hexanet\Common\CatalogBundle\Entity\Product $product
* #return Product
*/
public function addChild(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
die(var_dump($product));
$this->children[] = $product;
return $this;
}
/**
* Remove child
*
* #param \Hexanet\Common\CatalogBundle\Entity\Product $product
*/
public function removeChild(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
$this->children->removeElement($product);
}
/**
* Get children
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
/**
* Add parent
*
* #param \Hexanet\Common\CatalogBundle\Entity\Product $product
* #return Product
*/
public function addParent(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
$this->parents[] = $product;
return $this;
}
/**
* Remove parent
*
* #param \Hexanet\Common\CatalogBundle\Entity\Product $price
*/
public function removeParent(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
$this->parents->removeElement($product);
}
/**
* Get parents
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getParents()
{
return $this->parents;
}
/**
* Add product price
*
* #param \Hexanet\Common\CatalogBundle\Entity\ProductPrice $price
* #return Product
*/
public function addProductPrice(\Hexanet\Common\CatalogBundle\Entity\ProductPrice $price)
{
$this->product_prices[] = $price;
return $this;
}
/**
* Remove product price
*
* #param \Hexanet\Common\CatalogBundle\Entity\ProductPrice $price
*/
public function removeProductPrice(\Hexanet\Common\CatalogBundle\Entity\ProductPrice $price)
{
$this->product_prices->removeElement($price);
}
/**
* Get product prices
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProductPrices()
{
return $this->product_prices;
}
/**
* Add product price purchase
*
* #param \Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price
* #return Product
*/
public function addProductPricePurchase(\Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price)
{
$this->product_prices_purchase[] = $price;
return $this;
}
/**
* Remove product price purchase
*
* #param \Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price
*/
public function removeProductPricePurchase(\Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price)
{
$this->product_prices_purchase->removeElement($price);
}
/**
* Get product prices purchase
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProductPricesPurchase()
{
return $this->product_prices_purchase;
}
/**
* Add product price custom
*
* #param \Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price
* #return Product
*/
public function addProductPriceCustom(\Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price)
{
$this->product_prices_custom[] = $price;
return $this;
}
/**
* Remove product price custom
*
* #param \Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price
*/
public function removeProductPriceCustom(\Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price)
{
$this->product_prices_custom->removeElement($price);
}
/**
* Get product prices custom
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProductPricesCustom()
{
return $this->product_prices_custom;
}}
for the form i have this :
class ProductType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('manufacturer_reference')
->add('resume')
->add('product_category', 'entity', array(
'class' => 'HexanetCatalogBundle:ProductCategory',
'property' => 'title',
))
->add('children', 'collection', array(
'type' => new ProductChildrenType,
'allow_add' => true));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Hexanet\Common\CatalogBundle\Entity\Product'
));
}
public function getName()
{
return 'hexanet_common_catalogbundle_producttype';
}}
The problem is there, i dont know how to create the ProductChildrenType builder :
class ProductChildrenType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('product', 'entity', array(
'class' => 'HexanetCatalogBundle:Product',
'property' => 'title',
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Hexanet\Common\CatalogBundle\Entity\Product'
));
}
public function getName()
{
return 'hexanet_common_catalogbundle_productchildrentype';
}}
->add('product', 'entity',...) I have the error :
Neither property "product" nor method "getProduct()" nor method "isProduct()" exists in class "Hexanet\Common\CatalogBundle\Entity\Product".
Thx for the Help
I have a similar case for a store, so i can add extra products on the admin area, so i can offer them on checkout...
My partner at work and me solved this problem yesterday, so if you're still interested, here we go....
We are using Symfony 2.6.x , i haven't tested it on older versions of symfony yet.
->add('myExtras', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'StoreBundle:Productos',
'placeholder' => '-- Select an extra product --',
'property' => 'name',
'query_builder' => function (EntityRepository $er) use( $options ) {
return $er->createQueryBuilder('p')
->where('p.asociable = :asociable')
->andWhere('p.id != :selfid')
->setParameters( array('adjuntable' => '1', 'selfid' => $options['selfid'] ));
},
'label' => 'Extra Product'
),
'by_reference' => false,
'allow_add' => true,
'allow_delete' => true
))
instead of using a collection of form type for "children", we used a collection of type "entity", and we used a querybuilder to control the conditions we needed to get the right options to show.
using this we stopped having the messages, that you're getting... and for saving and removing the relation, when we add the children, we had to tell the children to set the parent... and for removing the same, first tell the children to remove the parent from the parent's list, and then remove the children from the children list... (in code is easier to see)
in the entity i have to collections myExtras (childrens) and imExtraOf (parents), so when adding a children, i have to tell the children i'm receiving the counterpart ->addImExtraOf (i am your father function) ... then we add the product to our extra list. and for removing, the same, we call first ->removeImExtraOf , if you don't do it this way, the relation will not be saved.
the Entity :
public function addMyExtra(Productos $extra)
{
$extra->addImExtraOf($this);
if( !$this->myExtras->contains($extra) ) {
$this->myExtras[] = $extra;
}
return $this;
}
public function removeMyExtra(Productos $extra)
{
$extra->removeImExtraOf($this);
$this->myExtras->removeElement($extra);
}
the orm mapping (yml): (myExtras = children, imExtraOf = parents )
manyToMany:
myExtras:
targetEntity: Productos
cascade: [ persist ]
mappedBy: imExtraOf
inversedBy: null
joinTable:
name: productos_has_productos
joinColumns:
-
name: extra_id
referencedColumnName: id
inverseJoinColumns:
-
name: base_id
referencedColumnName: id
orderBy: null
imExtraOf:
targetEntity: Productos
cascade: [ persist ]
mappedBy: null
inversedBy: myExtras
joinTable:
name: productos_has_productos
joinColumns:
-
name: base_id
referencedColumnName: id
inverseJoinColumns:
-
name: extra_id
referencedColumnName: id
orderBy: null
hope it helps someone.
I want to create a form with a drop-down list and text field.
My drop-down list contains values of my Agency Entity and my text field a week number.
I want to set default value based on my connected user but I don't know how.
I have modified my entity, my form and my controller:
I have an Entity Week with my Agency relation :
class Week
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ORM\ManyToOne(targetEntity="Agency", inversedBy="week", cascade={"persist"})
* #ORM\JoinColumn(name="agency_id", referencedColumnName="id")
*/
private $agency;
/**
* #var integer
*
* #ORM\Column(name="week_number", type="integer")
*/
private $week_number;
/**
* #var \DateTime
*
* #ORM\Column(name="week_start", type="datetime")
*/
private $week_start;
/**
* #var \DateTime
*
* #ORM\Column(name="week_end", type="datetime")
*/
private $week_end;
public function getAgency()
{
return $this->agency;
}
.... public function get.....
}
Then my Agency Entity :
class Agency
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=50)
*/
private $name;
/**
* #var integer
*
* #ORM\Column(name="nb_team", type="integer")
*/
private $nb_team;
/**
* #var \DateTime
*
* #ORM\Column(name="date_creation", type="datetime")
*/
private $date_creation;
/**
*
* #ORM\OneToMany(targetEntity="Week", mappedBy="agency", cascade={"persist"})
*/
private $week;
public function .....
}
My Form :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('agency', 'entity', array(
'class' => 'MyProjectBundle:Agency',
'property' => 'name',
/* 'query_builder' => function(\Doctrine\ORM\EntityRepository $er) {
return $er->createQueryBuilder('a')->orderBy('a.name', 'ASC');
},*/
'attr' => array('onchange' => 'javascript:this.form.submit();')
))->add('week_number', 'text');
}
And my Controller :
$num_week = 4;
$id = 3;
$agency_id = $em->getRepository('MyProjectBundle:Agency')->find($id);
$week = $em->getRepository('MyProjectBundle:Week')->WeekExiste($num_week, $week_start, $agency_id);
$form2 = $this->createForm(new FormType(), $week);
if ($request->isMethod('POST')) {
$form2->bind($request);
$data = $form2->getData();
$agency = $data['agency'];
}
else {
$agency = $em->getRepository('MyProjectBundle:Agency')->find($id);
}
$week return a correct Entity.
My form works for the week_number field but my drop down list doesn't select my agency I set in my controller.
I had the same problem with the default option value, you can check it on my question.
I've shared a full code.
symfony2 selected option