【问题标题】:zf2: how to inject service into custom form validator from listenerzf2:如何从侦听器将服务注入自定义表单验证器
【发布时间】:2015-12-01 11:35:08
【问题描述】:

我正在尝试在新用户 (ZfcUser) 注册到系统时应用自定义验证器。验证器应该使用服务。我正在尝试通过工厂注入服务,但看起来工厂中的代码永远没有机会运行和注入服务。

这是我的代码:

<?php
/**
 * OnlineFieldEvaluation - RegisterFilterListener.php
 *
 * Initial version by: vraskin
 * Initial version created on: 9/3/15
 */

namespace OFEZfcUser\Listener;


use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\Event;


class RegisterFilterListener extends AbstractListenerAggregate {

    public function attach(EventManagerInterface $events)
    {
        $sharedManager = $events->getSharedManager();
        $this->listeners[] = $sharedManager->attach('ZfcUser\Form\RegisterFilter', 'init', array($this, 'onInit'));
    }

    public function onInit(Event $e)
    {

        $filter = $e->getTarget();

        $filter->add(array(
            'name' => 'email',
            'required' => true,
            'validators' => array(
                array(
                    'name' => 'OFEZfcUser\Validators\OFEtoSFEmailValidator',
                    'options' => null,
                ),
            ),
        ));
    }

} 

Module.php

     public function getValidatorConfig() {
        return array(
//            'invokables' => array(
//                'OFEZfcUser\Validators\OFEtoSFEmailValidator' => 'OFEZfcUser\Validators\OFEtoSFEmailValidator'
//            ),
            'factories' => array(
//                'OFEZfcUser\Validators\OFEtoSFEmailValidator' => 'OFEZfcUser\Factories\OFEValidatorFactory',

                'OFEZfcUser\Validators\OFEtoSFEmailValidator' =>  function ($serviceManager) {
                    $ofeService =  $serviceManager->getServiceLocator()->get('OFEClientForRestSalesforceAPIService');
                    $ofeValidator = new \OFEZfcUser\Validators\OFEtoSFEmailValidator();
                    $ofeValidator->setOFEService($ofeService);

                    return $ofeValidator;
                }

            )
        );
    }

验证器

  <?php

namespace OFEZfcUser\Validators;

use Zend\Validator\AbstractValidator;

class OFEtoSFEmailValidator extends AbstractValidator{

    const NOTSFEMAIL = 'NOTSFEMAIL';

    protected $messageTemplates = array(
        self::NOTSFEMAIL => 'This user is not registered in our system. Please, contact a field administration',
    );

    protected $service;

    public function __construct(array $options = array()){
        parent::__construct($options);
    }

    public function isValid($value,$context = null){
        $this->setValue($value);
        if (!$this->validateSFEmail($value, $context['userRole'])) {
            $this->error(self::NOTURL);
            return false;
        }
        return true;
    }

    private function validateSFEmail($email, $userRole) {

    echo $this->service->greet();

    $sfRes = $this->service->isStudentExist($email, $userRole);

    var_dump( $sfRes );


    if ($sfRes != true && $sfRes != false ) {
        return false;
    } else {
        return $sfRes;
    }
}

    public function setOFEService($service)
    {
        $this->service = $service;
    }

} 

这是我得到的错误:$this->service 等于 null,并且在我看不到它正在调用工厂代码期间。但是验证器以某种方式被实例化。

致命错误:调用 C:\dev\projects\OnlineFieldEvaluation\module\OnlineFieldEvaluation\src\OFEZfcUser\Validators\OFEtoSFEmailValidator.php 中非对象的成员函数 greet() 第 50 行

编辑 2

我还尝试使用 validator\Callable 来调用验证器工厂,这样它就可以将服务注入验证器实例。但工厂也从未以这种方式被发现。

Module.php

 public function getValidatorConfig()
{
    return [
        'factories' => [
            'OFEtoSFEmailValidator' => function ($serviceManager) {
                $ofeService = $serviceManager->getServiceLocator()->get('OFEClientForRestSalesforceAPIService');
                $ofeValidator = new \OFEZfcUser\Validators\OFEtoSFEmailValidator(['service' => $ofeService]);

                return $ofeValidator;
            }

        ]
    ];
}

然后我尝试使用 Validator\Callable 从 RegisterFileterListener 实例化它

  namespace OFEZfcUser\Listener;

use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\Event;


class RegisterFilterListener extends AbstractListenerAggregate
{

    public function attach(EventManagerInterface $events)
    {
        $sharedManager = $events->getSharedManager();
        $this->listeners[] = $sharedManager->attach('ZfcUser\Form\RegisterFilter', 'init', array($this, 'onInit'));
    }

    public function onInit(Event $e)
    {
        $filter = $e->getTarget();

        $valid = new \Zend\Validator\Callback('OFEtoSFEmailValidator');

        $validators = $filter->get('email')->getValidatorChain();

        $factory = new \OFEZfcUser\Factories\OFEValidatorFactory();

        $filter->add(array(
            'name' => 'email',
            'required' => true,
            'validators' => array(
                array(
                    'name' => 'Callback',
                    'options' => array(
                        'messages' => array(
                            \Zend\Validator\Callback::INVALID_VALUE => 'My custom message',
                            \Zend\Validator\Callback::INVALID_CALLBACK => 'My custom message'
                        ),
                        'callback' => array($factory, 'createService')
                    )
                ),
            ),
        ));
    }

} 

【问题讨论】:

  • 您在验证器isValid() 方法中调用if (!$this-&gt;validateSFEmail()),但您似乎没有声明该方法。也许您的意思是调用服务方法? if (!$this-&gt;service-&gt;validateSFEmail())
  • @Crisp,对不起。我不小心删除了部分代码。我现在添加了它,我还添加了错误输出和更多解释。谢谢。

标签: php zend-framework2 zend-validate zfcuser


【解决方案1】:

我放弃了尝试从过滤器上的侦听器调用验证器工厂。我从 ZfcUser 复制了 RegisterFilter,并修改了它的构造函数以接受第三个验证器。然后我从 module.config.php 文件中调用验证器工厂,并将其注入到我的自定义过滤器中。

    'service_manager' => array(

        'factories' => array(
            'zfcuser_register_form' => function ($sm) {
                $options = $sm->get('zfcuser_module_options');
                $validators = $sm->get('ValidatorManager');
                $ofeVal = $validators->get('MyOFEtoSFEmailValidator');

                $registerFilter = new ZfcUserRegisterFilterExtension(
                    new Validator\NoRecordExists(array(
                        'mapper' => $sm->get('zfcuser_user_mapper'),
                        'key' => 'email'
                    )),
                    new Validator\NoRecordExists(array(
                        'mapper' => $sm->get('zfcuser_user_mapper'),
                        'key' => 'username'
                    )),
//                    My custom Validator to connect to SF and validate email
                    $ofeVal,
                    $options
                );

                $form = new \OFEZfcUser\Form\ZfcUserRegisterExtension(null, $options);

                $form->setInputFilter($registerFilter);

                return $form;
            },

        )),

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 2012-09-15
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    相关资源
    最近更新 更多