I need help with Symfony2 (2.8)
Created two entities Category and CategoryLang. It will be a categories.
<?php
namespace CreLabs\Bundle\SettingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;
/**
* #ORM\Entity(repositoryClass="CreLabs\Bundle\SettingBundle\Entity\CategoryRepository")
* #ORM\Table(name="category")
*/
class Category
{
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="boolean", nullable=true, options={"default": 1})
*/
protected $status;
/**
* #ORM\OneToMany(targetEntity="CategoryLang", mappedBy="category", cascade={"persist", "remove"})
*/
protected $locales;
/**
* #ORM\Column(type="datetime", nullable=false)
*/
protected $created_at;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $updated_at;
CategoryLang. It will be a translation of my categories.
<?php
namespace CreLabs\Bundle\SettingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;
/**
* #Entity
* #ORM\Table(name="category_lang")
*/
class CategoryLang
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
*/
protected $name;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
protected $description;
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="locales", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
/**
* #ORM\Column(type="string", length=2)
*/
protected $locale;
Now i trying add createFormBuilder Category Entity + CategoryLang Entities fields, but can not see normally form. Only can use array('mapped' => false and forward data from fields.
$form = $this->createFormBuilder($category);
$form = $form
->add('locale', HiddenType::class, array('mapped' => false, 'data' => $locale))
->add('name', TextType::class, array('mapped' => false, 'data' => $name))
->add('description', TextareaType::class, array('mapped' => false, 'required' => false, 'data' => $description))
->add($label, SubmitType::class, array('label' => $label));
$form = $form->getForm();
By the way have CategoryRepository with custom query
public function getCategory($category_id, $locale)
{
$repository = $this->getEntityManager()->getRepository('SettingBundle:Category');
$fields = array('p.id', 'category_info.name', 'category_info.description', 'p.status, category_info.locale');
$query = $repository->createQueryBuilder('p')
->select($fields)
->innerJoin('SettingBundle:CategoryLang', 'category_info', 'WITH', 'category_info.category = p.id')
->where('p.id = :category_id AND category_info.locale = :locale')
->setParameter('category_id', $category_id)
->setParameter('locale', $locale)
->getQuery();
$result = $query->getOneOrNullResult() != NULL ? new ArrayCollection($query->getSingleResult()) : false;
return $result;
}
Problems:
1. getCategory() -> return not object, but array or ArrayCollection. Can not be reused then need update fields in database.
/* #var $category Category */
$category = $this->getCategory($category_id, $form['locale']);
if ($category) {
// $category->setUpdatedAt(new ArrayCollection());
$locale = new CategoryLang();
$locale->setName($form['name']);
$locale->setDescription($form['description']);
$category->addLocale($locale);
$entityManager = $this->getEntityManager();
$entityManager->persist($category);
$entityManager->flush($category);
}
2. Can not get in create form builder information from child table.
Where is my problem? Can anybody help me understand my mistakes?
Related
I have implemented the 'collection' form type in my app, and it works great, including removing related records that are removed from the submitted data, however in order to save any newly added link record I have to manually loop through the links entities & set the owner as the entity being edited. I'm sure it should do this automatically, so what have I missed?
You'll see a...
/*****************************************************************
* This is the bit I've had to add to persist the new entries!!! *
*****************************************************************
... where I've had to manually link the entities in the AppController file.
The files
App Entity
<?php
namespace ...\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* App
*
* #ORM\Table()
* #ORM\Entity()
*/
class App
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ...
/**
* #var AppAppStoreData[]|ArrayCollection
*
* We use orphan removal here to remove the link data when deleting an app
* #ORM\OneToMany(targetEntity="AppAppStoreData", mappedBy="app", cascade={"all"}, orphanRemoval=TRUE)
*/
private $appAppStoreData;
// ...
/**
* #return ArrayCollection|AppAppStoreData[]
*/
public function getAppAppStoreData()
{
return $this->appAppStoreData;
}
/**
* #param ArrayCollection|AppAppStoreData[] $appAppStoreData
*
* #return $this
*/
public function setAppAppStoreData( $appAppStoreData )
{
$this->appAppStoreData = $appAppStoreData;
return $this;
}
}
AppStore Entity
<?php
namespace ...\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* AppStore
*
* #ORM\Table()
* #ORM\Entity()
*/
class AppStore
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ...
/**
* #var AppAppStoreData[]|ArrayCollection
*
* We use orphan removal here to remove the link data when deleting an app
* #ORM\OneToMany(targetEntity="AppAppStoreData", mappedBy="appStore", cascade={"all"}, orphanRemoval=TRUE)
*/
private $appAppStoreData;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
// ...
/**
* #return AppAppStoreData[]|ArrayCollection
*/
public function getAppAppStoreData()
{
return $this->appAppStoreData;
}
/**
* #param AppAppStoreData[]|ArrayCollection $appAppStoreData
*
* #return $this
*/
public function setAppAppStoreData( $appAppStoreData )
{
$this->appAppStoreData = $appAppStoreData;
return $this;
}
}
AppAppStoreData Entity
<?php
namespace ...\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* AppAppStoreData
*
* #ORM\Table()
* #ORM\Entity()
*/
class AppAppStoreData
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var App
*
* #ORM\ManyToOne(targetEntity="App", inversedBy="appAppStoreData")
* #ORM\JoinColumn(name="app_id", referencedColumnName="id")
*/
private $app;
/**
* #var AppStore
*
* #ORM\ManyToOne(targetEntity="AppStore", inversedBy="appAppStoreData")
* #ORM\JoinColumn(name="app_store_id", referencedColumnName="id")
*/
private $appStore;
/**
* #var string
*
* #ORM\Column(name="app_store_uri", type="string", length=1083)
*/
private $appUri;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set app
*
* #param App $app
*
* #return AppAppStoreData
*/
public function setApp(App $app)
{
$this->app = $app;
return $this;
}
/**
* Get app
*
* #return App
*/
public function getApp()
{
return $this->app;
}
/**
* Set appStore
*
* #param AppStore $appStore
*
* #return AppAppStoreData
*/
public function setAppStore(AppStore $appStore)
{
$this->appStore = $appStore;
return $this;
}
/**
* Get appStore
*
* #return AppStore
*/
public function getAppStore()
{
return $this->appStore;
}
/**
* Set appStoreLink
*
* #param string $appUri
*
* #return AppAppStoreData
*/
public function setAppUri( $appUri)
{
$this->appUri = $appUri;
return $this;
}
/**
* Get appStoreLink
*
* #return string
*/
public function getAppUri()
{
return $this->appUri;
}
}
AppType Form
<?php
namespace ...\Form\Type;
use ...\Entity\App;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class AppType extends AbstractType
{
/**
* Builds the App admin edit form
*
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm( FormBuilderInterface $builder, array $options )
{
$builder
// ...
->add( 'appAppStoreData', 'collection', [
'type' => new ,
'label' => 'App Store Links',
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'widget_add_btn' => array( 'label' => "Add App Store Details" ),
'widget_remove_btn' => array( 'label' => "Remove App Store Details" ),
'show_legend' => false, // dont show another legend of subform
'options' => array( // options for collection fields
'label_render' => false,
'widget_addon_prepend' => array(
'text' => '#',
),
'horizontal_input_wrapper_class' => "col-lg-8",
),
] );
}
/**
* Sets the Entity data class
*
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions( OptionsResolverInterface $resolver )
{
$resolver->setDefaults(
array(
'data_class' => '...\Entity\App',
)
);
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
public function getName()
{
return 'app';
}
}
AppAppStoreDataFieldsType
<?php
namespace ...\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class AppAppStoreDataFieldsType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm( FormBuilderInterface $builder, array $options )
{
$builder
->add( 'appStore', 'entity', [
'class' => '...Bundle:AppStore',
'property' => 'name',
'label' => 'App Store'
] )
->add( 'appUri', 'url', [
'label' => 'App URI'
] );
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions( OptionsResolverInterface $resolver )
{
$resolver->setDefaults( array(
'data_class' => '...\Entity\AppAppStoreData'
) );
}
/**
* #return string
*/
public function getName()
{
return 'app_store_data_fields';
}
}
App Controller
<?php
namespace ...\Controller;
use ...\Entity\UploadableInterface;
use ...\Exception\RecordNotFoundException;
use ...\Exception\RedirectException;
use ...\Entity\App;
use ...\Entity\AppRepository;
use ...\Entity\ClientRepository;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class AppController extends ClientAssetController
{
/**
* #param Request $request
* #param null $id
*
* #return Response
*/
public function editAction( Request $request, $id = null )
{
$app = #$this->getAppRepository()->find( $id );
// ...
$form = $this->createForm( 'app', $app )
->add( 'save', 'submit', [ 'label' => 'Save' ] );
$form->handleRequest( $request );
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist( $app );
/*****************************************************************
* This is the bit I've had to add to persist the new entries!!! *
*****************************************************************
/
foreach ($app->getAppAppStoreData() as $appAppStoreDatum) {
$appAppStoreDatum->setApp( $app );
}
$em->flush();
// ... Redirect
}
// ... Render
}
// ...
}
initialize the collection of appAppStoreData:
...
public function __construct()
{
$this->appAppStoreData = new ArrayCollection();
}
I want to use the query_builder in a Symfony2 FormType, I tried to make a simple request in my Postgresql shema using Doctrine DQL. It return me an error and i don't really understand how fix it :
PDOException: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "" AS id0 FROM ""
LINE 1: SELECT "0_."id" AS id0 FROM "DATA_WAREHOUSE"."WindFarm" "0_
This is the Windfarm class :
<?php
namespace Base\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* WindFarm
*
* #ORM\Table(name="""DATA_WAREHOUSE"".""WindFarm""")
* #ORM\Entity(repositoryClass="Base\CoreBundle\Repository\WindFarmRepository")
*/
class WindFarm
{
/**
* #ORM\OneToMany(targetEntity="Base\CoreBundle\Entity\Turbine", mappedBy="windFarm")
*/
private $turbines;
/**
* #var string $id
*
* #ORM\Column(name="""id""", type="string", length=32)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\SequenceGenerator(sequenceName="""DATA_WAREHOUSE"".""WindFarm_id_seq""", allocationSize=1, initialValue=1)
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="""name""", type="text", nullable=true)
*/
private $name;
/**
* #var string $alias
*
* #ORM\Column(name="""alias""", type="string", length=32, nullable=true)
*/
private $alias;
/**
* #var string $location
*
* #ORM\Column(name="""location""", type="text", nullable=true)
*/
private $location;
/**
* #var string $sncNbr
*
* #ORM\Column(name="""sncNbr""", type="string", length=8, nullable=true)
*/
private $sncNbr;
}
The DQL request in the WindFarmRepository:
public function getWindFarmsAndTurbines(){
$qb = $this->createQueryBuilder()
->select('wft')
->from('BaseCoreBundle:WindFarm', 'wft')
->leftJoin('wft.turbines', 't')
->addSelect('t')
->orderBy('t.alias');
return $qb;
}
The FormType :
<?php
namespace Base\CoreBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Base\CoreBundle\Repository\WindFarmRepository;
class TurbineStatusCodeType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('exportBegin', 'date', array('input' => 'datetime',
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',))
->add('exportEnd', 'date', array('input' => 'datetime',
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',))
->add('arrayId', 'textarea')
->add('turbines', 'entity', array('class' => 'BaseCoreBundle:WindFarm',
'property' => 'name',
'multiple' => true,
'expanded' => true,
'query_builder' => function(WindFarmRepository $repo){
return $repo->getWindFarmsAndTurbines();
}))
->add('save', 'submit');
}
/**
* #return string
*/
public function getName()
{
return 'base_corebundle_turbineStatusCodeType';
}
}
apparently, the problem is situated in the quote, I tried many solutions, but nothing work.
All of your Doctrine annotations are incorrect and have extra double-quotes.
#ORM\Column(name="""id""", type="string", length=32)
should be
#ORM\Column(name="id", type="string", length=32)
and so on
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 run into this problem with a couple of my entities now so I thought to try and get a hang of what really goes on, and I turn to my best source here (will add a bounty to this question as soon as it is eligible).
My user is part of a user group. I have a validator for the userGroup entity to make sure no two userGroups have the same name.
The problem is that when I go to editing a user, and try to select that userGroup for the user, symfony2 is behaving as if I were trying to create another userGroup with that same name, when in reality all I am doing is I am trying to select that userGroup for the user.
A user entity
<?php
// src/BizTV/UserBundle/Entity/User.php
namespace BizTV\UserBundle\Entity;
use BizTV\UserBundle\Validator\Constraints as BizTVAssert;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use BizTV\BackendBundle\Entity\company as company;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser implements AdvancedUserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//TODO: Add constraint on $name * #BizTVAssert\NameExists (and finish coding this constraint)
/**
* #var object BizTV\BackendBundle\Entity\company
*
* #ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* #ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company;
/**
* #var object BizTV\UserBundle\Entity\UserGroup
* #ORM\ManyToOne(targetEntity="BizTV\UserBundle\Entity\UserGroup")
* #ORM\JoinColumn(name="userGroup", referencedColumnName="id", nullable=true)
*/
protected $userGroup;
/**
* #ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="users")
* #ORM\JoinTable(name="access")
*/
private $access;
/**
* #var object BizTV\ContainerManagementBundle\Entity\Container
*
* This only applies to the BizTV server user accounts or "screen display accounts". Others will have null here.
*
* #ORM\ManyToOne(targetEntity="BizTV\ContainerManagementBundle\Entity\Container")
* #ORM\JoinColumn(name="screen", referencedColumnName="id", nullable=true)
*/
protected $screen;
/**
* #ORM\Column(type="boolean", nullable=true)
*/
protected $isServer;
public function __construct()
{
parent::__construct();
$this->access = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set company
*
* #param BizTV\BackendBundle\Entity\company $company
*/
public function setCompany(\BizTV\BackendBundle\Entity\company $company)
{
$this->company = $company;
}
/**
* Get company
*
* #return BizTV\BackendBundle\Entity\company
*/
public function getCompany()
{
return $this->company;
}
/**
* Add access
*
* #param BizTV\ContainerManagementBundle\Entity\Container $access
*/
public function addContainer(\BizTV\ContainerManagementBundle\Entity\Container $access)
{
$this->access[] = $access;
}
/**
* Get access
*
* #return Doctrine\Common\Collections\Collection
*/
public function getAccess()
{
return $this->access;
}
/**
* Set screen
*
* #param BizTV\ContainerManagementBundle\Entity\Container $screen
*/
public function setScreen(\BizTV\ContainerManagementBundle\Entity\Container $screen)
{
$this->screen = $screen;
}
/**
* Get screen
*
* #return BizTV\ContainerManagementBundle\Entity\Container
*/
public function getScreen()
{
return $this->screen;
}
/**
* Set isServer
*
* #param boolean $isServer
*/
public function setIsServer($isServer)
{
$this->isServer = $isServer;
}
/**
* Get isServer
*
* #return boolean
*/
public function getIsServer()
{
return $this->isServer;
}
/**
* Set userGroup
*
* #param BizTV\UserBundle\Entity\UserGroup $userGroup
*/
public function setUserGroup(\BizTV\UserBundle\Entity\UserGroup $userGroup = null)
{
$this->userGroup = $userGroup;
}
/**
* Get userGroup
*
* #return BizTV\UserBundle\Entity\UserGroup
*/
public function getUserGroup()
{
return $this->userGroup;
}
}
The UserGroup entity that the User is linked to:
<?php
namespace BizTV\UserBundle\Entity;
use BizTV\UserBundle\Validator\Constraints as BizTVAssert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* BizTV\UserBundle\Entity\UserGroup
*
* #ORM\Table()
* #ORM\Entity
*/
class UserGroup
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
* #BizTVAssert\NameExists
* #ORM\Column(name="name", type="string", length=255)
* #Assert\NotBlank(message = "Du måste ange ett gruppnamn")
*/
private $name;
/**
* #var object BizTV\BackendBundle\Entity\company
*
* #ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* #ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set company
*
* #param BizTV\BackendBundle\Entity\company $company
*/
public function setCompany(\BizTV\BackendBundle\Entity\company $company)
{
$this->company = $company;
}
/**
* Get company
*
* #return BizTV\BackendBundle\Entity\company
*/
public function getCompany()
{
return $this->company;
}
}
The NameExistsValidator
<?php
namespace BizTV\UserBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Doctrine\ORM\EntityManager as EntityManager;
class NameExistsValidator extends ConstraintValidator
{
private $container;
private $em;
public function __construct(Container $container, EntityManager $em) {
$this->container = $container;
$this->em = $em;
}
public function isValid($value, Constraint $constraint)
{
$em = $this->em;
$container = $this->container;
$company = $this->container->get('security.context')->getToken()->getUser()->getCompany();
//Fetch entities with same name
$repository = $em->getRepository('BizTVUserBundle:UserGroup');
//$repository = $this->getDoctrine()->getRepository('BizTVContainerManagementBundle:Container');
$query = $repository->createQueryBuilder('c')
->where('c.company = :company')
->setParameter('company', $company)
->orderBy('c.name', 'ASC')
->getQuery();
$groups = $query->getResult();
foreach ($groups as $g) {
if ($g->getName() == $value) {
$this->setMessage('Namnet '.$value.' är upptaget, vänligen välj ett annat', array('%string%' => $value));
return false;
}
}
return true;
}
}
User edit form
<?php
namespace BizTV\UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormValidatorInterface;
use Symfony\Component\Form\FormError;
use Doctrine\ORM\EntityRepository;
class editUserType extends AbstractType
{
function __construct($company)
{
$this->company = $company;
}
public function buildForm(FormBuilder $builder, array $options)
{
$company = $this->company;
$builder
->add('locked', 'checkbox', array('label' => 'Kontot är låst, användaren kan inte logga in '))
->add('username', 'text', array('label' => 'Användarnamn '))
;
$builder
->add('userGroup', 'entity', array(
'label' => 'Användargrupp',
'empty_value' => 'Ingen grupptillhörighet',
'property' => 'name',
'class' => 'BizTV\UserBundle\Entity\UserGroup',
'query_builder' => function(\Doctrine\ORM\EntityRepository $er) use ($company) {
$qb = $er->createQueryBuilder('a');
$qb->where('a.company = :company');
$qb->setParameters( array('company' => $company) );
$qb->orderBy('a.name', 'ASC');
return $qb;
}
));
$builder
->add('email', 'email', array('label' => 'Epost '))
->add('plainPassword', 'repeated', array('type' => 'password', 'first_name' => 'Nytt lösenord ', 'second_name' => 'Upprepa lösenord ',));
$builder
->add('roles', 'choice', array(
'label' => 'Roller',
'expanded' => true,
'multiple' => true,
'choices' => array(
'ROLE_CONTENT' => 'Innehåll (Användaren kan lägga till, redigera och ta bort innehåll där du nedan beviljar åtkomst)',
'ROLE_LAYOUT' => 'Skärmlayout (Användaren kan skapa ny skärmlayout, redigera befintlig eller ta bort gällande skärmlayout där du nedan beviljar åtkomst)',
'ROLE_VIDEO' => 'Videouppladdning (Användaren har rätt att ladda upp videofiler till företagets mediabibliotek)',
'ROLE_ADMIN' => 'Administratör (Användaren är administratör med fulla rättigheter till allt precis som det konto du nu är inloggad på, var mycket restriktiv med att tilldela denna behörighet).',
),
))
;
$builder
->add('access', 'entity', array(
'label' => 'Behörigheter',
'multiple' => true, // Multiple selection allowed
'expanded' => true, // Render as checkboxes
'property' => 'select_label',
'class' => 'BizTV\ContainerManagementBundle\Entity\Container',
'query_builder' => function(\Doctrine\ORM\EntityRepository $er) use ($company) {
$qb = $er->createQueryBuilder('a');
$qb->innerJoin('a.containerType', 'ct');
$qb->where('a.containerType IN (:containers)', 'a.company = :company');
$qb->setParameters( array('containers' => array(1,2,3,4), 'company' => $company) );
$qb->orderBy('ct.id', 'ASC');
return $qb;
}
));
$builder-> addValidator(new CallbackValidator(function(FormInterface $form){
$email = $form->get('email')->getData();
if (empty( $email )) {
$form['email']->addError(new FormError("Du måste ange en epostadress för användaren"));
}
}));
$builder-> addValidator(new CallbackValidator(function(FormInterface $form){
$username = $form->get('username')->getData();
if (strpos($username,'#') !== false) {
$form['username']->addError(new FormError("Användarnamnet får inte innehålla tecknet #"));
}
}));
$builder-> addValidator(new CallbackValidator(function(FormInterface $form){
$username = $form->get('username')->getData();
if (empty($username)) {
$form['username']->addError(new FormError("Du måste ange ett namn för användaren"));
}
}));
//TODO check if username exists
}
public function getName()
{
return 'biztv_userbundle_newusertype';
}
}
Your NameExistsValidator does this:
Fail if I find any user-group with the name I'm checking.
But I think you want it to do this:
Fail if I find another user-group with the name I'm checking.
In other words: the validator needs the complete UserGroup entity (or at least its id and name) to check for a user-group with the same name but different id.
Symfony 2 already has a UniqueEntity validator, why don't you use it?
Using annotations this would look something like this:
/**
* #ORM\Entity
* #AssertUniqueEntity(fields={"name"}, message="This name already exists")
*/
class UserGroup
{
One possible and simplest solution is to define Validation Groups. For example, when you create a group, you can use the validation group named 'create' or 'groups' and when you create a user does not specify a group. Then validator will not apply to user creation process.
Validation Groups can be assigned dynamically in the form class. An example of this you can see in the documentation.
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