ZF2 inputfilter doctrine NoObjectExists编辑对象不验证

 帅气zxc_925 发布于 2023-02-09 11:29

所以我得到了一个ZF2应用程序,在InputFilter中有一个Form和一个InputFilter,我有:

$this->add(
        array(
            'name'       => 'email',
            'required'   => true,
            'validators' => array(
                array(
                    'name' => 'EmailAddress'
                ),
                array(
                    'name'      => 'DoctrineModule\Validator\NoObjectExists',
                    'options' => array(
                        'object_repository' => $sm->get('doctrine.entitymanager.orm_default')->getRepository('YrmUser\Entity\User'),
                        'fields'            => 'email'
                    ),
                ),
            ),
        )
    );

效果很好,但是当我编辑现有对象并保存它时,NoObjectExists验证器说找到匹配的对象,因此它不会验证.有这个问题的解决方案吗?或者我应该删除编辑表单上的验证器并在插入重复时捕获异常?

更新: 如何在编辑表单中使用DoctrineModule\Validator\NoObjectExists - Zend Framework 2和Doctrine 2

是同样的问题,但答案是在编辑时删除验证器,这个过程不是一个解决方案.因为你仍然必须捕获插入副本时抛出的异常.我可以做到这一点没有问题,但我要求的是一个解决方案,使它与NoObjectExists一起使用(否则,如果我必须捕获重复项的异常,那么是否使用此验证器)

更新,添加其他相关代码(我的表单和实体有更多的字段,但我删除它们,以保持在这里可读)

形成:

namespace YrmUser\Form;

use Zend\Form\Form;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity;

use YrmUser\Entity\User;



class UserForm extends Form
{
protected $objectManager;

/**
 * __construct description
 *
 * @param String $name form name
 * 
 * @return void
 */
public function __construct($name = null)
{
    parent::__construct('new-user');
}

public function init()
{
    $this->setHydrator(
        new DoctrineHydrator($this->objectManager, 'YrmUser\Entity\User')
    )->setObject(new User());

    $this->setAttribute('method', 'post');


    $this->add(
        array(
            'name' => 'email',
            'attributes' => array(
                'type'  => 'email',
                'placeholder' =>'Email',
            ),
            'options' => array(
                'label' => 'Email',
            ),
        )
    );

}
}

过滤:

class UserFilter extends InputFilter
{
/**
 * [__construct description]
 * 
 * @param ServiceLocator $sm servicelocator
 */
public function __construct($sm)
{


    $this->add(
        array(
            'name'       => 'email',
            'required'   => true,
            'validators' => array(
                array(
                    'name' => 'EmailAddress'
                ),
                array(
                    'name'      => 'DoctrineModule\Validator\NoObjectExists',
                    'options' => array(
                        'object_repository' => $sm->get('doctrine.entitymanager.orm_default')->getRepository('YrmUser\Entity\User'),
                        'fields'            => 'email'
                    ),
                ),
            ),
        )
    );
}
}

控制器行动:

public function editAction() 
{
    $id = (int) $this->params('id', null);
    if (null === $id) {
        return $this->redirect()->toRoute('manage-users');
    }

    $em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');

    $formManager = $this->getServiceLocator()->get('FormElementManager');
    $form = $formManager->get('UserForm');

    $user = $em->find('YrmUser\Entity\User', $id);
    $form->setInputFilter(new UserFilter($this->getServiceLocator()));
    $form->bind($user);

    $request = $this->getRequest();
    if ($request->isPost()) {
        $form->setData($request->getPost());
        if ($form->isValid()) {
            $em->persist($user);
            $em->flush();
            return $this->redirect()->toRoute('manage-users');
        }
    }

    return array(
        'form' => $form,
        'id' => $id
    );
}

实体:

class User
{
/**
 * @var int
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;



/**
 * @var string
 * @ORM\Column(type="string", unique=true,  length=255)
 */
protected $email;



/**
 * Get id.
 *
 * @return int
 */
public function getId()
{
    return $this->id;
}

/**
 * Set id.
 *
 * @param int $id user id
 *
 * @return void
 */
public function setId($id)
{
    $this->id = (int) $id;
}


/**
 * Get email.
 *
 * @return string
 */
public function getEmail()
{
    return $this->email;
}

/**
 * Set email.
 *
 * @param string $email user email adress
 *
 * @return void
 */
public function setEmail($email)
{
    $this->email = $email;
}
}

提前致谢,

YRM

1 个回答
  • 我最近在我的项目中遇到了同样的问题,我花了很多时间寻找解决方案,我终于找到了这个模块LosBase.

    它使用两个海关验证其延长DoctrineModule\Validator\NoObjectExists:NoEntityExistsAdd行动和NoOtherEntityExistsEdit行动.

    所以我用这个appraoch来解决我的问题.这是我到目前为止所做的解决方案:

    NoOtherEntityExists验证器:

    use Zend\Validator\Exception\InvalidArgumentException;
    use DoctrineModule\Validator\NoObjectExists;
    
    class NoOtherEntityExists extends NoObjectExists
    {
        private $id; //id of the entity to edit
        private $id_getter;  //getter of the id
        private $additionalFields = null; //other fields
        public function __construct(array $options)
        {
            parent::__construct($options);
             if (isset($options['additionalFields'])) {
              $this->additionalFields = $options['additionalFields'];
             }
            $this->id = $options['id'];
            $this->id_getter = $options['id_getter'];
        }
        public function isValid($value, $context = null)
        {
            if (null != $this->additionalFields && is_array($context)) {
                $value = (array) $value;
                foreach ($this->additionalFields as $field) {
                    $value[] = $context[$field];
                }
            }
            $value = $this->cleanSearchValue($value);
            $match = $this->objectRepository->findOneBy($value);
    
            if (is_object($match) && $match->{$this->id_getter}() != $this->id) {
                if (is_array($value)) {
                    $str = '';
                    foreach ($value as $campo) {
                        if ($str != '') {
                            $str .= ', ';
                        }
                        $str .= $campo;
                    }
                    $value = $str;
                }
                $this->error(self::ERROR_OBJECT_FOUND, $value);
                return false;
            }
            return true;
        }
    }
    

    NoEntityExists验证器:

    use Zend\Validator\Exception\InvalidArgumentException;
    use DoctrineModule\Validator\NoObjectExists;
    
    class NoEntityExists extends NoObjectExists
    {
        private $additionalFields = null;
        public function __construct(array $options)
        {
            parent::__construct($options);
            if (isset($options['additionalFields'])) {
                $this->additionalFields = $options['additionalFields'];
            }
        }
        public function isValid($value, $context = null)
        {
            if (null != $this->additionalFields && is_array($context)) {
                $value = (array) $value;
                foreach ($this->additionalFields as $field) {
                    $value[] = $context[$field];
                }
            }
            $value = $this->cleanSearchValue($value);
            $match = $this->objectRepository->findOneBy($value);
            if (is_object($match)) {
                if (is_array($value)) {
                    $str = '';
                    foreach ($value as $campo) {
                        if ($str != '') {
                            $str .= ', ';
                        }
                        $str .= $campo;
                    }
                    $value = $str;
                }
                $this->error(self::ERROR_OBJECT_FOUND, $value);
                return false;
            }
            return true;
        }
    }
    

    将此验证器与inputFilter一起使用:

    在我的自定义中input filters,我添加了两个方法:一个用于附加NoEntityExists验证器,另一个用于附加NoOtherEntityExists验证器:

    /**
     * Appends doctrine's NoObjectExists Validator for Add FORM .
     *
     * @param \Doctrine\ORM\EntityRepository $repository
     * @return \Zend\InputFilter\InputFilter
     */
    public function appendAddValidator(EntityRepository $repository)
    {
        $this->add($this->getFactory()->createInput( array(
                'name' => 'libellesite', //unique field name
                'validators' => array(
                        array(
                                'name' => 'Netman\Form\NoEntityExists',//use namespace
                                'options' => array(
                                        'object_repository' => $repository,
                                        'fields' => 'libellesite',
                                        'messages' => array(
                                        'objectFound' => 'custom message here'
                                        ),
                                ),
                        ),
                )
        )));
        return $this;
    }
    
    /**
     * Appends doctrine's NoObjectExists Validator for EDIT FORM.
     *
     * @param \Doctrine\ORM\EntityRepository $repository
     * @return \Zend\InputFilter\InputFilter
     */
    public function appendEditValidator(EntityRepository $repository, $id)
    {
        $this->add($this->getFactory()->createInput( array(
                'name' => 'libellesite',
                'validators' => array(
                        array(
                                'name' => 'Netman\Form\NoOtherEntityExists',
                                'options' => array(
                                        'object_repository' => $repository,
                                        'fields' => 'libellesite',
                                        'id'=>$id, //
                                        'id_getter'=>'getCodesite',//getter for ID
                                        'messages' => array(
                                        'objectFound' => 'custom message here'
                                        ),
                                ),
                        ),
                )
        )));
        return $this;
    }
    

    控制器:

    addAction:

    $repository = $em->getRepository('Entity\Name');  
    $form->setInputFilter($filter->appendAddValidator($repository));
    

    editAction:

    $id = $this->params('id', null);
    $repository = $em->getRepository('Entity\Name');  
    $form->setInputFilter($filter->appendEditValidator($repository,$id));
    

    2023-02-09 11:32 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有