Skip to content

Instantly share code, notes, and snippets.

@n3b
Created July 6, 2011 21:22
Show Gist options
  • Save n3b/1068357 to your computer and use it in GitHub Desktop.
Save n3b/1068357 to your computer and use it in GitHub Desktop.
symfony2 dynamic validator constraints
<?php
namespace n3b\Bundle\Shop\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormEvents;
class CheckoutFullType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('deliver', 'checkbox')
->add('user_save', 'checkbox')
->add('checkout', new CheckoutType());
$builder->addEventSubscriber(new EventSubscriber\PreBindDataSubscriber());
$builder->addValidator(new Validator\CheckoutDeliveryValidator());
}
public function getDefaultOptions(array $options)
{
return array(
'validation_groups' => array('pass_through'),
'data_class' => 'n3b\Bundle\Shop\Entity\Customer',
);
}
}
<?php
namespace n3b\Bundle\Shop\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use n3b\Bundle\Shop\Model\Customer as BaseCustomer;
/**
* @ORM\Entity
*/
class Customer extends BaseCustomer
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(unique="true", nullable="true")
* @Assert\NotBlank(groups={"registration"})
* @Assert\Blank(groups={"pass_through"})
*/
protected $login;
}
<?php
namespace Symfony\Component\Form;
use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\Event\FilterDataEvent;
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Form implements \IteratorAggregate, FormInterface
{
...
//этого метода нет в дефолтной комплектации
public function setAttribute($name, $value)
{
$this->attributes[$name] = $value;
}
}
<?php
namespace n3b\Bundle\Shop\Form\EventSubscriber;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class PreBindDataSubscriber implements EventSubscriberInterface
{
public function onPreBindData(DataEvent $event)
{
$data = $event->getData();
if(isset($data['user_save']))
$event->getForm()->get('checkout')->get('customer')->setAttribute('validation_groups', array('registration'));
}
static public function getSubscribedEvents()
{
return array(FormEvents::PRE_BIND => 'onPreBindData');
}
}
@n3b
Copy link
Author

n3b commented Jul 8, 2011

Я не стал там ковыряться, решил инициализировать модель после байнда:

    $form = $this->services['ff']->create(new CheckoutFullType());

    if ($this->services['request']->getMethod() == 'POST') {
        $form->bindRequest($this->services['request']);
        $checkout = $form->get('checkout')->getData();

при таком раскладе в onPreBindData все поголовно в нулях.
По guesser'ам ждем фиксов. Пока накидал цепочку инжектов опций, начиная от билдера и заканчивая непосредственно guesser'ами.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment