2015-09-05 72 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; 
      }, 

     )),