संपादित करें में फ़ॉर्म इनपुट/तत्व कैसे बनाएं: मेरा मुख्य प्रश्न अब बन गया है 'मैं अपने फॉर्म, तत्व और इनपुट कक्षाओं के हाथों में कुछ स्वच्छ तरीके से सिद्धांत प्रबंधक प्रबंधक के साथ सेवा प्रबंधक कैसे प्राप्त करूं?' पूर्ण पोस्ट देखने के लिए पढ़ें।ZF2
मैं यहां उदाहरण के लिए कोशिश करने और पूछने जा रहा हूं इसलिए मेरे साथ भालू। मुझे बताएं कि मैं गलत/सही कहां जा रहा हूं या जहां मैं
सुधार कर रहा हूं, मैं पंजीकरण फॉर्म बनाने की कोशिश कर रहा हूं। मैं ZfcUser मॉड्यूल का उपयोग कर सकता हूं लेकिन मैं इसे अपने आप करना चाहता हूं। मैं ZF2 का उपयोग Doctrine2 के साथ भी कर रहा हूं ताकि मुझे उस मॉड्यूल से थोड़ा दूर ले जाया जा सके।
मेरे रणनीति थी यह,
बुलाया पंजीकरण फार्म
प्रत्येक तत्व के लिए अलग 'तत्व' कक्षाएं बनाएं एक रूप कक्षा बनाएं प्रत्येक तत्व का एक इनपुट विनिर्देश
होगा चूंकि प्रत्येक तत्व फॉर्म से एक अलग वर्ग है, इसलिए मैं इकाई को अलग से परीक्षण कर सकता हूं।
सभी ठीक लग रहा था जब तक मैं अपना उपयोगकर्ता नाम तत्व यह है कि जाँच करेगा कि उपयोगकर्ता नाम नहीं है अभी तक उपयोग करने के लिए एक सत्यापनकर्ता जोड़ना चाहते थे।
यहाँ कोड अब तक
namepsace My\Form;
use Zend\Form\Form,
Zend\Form\Element,
Zend\InputFilter\Input,
Zend\InputFilter\InputFilter,
/**
* Class name : Registration
*/
class Registration
extends Form
{
const USERNAME = 'username';
const EMAIL = 'email';
const PASSWORD = 'password';
const PASS_CONFIRM = 'passwordConfirm';
const GENDER = 'gender';
const CAPTCHA = 'captcha';
const CSRF = 'csrf';
const SUBMIT = 'submit';
private $captcha = 'dumb';
public function prepareForm()
{
$this->setName('registration');
$this->setAttributes(array(
'method' => 'post'
));
$this->add(array(
'name' => self::USERNAME,
'type' => '\My\Form\Element\UsernameElement',
'attributes' => array(
'label' => 'Username',
'autofocus' => 'autofocus'
)
)
);
$this->add(array(
'name' => self::SUBMIT,
'type' => '\Zend\Form\Element\Submit',
'attributes' => array(
'value' => 'Submit'
)
));
}
}
मैं एक बहुत मुझे लगता है कि जरूरी नहीं है हटा दिया है। नीचे मेरा उपयोगकर्ता नाम तत्व है।
namespace My\Form\Registration;
use My\Validator\UsernameNotInUse;
use Zend\Form\Element\Text,
Zend\InputFilter\InputProviderInterface,
Zend\Validator\StringLength,
Zend\Validator\NotEmpty,
Zend\I18n\Validator\Alnum;
/**
*
*/
class UsernameElement
extends Text
implements InputProviderInterface
{
private $minLength = 3;
private $maxLength = 128;
public function getInputSpecification()
{
return array(
'name' => $this->getName(),
'required' => true,
'filters' => array(
array('name' => 'StringTrim')
),
'validators' =>
array(
new NotEmpty(
array('mesages' =>
array(
NotEmpty::IS_EMPTY => 'The username you provided is blank.'
)
)
),
new AlNum(array(
'messages' => array(Alnum::STRING_EMPTY => 'The username can only contain letters and numbers.')
)
),
new StringLength(
array(
'min' => $this->getMinLength(),
'max' => $this->getMaxLength(),
'messages' =>
array(
StringLength::TOO_LONG => 'The username is too long. It cannot be longer than ' . $this->getMaxLength() . ' characters.',
StringLength::TOO_SHORT => 'The username is too short. It cannot be shorter than ' . $this->getMinLength() . ' characters.',
StringLength::INVALID => 'The username is not valid.. It has to be between ' . $this->getMinLength() . ' and ' . $this->getMaxLength() . ' characters long.',
)
)
),
array(
'name' => '\My\Validator\UsernameNotInUse',
'options' => array(
'messages' => array(
UsernameNotInUse::ERROR_USERNAME_IN_USE => 'The usarname %value% is already being used by another user.'
)
)
)
)
);
}
}
अब यहाँ मेरी सत्यापनकर्ता
namespace My\Validator;
use My\Entity\Helper\User as UserHelper,
My\EntityRepository\User as UserRepository;
use Zend\Validator\AbstractValidator,
Zend\ServiceManager\ServiceManagerAwareInterface,
Zend\ServiceManager\ServiceLocatorAwareInterface,
Zend\ServiceManager\ServiceManager;
/**
*
*/
class UsernameNotInUse
extends AbstractValidator
implements ServiceManagerAwareInterface
{
const ERROR_USERNAME_IN_USE = 'usernameUsed';
private $serviceManager;
/**
*
* @var UserHelper
*/
private $userHelper;
protected $messageTemplates = array(
UsernameNotInUse::ERROR_USERNAME_IN_USE => 'The username you specified is being used already.'
);
public function isValid($value)
{
$inUse = $this->getUserHelper()->isUsernameInUse($value);
if($inUse)
{
$this->error(UsernameNotInUse::ERROR_USERNAME_IN_USE, $value);
}
return !$inUse;
}
public function setUserHelper(UserHelper $mapper)
{
$this->userHelper = $mapper;
return $this;
}
/**
* @return My\EntityRepository\User
*/
public function getUserHelper()
{
if($this->userHelper == null)
{
$this->setUserHelper($this->getServiceManager()->get('doctrine.entitymanager.orm_default')->getObjectRepository('My\Entity\User'));
}
return $this->userHelper;
}
public function setServiceManager(ServiceManager $serviceManager)
{
echo get_class($serviceManager);
echo var_dump($serviceManager);
$this->serviceManager = $serviceManager;
return $this;
}
/**
*
* @return ServiceManager
*/
public function getServiceManager()
{
return $this->serviceManager;
}
}
क्यों यह मेरे लिए एक अच्छा विचार की तरह लग किया है?
यह एक अच्छी टेस्टेबिलिटी/पुन: उपयोग करने की पसंद की तरह लग रहा था क्योंकि मैं आवश्यकता होने पर अपने आवेदन में अलग-अलग तत्वों का दोबारा उपयोग कर सकता हूं।
मैं प्रत्येक तत्व द्वारा उत्पन्न प्रत्येक इनपुट का परीक्षण कर सकता हूं यह सुनिश्चित करने के लिए कि यह इनपुट को सही ढंग से स्वीकार/अस्वीकार करता है।
यह तत्व
public function testFactoryCreation()
{
$fac = new Factory();
$element = $fac->createElement(array(
'type' => '\My\Form\Registration\UsernameElement'
));
/* @var $element \My\Form\Registration\UsernameElement */
$this->assertInstanceOf('\My\Form\Registration\UsernameElement',
$element);
$input = $fac->getInputFilterFactory()->createInput($element->getInputSpecification());
$validators = $input->getValidatorChain()->getValidators();
/* @var $validators \Zend\Validator\ValidatorChain */
$expectedValidators = array(
'Zend\Validator\StringLength',
'Zend\Validator\NotEmpty',
'Zend\I18n\Validator\Alnum',
'My\Validator\UsernameNotInUse'
);
foreach($validators as $validator)
{
$actualClass = get_class($validator['instance']);
$this->assertContains($actualClass, $expectedValidators);
switch($actualClass)
{
case 'My\Validator\UsernameNotInUse':
$helper = $validator['instance']->getUserHelper();
//HAVING A PROBLEM HERE
$this->assertNotNull($helper);
break;
default:
break;
}
}
}
के लिए मेरे इकाई परीक्षण का उदाहरण है
समस्या मैं आ रही है कि सत्यापनकर्ता केँ ठीक से नहीं लाई जा सकती है, जो वास्तव में सिद्धांत से एक UserRepository है । ऐसा इसलिए हो रहा है क्योंकि वैधकर्ता केवल अनुप्रयोग प्रबंधक के उपयोग के बजाय ValidatorPluginManager को ServiceManager के रूप में एक्सेस प्राप्त करते हैं।
मुझे यह त्रुटि वैलिडेटर भाग के लिए मिलती है, हालांकि अगर मैं सामान्य सेवा प्रबंधक पर एक ही विधि प्राप्त करता हूं तो यह कोई समस्या नहीं है।
1) Test\My\Form\Registration\UsernameElementTest::testFactoryCreation
Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for doctrine.entitymanager.orm_default
var_dump ($ serviceManager) सत्यापनकर्ता में मुझे पता चलता है कि यह वर्ग ValidatorPluginManager की है।
मैं इतना
'service_manager' => array(
'factories' => array(
'My\Validator\UsernameNotInUse' => function($sm)
{
$validator = new \My\Validator\UsernameNotInUse();
$em = $serviceManager->get('doctrine.entitymanager.orm_default');
/* @var $em \Doctrine\ORM\EntityManager */
$validator->setUserHelper($em->getRepository('\My\Entity\User'));
return $validator;
}
)
तरह service_manager प्रविष्टि में एक कारखाना लगाने की कोशिश की लेकिन क्योंकि यह अनुप्रयोग स्तर सेवा प्रबंधक से सलाह नहीं कर रहा है काम नहीं किया।
तो, समग्र, यहाँ मेरे सवालों हैं:
फार्म और तत्वों एक अच्छा एक को अलग करने की इस रणनीति है? क्या मुझे इस तरह से चलना चाहिए? विकल्प क्या हैं? (मैं टेस्टेबिलिटी के लिए सामान तोड़ने के लिए हूं) मैं केवल मूल रूप से सभी इनपुट के संयोजन के साथ ही फॉर्म का परीक्षण करने जा रहा था, लेकिन ऐसा लगता था कि मैं बहुत अधिक करने की कोशिश कर रहा हूं।
मैं ऊपर दिए गए मुद्दे को कैसे हल करूं?
क्या मुझे ज़ेंड के फॉर्म/एलिमेंट/इनपुट पार्ट्स का उपयोग किसी अन्य तरीके से करना चाहिए जिसे मैं नहीं देख रहा हूं?
editin आप पहले से ही है फ़ॉर्म के बारे में [docs] (http://zf2.readthedocs.org/en/latest/modules/zend.form.quick-start.html) की जांच की? मैं विशेष रूप से एनोटेशन का उपयोग करने की सलाह देता हूं, क्योंकि यह फॉर्म बनाने के लिए सबसे तेज़ तरीका है। –
@DanielM मैंने आपके द्वारा उल्लेखित दस्तावेज़ों पर ध्यान दिया है, लेकिन 'मैं प्रत्येक इनपुट को अलग-अलग परीक्षण कैसे कर सकता हूं?' का सवाल बाकी है। एनोटेशन विधि के साथ मुझे पूरी तरह से एहसास हुआ फॉर्म सही मिलेगा? तो क्या मुझे हर इनपुट संयोजन का उपयोग करने के लिए मजबूर नहीं किया जाएगा? –
ठीक है, मैं उनका परीक्षण नहीं करता हूं। मुझे नहीं लगता कि परीक्षण की आवश्यकता यहां है क्योंकि तत्व वर्गों का परीक्षण किया जाता है, वैधकर्ताओं का परीक्षण किया जाता है और इनपुट फ़िल्टर भी होते हैं। बेशक, यदि आप किसी विशेष उद्देश्य के लिए एक नई एलिमेंट क्लास बनाते हैं जो मौजूदा तत्वों के अनुरूप नहीं है, तो आपको नए टेस्ट केस बनाना चाहिए। अन्यथा, ठीक है। और हां, एनोटेशन का उपयोग करके बनाए गए फॉर्मों को बिना किसी काम के पूरी तरह से प्रस्तुत किया जा सकता है, 'यह $ echo-> formCollection ($ myForm) को छोड़कर;' दृश्य के अंदर यदि आपको किसी भी अनुकूलित प्रतिपादन की आवश्यकता नहीं है। –