我在我的应用程序中有一个注册表单,我想使用vmelnik-ukraine / DoctrineEncryptBundle为Symfony加密数据.
注册表格来自FOSUserBundle.
我已经配置并安装了捆绑包并在实体中导入了@Encrypted注释,如下所示:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;
use VMelnik\DoctrineEncryptBundle\Configuration\Encrypted;
/**
* Developer
*
* @ORM\Entity
* @ORM\Table(name="fos_user")
*/
class Developer extends BaseUser
{
...
/**
* @var string
* @ORM\Column(name="firstname", type="string", length=255)
* @Encrypted
* @Assert\Length(
* min = 2,
* max = 50,
* minMessage = "profile.register.notification.name.too-short",
* maxMessage = "profile.register.notification.name.too-long"
* )
*/
private $firstname;
但是现在,当提交表单时,我收到以下错误:
Field "firstname" is not a valid field of the entity "AppBundle\Entity\Developer" in PreUpdateEventArgs.
我究竟做错了什么?
最佳答案 我正在使用
a noticeably similar extension作为Doctrine / Zend,我遇到了同样的问题.我注意到它发生在:
>我标记了一个字段@Encrypted(例如姓名)
>我在数据库中留下了未加密的值(例如bob)
>我写了那个表行而没有改变未加密的值(例如(id,bob,x,y,z))
我将问题追溯到DoctrineEncryptSubscriber.php的源代码(这在vmelnik-ukraine / DoctrineEncryptBundle中是相同的):
public function preUpdate(PreUpdateEventArgs $args) {
$reflectionClass = new ReflectionClass($args->getEntity());
$properties = $reflectionClass->getProperties();
foreach ($properties as $refProperty) {
if ($this->annReader->getPropertyAnnotation($refProperty, self::ENCRYPTED_ANN_NAME)) {
$propName = $refProperty->getName();
$args->setNewValue($propName, $this->encryptor->encrypt($args->getNewValue($propName))); // this line is the problem
}
}
}
$args-> setNewValue(…)调用assertValidField($field),它检查@Encrypted字段是否在entityChangeSet中…它不是因为我没有对它进行任何更改.所以它引发了一个例外.当数据库中的值已经加密时,这不会发生,因为那时entityChangeset具有旧值的加密值和新值的明文.
我正在使用的补丁是在我们实际更改字段时仅调用setNewValue(),如下所示:
public function preUpdate(PreUpdateEventArgs $args)
{
$reflectionClass = new ReflectionClass($args->getEntity());
$properties = $reflectionClass->getProperties();
foreach ($properties as $refProperty) {
if ($this->annReader->getPropertyAnnotation($refProperty, self::ENCRYPTED_ANN_NAME)) {
$propName = $refProperty->getName();
if ($args->hasChangedField($propName)) {
$args->setNewValue($propName, $this->encryptor->encrypt($args->getNewValue($propName)));
}
}
}
}