Create model instance in Form in ZF2 like ZF1? - zend-framework

In ZF1 it is possible to create an instance of a model and also access its properties from any form class.`
class Application_Form_Drydepot extends Zend_Form
{
$model = new Application_Model_DbTable_DrydepotModel();
$List = $model ->formationSelect();
array_unshift($List, array('key' => '', 'value' => '--Please Select--'));
$id = new Zend_Form_Element_Hidden('id');
$id->addFilter('Int')
->setDecorators($this->elementDecoration);
$formation = new Zend_Form_Element_Select('formation_id');
$formation->setLabel('Formation Name')
->setRequired(true)
->setAttrib('id', 'formation')
->setAttrib('class', 'required')
->addValidator('NotEmpty', true)
->setMultiOptions($List)
->setDecorators($this->elementDecoration);
}
In here $model directly possible to call but use it easily but zf2 it is quite difficult. I am not successfull about to do it. In ZF2 how do I do it same operation.

Another ways are like here : the documentation
Programmatic Form Creation
ZF2 Coding close to ZF1
use Zend\Captcha;
use Zend\Form\Element;
use Zend\Form\Form;
$captcha = new Element\Captcha('captcha');
$captcha
->setCaptcha(new Captcha\Dumb())
->setLabel('Please verify you are human');
$form = new Form('my-form');
$form->add($captcha);

Related

Pass the current querystring parameters through symfony forms

Our application uses several webforms and some of them only should add or change several parameters in the querystring. As example there are a filter form and a form for the list order (just a dropdown).
Both are indipendant, but if I change one, I have to pass the current querystring parameters with the new request. How can I manage it?
This is just one of the possible solutions, it will depend on your implementation if it would help you.
<?php
$allowedQueryParams = array('param1', 'param2', 'param3');
// I'll fake a request here
$request = new Request(array('param2' => 'foo', 'param3' => 'bar', 'param4' => 'dummy'));
$formFactory = Forms::createFormFactoryBuilder()->getFormFactory();
$formBuilder = $formFactory->createBuilder();
$formBuilder->add('param1', 'text');
$data = array();
foreach ($allowedQueryParams as $param) {
if ($request->query->has($param)) {
// Add the query param as hidden field to you form
$formBuilder->add($param, 'hidden');
$data[$param] = $request->query->get($param);
}
}
$formBuilder->setData($data);
$form = $formBuilder->getForm();
So basically you add hidden fields with the current query parameters.
Edit:
But if you would have many forms, you might want to do this with an EventSubscriber
An alternative approach would be to combine the two forms into one master form.
From your controller:
$formData = array(
'filterParams' => array(), // Default filter parameters
'listOrderParams' => array(), // Default list order parameters
);
$form = $this->createFormBuilder($task)
->add('filterParams', new FilterFormType())
->add('listOrderParams', new ListOrderFormType())
->add('update', 'submit')
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$formData = $form->getData();

CakePHP - Using a different model in current model

I am creating a custom validation function in my model in CakePHP. After reading similar questions I have understood that I could be using ClassRegistry::init('Model'); to load a foreign model in my current model. But it doesn't say much more on the syntax and how to actually use it afterwards. This is what I have tried, but nothing "is happening" when I am trying to print the array to see if it contains the right stuff. Basically I want to pull out the User data to use it in my validation.
class Booking extends AppModel {
public $name = 'Booking';
public $validate = array(
'start_time' => array(
'noOptionViolation' => array(
'rule' => 'noOptionViolation',
'allowEmpty' => false
)
),
);
public function noOptionViolation ($start_time) {
$this->User = ClassRegistry::init('User');
$allUsers = $this->User->find('all');
print_r($allUsers);
}
Is this correct syntax? Can I use all the methods of $this->User just like I would in a controller?
You can use import as detailed on this post:
https://stackoverflow.com/a/13140816/1081396
App::import('Model', 'SystemSettings.SystemSetting');
$settings = new SystemSetting();
$mySettings = $settings->getSettings();
In your example it would be like:
App::import('Model', 'Users.User');
$user = new User();
$allUsers = $user->find('all');
print_r($allUsers);
You could better use the import at the beginning of the model.
You could use this too to load Models
$this->loadModel('User');
and access all functions by
$this->User

zend framework 2 how disable multiple errors messages of validator

I am trying to de that the EmailValidator class return me only one error messages.
In other forums I have seen that in ZF1 only is possible make it extending the Validator class.
Anybody know if in ZF2 there is a more easy way for make it?
This is my code for if anyone it help, in this I call setMessages method for overwrite the default messagestemplate, but not works.
$form = new ParticipantForm();
$mailInput = new Input('mail');
$validator = new ValidatorEmailAddres();
$validator->setMessages(
array(
ValidatorHostName::UNKNOWN_TLD => 'hola'
)
);
$mailInput->getValidatorChain()->addValidator($validator);
$mailInputFilter = new InputFilter();
$mailInputFilter->add($mailInput);
$form->setInputFilter($mailInputFilter);
$form->setData($_POST);
Try this:
$validator = new \Zend\Validator\EmailAddres();
$validator->setMessage('something broke bla');
or to set a specific message:
$validator = new \Zend\Validator\EmailAddres();
$validator->setMessage('something broke bla', \Zend\Validator\EmailAddres::LENGTH_EXCEEDED);

How to preopulate zend file elements

I have a Zend form like this:
$this->setName('Add Job');
$id = new Zend_Form_Element_Hidden('id');
$id->addFilter('Int');
$name = new Zend_Form_Element_Text('name');
$name->setLabel('Name')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$file = new Zend_Form_Element_File('file');
$file->setLabel('File')
->setRequired(true);
$category = new Zend_Form_Element_Checkbox('category');
$category->setLabel('Express?')
->setRequired(true)
->setCheckedValue('2')
->setUncheckedValue('1');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('id', 'submitbutton');
The "add" action is working fine but I'm not working on the "edit" action using this in my controller:
$id = $this->_getParam('id', 0);
if ($id > 0) {
$jobs = new Application_Model_DbTable_Jobs();
$form->populate($jobs->getJob($id));
}
and the form prepopulates just fine except for the file element. In the DB, I've got the filename saved and I'd like to display it in the edit form somehow - is there a standard way of handling this in Zend?
Thanks,
Phil
You cannot prepopulate a file-input-element.
That is not a restriction by Zend_Form. The html input-file-element has no "value" attribute.
i used a trick, to pass the filename to the view, so one can for example show the image next to the upload. In your form type this:
$this->getElement('image')->setAttrib('class', $this->_myParams['data']['image']);
$image->setDecorators(array(
'File',
array('ViewScript', array('viewScript' => '/ditta/_image.phtml', 'placement' => false)))
);/
then in the viewscript use
$image = $this->element->getAttrib('class');//get name of file
$this->element->setAttrib('class', '');//delete class

Validate a set of fields / group of fields in Zend Form

Is there any good solution for the following requirements:
A form with one field for zip code and default validators like number, length, etc.
After submission, the form is checked against a database.
If the zip code is not unique we have to ask for an city.
Examples:
Case 1: Submited zip code is unique in database. Everything is okay. Process form
Case 2: Submited zip code is not unique. Add a second field for city to the form. Go back to form.
We want to handle this in an generic way (not inside an controller). We need this logic for
a lot of forms. First thought was to add it to isValid() to every form or write a
validator with logic to add fields to the form. Subforms are not possible for us, because we need this for different fields (e.g. name and street).
Currently I'm using isValid method inside my forms for an User Form to verify the password and confirm password field. Also, when the form is displayed in a New Action, there are no modifications, but when displayed in an Edit Action, a new field is added to the form.
I think that is a good option work on the isValid method and add the field when the validation return false, and if you want something more maintainable, you should write your own validatator for that purpose.
Take a look at my code:
class Admin_Form_User extends Zf_Form
{
public function __construct($options = NULL)
{
parent::__construct($options);
$this->setName('user');
$id = new Zend_Form_Element_Hidden('id');
$user = new Zend_Form_Element_Text('user');
$user->setLabel('User:')
->addFilter('stripTags')
->addFilter('StringTrim')
->setAllowEmpty(false)
->setRequired(true);
$passwordChange = new Zend_Form_Element_Radio('changePassword');
$passwordChange->setLabel('Would you like to change the password?')
->addMultiOptions(array(1 => 'Sim', 2 => 'Não'))
->setValue(2)
->setSeparator('');
$password = new Zend_Form_Element_Password('password');
$password->setLabel('Password:')
->addFilter('stripTags')
->addFilter('StringTrim')
->setRequired(true);
$confirm_password = new Zend_Form_Element_Password('confirm_password');
$confirm_password->setLabel('Confirm the password:')
->addFilter('stripTags')
->addFilter('StringTrim')
->addValidator('Identical')
->setRequired(true);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Save');
$this->addElements(array($id,$name,$lastname,$group,$user,$passwordChange,$password,$confirm_password,$submit));
$this->addDisplayGroup(array('password','confirm_password'),'passwordGroup');
$this->submit->setOrder(8);
$this->setDisplayGroupDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
)
);
$passwordChange->clearDecorators();
}
public function addPasswordOption()
{
$this->changePassword->loadDefaultDecorators();
$this->getDisplayGroup('passwordGroup')
->addDecorators(array(
array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
)
);
$this->password->setRequired(false);
$this->confirm_password->setRequired(false);
}
public function setPasswordRequired($flag = true)
{
$this->password->setRequired($flag);
$this->confirm_password->setRequired($flag);
}
public function isValid($data)
{
$confirm = $this->getElement('confirm_password');
$confirm->getValidator('Identical')->setToken($data['password']);
return parent::isValid($data);
}
}
So, in my controller:
public function newAction()
{
$this->view->title = "New user";
$this->view->headTitle($this->view->title, 'PREPEND');
$form = $this->getForm();
if($this->getRequest()->isPost())
{
$formData = $this->_request->getPost();
if($form->isValid($formData))
{
$Model = $this->getModel();
$id = $Model->insert($formData);
$this->_helper->flashMessenger('The user data has beed updated.');
$this->_helper->redirector('list');
}
}
$this->view->form = $form;
}
public function editAction()
{
$this->view->title = "Edit user";
$this->view->headTitle($this->view->title, 'PREPEND');
$id = $this->getRequest()->getParam('id');
$form = $this->getForm();
// Add yes or no password change option
$form->addPasswordOption();
$Model = $this->getModel();
if($this->getRequest()->isPost())
{
$formData = $this->getRequest()->getPost();
// Change password?
if($formData['changePassword'] == 2) $form->setPasswordRequired(false);
if($form->isValid($formData))
{
$Model->update($formData);
$this->_helper->flashMessenger('The user data has beed updated.');
$this->_helper->redirector('list');
}
}
$data = $Model->getById($id)->toArray();
$form->populate($data);
$this->view->form = $form;
}
You will probably need a Javascript form validator for that. In the submit function perform an AJAX call to check if the zipcode is unique. If not, show an extra city field.
But you still have to perform the validation server side: never trust user input, even if it's validated on the client side.