可以创建一个工厂来实例化自定义表单验证器吗? [英] Possible to create a factory to instantiate custom Form validators?

查看:20
本文介绍了可以创建一个工厂来实例化自定义表单验证器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(使用 Zend 框架 2.2.4)

(using Zend Framework 2.2.4)

我的验证器工厂在验证时似乎并不存在".如果我尝试从包含表单的控制器实例化验证器,则相反,它可以正常工作:

My validator factory, doesn't seem to "exist" at validation time. If I attempt to instantiate the validator from the controller in which the form is housed, it conversely works fine:

这有效...

$mycustomvalidator = $this->getServiceLocator()
    ->get('ValidatorManager')
    ->get('LDP_PinAvailable');

以下是代码中其他设置的方式,我似乎无法找到问题,希望避免打开 ZF2 源代码来理解.从文档来看,这似乎是正确的.

Here's how things are set up otherwise in the code, I can't seem to find the problem, and was hopeful to avoid opening up ZF2 source to understand. By way of documentation, it seems right.

模块配置

public function getValidatorConfig()
{
    return array(
       'abstract_factories' => array(
           '\LDP\Form\Validator\ValidatorAbstractFactory',
       ),
    );
}

工厂课堂

namespace LDP\Form\Validator;

use Zend\ServiceManager\AbstractFactoryInterface,
    Zend\ServiceManager\ServiceLocatorInterface;

class ValidatorAbstractFactory implements AbstractFactoryInterface
{
    public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
    {
        return stristr($requestedName, 'LDP_PinAvailable') !== false;
    }


    public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
    {
        // baked in for sake of conversation
        $validator = new \LDP\Form\Validator\PinAvailable();

        if( $validator instanceof DatabaseFormValidatorInterface )
            $validator->setDatabase( $locator->get('mysql_slave') );

        return $validator;
    }
}

自定义验证器

namespace LDP\Form\Validator;

class PinAvailable extends \Zend\Validator\AbstractValidator implements DatabaseFormValidatorInterface
{

    /**
     * @var \Zend\Db\Sql\Sql
     */
    private $database;

    public function setDatabase( \Zend\Db\Sql\Sql $db )
    {
        $this->database = $db;
    }


    public function isValid( $value )
    {
        $DBA = $this->database->getAdapter();
        // do the mixed database stuff here
        return true;
    }
}

最后,数组的表单字段验证器配置部分:

Lastly, the form field validator config part of the array:

'pin' => array(
    'required' => true,
        'filters'  => array(
            array('name' => 'alnum'),
            array('name' => 'stringtrim'),
        ),
        'validators' => array(
            array( 'name' => 'LDP_PinAvailable' )
        ),
    ),
),

将它们拼凑在一起,加载表单,并在提交时使用下面的堆栈跟踪:

Piecing it all together, the form loads, and when submitted, it does with the stack trace below:

2013-10-28T17:09:35-04:00 ERR (3): Exception:
1: Zend\Validator\ValidatorPluginManager::get was unable to fetch or create an instance for LDP_PinAvailable
Trace:
#0 /Users/Saeven/Documents/workspace/Application/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php(103): Zend\ServiceManager\ServiceManager->get('LDP_PinAvailabl...', true)
#1 /Users/Saeven/Documents/workspace/Application/vendor/zendframework/zendframework/library/Zend/Validator/ValidatorChain.php(82): Zend\ServiceManager\AbstractPluginManager->get('LDP_PinAvailabl...', Array)

推荐答案

继续挖掘,我找到了问题所在.它在 Zend\Validator\ValidatorChain 大约第 80 行提取到这些行:

Digging some more, I've found the problem. It distilled to these lines in Zend\Validator\ValidatorChain circa line 80:

public function plugin($name, array $options = null)
{
    $plugins = $this->getPluginManager();
    return $plugins->get($name, $options);
} 

上下文中没有可用的插件管理器.

There was no plugin manager available in context.

在控制器中准备表单时,谷歌搜索了大约三秒钟才发现必须这样做:

It took about three seconds of Googling to find that I had to do this when I prepared the form in the controller:

 $validators = $this->getServiceLocator()->get('ValidatorManager');
 $chain      = new ValidatorChain();
 $chain->setPluginManager( $validators );
 $form->getFormFactory()->getInputFilterFactory()->setDefaultValidatorChain( $chain );

希望这对其他人有所帮助.以这种方式设置时,您可以使用常规的旧类名,无需扭曲类名.

Hopefully this helps someone else. You are able to use regular old classnames when setting it up this way, no need to warp the classnames.

这篇关于可以创建一个工厂来实例化自定义表单验证器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆