Symfony2 embed form with file into another form - forms

I have an Item entity and an Image entity, which a OneToOne relation between them.
I also have an ItemType and ImageType forms.
Until now when I have a situation like this one I use the two forms separately (rendering them into a single html form) and setting the relation inside the controller or the form handler. Is there a -symfony- way to embed the ImageType form into the ItemType one?
A little code maybe can help.
Item:
namespace Company\ItemBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use NewZaarly\ImageBundle\Entity\Image;
/**
* #ORM\Table()
* #ORM\Entity()
*/
class Item
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $title;
/**
* #var \NewZaarly\ImageBundle\Entity\ImageItem
* #ORM\OneToOne(targetEntity="NewZaarly\ImageBundle\Entity\ImageItem", mappedBy="item", cascade={"persist", "merge", "remove"})
*/
private $image;
//other fields. Setters and getters
}
Image:
<?php
namespace Company\ImageBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* #ORM\Table()
* #ORM\Entity()
* #ORM\HasLifecycleCallbacks
*/
class Image
{
/**
* #Assert\File(maxSize = "2M", mimeTypes = {"image/png", "image/jpg", "image/jpeg"})
*/
protected $file;
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="image", type="string", length=255, nullable=true)
*/
protected $image;
//other fields, setter and getters
}
ImageType
<?php
namespace Company\ImageBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('file', 'file', array('required' => true));
}
public function getName()
{
return 'image';
}
}
And the ItemType form
<?php
namespace Company\ItemBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Company\ImageBundle\Form\Type\ImageType;
class ItemType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('title', 'text');
$builder->add('image', new ImageType()); // <-- this is what I'd like to do
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Company\ItemBundle\Entity\Item');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'Company\ItemBundle\Entity\Item'));
}
public function getName()
{
return 'item';
}
}
Doing it like this I get an error when binding the request because the image is an array an not an Image object, what is expected in the setImage method in the Item class.
My handle function is pretty simple:
public function handle(FormInterface $form, Request $request)
{
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
$item = $form->getData();
$this->itemManager->saveItem($item);
return true;
}
}
return false;
}
Any idea? I don't like the first way I specified for doing it.

I had the same problem and I solved by adding data_class to embedded field, in my case I define the upload form as service (app_document_upload)
//Document Class
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//other fields here ...
->add('image', 'app_document_upload', array(
'data_class' => 'App\DocumentBundle\Entity\Document'
))
}

Related

Symfony, How to properly set up a form that uses multiple entities?

I have a user creation page that uses User entity form with Username and Email attributes.
I would like when creating a user to be able to choose the tools he will have access to. To do this, retrieve all the tools and display them in a checkbox. Thus, once the form has been validated, the user obtains a username, an email and the tools to which he has access.
In my User class I can add a tool from the Tool entity using the AddTool() method.
How can I integrate the tools into my user creation form? I don't see how to do I'm lost.
Class User :
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
*/
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=180)
*/
private $username;
/**
* #ORM\Column(type="json")
*/
private $roles = [];
/**
* #var string The hashed password
* #ORM\Column(type="string")
*/
private $password;
/**
* #ORM\ManyToMany(targetEntity=Tool::class, mappedBy="users", fetch="EAGER")
*/
private $tools;
/**
* #ORM\Column(type="string", length=125, unique=true)
*/
private $email;
public function __construct()
{
$this->tools = new ArrayCollection();
}
// SOME FUNCTIONS
/**
* #return Collection|Tool[]
*/
public function getTools(): Collection
{
return $this->tools;
}
public function addTool(Tool $tool): self
{
if (!$this->tools->contains($tool)) {
$this->tools[] = $tool;
$tool->addUser($this);
}
return $this;
}
public function removeTool(Tool $tool): self
{
if ($this->tools->removeElement($tool)) {
$tool->removeUser($this);
}
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
}
UserType :
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('username')
->add('email')
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
In Your UserType buildForm function add something like:
$builder
->add('username')
->add('email')
->add('Tools', EntityType::class, [
'class' => Tool::class,
'multiple' => true
])
;
And You need to create a function in Tool::class definition that will allow display it as a string:
#[Pure] public function __toString(): string
{
return ''.$this->getFullName();
}
It should allow You to select Tools entities during the generation of User forms.

How to extend register form by additional fields in FOSUserBundle and Symfony3

I'm learning Symfony3 framework. At now I've build project that contain two Entities: User and Catalog. Catalog entity is for additional Company data (company name, address, and so on) - it's like a business card. Single User (but not all) is connected only with one Business Card (Catalog entity) and that's why I've decided to use two separate entities. Some users have access e.g. to backend and other ones have possibility to add and manage their one Business Card.
I want to allow user for fill in his Company details while he is registering. I'm using FOSUserBundle for User entity. At now I have registration form working but I'm stuck and need Your help with embed my CatalogType form.
CatalogType form:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CatalogType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('address')
->add('city')
->add('province')
->add('postcode')
->add('telephone')
->add('fax')
->add('mobile')
->add('email')
->add('webpage')
->add('misc')
;
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'app_user_registration';
}
}
User entity:
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User extends BaseUser
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var
*
* #ORM\OneToMany(targetEntity="Comment", mappedBy="user")
*/
private $comments;
/**
* #var
*
* #ORM\OneToOne(targetEntity="Catalog", mappedBy="user")
*/
private $catalog;
public function __construct()
{
parent::__construct();
$this->comments = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Add comment
*
* #param \AppBundle\Entity\Comment $comment
*
* #return User
*/
public function addComment(\AppBundle\Entity\Comment $comment)
{
$this->comments[] = $comment;
return $this;
}
/**
* Remove comment
*
* #param \AppBundle\Entity\Comment $comment
*/
public function removeComment(\AppBundle\Entity\Comment $comment)
{
$this->comments->removeElement($comment);
}
/**
* Get comments
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getComments()
{
return $this->comments;
}
/**
* Set catalog
*
* #param \AppBundle\Entity\Catalog $catalog
*
* #return User
*/
public function setCatalog(\AppBundle\Entity\Catalog $catalog = null)
{
$this->catalog = $catalog;
return $this;
}
/**
* Get catalog
*
* #return \AppBundle\Entity\Catalog
*/
public function getCatalog()
{
return $this->catalog;
}
}
Catalog entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Catalog
*
* #ORM\Table(name="catalog")
* #ORM\Entity(repositoryClass="AppBundle\Repository\CatalogRepository")
*/
class Catalog
{
// ... definition a lot of private variables ...
/**
* #var
*
* #ORM\OneToOne(targetEntity="User", inversedBy="catalog")
* #ORM\JoinColumn(name="user_id", nullable=true)
*/
private $user;
// ...
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return Catalog
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
Services config file:
// app/config/services.yml
services:
app.form.registration:
class: AppBundle\Form\CatalogType
tags:
- { name: form.type, alias: app_user_registration }
When I'm trying to display register form under http://localhost:8000/register/
I'm getting an error:
Neither the property "name" nor one of the methods "getName()",
"name()", "isName()", "hasName()", "__get()" exist and have public
access in class "AppBundle\Entity\User".
I know where is the problem, but I don't know how to properly solve it so it would be great if somebody can help me where I should looking for solutions or how it should be solved.
Thanks.
CatalogType should not extend RegistrationFormType. It should be form type for AppBundle\Entity\Catalog.
You should make form type, that is based on User class (subclass of FOS\UserBundle\Model\User), and that embeds CatalogType form.
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('...', ...)
->add('tasks', CollectionType::class, array(
'entry_type' => CatalogType::class,
...
));
...
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User',
));
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
}
class CatalogType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('address')
->add('city')
->add('province')
->add('postcode')
->add('telephone')
->add('fax')
->add('mobile')
->add('email')
->add('webpage')
->add('misc')
;
}
...
}
More on embedding forms: https://symfony.com/doc/current/form/form_collections.html
More on overriding FosUserBundle forms: http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html

Same Table, Two entities (or class) in symfony

I'd like to build two class that refer to the same table.
For example:
Table Invoice:
idInvoice, IdClient, idProduct.
I've got one entity that shows general information (idClient and idInvoice) and than I've got an entity that allows me to show a dynamically generated form (id Product).
For every invoice I need one or more product so I should be able to insert different row for different product.
How can I link this different entities on the same table?
When I submit the form I need to extract all data from Product information and all data from Client and then I need to insert on MySQL.
I have got ORDER TABLE and PRODUCT TABLE. They are in a one to many relationship (one order, more product.) I created two entities: Order and Product and these are the classes:
ORDER CLASS
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="ordini")
*/
class Ordine
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $idOrdine;
/**
*
* #ORM\OnetoMany(targetEntity="Prodotto", cascade={"persist"},
mappedBy="prodotto")
*
*/
protected $prodotti;
/**
* Get idOrdine
*
* #return integer
*/
public function getIdOrdine()
{
return $this->idOrdine;
}
public function __costruct()
{
$this->prodotti= new ArrayCollection();
}
public function setProdotti(ArrayCollection $prodotti)
{
$this->prodotti = $prodotti;
//return $this;
}
public function addProdotti(Prodotto $prod) {
$this->prodotti[] = $prod;
return $this;
}
public function addProdotto(Prodotto $prodotto) {
$this->prodotti[] = $prodotto;
$prodotto->setOrdine($this);
return $this;
}
public function getProdotti() {
return $this->prodotti;
}
}
PRODUCT CLASS
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="prodotto")
*/
class Prodotto
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $idProdotto;
/**
* #ORM\Column(type="string", length=100, nullable=TRUE)
*
*/
protected $modello;
/**
* #ORM\ManyToOne(targetEntity="Ordine", inversedBy="prodotti")
* #var AppBundle\Entity\Ordine
*/
protected $ordini;
/**
* Get idProdotto
*
* #return integer
*/
public function getIdProdotto()
{
return $this->idProdotto;
}
/**
* Set modello
*
* #param string $modello
* #return Prodotto
*/
public function setModello($modello)
{
$this->modello = $modello;
return $this;
}
/**
* Get modello
*
* #return string
*/
public function getModello()
{
return $this->modello;
}
}
Then I created a Form that allows me to create an order (invoice) and I can dynamically generate Product Field.
I should be on the right way but now it gives me an error:
Expected argument of type "Doctrine\Common\Collections\ArrayCollection",
"array" given
My OrderForm is:
namespace AppBundle\Form\Documentofiscale;
use Symfony\Component\Form\TextField;
use Symfony\Component\Form\Checkbox;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use AppBundle\Entity\Prodotto;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class FormDocumentoFiscale extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// $builder->add('idCliente');
//$builder->add('save', 'submit', array('label' => 'INSERISCI
DOCUMENTO'));
$builder->add('prodotti', 'collection', array(
'type' => new FormAggiuntaProdotti(),
'allow_add' => true,
'by_reference' => false,
)
);
$builder->add('save', 'submit', array('label' => 'INSERISCI
DOCUMENTO'));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Ordine',
));
}
public function getName()
{
return 'documento';
}
}
And my dynamically generated Form is:
namespace AppBundle\Form\Documentofiscale;
use Symfony\Component\Form\TextField;
use Symfony\Component\Form\Checkbox;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use AppBundle\Entity\Prodotto;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class FormAggiuntaProdotti extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('modello');
//// $builder->add('idCliente');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Prodotto',
));
}
public function getName()
{
return 'prodotto';
}
}

In the Symfony2 documentation you can embed a collection of forms to add object, but how do you select from existing objects to add to the collection?

Not sure that was the clearest way of asking my question, but basically I want to try and achieve the below in Symfony2:
It is important to note that I have tried the embed a collection as per the documentation, but I am not looking to create a new object and add to the collection I am trying to select an existing object to add to the collection.
I currently have a product group entity that simply consists of an ID, Name and collection of products:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Product Group
* #ORM\Table(name="productGroups")
* #ORM\HasLifecycleCallbacks
*/
class ProductGroup
{
/**
* #var integer
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="name", type="string", length=255)
*/
protected $name;
/**
* #ORM\ManyToMany(targetEntity="Product", mappedBy="productGroups")
**/
protected $products;
...
I then have the product entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Product
* #ORM\Table(name="products")
* #ORM\HasLifecycleCallbacks
*/
class Product
{
/**
* #var integer
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="name", type="string", length=255)
*/
protected $name;
/**
* #var string
* #ORM\Column(name="code", type="string", length=20)
*/
protected $name;
/**
* #ORM\ManyToMany(targetEntity="ProductGroup", mappedBy="products")
**/
protected $productGroups;
...
What I am trying to do is create a form that allows me to create and update a product group.
I want to enter a name for the product group and then select products by ticking a check box against the rows of a table. The idea being that I could use something like datatables to filter the products to make it easier to add.
To start this off I have added a Product Group Type:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ProductGroupType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('products', 'collection', array(
'type' => new ProductType()
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\ProductGroup',
));
}
public function getName()
{
return 'product_group';
}
}
I then have the Product Type:
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('code');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Product',
));
}
public function getName()
{
return 'product';
}
}
Now I am very confused about how I can have a table of products that have a checkbox that once selected and the form saved are saved against the product group.
Can anyone help or suggest any other way of doing this?
I have attached an image of what I am trying to achieve if that helps.
Thanks in advance.
Use the entity form type:
http://symfony.com/doc/current/reference/forms/types/entity.html
$builder->add('name', 'text')
->add('code', 'text')
->add(
'ProductGroups', 'entity', array(
'class' => 'YourBundle:ProductGroups',
'label' => 'Select ProductTypes',
'placeholder' => 'Select ProductGroups',
'multiple' => true,
'expanded' => true
))
->getForm();
}
The Multiple tag will generate a list of checkboxes that allows you to select multiple productGroups

Symfony2 (2.7) Form Entity Data Transformer

I'm trying to customize a selection list's text while using the entity's ID. This is because I want the list options to be specific to the authenticated user. The database text values are Full Name, By City and State, and Anonymous, but I want it to actually display the user's full name (John Smith), User in Denver, CO, and Anonymous. I'm attempting to use a view data transformer to achieve this, but with no luck. I'd rather not use Javascript to achieve this if possible.
Here's my main form type:
<?php
namespace Members\MessagesBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\SecurityContext;
class MessageType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('viewability', 'viewability_entity', array(
'class' => 'MessagesBundle:Viewability',
'property' => 'name',
'required' => true,
))
->add('body', new MessageBodyType())
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Members\MessagesBundle\Entity\Message',
));
}
/**
* #return string
*/
public function getName()
{
return 'members_messages_message';
}
}
Here's my custom form type for Viewability (the entity which I would like to transform):
<?php
namespace Members\MessagesBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\SecurityContext;
use Members\MessagesBundle\Form\DataTransformer\MessageNameTransformer;
class ViewabilityType extends AbstractType
{
private $context;
/**
* #param SecurityContext $context
*/
public function __construct(SecurityContext $context)
{
$this->context = $context;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new MessageNameTransformer($this->context);
$builder->addViewTransformer($transformer);
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'invalid_message' => 'The selected issue does not exist',
));
}
/**
* #return string
*/
public function getParent()
{
return 'entity';
}
/**
* #return string
*/
public function getName()
{
return 'viewability_entity';
}
}
Here's my service which defines the Viewability Type:
members.messages.form.type.viewability_entity:
class: Members\MessagesBundle\Form\ViewabilityType
tags:
- { name: form.type, alias: viewability_entity }
arguments: [#security.context]
Here's my Viewability Entity:
<?php
namespace Members\MessagesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
*/
class Viewability
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
public function __construct()
{
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
}
Finally, here's my data transformer:
<?php
namespace Members\MessagesBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Members\MessagesBundle\Entity\Viewability;
use Symfony\Component\Security\Core\SecurityContext;
class MessageNameTransformer implements DataTransformerInterface
{
private $user;
/**
* #param SecurityContext $context
*/
public function __construct(SecurityContext $context)
{
$this->user = $context->getToken()->getUser();
}
/**
* #param Viewability|null $viewability
* #return string
*/
public function transform($viewability)
{
if (null === $viewability) {
return '';
}
if($viewability === 'Full Name')
return sprintf('%s %s', $this->user->getInfo()->getFirstName(), $this->user->getInfo()->getLastName());
if($viewability === 2)
return sprintf('Lawyer in %s, %s', $this->user->getInfo()->getAddress()->getCity(), $this->user->getInfo()->getAddress()->getState());
if($viewability === 3)
return 'Anonymous';
}
/**
* #param Viewability $viewability
* #return Viewability
*/
public function reverseTransform($viewability)
{
return $viewability;
}
}
The data passed into transform() always seems to be null or "" (empty string).
Thanks for any help.
So I ended up taking a different approach to solving this. Originally I was trying to transform data coming from an entity. Fortunately this entity didn't really need to be a database entity after all and a simple choice type sufficed. This doesn't solve the specific issue of transforming an entity list, but it allows me to customize the drop down list values.
The viewability entity was removed and the relationship in the Message entity was changed to an integer field.
My main type is now as follows:
class MessageType extends AbstractType
{
private $user;
public function __construct($user)
{
$this->user = $user;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('body', new MessageBodyType())
->add('viewability', 'choice', array(
'choices' => array(
1 => $user->getFirstName(),
2 => $user->getAddress()->getCity(),
3 => 'Anonymous',
),
'multiple' => false,
'label' => 'Send Message As',
'data' => 0,
))
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Members\MessagesBundle\Entity\Message',
));
}
/**
* #return string
*/
public function getName()
{
return 'members_messages_message';
}
}