Skip to content

Instantly share code, notes, and snippets.

@johnkary
Created November 30, 2012 16:09
Show Gist options
  • Select an option

  • Save johnkary/4176691 to your computer and use it in GitHub Desktop.

Select an option

Save johnkary/4176691 to your computer and use it in GitHub Desktop.

Revisions

  1. johnkary revised this gist Nov 30, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion UserType.php
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    <?php

    namespace Acme\StudentBundle\Form;
    namespace Acme\UserBundle\Form;

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
  2. johnkary created this gist Nov 30, 2012.
    59 changes: 59 additions & 0 deletions ReadOnlyFieldSubscriber.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    <?php

    namespace Acme\UserBundle\Listener;

    use Symfony\Component\Form\FormEvent;
    use Symfony\Component\Form\FormEvents;
    use Symfony\Component\Form\FormFactoryInterface;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;

    /**
    * Configures fields that are read-only to the user completing the form
    * and unchangeable.
    *
    * @author johnkary
    */
    class ReadOnlyFieldSubscriber implements EventSubscriberInterface
    {
    private $factory;

    public function __construct(FormFactoryInterface $factory)
    {
    $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
    return array(
    FormEvents::PRE_SET_DATA => 'preSetData',
    FormEvents::POST_BIND => 'postBind',
    );
    }

    public function preSetData(FormEvent $event)
    {
    $user = $event->getData();
    $form = $event->getForm();

    // During form creation setData() is called with null as an argument
    // by the FormBuilder constructor. You're only concerned with when
    // setData is called with an actual Entity object in it (whether new
    // or fetched with Doctrine). This if statement lets you skip right
    // over the null condition.
    if (null === $user) {
    return;
    }

    $form->add($this->factory->createNamed('phoneNumber', 'text', $user->getPhoneNumber(), array(
    'mapped' => false,
    'read_only' => true,
    )));
    }

    public function postBind(FormEvent $event)
    {
    $user = $event->getData();
    // The User's phoneNumber property is the same even if you modified it via the browser
    var_dump($user->getPhoneNumber());exit;
    }
    }
    54 changes: 54 additions & 0 deletions UserType.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    <?php

    namespace Acme\StudentBundle\Form;

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use Doctrine\Common\Persistence\ObjectManager;

    use Acme\UserBundle\Entity\User;
    use Acme\UserBundle\Listener\ReadOnlyFieldSubscriber;

    class UserType extends AbstractType
    {
    /**
    * EntityManager that handles persisting User entities
    * @var ObjectManager
    */
    private $em;

    public function __construct(ObjectManager $em)
    {
    $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
    $subscriber = new ReadOnlyFieldSubscriber($builder->getFormFactory());
    $builder->addEventSubscriber($subscriber);

    $builder
    ->add('addressStreet')
    ->add('addressCity')
    ->add('addressState', 'choice', array(
    'required' => false,
    'empty_value' => '',
    'choices' => array('CA' => 'California', 'CO' => 'Colorado'),
    ))
    ->add('addressZip')
    ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
    $resolver->setDefaults(array(
    'data_class' => 'Acme\UserBundle\Entity\User'
    ));
    }

    public function getName()
    {
    return 'acme_userbundle_usertype';
    }
    }