Symfony2的做表单验证而不是数据库验证

Symfony2的做表单验证而不是数据库验证

问题描述:

我有一个信用卡式的实体,现在我想在此执行基本验证,在实体,如:Symfony2的做表单验证而不是数据库验证

/** 
* @ORM\Column(name="number", type="string", length=255) 
* @Assert\CardScheme(
*  schemes={"VISA", "MASTERCARD", "DISCOVER", "DINERS"}, 
*  message="The card number is not valid, we only support Visa, Mastercard, Discover og Diners club." 
*) 
*/ 
private $number; 

但问题是,我存储卡号加密。

他们最终看起来很不一样,在我的表单类型中,我这样做是为了加密值并删除所有不需要的东西。

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('number') 
     ->add('expiration_year', 'choice', array(
      'required' => true, 
      'choices' => $this->buildYearChoices() 
     )) 
     ->add('expiration_month', 'choice', array(
      'required' => true, 
      'choices' => array(
       '01' => '01', 
       '02' => '02', 
       '03' => '03', 
       '04' => '04', 
       '05' => '05', 
       '06' => '06', 
       '07' => '07', 
       '08' => '08', 
       '09' => '09', 
       '10' => '10', 
       '11' => '11', 
       '12' => '12', 
      ) 
     )) 
     ->add('cvc', 'text'); 

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) 
    { 
     $data = $event->getData(); 
     $number = preg_replace("/[^0-9]/", "", $data['number']); 

     $data['number'] = $number; 

     $event->setData($data); 
    }); 

    $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) 
    { 
     $credit_card = $event->getData(); 
     $number = $credit_card->getNumber(); 

     $customer_helper = $this->container->get('customer_helper'); 

     $crypt = $customer_helper->encryptCreditCardNumber($number); 
     $credit_card->setNumber($crypt); 

     $event->setData($credit_card); 
    }); 

} 

即使寿我知道表单验证进行pre_submit,我还是老样子得到验证错误,当我对它进行加密上提交,而不是

编辑:加密和解密emthods:

public function encryptCreditCardNumber($plaintext) { 
    $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. 
    $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM); //Creates an initialization vector (IV) from a random source. 
    $ciphertext = mcrypt_encrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $plaintext, self::MODE, $iv); //Encrypts the data and returns it. 
    return base64_encode($iv.$ciphertext); //Encode Base 64 
} 

public function decryptCreditCardNumber($ciphertext) { 
    $ciphertext = base64_decode($ciphertext); //Decode Base 64 
    $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. 
    if (strlen($ciphertext) < $ivSize) { 
     throw new Exception('Missing initialization vector'); 
    } 

    $iv = substr($ciphertext, 0, $ivSize); 
    $ciphertext = substr($ciphertext, $ivSize); 
    $plaintext = mcrypt_decrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $ciphertext, self::MODE, $iv); //Decrypts the data and returns it. 
    return rtrim($plaintext, "\0"); 
} 

您可以捕获原则事件prePersistpreUpdate,以在运行中(在保留数据之前,很好地在表单验证之后)用加密的代码替换普通代码。

要解密它,你可以使用postLoad

更多关于doctrine events is here

请注意,原则事件不同于表单事件,不会干扰表单或验证(甚至可能根本没有表单)。

编辑:进样关键

每当你需要注入静态信息到一个实体,比如一个参数或功能,使用依赖注入。

如果您有捆绑软件,请转到DependencyInjection文件夹并编辑Configuration.php文件(或者是另一个?我现在不记得了)。

您想要查找的是使用load方法加载参数的方法。

权后,从配置获取需要的参数,这样的设置在类的静态成员:

MyEntity::$secretKey = $configuration->getParameter('secretkey'); 

实体里面只是细读与信息:

self::$secretKey 

我把这个写在了我的头顶,这么多的不准确之处可能已经溜进去了。关键是全部关于静态注入参数如上所示。

+0

问题与此,是否需要将事件置于我的实体中?加密密钥存储在parameters.yml中,所以我不保存在代码中,但我无法将容器放入实体 –

+0

而这样做会是不好的做法,据我了解 –

+0

我发布了我的加密和解密方法,以澄清 –

您可以创建验证目的的非映射实体属性:

/** 
* @Assert\CardScheme(
*  schemes={"VISA", "MASTERCARD", "DISCOVER", "DINERS"}, 
*  message="The card number is not valid, we only support Visa, Mastercard, Discover og Diners club." 
*) 
*/ 
private $rawNumber; 

/** 
* @ORM\Column(name="number", type="string", length=255) 
*/ 
private $number; 

,然后设置数量与表单验证后rawNumber的加密值:

$creditCard->setNumber(
    your_encryption_function(
     $creditCard->getRawNumber() 
    ) 
);