Long story short.
I use Doctrine's Single Table Inheritance mapping to map three different contexts (classes) of the one common entity: NotActivatedCustomer, DeletedCustomer, and Customer. Also, there is an AbstractCustomer which contains the next:
App\Identity\Domain\Customer\AbstractCustomer:
type: entity
inheritanceType: SINGLE_TABLE
discriminatorColumn:
name: discr
type: string
discriminatorMap:
Customer: App\Identity\Domain\Customer\Customer
NotActivatedCustomer: App\Identity\Domain\Customer\NotActivatedCustomer
DeletedCustomer: App\Identity\Domain\Customer\DeletedCustomer
table: customer
id:
id:
type: customer_id
unique: true
generator:
strategy: CUSTOM
customIdGenerator:
class: Symfony\Bridge\Doctrine\IdGenerator\UuidV4Generator
fields:
email:
type: email
length: 180
unique: true
A Subtype definition example:
<?php
declare(strict_types=1);
namespace App\Identity\Domain\Customer;
use App\Identity\Domain\User\Email;
class DeletedCustomer extends AbstractCustomer
{
public const TYPE = 'DeletedCustomer';
public function __construct(CustomerId $id)
{
$this->_setId($id);
$this->_setEmail(new Email(sprintf('%s#mail.local', $id->value())));
}
}
The Use Case:
<?php
declare(strict_types=1);
namespace App\Identity\Application\Customer\UseCase\DeleteCustomer;
use App\Identity\Application\Customer\CustomerEntityManager;
use App\Identity\Application\User\AuthenticatedCustomer;
use App\Identity\Domain\Customer\DeletedCustomer;
use App\Shared\Application\ImageManager;
final class DeleteCustomerHandler
{
private CustomerEntityManager $customerEntityManager;
private AuthenticatedCustomer $authenticatedCustomer;
private ImageManager $imageManager;
public function __construct(AuthenticatedCustomer $authenticatedCustomer,
CustomerEntityManager $customerEntityManagerByActiveTenant,
ImageManager $customerPhotoManager)
{
$this->customerEntityManager = $customerEntityManagerByActiveTenant;
$this->authenticatedCustomer = $authenticatedCustomer;
$this->imageManager = $customerPhotoManager;
}
public function handle(): void
{
$customer = $this->authenticatedCustomer->customer();
$photo = (string) $customer->photo();
$deletedCustomer = new DeletedCustomer($customer->id());
// TODO OR return DeletedCustomer that way
// $deletedCustomer = $customer->deactive();
// entityManager->merge() called here
$this->customerEntityManager->sync($deletedCustomer);
// simple entityManager->flush() under the hood
$this->customerEntityManager->update();
// that's a raw query to update discriminator field, hackish way I'm using
// UPDATE customer SET discr = ? WHERE id = ?
$this->customerEntityManager->updateInheritanceType($customer, DeletedCustomer::TYPE);
if ($photo) {
$this->imageManager->remove($photo);
}
}
}
So if you have already an existing Customer persisted and run DeleteCustomerHandler, the Customer will be updated, but its discriminator field won't!
Googling that, there is no way to update the discriminator field not going some hackish way like I do (running raw query manually to update the field).
Also, I need to use the EntityManager->merge() method to add manually initialized DeletedCustomer to internal UnitOfWork. Looks a little bit dirty too, and it's a deprecated method for Doctrine 3, so the question also is there a better way to handle my case?
So, to conclude all the questions:
Am I doing Customer's status change to DeletedCustomer completely wrong? I'm just trying to avoid Customer God Object, distinguish this Entity's bounded contexts, kinda that.
How to avoid EntityManager->merge() there? AuthenticatedCustomer comes from session (JWT).
I think you're absolutely right to want to avoid Customer turning into a god object. Inheritance is one way to do it, but using it for customers in different statuses can lead to problems.
The two key problems in my experience:
As new statuses emerge, will you keep adding different inherited entities?
What happens when you have a customer move through two different statuses, such as a customer that was a NotActivatedCustomer but is now a DeletedCustomer?
So I keep inheritance only when the inherited type is genuinely more specific type, where a given entity will only ever be one of those types for its entire lifecycle. Cars don't become motorbikes, for example.
I have two patterns for solving the problem differently to you. I tend to start with the first and move to the second.
interface DeletedCustomer
{
public function getDeletedAt(): DateTime;
}
interface NotActivatedCustomer
{
public function getCreatedAt(): DateTime;
}
class Customer implements DeletedCustomer, NotActivatedCustomer
{
private $id;
private $name;
private DateTime $deletedAt;
private bool $isActivated = false;
public function getDeletedAt(): DateTime {...}
public function getCreatedAt(): DateTime {...}
}
class DeletedCustomerRepository
{
public function findAll(): array
{
return $this->createQuery(<<<DQL
SELECT customer
FROM Customer
WHERE customer.deletedAt IS NOT NULL
>>>)->getQuery()->getResults();
}
}
class NotActivatedCustomerRepository
{
public function findAll(): array
{
return $this->createQuery(<<<DQL
SELECT customer
FROM Customer
WHERE customer.isActivated = false
>>>)->getQuery()->getResults();
}
}
class DeletedCustomerService
{
public function doTheThing(DeletedCustomer $customer) {}
}
This reduces coupling, which is one of the main problems with god objects. So when the columns start to proliferate, I can move them off to real entities that join to the Customer. Components that refer to DeletedCustomer will still receive one.
The second pattern is event-sourcing-lite - have a many-to-one relationship with a "CustomerLifecycleEvent" entity. Query based on whether the customer has a "deleted" event. This second approach is much more complex, both to update and query. You can still have dedicated repositories that return entities like DeletedCustomer, but you'll need to do a bit more boilerplate.
Im learning symfony 3 & doctrine and i created a form with entity collection. Entities are Post and Tags with manyTomany relation. Main form is Post with collection of tags.
I want to pass only IDs (primary key) of tags in my collection. In result i have only one field in tag form:
$builder->add('tagId');
I created autocomplete for it, thats why i need only primary key.
After saving my form, doctrine create new tag entities with passed ids but i want to find those entities instead of creating new. Have no clue...
I was trying to make it work inside my controller:
$formTags = $form->get('tag');
foreach ($formTags->getData() as $key => $formTag)
{
// here i have new entities with id ;/
if($formTag->getTagId())
{
// so i tryied to find them, and replace it
$formTags->offsetSet($key,
array($this->getDoctrine()->getRepository('BlogBundle:Tag')
->find($formTag->getTagId())));
}
}
But symfony throw me exceptions, also with setData method. Cant change it after form is submitted. I hope you guys can help me!
i was trying to make data transformer. Forget to mention :) Problem Was that my transformer change tagId field to tag object. In result i had tag object with new entity, and instead tagId value - there was another object inside, transformed. So dont work like expected for me. I think i should make transformer for collection field instead of tag id, but have no idea how make it work. I tryied to make "tag" field inside collection and transform it, but doctrine try always to get value from entity based on fields so no getTag() method found :)
You can use Symfony DataTransfomer in your TagType to transform the tagId to a Tag Entity .
From Symfony DataTransformer docs :
Data transformers are used to translate the data for a field into a format that can be displayed in a form (and back on submit).
...
Say you have a many-to-one relation from the Task entity to an Issue entity (i.e. each Task has an optional foreign key to its related Issue). Adding a listbox with all possible issues could eventually get really long and take a long time to load. Instead, you decide you want to add a textbox, where the user can simply enter the issue number.
I made it. With data transformers, but we need to make transformer for collection, not for field inside collection.
So its look like that (works!).
My PostType.php form need to have entity manager (like inside documentation, about data transformers), and data transformer for collection, so i added:
# PostType.php form
namespace BlogBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use BlogBundle\Form\DataTransformer\TagToIdTransformer;
use Doctrine\Common\Persistence\ObjectManager;
class PostType extends AbstractType
{
private $manager;
public function __construct(ObjectManager $manager)
{
// needed for transformer :(
// and we need to register service inside app config for this. Details below
$this->manager = $manager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tag', CollectionType::class, array(
'entry_type' => TagType::class,
'by_reference' => false,
'allow_add' => true,
))
->add('save', SubmitType::class, array('label' => 'Save'));
$builder->get('tag')
->addModelTransformer(new TagToIdTransformer($this->manager));
}
}
Constructor will trow exception, we need to pass ObjectManager to it. To make it, modify config file inside your bundle:
# src/BlogBundle/Resources/config/services.yml
services:
blog.form.type.tag:
class: BlogBundle\Form\PostType
arguments: ["#doctrine.orm.entity_manager"]
tags:
- { name: form.type }
Now lets make transformer for a collection! I made it wrong before, because i was trying to make like inside documentation, for one field. For collection we need to transform whole array of tags (its manyToMany collection):
<?php
namespace BlogBundle\Form\DataTransformer;
use BlogBundle\Entity\Tag;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class TagToIdTransformer implements DataTransformerInterface
{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
/**
* Transforms array of objects (Tag) to an array of string (number).
*
* #param array|null $tags
* #return string
*/
public function transform($tags)
{
$result = array();
if (null === $tags) {
return null;
}
foreach ($tags as $tag)
{
$result[] = $tag->getTagId();
}
return $result;
}
/**
* Transforms an array of strings (numbers) to an array of objects (Tag).
*
* #param string $tagsId
* #return Tag|null
* #throws TransformationFailedException if object (Tag) is not found.
*/
public function reverseTransform($tagsId)
{
// no issue number? It's optional, so that's ok
if (!$tagsId) {
return;
}
$result = array();
$repository = $this->manager
->getRepository('BlogBundle:Tag');
foreach ($tagsId as $tagId) {
$tag = $repository->find($tagId);
if (null === $tag) {
// causes a validation error
// this message is not shown to the user
// see the invalid_message option
throw new TransformationFailedException(sprintf(
'An tag with id "%s" does not exist!',
$tagId
));
}
$result[] = $tag;
}
return $result;
}
}
Everything works fine now. I can easy save my entities with autocomplete that populate IDs of tags only
I am currently on a project where i have a lot of entities with a lot of fields (clients with addresses, phones, age, firm number...), and i am doing it for a French client. So i code in English:
class Client
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $firstName;
}
And i have a config like this:
AppBundle\Entity\Client:
type: entity
table: null
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
firstName:
type: string
length: 255
options:
label: Prénom
So the options.label doesn't seem to work, i'm wondering where i could do these translations as it will concern a lot of fields, and as I am using Sonata admin i don't want to be obliged to put them in the ClientAdmin class:
/**
* #param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('firstName')
->add('lastName')
->add('birthDate', 'birthday')
;
}
/**
* #param ShowMapper $showMapper
*/
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('id')
->add('firstName')
->add('lastName')
->add('birthDate')
;
}
because i would have to translate at least twice (form, display...) so I would love it to handle one translation in all the app.
Any idea ? I looked into the Gedmo translatable extension, but it doesn't correspond to what I am looking for: i simply want to translate the labels of the form, the whole application will be in a unique language: french.
Symfony 2.6
Doctrine 2.2 to 2.5
For those who don't know it, turned out that the automatic labels are already translation keys, you simply need to specify the translation_domain in your form, so i have now a messages.fr.yml:
First Name: Prénom
And it's enough! No need to generate / specify a translation label. Plus it is reusable in between forms with similar fields ! This works within our out of sonata admin's focus.
You should take a look at this. It will help you automate the translation process. http://jmsyst.com/bundles/JMSTranslationBundle
You'll just have to use keys instead of real labels(although it's optional in your case), like this:
$formMapper
->add('firstName',null, array('label'=>'sonata.user.firstName')
Then you just run a command and it will extract all the keys in a nice web GUI, and you can translate them from there in whatever language you want.
try this:
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Client',
'label' => 'Prénom'
));
}
Im new to PHP so apologies if this is a simple question. Please could you tell me how to auto select a date drop down in PHP (uses 3 drop downs - day/month/year). This is what my PHP code looks like:
$s = '01/08/2014 11:00:02';
$date = strtotime($s);
$objectToParse->setDateReceived(date('d/M/Y H:i:s', $date));
$form = $this->createForm(new Type(), $objectToParse);
And then the form looks like:
class Type extends AbstractType {
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('dateReceived', 'date', array(
'required' => false
))
}
}
I expected a \DateTime. But at the moment I just receive a
500 Internal Server Error - TransformationFailedException error
On your class Type, add something like :
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\AcmeBundle\Entity\MyObject',
));
}
It makes the binding between the given entity (MyObject) and the form.
From Forms (The Symfony Book) : :
Every form needs to know the name of the class that holds the
underlying data (e.g. Acme\TaskBundle\Entity\Task). Usually, this is
just guessed based off of the object passed to the second argument to
createForm (i.e. $task). Later, when you begin embedding forms, this
will no longer be sufficient. So, while not always necessary, it's
generally a good idea to explicitly specify the data_class option
Also, you need to give a DateTime to the setter setDateReceived. What you gives with the datefunction is a string.
What you need to do is :
$s = '01/08/2014 11:00:02';
$date = \DateTime::createFromFormat('d/M/Y H:i:s', $s);
$objectToParse->setDateReceived($date);
Is there an easy way to set a default value for text form field?
you can set the default value with empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
Can be use during the creation easily with :
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
I've contemplated this a few times in the past so thought I'd jot down the different ideas I've had / used. Something might be of use, but none are "perfect" Symfony2 solutions.
Constructor
In the Entity you can do $this->setBar('default value'); but this is called every time you load the entity (db or not) and is a bit messy. It does however work for every field type as you can create dates or whatever else you need.
If statements within get's
I wouldn't, but you could.
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
Factory / instance.
Call a static function / secondary class which provides you a default Entity pre-populated with data. E.g.
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
Not really ideal given you'll have to maintain this function if you add extra fields, but it does mean you're separating the data setters / default and that which is generated from the db. Similarly you can have multiple getFactories should you want different defaulted data.
Extended / Reflection entities
Create a extending Entity (e.g. FooCreate extends Foo) which gives you the defaulted data at create time (through the constructor). Similar to the Factory / instance idea just a different approach - I prefer static methods personally.
Set Data before build form
In the constructors / service, you know if you have a new entity or if it was populated from the db. It's plausible therefore to call set data on the different fields when you grab a new entity. E.g.
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
Form Events
When you create the form you set default data when creating the fields. You override this use PreSetData event listener. The problem with this is that you're duplicating the form workload / duplicating code and making it harder to maintain / understand.
Extended forms
Similar to Form events, but you call the different type depending on if it's a db / new entity. By this I mean you have FooType which defines your edit form, BarType extends FooType this and sets all the data to the fields. In your controller you then simply choose which form type to instigate. This sucks if you have a custom theme though and like events, creates too much maintenance for my liking.
Twig
You can create your own theme and default the data using the value option too when you do it on a per-field basis. There is nothing stopping you wrapping this into a form theme either should you wish to keep your templates clean and the form reusable. e.g.
form_widget(form.foo, {attr: { value : default } });
JS
It'd be trivial to populate the form with a JS function if the fields are empty. You could do something with placeholders for example. This is a bad, bad idea though.
Forms as a service
For one of the big form based projects I did, I created a service which generated all the forms, did all the processing etc. This was because the forms were to be used across multiple controllers in multiple environments and whilst the forms were generated / handled in the same way, they were displayed / interacted with differently (e.g. error handling, redirections etc). The beauty of this approach was that you can default data, do everything you need, handle errors generically etc and it's all encapsulated in one place.
Conclusion
As I see it, you'll run into the same issue time and time again - where is the defaulted data to live?
If you store it at db/doctrine level what happens if you don't want to store the default every time?
If you store it at Entity level what happens if you want to re-use that entity elsewhere without any data in it?
If you store it at Entity Level and add a new field, do you want the previous versions to have that default value upon editing? Same goes for the default in the DB...
If you store it at the form level, is that obvious when you come to maintain the code later?
If it's in the constructor what happens if you use the form in multiple places?
If you push it to JS level then you've gone too far - the data shouldn't be in the view never mind JS (and we're ignoring compatibility, rendering errors etc)
The service is great if like me you're using it in multiple places, but it's overkill for a simple add / edit form on one site...
To that end, I've approached the problem differently each time. For example, a signup form "newsletter" option is easily (and logically) set in the constructor just before creating the form. When I was building forms collections which were linked together (e.g. which radio buttons in different form types linked together) then I've used Event Listeners. When I've built a more complicated entity (e.g. one which required children or lots of defaulted data) I've used a function (e.g. 'getFactory') to create it element as I need it.
I don't think there is one "right" approach as every time I've had this requirement it's been slightly different.
Good luck! I hope I've given you some food for thought at any rate and didn't ramble too much ;)
If you need to set default value and your form relates to the entity, then you should use following approach:
// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
...
->add(
'myField',
'text',
array(
'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
)
);
}
Otherwise, myField always will be set to default value, instead of getting value from entity.
You can set the default for related field in your model class (in mapping definition or set the value yourself).
Furthermore, FormBuilder gives you a chance to set initial values with setData() method. Form builder is passed to the createForm() method of your form class.
Also, check this link: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
If your form is bound to an entity, just set the default value on the entity itself using the construct method:
public function __construct()
{
$this->field = 'default value';
}
Approach 1 (from http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/)
Simply set the default value in your entity, either in the variable declaration or the constructor:
class Entity {
private $color = '#0000FF';
...
}
or
class Entity {
private $color;
public function __construct(){
$this->color = '#0000FF';
...
}
...
}
Approach 2 from a comment in the above link, and also Dmitriy's answer (not the accepted one) from How to set default value for form field in Symfony2?
Add the default value to the data attribute when adding the field with the FormBuilder, adapted from Dmitriy's answer.
Note that this assumes that the property will and will only have the value null when it's a new, and not an existing, entity.
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('color', 'text', array(
'label' => 'Color:',
'data' => (isset($options['data']) && $options['data']->getColor() !== null) ? $options['data']->getColor() : '#0000FF'
)
);
}
A general solution for any case/approach, mainly by using a form without a class or when we need access to any services to set the default value:
// src/Form/Extension/DefaultFormTypeExtension.php
class DefaultFormTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if (null !== $options['default']) {
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($options) {
if (null === $event->getData()) {
$event->setData($options['default']);
}
}
);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('default', null);
}
public function getExtendedType()
{
return FormType::class;
}
}
and register the form extension:
app.form_type_extension:
class: App\Form\Extension\DefaultFormTypeExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
After that, we can use default option in any form field:
$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
Don't use:
'data' => 'Default value'
Read here: https://symfony.com/doc/current/reference/forms/types/form.html#data
"The data option always overrides the value taken from the domain data (object) when rendering. This means the object value is also overriden when the form edits an already persisted object, causing it to lose its persisted value when the form is submitted."
Use the following:
Lets say, for this example, you have an Entity Foo, and there is a field "active" (in this example is CheckBoxType, but process is the same to every other type), which you want to be checked by default
In your FooFormType class add:
...
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
...
public function buildForm( FormBuilderInterface $builder, array $options )
{
...
$builder->add('active', CheckboxType::class, array(
'label' => 'Active',
));
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event){
$foo = $event->getData();
// Set Active to true (checked) if form is "create new" ($foo->active = null)
if(is_null($foo->getActive())) $foo->setActive(true);
}
);
}
public function configureOptions( OptionsResolver $resolver )
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle:Foo',
));
}
You can set a default value, e.g. for the form message, like this:
$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
->add('name', 'text')
->add('email', 'email')
->add('message', 'textarea')
->add('send', 'submit')
->getForm();
In case your form is mapped to an Entity, you can go like this (e.g. default username):
$user = new User();
$user->setUsername('John Doe');
$form = $this->createFormBuilder($user)
->add('username')
->getForm();
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
if ($data == null) {
$form->add('position', IntegerType::class, array('data' => 0));
}
});
My solution:
$defaultvalue = $options['data']->getMyField();
$builder->add('myField', 'number', array(
'data' => !empty($defaultvalue) ? $options['data']->getMyField() : 0
)) ;
Just so I understand the problem.
You want to adjust the way the form is built based on data in your entity. If the entity is being created then use some default value. If the entity is existing use the database value.
Personally, I think #MolecularMans's solution is the way to go. I would actually set the default values in the constructor or in the property statement. But you don't seem to like that approach.
Instead you can follow this: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
You hang a listener on your form type and you can then examine your entity and adjust the builder->add statements accordingly based on havine a new or existing entity. You still need to specify your default values somewhere though you could just code them in your listener. Or pass them into the form type.
Seems like a lot of work though. Better to just pass the entity to the form with it's default values already set.
If you're using a FormBuilder in symfony 2.7 to generate the form, you can also pass the initial data to the createFormBuilder method of the Controler
$values = array(
'name' => "Bob"
);
$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');
If you set 'data' in your creation form, this value will be not modified when edit your entity.
My solution is :
public function buildForm(FormBuilderInterface $builder, array $options) {
// In my example, data is an associated array
$data = $builder->getData();
$builder->add('myfield', 'text', array(
'label' => 'Field',
'data' => array_key_exits('myfield', $data) ? $data['myfield'] : 'Default value',
));
}
Bye.
Often, for init default values of form i use fixtures. Of cause this way is not easiest, but very comfortable.
Example:
class LoadSurgeonPlanData implements FixtureInterface
{
public function load(ObjectManager $manager)
{
$surgeonPlan = new SurgeonPlan();
$surgeonPlan->setName('Free trial');
$surgeonPlan->setPrice(0);
$surgeonPlan->setDelayWorkHours(0);
$surgeonPlan->setSlug('free');
$manager->persist($surgeonPlan);
$manager->flush();
}
}
Yet, symfony type field have the option data.
Example
$builder->add('token', 'hidden', array(
'data' => 'abcdef',
));
There is a very simple way, you can set defaults as here :
$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);
$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();
Default values are set by configuring corresponding entity. Before binding the entity to form set its color field to "#0000FF":
// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);
If that field is bound to an entity (is a property of that entity) you can just set a default value for it.
An example:
public function getMyField() {
if (is_null($this->MyField)) {
$this->setMyField('my default value');
}
return $this->MyField;
}
I usually just set the default value for specific field in my entity:
/**
* #var int
* #ORM\Column(type="integer", nullable=true)
*/
protected $development_time = 0;
This will work for new records or if just updating existing ones.
As Brian asked:
empty_data appears to only set the field to 1 when it is submitted with no value.
What about when you want the form to default to displaying 1 in the
input when no value is present?
you can set the default value with empty_value
$builder->add('myField', 'number', ['empty_value' => 'Default value'])
I solved this problem, by adding value in attr:
->add('projectDeliveringInDays', null, [
'attr' => [
'min'=>'1',
'value'=>'1'
]
])