18

Using Symfony2 entity field type one should specify property option:

$builder->add('customers', 'entity', array(
    'multiple' => true,
    'class'    => 'AcmeHelloBundle:Customer',
    'property' => 'first',
));

But sometimes this is not sufficient: think about two customers with the same name, so display the email (unique) would be mandatory.

Another possibility is to implement __toString() into the model:

class Customer
{
    public $first, $last, $email;

    public function __toString()
    {
        return sprintf('%s %s (%s)', $this->first, $this->last, $this->email);
    }
}

The disadvances of the latter is that you are forced to display the entity the same way in all your forms.

Is there any other way to make this more flexible? I mean something like a callback function:

$builder->add('customers', 'entity', array(
    'multiple' => true,
    'class'    => 'AcmeHelloBundle:Customer',
    'property' => function($data) {
         return sprintf('%s %s (%s)', $data->first, $data->last, $data->email);
     },
));
j0k
  • 22,600
  • 28
  • 79
  • 90
  • I have this exact same situation and was planning to post a question on SO soon... I'm looking forward to the answer. – Icode4food Mar 28 '12 at 22:44

3 Answers3

41

I found this really helpful, and I wound a really easy way to do this with your code so here is the solution

$builder->add('customers', 'entity', array(
'multiple' => true,
'class'    => 'AcmeHelloBundle:Customer',
'property' => 'label',
));

And in the class Customer (the Entity)

public function getLabel()
{
    return $this->lastname .', '. $this->firstname .' ('. $this->email .')';
}

eh voila :D the property get its String from the Entity not the Database.

Detmud
  • 426
  • 4
  • 2
  • 6
    You should probably use the getters and not access the values directly. `return $this->getLastname() .', '. $this->getFirstname() .' ('. $this->getEmail() .')';` – Andrew Atkinson May 03 '13 at 11:18
  • This is great, except if you need to generate a thumbnail or something that you can't do from the model... – darkbluesun Jul 17 '15 at 05:10
2

Passing a closure does not work yet, but will be added to Symfony soon: https://github.com/symfony/symfony/issues/4067

Bernhard Schussek
  • 4,823
  • 26
  • 33
1

It seems this can be achievable by adding following block after elseif ($this->labelPath) block in ObjectChoiceList.php.

elseif (is_callable($this->labelPath)) {
  $labels[$i] = call_user_func($this->labelPath, $choice);
}

Haven't tried it though :).

Mun Mun Das
  • 14,992
  • 2
  • 44
  • 43
  • 1
    That does look like it would work, but require hacking Symfony. I would prefer to avoid that if possible. Surely there is a "correct" way to do this. It seems to me like a fairly substantial issue. – Icode4food Mar 29 '12 at 12:14
  • Well it is the only way AFIK. To make it to Symfony2 core a PR needs to be send to github. I may submit a PR with proper unit test if I get free time. If any one submit a PR that is also good. – Mun Mun Das Mar 29 '12 at 14:47
  • @m2mdas Let us know if you do submit a PR. I'm not hurting for this functionality right now but I will be at some point and may do it myself if someone else hasn't taken care of this by then. – Icode4food Mar 29 '12 at 17:45