I'm using Doctrine 2 in a Zend Framework application and require functionality similar to Zend_Validate_Db_RecordExists and Zend_Validate_Db_NoRecordExists.
For example, when a user enters a new item, I need to validate that a duplicate entry doesn't already exist. This is easy to accomplish with Zend_Db by adding the Db_NoRecordExists validator on my forms.
I tried implementing the custom-validator solution proposed here, but I can't figure out how they are communicating with Doctrine to retrieve entities (I suspect this approach may no longer work post-Doctrine 1.x).
The FAQ section of the Doctrine manual suggests calling contains() from the client code, but this only covers collections, and if possible I'd like to handle all of my form validation consistently from within my form models.
Can anyone suggest a way to use these Zend validators with Doctrine 2 DBAL configured as the database connection/resource?
It's quite straightforward, really.
I have a few Zend_Validate-type validators that talk to Doctrine ORM, so I have an abstract class that they descend from.
Here's the abstract class:
<?php
namespace TimDev\Validate\Doctrine;
abstract class AbstractValidator extends \Zend_Validate_Abstract{
/**
* #var Doctrine\ORM\EntityManager
*/
private $_em;
public function __construct(\Doctrine\ORM\EntityManager $em){
$this->_em = $em;
}
public function em(){
return $this->_em;
}
}
Here's my NoEntityExists validator:
<?php
namespace TimDev\Validate\Doctrine;
class NoEntityExists extends AbstractValidator{
private $_ec = null;
private $_property = null;
private $_exclude = null;
const ERROR_ENTITY_EXISTS = 1;
protected $_messageTemplates = array(
self::ERROR_ENTITY_EXISTS => 'Another record already contains %value%'
);
public function __construct($opts){
$this->_ec = $opts['class'];
$this->_property = $opts['property'];
$this->_exclude = $opts['exclude'];
parent::__construct($opts['entityManager']);
}
public function getQuery(){
$qb = $this->em()->createQueryBuilder();
$qb->select('o')
->from($this->_ec,'o')
->where('o.' . $this->_property .'=:value');
if ($this->_exclude !== null){
if (is_array($this->_exclude)){
foreach($this->_exclude as $k=>$ex){
$qb->andWhere('o.' . $ex['property'] .' != :value'.$k);
$qb->setParameter('value'.$k,$ex['value'] ? $ex['value'] : '');
}
}
}
$query = $qb->getQuery();
return $query;
}
public function isValid($value){
$valid = true;
$this->_setValue($value);
$query = $this->getQuery();
$query->setParameter("value", $value);
$result = $query->execute();
if (count($result)){
$valid = false;
$this->_error(self::ERROR_ENTITY_EXISTS);
}
return $valid;
}
}
Used in the context of a Zend_Form (which has an em() method like the abstract class above):
/**
* Overrides superclass method to add just-in-time validation for NoEntityExists-type validators that
* rely on knowing the id of the entity in question.
* #param type $data
* #return type
*/
public function isValid($data) {
$unameUnique = new NoEntityExists(
array('entityManager' => $this->em(),
'class' => 'PMS\Entity\User',
'property' => 'username',
'exclude' => array(
array('property' => 'id', 'value' => $this->getValue('id'))
)
)
);
$unameUnique->setMessage('Another user already has username "%value%"', NoEntityExists::ERROR_ENTITY_EXISTS);
$this->getElement('username')->addValidator($unameUnique);
return parent::isValid($data);
}
Check out the RecordExists.php and NoRecordExists.php classes in my project:-
https://github.com/andyfenna/AJF-IT/tree/master/library/AJFIT/Validate
I hope these are some use to you.
Thanks
Andrew
Related
I have implemented an EventListener class and declare it in services.yaml
I'd like to return to my Controller a variable when entity is persited and send this variable to twig template. I want to show a step form in my view showing Entity name in green for example when data has been persisted in database. If it works I will use the same process in another controller where I persist multiple entities. To sum up: How to notify a controller that a specific entity has been persisted by passing a variable?
The eventlistener
<?php
namespace App\EventListener;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use App\Entity\Article;
class TodoListener {
public function postPersist(LifecycleEventArgs $args) {
$entity = $args->getObject();
if(!$entity instanceof Article)
return;
$var = 'foo';
return $var;
}
}
services.yaml
App\EventListener\TodoListener:
tags:
- { name: doctrine.event_listener, event: postPersist }
Controller
/**
* #Route("/blog/new", name="blog_create")
* #Route("/blog/{id}/edit", name="blog_edit")
*/
public function form(Article $article = null, Request $request, ObjectManager $manager)
{
if (!$article) {
$article = new Article();
}
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if (!$article->getId()) {
$article->setCreatedAt(new \dateTime());
}
$manager->persist($article);
$manager->flush();
/**
* Get back variable when entity is persisted ???
*/
return $this->redirectToRoute('blog_show', ['id' => $article->getId()]);
}
return $this->render('blog/create.html.twig', [
'formArticle' => $form->createView(),
'editMode' => $article->getId() !== null
]);
}
In short: you can’t.
You can try to work around it with a custom symfony event, but is very bad.
If you want to know if an entity is new or already persisted you should call getEntityState on entity manager’s UnitOfWork or split the flows between actions (write two distinct actions for new and edit).
Anyway, just a suggestion: set the createdAt field into the entity constructor ;)
I am trying to write a unit test for FormErrorSerializer that converts Symfony $form->getErrors() to a readable array.
My current approach is to create the form, give it data, and look for validation errors, but form is always valid. I don't get any errors no matter what data I provide to form.
In normal REST request/response it is working well and I am getting appropriate error message. I need help with getting the error messages in unit test.
namespace App\Tests\Unit;
use App\Form\UserType;
use App\Serializer\FormErrorSerializer;
use Symfony\Component\Form\Test\Traits\ValidatorExtensionTrait;
use Symfony\Component\Form\Test\TypeTestCase;
use Symfony\Component\Translation\Translator;
class FormErrorSerializerTest extends TypeTestCase
{
/**
* ValidatorExtensionTrait needed for invalid_options
* https://github.com/symfony/symfony/issues/22593
*/
use ValidatorExtensionTrait;
public function testConvertFormToArray(){
$form_data = [
'email' => 'test',
'plainPassword' => [
'pass' => '1',
'pass2' => '2'
]
];
$translator = new Translator('de');
$form = $this->factory->create(UserType::class);
$form->submit($form_data);
if( $form->isValid() ) {
echo "Form is valid"; exit;
}
$formErrorSerializer = new FormErrorSerializer($translator);
$errors = $formErrorSerializer->convertFormToArray($form);
print_r($errors); exit;
}
}
Find below the Serializer:
namespace App\Serializer;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Translation\TranslatorInterface;
/**
* Serializes invalid Form instances.
*/
class FormErrorSerializer
{
private $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
public function convertFormToArray(FormInterface $data)
{
$form = $errors = [];
foreach ($data->getErrors() as $error) {
$errors[] = $this->getErrorMessage($error);
}
if ($errors) {
$form['errors'] = $errors;
}
$children = [];
foreach ($data->all() as $child) {
if ($child instanceof FormInterface) {
$children[$child->getName()] = $this->convertFormToArray($child);
}
}
if ($children) {
$form['children'] = $children;
}
return $form;
}
private function getErrorMessage(FormError $error)
{
if (null !== $error->getMessagePluralization()) {
return $this->translator->transChoice(
$error->getMessageTemplate(),
$error->getMessagePluralization(),
$error->getMessageParameters(),
'validators'
);
}
return $this->translator->trans($error->getMessageTemplate(), $error->getMessageParameters(), 'validators');
}
}
Ok, I was able to do this in 2 different ways.
First solution was to load the validator in getExtensions method. The factory in TypeTestCase doesn't bring the validator with it. So, not only you have to load the validator but you also have to explicitly specify the validations. You can specify validation using methods provided by symfony or you can directly point validator to the YAML or xml file if you are using one.
public function getExtensions()
{
$validator = (new ValidatorBuilder())
->addYamlMapping("path_to_validations.yaml")
->setConstraintValidatorFactory(new ConstraintValidatorFactory())
->getValidator();
$extensions[] = new CoreExtension();
$extensions[] = new ValidatorExtension($validator);
return $extensions;
}
However, I didn't use the above approach. I went with even better solution. Due to high complexity of my test case (as it needed multiple services), I went with a special container provided by Symfony's KernelTestCase. It provides private services in tests, and the factory it provides comes with validator and validations, just like you code in controller. You do not need to load validator explicitly. Find below my final test that extends KernelTestCase.
namespace App\Tests\Unit\Serializer;
use App\Entity\User;
use App\Form\UserType;
use App\Serializer\FormErrorSerializer;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Translation\TranslatorInterface;
class FormErrorSerializerTest extends KernelTestCase
{
/**
* {#inheritDoc}
*/
protected function setUp()
{
$kernel = self::bootKernel();
}
public function testConvertFormToArray_invalidData(){
$form_data = [
'email' => 'test',
'plainPassword' => [
'pass' => '1111',
'pass2' => ''
]
];
$user = new User();
$user->setEmail($form_data['email']);
$user->setPlainPassword($form_data['plainPassword']['pass']);
$factory = self::$container->get(FormFactoryInterface::class);
/**
* #var FormInterface $form
*/
$form = $factory->create(UserType::class, $user);
$form->submit($form_data);
$this->assertTrue($form->isSubmitted());
$this->assertFalse($form->isValid());
$translator = self::$container->get(TranslatorInterface::class);
$formErrorSerializer = new FormErrorSerializer($translator);
$errors = $formErrorSerializer->convertFormToArray($form);
$this->assertArrayHasKey('errors', $errors['children']['email']);
$this->assertArrayHasKey('errors', $errors['children']['plainPassword']['children']['pass']);
}
public function testConvertFormToArray_validData(){
$form_data = [
'email' => 'test#example.com',
'plainPassword' => [
'pass' => 'somepassword#slkd12',
'pass2' => 'somepassword#slkd12'
]
];
$user = new User();
$user->setEmail($form_data['email']);
$user->setPlainPassword($form_data['plainPassword']['pass']);
$factory = self::$container->get(FormFactoryInterface::class);
/**
* #var FormInterface $form
*/
$form = $factory->create(UserType::class, $user);
$form->submit($form_data);
$this->assertTrue($form->isSubmitted());
$this->assertTrue($form->isValid());
$translator = self::$container->get(TranslatorInterface::class);
$formErrorSerializer = new FormErrorSerializer($translator);
$errors = $formErrorSerializer->convertFormToArray($form);
$this->assertArrayNotHasKey('errors', $errors['children']['email']);
$this->assertArrayNotHasKey('errors', $errors['children']['plainPassword']['children']['pass']);
}
}
Please note that Symfony 4.1 has a special container that allows fetching private services.
self::$kernel->getContainer(); is not special container. It will not fetch private services.
However, self::$container; is special container that provides private services in testing.
More about this here.
This is the common porblem.
There is the form with many checkbocks. Making the checkbocks are aviable and click save, fields corresponding checkbock-labels don't save.
PersonAdmin class contains
...
->add('books', 'sonata_type_model',
array('by_reference' => false, 'expanded' => true, 'multiple' => true, 'label' => 'Books'))
...
Entity class contains
/**
* #ORM\ManyToMany(targetEntity="Book", mappedBy="persons", cascade={"persist"})
* #ORM\JoinTable(name="person_book")
*/
protected $books;
....
public function __construct()
{
$this->books = new ArrayCollection();
}
public function addBook(Book $book)
{
$this->books[] = $book;
return $this;
}
and geters, seters...
I unsuccessfully searched for a solution. I have found that it is necessary to add
'by_reference' => false,
or
cascade={"persist"}
but I have all of this in my code.
As mentioned before you need to save relation in both sides. But I would prefer another way: to save relation in the add actions of your entities:
//In the Person entity:
public function addBook(Book $book)
{
$book->addPerson($this);
$this->books[] = $book;
return $this;
}
//In the Book entity (if you have the same problem for another side):
public function addPerson(Person $person)
{
$person->addBook($this);
$this->persons[] = $person;
return $this;
}
You have to save at both sides.
Override the default editAction and createAction in a custom crud controller.
e.g.:
It's an example of a many to many relationship between artists and events.
($object is the current object you are editing/creating in the action)
foreach ($form['selectArtists']->getData() as $key => $value) {
$artist = $em->getRepository('MyCompanyProjectBundle:Artist')->findOneById($value);
$object->addArtist($artist);
$artist->addEvent($object);
$em->persist($artist);
}
Use edit=>inline .
->add('books', 'sonata_type_collection',
array('by_reference' => false, 'label' => 'Books'),
array('edit'=>'inline','inline'=>'table'))
May be help you.
i am a little baffled by this;
my post forms is not populating the values received from the returned post values; i suspect the problem is arising from my getJobId() in my jobsort class values;
below is my form:
public function jobSortAction()
{
$form = new CreateJobSortForm($this->getEntityManager());
$jobSort = new JobSort();
$form->setInputFilter($jobSort->getInputFilter());
$id= 11;
$jobSort->setId($id);
$form->bind($jobSort);
if ($this->request->isPost()) {
//$post = $this->request->getPost();
$form->setData($this->request->getPost());
//var_dump($post);
//var_dump($jobSort);
if ($form->isValid()) {
$this->getEntityManager()->persist($jobSort);
$this->getEntityManager()->flush();
}
}
return array('form' => $form);
}
below is the var_dumped values of the 'return post values' and the Jobsort() object. You will note that the returned post values has values for both the Id and the JobId
object(Zend\Stdlib\Parameters)[168]
public 'JobSort' =>
array (size=2)
'jobId' => string '5' (length=1)
'id' => string '11' (length=2)
public 'submit' => string 'Submit' (length=6)
object(Workers\Entity\JobSort)[394]
protected 'inputFilter' => null
protected 'id' => int 11
protected 'jobId' => null
protected 'workerservicelist' => null
yet, when i populate the values, it does not seem to record the values for the jobId
below is my jobsort entity class:
class JobSort
{
protected $inputFilter;
/**
* #ORM\Id
*
* #ORM\Column(name="user_id", type="integer")
*/
protected $id;
/**
* #ORM\Column(name="jobId", type="integer")
*/
protected $jobId;
public function setId($id)
{
return $this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setJobId($jobId)
{
return $this->jobId = $jobId;
}
public function getJobId( )
{
return $this->jobId;
}
is there any advice or suggestions on what i need to do to find out why the values are not been populated
warm regards
Andreea
by the way; the form actually works when i had the Id of CLASS jobsort set to
#ORM\GeneratedValue(strategy="AUTO")
the problem started when i took it out and set it to manual
Hello again
here is my form:
this is the error message i received;
An exception occurred while executing 'INSERT INTO worker_main_jobsort (user_id, jobId) VALUES (?, ?)' with params [11, null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'jobId' cannot be null
here is my form:
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Form;
use Workers\Form\Fieldset\JobSortFieldset;
class CreateJobSortForm extends Form
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('create-Job-post-form');
// The form will hydrate an object of type "BlogPost"
$this->setHydrator(new DoctrineHydrator($objectManager, 'Workers\Entity\JobSort'));
// Add the user fieldset, and set it as the base fieldset
$JobSortFieldset = new JobSortFieldset($objectManager);
$JobSortFieldset->setUseAsBaseFieldset(true);
$this->add($JobSortFieldset);
// Optionally set your validation group here
// … add CSRF and submit elements …
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Submit',
'id' => 'submitbutton',
),
));
// Optionally set your validation group here
}
}
and here is the fieldset class:
class JobSortFieldset extends Fieldset
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('JobSort');
$id= 10;
$this->setHydrator(new DoctrineHydrator($objectManager, 'Workers\Entity\JobSort'))
->setObject(new JobSort());
}
}
this addition is in response to rafaame solution;
i amended my form as recommended; however it still not working. i think the issue now is that Rafaame solution is in regarding to zendDB save method, but i am using doctrine persis**t and **flush method . i accordingly get the following error message;
Call to undefined method Workers\Entity\JobSort::save()
below is my amended form:
public function jobSortAction()
{
$form = new CreateJobSortForm($this->getEntityManager() );
$jobSort = new JobSort();
if($this->request->isPost())
{
$form->setData($this->request->getPost());
if ($form->isValid())
{
$entity = $form->getData();
$model = new JobSort();
$model->save($entity);
// $this->getEntityManager()->persist( $model);
// $this->getEntityManager()->flush();
}
}
return array('form' => $form);
}
in response to Rafaame question about what problems i had,the message that i am now receiving is this:
**
EntityManager#persist() expects parameter 1 to be an entity object,
array given.
**
below is my function:
public function jobSortAction()
{
$serviceLocator = $this->getServiceLocator();
$objectManager = $this->getEntityManager();
$form = new CreateJobSortForm($this->getEntityManager());
if ($this->request->isPost())
{
$form->setData($this->request->getPost());
if ($form->isValid()) {
$entity = $form->getData();
$model = new JobSort($objectManager, $serviceLocator);
$model->getEntityManager()->persist($entity);
$model->getEntityManager()->flush();
}
}
return array('form' => $form);
}
my form; i.e where the hydrator should be set
namespace Workers\Form;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Form;
use Workers\Form\Fieldset\JobSortFieldset;
class CreateJobSortForm extends Form
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('JobSort');
// The form will hydrate an object of type "BlogPost"
$this->setHydrator(new DoctrineHydrator($objectManager, 'Workers\Entity\JobSort'));
// Add the user fieldset, and set it as the base fieldset
$JobSortFieldset = new JobSortFieldset($objectManager);
$JobSortFieldset->setUseAsBaseFieldset(true);
$this->add($JobSortFieldset);
If you check your code, you are creating a JobSort entity, setting only its id and binding it to the form:
$jobSort = new JobSort();
$jobSort->setId($id);
$form->bind($jobSort);
After that, you are dumping $jobSort and $this->request->getPost(). So, obviously, you are getting jobId in the POST data but not in the entity (you didn't set the entity's jobId before binding it to the form). There's nothing wrong with your entity's code.
The solution for this: don't bind anything to the form. You should only bind an entity to the form in the case of an edit action, that you fetch the entity from the database and want to populate the form with its values.
Example of add action:
public function addAction()
{
$serviceLocator = $this->getServiceLocator();
$objectManager = $this->getObjectManager();
$form = new Form\EmailCampaign\Add($serviceLocator, $objectManager);
if($this->request instanceof HttpRequest && $this->request->isPost())
{
$form->setData($this->request->getPost());
if($form->isValid())
{
$entity = $form->getData();
//If you want to modify a property of the entity (but remember that it's not recommended to do it here, do it in the model instead).
//$entity->setJobId(11);
$model = new Model\EmailCampaign($serviceLocator, $objectManager);
$model->save($entity);
if($entity->getId())
{
$this->flashMessenger()->addSuccessMessage('Email campaign successfully added to the database.');
return $this->redirect()->toRoute('admin/wildcard', ['controller' => 'email-campaign', 'action' => 'edit', 'id' => $entity->getId()]);
}
else
{
$this->flashMessenger()->addErrorMessage('There was an error adding the email campaign to the database. Contact the administrator.');
}
}
}
return new ViewModel
([
'form' => $form,
]);
}
Example of edit action:
public function editAction()
{
$serviceLocator = $this->getServiceLocator();
$objectManager = $this->getObjectManager();
$form = new Form\EmailCampaign\Edit($serviceLocator, $objectManager);
$id = $this->getEvent()->getRouteMatch()->getParam('id');
$entity = $objectManager
->getRepository('Application\Entity\EmailCampaign')
->findOneBy(['id' => $id]);
if($entity)
{
$form->bind($entity);
if($this->request instanceof HttpRequest && $this->request->isPost())
{
$form->setData($this->request->getPost());
if($form->isValid())
{
//If you want to modify a property of the entity (but remember that it's not recommended to do it here, do it in the model instead).
//$entity->setJobId(11);
$model = new Model\EmailCampaign($serviceLocator, $objectManager);
$model->save($entity);
$this->flashMessenger()->addSuccessMessage('Email campaign successfully saved to the database.');
}
}
}
else
{
$this->flashMessenger()->addErrorMessage('A email campaign with this ID was not found in the database.');
return $this->redirect()->toRoute('admin', ['controller' => 'email-campaign']);
}
return new ViewModel
([
'form' => $form,
'entity' => $entity,
]);
}
Hope this helps.
EDIT:
What I provided was an example of how to handle the form and the entities with Doctrine 2 + ZF2.
What you have to keep in mind is that Doctrine doesn't work with the concept of models, it just understands entities. The model I'm using in my application is a concept of the MVC (Model-View-Controller) design pattern (that ZF2 uses) and I have decided to wrap the entity manager calls (persist and flush) inside my model's method, that I named save() (in the case the entity needs some special treatment before being save to the database and also because it is not a good practice to use the entity manager directly in the controller - see this slide of Marcos Pivetta presentation http://ocramius.github.io/presentations/doctrine2-zf2-introduction/#/66).
Another thing that you may be misunderstanding is that when you do $form->getData() to a form that has the DoctrineObject hydrator, it will return you the entity object, and not an array with the data (this last happens if it has no hydrator). So you don't need to create the entity after doing $form->getData(), and if you do so, this created entity won't have any information provided by the form.
Your code should work now:
public function jobSortAction()
{
$serviceLocator = $this->getServiceLocator();
$entityManager = $this->getEntityManager();
$form = new CreateJobSortForm($entityManager);
if ($this->request->isPost())
{
$form->setData($this->request->getPost());
if ($form->isValid()) {
//I'm considering you are setting the DoctrineObject hydrator to your form,
//so here we will get the entity object already filled with the form data that came through POST.
$entity = $form->getData();
//Again, if you need special treatment to any data of your entity,
//you should do it here (well, I do it inside my model's save() method).
//$entity->setJobId(11);
$entityManager->persist($entity);
$entityManager->flush();
}
}
return array('form' => $form);
}
Good morning everyone! Is a form of.
Class ReleasesType:
$builder
->add('doid', 'text')
->add('dourl', 'text')
->add('artists', 'entity', array(
'class' => 'MReleaseCoreBundle:Artists',
'property' => 'name',
'expanded' => true ,
'multiple' => true
));
Сonnection with them one-to-many:
Class 'Artists':
/**
* #ORM\OneToMany(targetEntity="ReleasesArtists" , mappedBy="artists" , cascade={"all"})
* */
private $da;
public function __construct() {
$this->da = new \Doctrine\Common\Collections\ArrayCollection();
}
Class 'ReleasesArtists':
/**
* #ORM\ManyToOne(targetEntity="Releases", inversedBy="da")
* #ORM\JoinColumn(name="releases_id", referencedColumnName="id")
* */
private $releases;
/**
* #ORM\ManyToOne(targetEntity="Artists", inversedBy="da")
* #ORM\JoinColumn(name="artists_id", referencedColumnName="id")
* */
private $artists;
And of course the entity 'Releases':
/**
* #ORM\OneToMany(targetEntity="ReleasesArtists" , mappedBy="releases", cascade={"all"} , orphanRemoval=true)
*/
private $da;
public function getArtists() {
$artists = new ArrayCollection();
foreach($this->da as $p) {
$artists[] = $p->getArtists()->getName();
}
return $artists;
}
public function addDa($da) {
$this->da[] = $da;
}
public function setArtists($artists) {
foreach($artists as $p) {
$po = new \MRelease\CoreBundle\Entity\ReleasesArtists();
$po->setReleases($this);
$po->setArtists($p);
$this->addDa($po);
}
}
Connection is working correctly, all outputs. But does not "checked". In what may be the problem?
Thanks!
Into your controller, where you build and output your form, you have to do something like this
public function myFooAction(Request $request, $releasesId)
{
$repo = $this->getDoctrine()->getManager()->getRepository('YourBundleName:Releases');
$releasesObject = $repo->findOneById($releasesId);
$form = $this->createForm(new ReleasesType(), $releasesObject);
return $this->render('YourBundle::TemplateToRender, array('form'=>$form);
}
What happen here, and why is working?
I've made some assumptions as you don't provide any controller code. First of all, I assume that you have an action like myFooAction() where you do form operation and I suppose, also, that you pass to this action an id for load object from DB and tie it to your form - if I understood correctly your question.
So, first line of action is for retrieve repository for this object. Once you've got repo, you can fetch your object (second line). On third line I use Symfony2 form's facility and "connect" object to his form type: with this, all values contained into this object will be reported into your form (so checkboxes will have correct value). Last line is for render form.
Obviously, your action logic could be different but concept expressed here could be replicated with "different" implementation everywhere.