php - Symfony2 表单验证器 - 刷新前比较旧值和新值

标签 php symfony doctrine-orm entity validation

我想知道是否有一种方法可以在刷新之前比较实体内验证器中的旧值和新值。

我有一个 Server 实体,可以很好地呈现表单。该实体与 status (N->1) 有关系,当状态从 Unracked 更改为 Racked 时,需要检查通过 SSH 和 FTP 访问服务器。如果未实现访问,则验证器应该失败。

我已将验证器回调映射到 Server 实体中的方法 isServerValid() ,如此处所述 http://symfony.com/doc/current/reference/constraints/Callback.html .我显然可以通过 $this->status 访问"new"值,但我怎样才能获得原始值?

在伪代码中,是这样的:

public function isAuthorValid(ExecutionContextInterface $context)
{
    $original = ... ; // get old values
    if( $this->status !== $original->status && $this->status === 'Racked' && $original->status === 'Unracked' )
    {
        // check ftp and ssh connection
        // $context->addViolationAt('status', 'Unable to connect etc etc');
    }
}

提前致谢!

最佳答案

Symfony 2.5 的完整示例 ( http://symfony.com/doc/current/cookbook/validation/custom_constraint.html )

在此示例中,实体“NoDecreasingInteger”的字段“integerField”的新值必须大于存储值。

创建约束:

// src/Acme/AcmeBundle/Validator/Constraints/IncrementOnly.php;
<?php
namespace Acme\AcmeBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class IncrementOnly extends Constraint
{
  public $message = 'The new value %new% is least than the old %old%';

  public function getTargets()
  {
    return self::CLASS_CONSTRAINT;
  }

  public function validatedBy()
  {
    return 'increment_only';
  }
}

创建约束验证器:

// src/Acme/AcmeBundle/Validator/Constraints/IncrementOnlyValidator.php
<?php
namespace Acme\AcmeBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

use Doctrine\ORM\EntityManager;

class IncrementOnlyValidator extends ConstraintValidator
{
  protected $em;

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

  public function validate($object, Constraint $constraint)
  {
    $new_value = $object->getIntegerField();

    $old_data = $this->em
      ->getUnitOfWork()
      ->getOriginalEntityData($object);

    // $old_data is empty if we create a new NoDecreasingInteger object.
    if (is_array($old_data) and !empty($old_data))
      {
        $old_value = $old_data['integerField'];

        if ($new_value < $old_value)
          {
            $this->context->buildViolation($constraint->message)
              ->setParameter("%new%", $new_value)
              ->setParameter('%old%', $old_value)
              ->addViolation();
          }
      }
  }
}

将验证器绑定(bind)到实体:

// src/Acme/AcmeBundle/Resources/config/validator.yml
Acme\AcmeBundle\Entity\NoDecreasingInteger:
  constraints:
     - Acme\AcmeBundle\Validator\Constraints\IncrementOnly: ~

将 EntityManager 注入(inject) IncrementOnlyValidator:

// src/Acme/AcmeBundle/Resources/config/services.yml
services:
   validator.increment_only:
        class: Acme\AcmeBundle\Validator\Constraints\IncrementOnlyValidator
        arguments: ["@doctrine.orm.entity_manager"]
        tags:
            - { name: validator.constraint_validator, alias: increment_only }

关于php - Symfony2 表单验证器 - 刷新前比较旧值和新值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17306635/

相关文章:

php - 在 php laravel 中将 html 转换为 json

php - 使用 PayumBundle 注册自定义网关

php - symfony用较低的函数创建数据库索引

自动生成的 Symfony2 表单 <select> 字段中的 HTML5 验证

symfony - 具有继承映射的多对一自引用

doctrine-orm - 实体与存储库(有什么区别)

mysql - 语法错误 - Doctrine\ORM\Query\QueryException

php - 检索插入记录的 ID : Php & MS SQL SERVER

PHPUnit : Fatal error handling

php - 强制 SSL 服务器和子域崩溃