10

パスワードフィールドの複雑さをチェックするユーザー登録フォームを作成しようとしています。ドキュメントに従ってこれを行うためのカスタムバリデーターを作成しました。このファイルは、User \ src \ User\Validatorの「User」モジュールにあります。

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

ユーザー登録フォームでこのバリデーターを使用しようとすると、問題が発生します。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のドキュメントと例は、フォームなどとの統合に対処するためのバリデーターの記述を超えることはありません。アドバイスをいただければ幸いです。

4

5 に答える 5

6

この回避策を試すことができます...Module.phpでバリデーターを登録しますが、関数getValidatorConfigまたはmodule.config.phpのキー「validators」で登録します。

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

次に、User.phpでこれを試してください:(ただし、サービスロケーターにアクセスできる必要があります。UserFactoryなどから挿入できます)。

$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);

これは私のために働きます。

マーティン

于 2013-03-22T02:10:22.377 に答える
5

例で使用しようとしている「ショートネーム」バリデーターのロードは、そのショートネーム/エイリアスを最初にバリデータープラグインマネージャー()に登録した場合にのみ機能しますZend\Validator\ValidatorPluginManager

これに代わる方法の1つ(および私が行う方法)は、フォームフィルターオブジェクトを作成するときに必要なカスタムバリデーターのインスタンスを挿入することです。これは、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

ここでは、2つのZfcUser\Validator\NoRecordExistsバリデーターインスタンス(1つは電子メール用、もう1つはユーザー名用)が、登録フォーム()の入力フィルターオブジェクトのコンストラクターに挿入されます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

もう1つの方法は、完全修飾クラス名をバリデーター名として使用することです(つまり、「PasswordStrengthValidator」ではなく「User \ Validator \ PasswordStrength」)。これを自分で試したことはありません。

于 2012-11-21T19:21:05.037 に答える
3

呼び出し可能な構成を削除します。

そして、バリデーターの設定を次のように変更します。

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

私のために働いてください。

于 2012-11-24T13:34:23.690 に答える
1

Rufinusソリューションは魅力のように機能します。カスタムバリデーターを使用するために私が従った手順は次のとおりです(私の場合、Webが実際に存在するかどうかを確認するためのURLバリデーター)。

1)module.config.php内

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

2)パス内Application / 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'
                        )
                    )
        )));

追加)アプリ内のどこか(つまり、コントローラーアクション内)で使用する場合は、ValidatorManagerプラグインから取得できます。

$urlValidator = $this->getServiceLocator()->get('ValidatorManager')->get('UrlValidator');
于 2014-02-06T07:59:42.593 に答える
0

はい、Contiが述べているように、またはたとえばサービスマネージャー、または次の例ではDoctrineエンティティマネージャーを注入する必要がある場合はファクトリとして呼び出すことができます。このように非常にエレガントなソリューションです。

 'validators' => array(
        'invokables' => array(
            //'emailExist' => 'Application\MyValidation\EmailExistValidator',
        ),
        'factories' => array(
            'emailExist' => function ($vm) {
                $serviceLocator = $vm->getServiceLocator();
                $emailExistValidator = new \Application\MyValidation\EmailExistValidator();
                $doctrineEntityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
                $emailExistValidator->setObjectManager($doctrineEntityManager);
                return $emailExistValidator;
            },
        ),
    ),
于 2017-09-23T19:05:21.907 に答える