2012-11-20 2 views
9

암호 필드의 복잡성을 검사하는 사용자 등록 양식을 만들려고합니다. documentation에 따라이 작업을 수행하는 사용자 정의 유효성 검사기를 작성했습니다. 이 파일은 User \ src \ User \ Validator의 'User'모듈에 있습니다.젠드 프레임 워크 2 폼용 사용자 정의 검사기

<?php 

namespace User\Validator; 

use Zend\Validator\AbstractValidator; 

class PasswordStrength extends AbstractValidator { 

const LENGTH = 'length'; 
const UPPER = 'upper'; 
const LOWER = 'lower'; 
const DIGIT = 'digit'; 

protected $messageTemplates = array(
    self::LENGTH => "'%value%' must be at least 6 characters long", 
    self::UPPER => "'%value% must contain at least one uppercase letter", 
    self::LOWER => "'%value% must contain at least one lowercase letter", 
    self::DIGIT => "'%value% must contain at least one digit letter" 
); 

public function isValid($value) { 
    ... validation code ... 
} 
} 

내 사용자 등록 양식에서이 유효성 검사기를 사용하려고 할 때 문제가 발생합니다. Validator를 Module.php에서 구성하여 ServiceManager에 추가하려고했습니다.

public function getServiceConfig() { 
    return array(
     'invokables' => array(
      'PasswordStrengthValidator' => 'User\Validator\PasswordStrength' 
     ), 
    ); 
} 

그런 다음 User.php의 입력 필터에 추가했습니다.

public function getInputFilter() { 
    if (!$this->inputFilter) { 
     $inputFilter = new InputFilter(); 
     $factory  = new InputFactory(); 

     $inputFilter->add($factory->createInput(array(
      'name'  => 'username', 
      'required' => true, 
      'validators' => array(
       array(
        'name' => 'StringLength', 
        'options' => array(
         'encoding' => 'UTF-8', 
         'min'  => 1, 
         'max'  => 100, 
        ), 
       ), 
      ), 
     ))); 

     $inputFilter->add($factory->createInput(array(
      'name'  => 'password', 
      'required' => true, 
      'validators' => array(
       array(
        'name' => 'PasswordStrengthValidator', 
       ), 
      ), 
     ))); 

     $this->inputFilter = $inputFilter; 
    } 

    return $this->inputFilter; 
} 

그러나 양식에 액세스하여 제출 단추를 누르면 ServiceNotFoundException이 발생합니다.

Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for PasswordStrengthValidator 

ServiceManager 구성에 문제가 있습니까? 나는 이것이 처음부터 사용자 정의 유효성 검사기를 사용하는 적절한 방법인지 확실하지 않습니다. 나는 ZF1을 사용하여 많은 예제를 발견했지만 ZF2에 대한 문서와 예제는 폼과의 통합을 다루기 위해 유효성 검사기를 작성하는 것 이상으로 확장하지 않습니다. 모든 조언은 크게 감사 할 것입니다.

답변

3

예제에서 사용하려고하는 "짧은 이름"유효성 검사기로드는 유효성 검사기 플러그인 관리자 (Zend\Validator\ValidatorPluginManager)로 짧은 이름/별칭을 먼저 등록한 경우에만 작동합니다.

폼 필터 개체를 만들 때 필요한 사용자 지정 유효성 검사기의 인스턴스를 삽입하면됩니다. 이것은 ZfcUser이를 수행하는 방법 :

// Service factory definition from Module::getServiceConfig 
'zfcuser_register_form' => function ($sm) { 
    $options = $sm->get('zfcuser_module_options'); 
    $form = new Form\Register(null, $options); 
    $form->setInputFilter(new Form\RegisterFilter(
     new Validator\NoRecordExists(array(
      'mapper' => $sm->get('zfcuser_user_mapper'), 
      'key' => 'email' 
     )), 
     new Validator\NoRecordExists(array(
      'mapper' => $sm->get('zfcuser_user_mapper'), 
      'key' => 'username' 
     )), 
     $options 
    )); 
    return $form; 
}, 

출처 : 여기 https://github.com/ZF-Commons/ZfcUser/blob/master/Module.php#L100

ZfcUser\Validator\NoRecordExists 검증 인스턴스 (이메일 용과 자명 하나)를위한 입력 필터 객체의 생성자에 주입 등록 양식 (ZfcUser\Form\RegisterFilter).

다음, ZfcUser\Form\RegisterFilter 클래스 내부의 유효성 검사기는 요소 정의에 추가됩니다

$this->add(array(
    'name'  => 'email', 
    'required' => true, 
    'validators' => array(
     array(
      'name' => 'EmailAddress' 
     ), 
     // Constructor argument containing instance of the validator 
     $emailValidator 
    ), 
)); 

출처 : https://github.com/ZF-Commons/ZfcUser/blob/master/src/ZfcUser/Form/RegisterFilter.php#L37

나는 다른 대안이 검증으로 정규화 된 클래스 이름을 사용하는 것입니다 생각 이름 (예 : "PasswordStrengthValidator"대신 "User \ Validator \ PasswordStrength").이 시도는 본 적이 없습니다.

+0

허, 나는 그것을 내가 등록한 이름과 관련이 있다는 것을 몰랐습니다 ... 실제로 마지막 제안을 시도해 보았습니다. ServiceManager는 정규화 된 클래스 이름으로 트릭을 수행했습니다. 당신의 도움을 주셔서 감사합니다! –

3

invokable 구성을 제거하십시오.

그리고 귀하의 유효성 검사기 설정을 수정 : 나를 위해

$inputFilter->add($factory->createInput(array(
      'name'  => 'password', 
      'required' => true, 
      'validators' => array(
       array(
        'name' => 'User\Validator\PasswordStrength', 
       ), 
      ), 
     ))); 

작업 할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 나는 이것이 가능할 것이라고 믿지만, 호출 가능한 구성을 제거하면 유효성 검사기가 ServiceManager에 등록되지 않습니다. 괜찮습니다.하지만이 작업에 ServiceManager를 사용하는 것이 좋습니다. –

5

당신은 '유효성 검사기'Module.php뿐만 기능 getValidatorConfig 또는 키에 module.config.php에서 검증 registrer이 해결 ... 을 시도 할 수 있습니다.

당신의 User.php에서 다음
public function getValidatorConfig() { 
    return array(
    'invokables' => array(
     'PasswordStrengthValidator' => 'User\Validator\PasswordStrength' 
    ), 
); 
} 

,이 시도 : 를 이것은 나를 위해 작동

$validatorManager = $this->getServiceLocator()->get('ValidatorManager'); 
// here you can test $validatorManager->get('PasswordStrengthValidator'); 

$validatorChain = new ValidatorChain(); 
$validatorChain->setPluginManager($validatorManager); 

$inputFilter = new InputFilter(); 
$inputFilter->getFactory()->setDefaultValidatorChain($validatorChain); 

을 (하지만 서비스 로케이터에 액세스 할 수 있어야합니다, 당신은 등 UserFactory에서 주입 할 수 있습니다).

마틴

1

Rufinus 솔루션은 매력처럼 작동합니다.

1) 경로 응용 프로그램에서 module.config.php

'validators' => array(
    'invokables' => array(
     'UrlValidator' => 'Application\Validators\UrlValidator' 
    ), 
) 

2)에서 : 단계는 내가 (웹이 실제로 존재하는 경우 제 경우에 URL의 유효성이 확인) 된 사용자 정의 유효성 검사기를 사용하는 다음 형태 /src/Application/Validators/UrlValidator.php

namespace Application\Validators; 
use Zend\Validator\AbstractValidator;      
class UrlValidator extends AbstractValidator{ 
    const NOTURL = 'NOTURL'; 

    protected $messageTemplates = array(
     self::NOTURL => 'Value should be a valid URL', 
    ); 

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

    public function isValid($value){ 
     $this->setValue($value);  
     if (!$this->validateurl($value)) { 
      $this->error(self::NOTURL); 
      return false; 
     } 
     return true; 
    } 
    private function validateurl($url) { 
     $ch = curl_init(); // initialize curl handle 
     curl_setopt($ch, CURLOPT_URL, $url); // set url to post to 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
     curl_setopt($ch, CURLOPT_HEADER, 1); 
     $result = curl_exec($ch); 

     $info = curl_getinfo($ch); 
     $code = $info['http_code']; 
     curl_close($ch); 

     if ($code == substr($code, 0, 1) || substr($code, 0, 1) == '4' || substr($code, 0, 1) == '5') { 
      return false; 
     } else { 
      return true; 
     } 
    } 
} 

3)

$inputFilter->add($factory->createInput(array(
        'name' => 'url',      
        'validators' => array(
         array(
          'name' => 'NotEmpty', 
          'options' => array(
           'messages' => array(
            'isEmpty' => 'URL is required' 
           ) 
          ) 
         ), 
         array(
          'name'=>'Application\Validators\UrlValidator' 
         ) 
        ) 
     ))); 

Extr a) 앱의 어디서나 사용하고 싶을 때 (예 : 컨트롤러 액션) 내부에, 당신은 ValidatorManager 플러그인에서 검색 할 수 콘티에 의해 진술 또는 경우에 공장으로 당신이 예를 들어 서비스 관리자 또는 교리 엔티티 매니저를 주입하기 위해 필요로하는

$urlValidator = $this->getServiceLocator()->get('ValidatorManager')->get('UrlValidator'); 
+0

실제 URL 확인 (이러한 컬 호출)을 서비스 메소드에 넣으려면 어떨까요? 이 유효성 검사기에 서비스를 삽입하는 방법은 무엇입니까? 그렇지 않은 경우 유효성 검사기에서 인스턴스화하려면? – Stephane

0

예, 그것은 호출 가능한 일 수있다 다음 예제를 참조하십시오. 이것은 매우 우아한 해결책입니다.