2012-11-20 22 views
9

मैं उपयोगकर्ता पंजीकरण फॉर्म बनाने की कोशिश कर रहा हूं जो पासवर्ड फ़ील्ड की जटिलता की जांच करता है। मैंने documentation के अनुसार ऐसा करने के लिए एक कस्टम सत्यापनकर्ता लिखा है। यह फ़ाइल उपयोगकर्ता \ src \ उपयोगकर्ता \ Validator पर मेरे 'उपयोगकर्ता' मॉड्यूल में रहती है।फॉर्म के लिए ज़ेंड फ्रेमवर्क 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 ... 
} 
} 

मेरी समस्या मेरे उपयोगकर्ता पंजीकरण फॉर्म में इस सत्यापनकर्ता का उपयोग करने की कोशिश में उत्पन्न होती है। मैंने ServiceManager को Module.php में कॉन्फ़िगर करके सत्यापनकर्ता को जोड़ने का प्रयास किया।

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

हालांकि, जब मैं फॉर्म तक पहुंचता हूं और सबमिट बटन दबाता हूं, तो मुझे सर्विस नॉटफाउंड अपवाद मिलता है।

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

क्या मेरी सेवा प्रबंधक कॉन्फ़िगरेशन में कोई समस्या है? मुझे यह भी यकीन नहीं है कि कस्टम वैधानिक का उपयोग करने के लिए यह सही तरीका है या नहीं। मुझे ZF1 का उपयोग करके बहुत सारे उदाहरण मिल गए हैं, लेकिन जेडएफ 2 के लिए प्रलेखन और उदाहरण जो मैंने पाया है, कभी भी फॉर्मेट के साथ अपने एकीकरण को संबोधित करने के लिए सत्यापनकर्ता के लेखन से परे नहीं बढ़ता है। किसी भी सलाह की सराहना की जाएगी।

उत्तर

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

मेरा मानना ​​है कि एक और विकल्प सत्यापनकर्ता के रूप में पूरी तरह से योग्य वर्ग के नाम का उपयोग करने के लिए है नाम (यानी: "उपयोगकर्ता \ Validator \ passwordStrength" बस "passwordStrengthValidator" के बजाय), हालांकि मैंने कभी इसे स्वयं का प्रयास नहीं किया है।

+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 इस समाधान ... कोशिश कर सकते हैं।

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

यह मेरे लिए काम करता है।

मार्टिन

1

रूफिनस समाधान आकर्षण की तरह काम करता है।

1) module.config.php

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

2) पथ आवेदन में: चरणों मैं गया (मेरे मामले में एक यूआरएल सत्यापनकर्ता अगर वेब वास्तव में मौजूद है की जाँच करने के लिए) एक कस्टम सत्यापनकर्ता उपयोग करने के लिए पीछा किया /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 ए) यदि आप इसे ऐप में कहीं भी इस्तेमाल करना चाहते हैं (यानी। एक नियंत्रक कार्रवाई) के अंदर, आप ValidatorManager प्लगइन से प्राप्त कर सकते हैं:

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

क्या होगा यदि आप एक सेवा विधि में बैठे वास्तविक यूआरएल चेक (इन कर्ल कॉल) चाहते हैं? इस वैधकर्ता को सेवा इंजेक्ट करने का कोई तरीका? या, यदि नहीं, तो इसे वैधकर्ता के भीतर से तुरंत चालू करने के लिए? – Stephane

0

हाँ, यह के रूप में कोंटी द्वारा कहा गया या मामले में कारखाने के रूप में आप में उदाहरण के लिए सेवा प्रबंधक, या सिद्धांत इकाई प्रबंधक इंजेक्षन करने की जरूरत है invokable हो सकता है उदाहरण के बाद। यह बहुत ही सुरुचिपूर्ण समाधान इस तरह से है:

'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; 
      }, 
     ), 
    ),