symfony2 forms dynamically Generate Forms Based on user Data - php

I'm very new to symfony2 and i want to create a form. The values of fields should base on user data.
I have projects and users with a n:m-relation and now i want to embed a form in twig where I can assign users (multiple with one click) and projects. My class for user looks like:
// src/Pso/LogBundle/Entity/User.php
namespace Pso\LogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="users", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"})
* #ORM\Entity(repositoryClass="Pso\LogBundle\Entity\UserRepository")
*/
class User implements AdvancedUserInterface, \Serializable
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* #ORM\Column(type="string", length=32)
*/
private $salt;
/**
* #ORM\Column(type="string", length=250)
*/
private $password;
/**
* #ORM\Column(type="string", length=60, unique=true)
*/
private $email;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users")
* #ORM\JoinTable(name="user_role",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*
*/
private $roles;
The class for project looks like:
// src/Pso/ProjectBundle/Entity/Project.php
namespace Pso\ProjectBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="project", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"})
* #ORM\Entity(repositoryClass="Pso\ProjectBundle\Entity\ProjectRepository")
*/
class Project
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id()
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, unique=true, nullable=false)
*/
private $project_nr;
/**
* #ORM\ManyToOne(targetEntity="Pso\ProjectBundle\Entity\Mandator", inversedBy="projects")
* #ORM\JoinColumn(name="mandator_id", referencedColumnName="id")
*/
private $mandator;
/**
* #ORM\Column(type="string", length=80, nullable=false)
*/
private $project_name;
/**
* #ORM\Column(type="string", length=50)
*/
private $customer;
/**
* #ORM\Column(type="string", length=50)
*/
private $label;
/**
* #ORM\Column(type="date")
*/
private $shipping_date;
/**
* #ORM\Column(type="float")
*/
private $advance_payment;
/**
* #ORM\Column(type="integer", length=1)
*/
private $probability;
/**
* #ORM\Column(type="blob")
*/
private $special_demand;
/**
* #ORM\Column(type="string", length=4)
*/
private $currency;
/**
* #ORM\Column(type="integer", length=1, nullable=false)
*/
private $status;
/**
* #ORM\Column(type="string", length=100)
*/
private $contract_nr;
/**
* #ORM\Column(type="datetime", nullable=false)
*/
private $dbinsert;
/**
* #ORM\Column(type="datetime", nullable=false)
*/
private $dbupdate;
/**
* #ORM\ManyToMany(targetEntity="Pso\LogBundle\Entity\User", cascade={"persist", "remove"})
*/
private $users;
public function __construct() {
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
My ProjectuserType looks like:
namespace Pso\ProjectBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Doctrine\ORM\EntityRepository;
class ProjectuserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('project','text')
;
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$form = $event->getForm();
$formOptions = array(
'class' => 'Pso\LogBundle\Entity\User',
'property' => 'username',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('x')->FROM('PsoLogBundle:user', 'u')
->WHERE('u.id = :id')
->setParameter('id',5)
;
// or call a method on your repository that returns the query builder
// the $er is an instance of your UserRepository
// return $er->findnotsignedusers();
},
);
// or call a method on your repository that returns the query builder
// the $er is an instance of your UserRepository
// return $er->createOrderByFullNameQueryBuilder();
},
);
// create the field, this is similar the $builder->add()
// field name, field type, data, options
$form->add('user', 'entity', $formOptions);
}
);
}
public function getName()
{
return 'Projectuser';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => null,
));
}
}
With the Type I oriented on the post and on documentation about chapter "How to dynamically Generate Forms Based on user Data"
With my Code I always get the error "Class Pso\ProjectBundle\Form\EntityRepository does not exist". I think I doesn't get right documentation. I don't want to get the data out of my ProjectRepository. This exists but the namespace is Pso\ProjectBundle\Form.
But my intention ist to get the data with the querybuilder in my EventListener. Every tipp would be appreciated.

Add this line in your ProjectuserType class : use Doctrine\ORM\EntityRepository
Hope it's helpful.
Best regards.

Related

Doctrine field has value in database but is null when mapped

I am having this strange issue with Doctrine .
When I use find(id) to find an entity, all fields are null except the id. I have double checked the values in database and they are are not null.
The strange thing is when I issue a native mysql query and try to find the entity that doctrine tries to fetch I get non Null value so probably it's a doctrine way of fetching values problem.
Here is my entity :
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
*
*
* #ORM\Entity()
* #ORM\Table(name="hui_address")
*/
class Address
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer", nullable=true)
*/
protected $client_id;
/**
* #ORM\Column(type="integer", nullable=true)
*/
protected $region_id;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $street;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $city;
/**
* #ORM\Column(name="`state`", type="text", nullable=true)
*/
protected $state;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $zip_code;
/**
* #ORM\Column(type="float", precision=10, scale=6, nullable=true)
*/
protected $latitude;
/**
* #ORM\Column(type="float", precision=10, scale=6, nullable=true)
*/
protected $longitude;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $notes;
/**
* #ORM\Column(name="`status`", type="boolean", nullable=true)
*/
protected $status;
/**
* #ORM\Column(type="smallint", nullable=true)
*/
protected $archive;
/**
* #ORM\Column(type="datetime")
*/
protected $created_at;
/**
* #ORM\OneToMany(targetEntity="Store", mappedBy="address")
* #ORM\JoinColumn(name="id", referencedColumnName="address_id")
*/
protected $Stores;
/**
* #ORM\ManyToOne(targetEntity="Client", inversedBy="Addresses")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
protected $client;
/**
* #ORM\OneToMany(targetEntity="Client", mappedBy="PPBAddress")
* #ORM\JoinColumn(name="id", referencedColumnName="ppb_address_id")
*/
protected $clientHQ;
/**
* #ORM\ManyToOne(targetEntity="Region", inversedBy="Addresses")
* #ORM\JoinColumn(name="region_id", referencedColumnName="id")
*/
protected $region;
public function __construct()
{
if (!$this->created_at) {
$this->created_at = new \DateTime();
}
$this->Clients = new ArrayCollection();
$this->Stores = new ArrayCollection();
}
public function __toString()
{
return (!$this->street || strlen($this->street) == 0 || !$this->city || !$this->city)
? "Address incomplete"
: sprintf('%s, %s %s %s', $this->street, $this->city, $this->state, $this->zip_code);
}
public function __sleep()
{
return array('id', 'client_id', 'region_id', 'street', 'city', 'state', 'zip_code', 'latitude', 'longitude', 'notes', 'status', 'archive', 'created_at');
}
}
You are missing getters and setters in the entity class.
php bin/console doctrine:generate:entities *your bundle*
will generate them automatically
There was nothing wrong with doctrine. It turns out that the address is fetched from a native query and only the id is selected , that's why I am getting the value for id and null for the rest.
This is how addresses are found :
$query = $this->getManager()->createNativeQuery('SELECT .... ')

Doctrine 2 removes parent row

I have defined two database entities
Project:
use Doctrine\ORM\Mapping as ORM;
use \Kdyby\Doctrine\Entities\MagicAccessors;
/**
* #ORM\Entity
*/
class Project extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
public $id;
/**
* #ORM\Column(type="string")
*/
public $title;
/**
* #ORM\Column(type="text")
* #var string
*/
public $description;
/**
* #ORM\Column(type="datetime", nullable=true)
* #var DateTime
*/
public $created;
/**
* #ORM\Column(type="boolean")
* #var string
*/
public $public;
/**
* #ORM\Column(type="blob")
* #var string
*/
public $thumbnail;
public function __construct()
{
$this->created = new \DateTime();
$this->public = 0;
}
}
and Personage:
use Doctrine\ORM\Mapping as ORM;
use \Kdyby\Doctrine\Entities\MagicAccessors;
/**
* #ORM\Entity
*/
class Personage extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
public $id;
/**
* #ORM\Column(type="string")
*/
public $name;
/**
* #ORM\Column(type="text", nullable=true)
* #var string
*/
public $shortDescription;
/**
* #ORM\Column(type="text", nullable=true)
* #var string
*/
public $playerDescription;
/**
* #ORM\Column(type="datetime")
* #var DateTime
*/
public $created;
/**
* #ORM\Column(type="integer")
* #var string
*/
public $creator;
/**
* #ORM\Column(type="boolean", options={"default" = false})
* #var boolean
*/
public $inGraph;
/**
* #ORM\Column(type="boolean", nullable=false, options={"default" = 0})
* #var boolean
*/
public $deleted;
/**
* #ORM\ManyToOne(targetEntity="Project", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="project", referencedColumnName="id", onDelete="CASCADE")
* #var string
*/
public $project_id;
public function __construct()
{
$this->deleted = 0;
$this->inGraph = 0;
}
}
Every Personage entity belongs to some project. But whenever I try to remove Personage either this way:
public function removeChar($id)
{
$a = $this->EntityManager->find('App\Personage', $id);
if($a->deleted)
{
$this->EntityManager->remove($a);
$this->EntityManager->flush();
}
}
or using dql. It removes the whole project row as well. What i want is whenever project is removed it removes all characters corresponding but NOT other way around.
I tried to remove
cascade={"persist", "remove"}
part from Project entity declaration (and updating database via console) but it said everything was in sync and did nothing. So I removed whole database and build it without cascade={"persist", "remove"}, but the problem was not solved.
remove onDelete="CASCADE" from
#ORM\JoinColumn(name="project", referencedColumnName="id", onDelete="CASCADE")
and add
#ORM\OneToMany(targetEntity="Personage", mappedBy="project_id",cascade={"remove"})
private $personages;
in the project entity.

Doctrine Extensions Symfony2

I install Doctrine Extensions like here How to install Doctrine Extensions in a Symfony2 project
This is my Entity Class
<?php
namespace My\NewsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* News
*
* #ORM\Table()
* #ORM\Entity
*/
class News
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=150)
*/
protected $title;
/**
* #ORM\Column(type="text")
*/
protected $content;
/**
* #ORM\Column(type="text")
*/
protected $description;
/**
* #ORM\Column(type="string", length=150)
*/
protected $keywords;
/**
* #Gedmo\Slug(fields={"title"})
* #ORM\Column(length=128, unique=true)
*/
private $slug;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #ORM\Column(name="updated_at", type="datetime")
* #Gedmo\Timestampable(on="update")
*/
private $updated_at;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
php app/console doctrine:generate:entities My
gives me a a error
[Doctrine\Common\Annotations\AnnotationException]
[Semantical Error] The annotation "#Gedmo\Mapping\Annotation\Slug" in property My\NewsBundle\Entity\News::$slug does not exist, or could not be auto -loaded.
Should i add something in config or someting else? Thanks for help.

Class Doctrine\Common\Collections\ArrayCollection is not a valid entity or mapped super class

I have Three entities:
FeatureValue.php
<?php
namespace Webmuch\ProductBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class FeatureValue
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length="100")
*/
protected $name;
/**
* #ORM\OneToMany(targetEntity="FeatureType", mappedBy="name")
*/
private $featuretype;
public function __construct()
{
$this->featuretype = new \Doctrine\Common\Collections\ArrayCollection();
}
FeatureType.php
<?php
namespace Webmuch\ProductBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Webmuch\ProductBundle\Entity\FeatureValue;
/**
* #ORM\Entity
*/
class FeatureType
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
protected $title;
/**
* #ORM\ManyToOne(targetEntity="FeatureValue", inversedBy="featuretype",cascade={"persist"})
* #ORM\JoinColumn(name="feature_value_id", referencedColumnName="id")
*/
protected $name;
public function __construct()
{
$this->name = new \Doctrine\Common\Collections\ArrayCollection();
}
Product.php
<?php
namespace Webmuch\ProductBundle\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection as ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table()
* #ORM\HasLifecycleCallbacks
*/
class Product
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="Store")
*/
protected $store;
/**
* #ORM\ManyToMany(targetEntity="Webmuch\CategoryBundle\Entity\Category")
*/
protected $category;
/**
* #Gedmo\Sluggable
* #ORM\Column(type="string", length=255)
*/
protected $title;
/**
* #Gedmo\Slug(updatable=false, unique=true)
* #ORM\Column(type="string", length=255)
*/
protected $slug;
/**
* #ORM\Column(type="integer")
*/
protected $quantity;
/**
* #ORM\Column(type="boolean")
*/
protected $active;
/**
* #ORM\Column(type="text", length="4000", nullable="true")
*/
protected $preview;
/**
* #ORM\ManyToMany(targetEntity="FeatureType")
* #ORM\JoinColumn(name="feature_type_id", referencedColumnName="id")
*/
protected $features;
public function __toString()
{
return $this->getTitle();
}
}
My problem is that when i add FeatureValue in FeatureType then show me error Class "Doctrine\Common\Collections\ArrayCollection is not a valid entity or mapped super class."
In my project i want FeatureType along with FeatureValue in my Product entity.
suppose in FeatureType two property Size and Colour.Now in FeatureType Size- Three FeatueValue Small,Medium,Large have been given and also suppose in FeatureType Colour- Three FeatureValue Red,Green,Yello have been given.
Now i want to show both the FeatureType along with their FeatureValue in my Product Entity.
So any one tell me how it can be done.I have tried a lot of but not succeed.
In Webmuch\ProductBundle\Entity\FeatureType::__construct you assign an ArrayCollection to $this->name, this is wrong, as this is a ToOne and not a ToMany.
Just remove this line.

Symfony 2 embed form for doctrine one to many relation using sonata admin generator

I am trying to implemet CRUD using sonata admin generator.
I have two table and Vendor and vendor contacts.
My entity tables are like this
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity
* #ORM\Table(name="vendor")
*/
class Vendor{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="VendorContact", mappedBy="vendor_contact")
*/
public $contact;
/**
* #ORM\Column(type="string", length=100)
*/
protected $name;
/**
* #ORM\Column(type="string", length=100)
*/
protected $userName;
/**
* #ORM\Column(type="string", length=100)
*/
protected $password;
/**
* #ORM\Column(type="integer")
*/
private $status;
/**
* #ORM\Column(type="date")
*/
protected $contractBeginDate;
/**
* #ORM\Column(type="date")
*/
protected $contractEndDate;
/**
* #ORM\Column(type="datetime", nullable="true")
*/
protected $createdAt;
/**
* #ORM\Column(type="datetime", nullable="true")
*/
protected $updatedAt;
public function __construct()
{
$this->contact = new ArrayCollection();
}
And my vendor contact entity class is like this
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity
* #ORM\Table(name="vendor_contact")
*/
class VendorContact{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Vendor", inversedBy="contact")
* #ORM\JoinColumn(name ="vendor_id", referencedColumnName="id")
*/
protected $vendorContact;
/**
* #ORM\Column(type="string", length=1000)
*/
protected $street;
/**
* #ORM\Column(type="string", length=100)
*/
protected $city;
/**
* #ORM\Column(type="string", length=100)
*/
protected $state;
/**
* #ORM\Column(type="string", length=100)
*/
protected $country;
/**
* #ORM\Column(type="string", length=50)
*/
protected $zip;
/**
* #ORM\Column(type="string", length=50)
*/
protected $contact_numb;
/**
* #ORM\Column(type="string", length=100)
*/
protected $email;
/**
* #ORM\Column(type="integer")
*/
protected $contact_type;
/**
* #ORM\Column(type="datetime", nullable="true")
*/
protected $createdAt;
/**
* #ORM\Column(type="datetime", nullable="true")
*/
protected $updatedAt;
My sonata Admin class is like:
class VendorAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('name')
->add('user_name','text')
->add('password','text')
->add('status')
->add('contract_begin_date','date')
->add('contract_end_date','date');
$formMapper->add('contact', 'collection', array('type' => new VendorContactType()));
// ->end();
;
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->add('name')
->add('userName')
->add('contractBeginDate')
->add('contractEndDate')
->add('_action', array(), array(
'actions' => array(
'edit' => array(),
),
))
;
}
}
And vendor contact form builder is like this:
class VendorContactType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('street')
->add('city')
->add('state')
->add('country')
->add('zip')
->add('contact_numb')
->add('email')
->add('contact_type')
;
}
public function getName()
{
return 'vendor_contact';
}
public function getDefaultOptions(array $options){
return array('data_class' => 'JiniVod\StoreBundle\Entity\VendorContact');
}
}
But when i am executing this add vendor using to sonata admin crud function i am not getting form field for vendor contact. I am onlty getting label contact
Can any one please help me.
Thanks in advance.
Instead of using the 'collection' Type you should 'use sonata_type_model'

Categories