简体   繁体   English

zf2:如何将服务从侦听器注入到自定义表单验证器中

[英]zf2: how to inject service into custom form validator from listener

I am trying to apply custom validator when a new user (ZfcUser) registers to the system. 我正在尝试在新用户(ZfcUser)注册到系统时应用自定义验证器。 The validator supposed to use a service. 验证者应该使用服务。 I am trying to inject service through the factory, but it looks like code in the factory never get a chance to run and to inject a service. 我试图通过工厂注入服务,但是看来工厂中的代码永远都没有机会运行和注入服务。

Here is my code : 这是我的代码:

<?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 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;
                }

            )
        );
    }

Validator 验证器

  <?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;
    }

} 

And this is the error I am getting: $this->service is equal to null, and during I do not see it is calling Factory code. 这就是我得到的错误:$ this-> service等于null,在此期间我没有看到它正在调用Factory代码。 But validator is instantiated somehow. 但是验证器以某种方式实例化。

Fatal error: Call to a member function greet() on a non-object in C:\\dev\\projects\\OnlineFieldEvaluation\\module\\OnlineFieldEvaluation\\src\\OFEZfcUser\\Validators\\OFEtoSFEmailValidator.php on line 50 致命错误:在第50行的C:\\ dev \\ projects \\ OnlineFieldEvaluation \\ module \\ OnlineFieldEvaluation \\ src \\ OFEZfcUser \\ Validators \\ OFEtoSFEmailValidator.php的非对象上调用成员函数greet()

在此处输入图片说明

EDIT 2 编辑2

I also tried to use validator\\Callable to call validator factory, so it could inject a service into validator instance. 我还尝试使用Validator \\ Callable来调用验证器工厂,因此它可以将服务注入到验证器实例中。 But factory was never found that way either. 但是工厂也从来没有那样被发现过。

Module.php Module.php

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

                return $ofeValidator;
            }

        ]
    ];
}

And then I am trying to instantiate it from RegisterFileterListener with Validator\\Callable 然后我尝试使用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')
                    )
                ),
            ),
        ));
    }

} 

I gave up trying to invoke validator factory from a listener on a filter. 我放弃了尝试从筛选器上的侦听器调用验证器工厂的尝试。 I copied RegisterFilter from ZfcUser, and modified its constructor to accept a third validator. 我从ZfcUser复制了RegisterFilter,并修改了其构造函数以接受第三个验证器。 Then I invoked validator factory from module.config.php file, and injected it to my custom filter. 然后,我从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;
            },

        )),

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM