2015-09-05 76 views
1

我想在新用户(ZfcUser)注册到系统时应用自定义验证程序。验证器应该使用服务。我试图通过工厂注入服务,但它看起来像工厂中的代码永远不会有机会运行并注入服务。zf2:如何注入服务到来自监听器的自定义表单验证程序

这里是我的代码:

<?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,并且在我看不到它正在调用Factory代码。但验证器以某种方式实例化。

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

enter image description here

EDIT 2

我还试图用验证\赎回调用验证器工厂,因此它可以注入一个服务为验证实例。但工厂从来没有这样找到过。

Module.php

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

       return $ofeValidator; 
      } 

     ] 
    ]; 
} 

然后我试图从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') 
        ) 
       ), 
      ), 
     )); 
    } 

} 
+0

您在验证器的isValid()方法中调用了'if(!$ this-> validateSFEmail())',但您似乎没有声明该方法。也许你打算调用服务方法? '如果(!$ this-> service-> validateSFEmail())' – Crisp

+0

@Crisp,对不起。我不小心删除了部分代码。我现在添加了它,并且还添加了错误输出和更多解释。谢谢。 – vlr

回答

0

实例化它,我放弃了试图从听众调用验证器厂在过滤器上。我从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; 
      }, 

     )),