ZF2 - How to add a new Form in an existing Controller? - php

I have a login Form LoginForm.php with its Filter LoginFilter.php, that has a View /login/index.phtml, a Controller LoginController.php, two Factory LoginControllerFactory.php & LoginFormFactory.php and it is called in the config.module.php and works perfect. The Form is correctly displayed.
I have a ViewController.php that has a method idAction that shows a post by its id passed by parameter from the homepage in a View called /view/id.phtml. I want to display this Form I created within this View and I don't know how. First, I created the Form exactly as I created the login Form, but I realized that I already configured my id child-route, inside of view route with a Factory in module.config.php.
Then, I tried to set the form in the idAction method, exactly as I did in indexAction in LoginController.php Controller, but I'm receiving the following error: An exception was raised while creating "Rxe\Factory\ViewController"; no instance returned.
I will now show you what I did to try to display this new Form.
First, the Form itself:
class CommentForm extends Form
{
public function buildForm()
{
$this->setAttribute('method', 'POST');
$this->setAttribute('id', 'add-comment-form');
$this->add(array(
'name' => 'comment',
'type' => 'textarea',
'options' => array(
'label' => 'Category'
),
'attributes' => array(
'class' => 'form-control'
)
));
$this->add(array(
'name' => 'submit',
'type' => 'submit',
'attributes' => array(
'class' => 'btn btn-success',
'value' => 'Comment'
)
));
}
}
Form's CommentFormFactory.php calling its Filter and building the Form:
class CommentFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$form = new CommentForm();
$form->setInputFilter($serviceLocator->get('Rxe\Factory\CommentFilter'));
$form->buildForm();
return $form;
}
}
The ViewControllerFactory.php calling the CommentFormFactory.php, just like in LoginControllerFactory.php:
class ViewControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$viewController = new ViewController();
$viewController->setPostsTable($serviceManager->get('Rxe\Factory\PostsTable'));
$viewController->setCommentsTable($serviceManager->get('Rxe\Factory\CommentsTable'));
$viewController->setCommentForm($serviceManager->get('Rxe\Factory\CommentForm'));
return $viewController;
}
}
The ViewController.php, calling the form within its idAction's ViewModel:
class ViewController extends AbstractActionController
{
use PostsTableTrait;
use CommentsTableTrait;
private $commentForm;
function setCommentForm($commentForm)
{
$this->commentForm = $commentForm;
}
public function indexAction()
{
$category = $this->params()->fromRoute('category');
return new ViewModel(array(
'posts' => $this->postsTable->getPostsByCategory($category),
'categories' => $category
));
}
public function idAction()
{
$id = $this->params()->fromRoute('id');
$viewModel = new ViewModel(array(
'commentForm' => $this->commentForm,
'commentParams' => $this->params()->fromPost(),
'messages' => $this->flashMessenger()->getMessages(),
'posts' => $this->postsTable->getPostById($id),
'posts' => $this->commentsTable->getNumberOfCommentsByPost($id),
'comments' => $this->commentsTable->getCommentsByPost($id)
));
$viewModel->setTemplate('rxe/view/id.phtml');
if ($this->getRequest()->isPost()) {
$this->commentForm->setData($this->params()->fromPost());
if ($this->commentForm->isValid()) {
$this->flashMessenger()->addMessage('Thank you for your comment. :)');
} else {
$this->flashMessenger()->addMessage('Your comment wasn\'t sent.');
}
}
return $viewModel;
}
}
And finally my module.config.php
'controllers' => array(
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
'factories' => array(
'Rxe\Factory\LoginController' => 'Rxe\Factory\LoginControllerFactory',
'Rxe\Factory\ViewController' => 'Rxe\Factory\ViewControllerFactory',
'Rxe\Factory\IndexController' => 'Rxe\Factory\IndexControllerFactory'
)
),
'service_manager' => array(
'factories' => array(
'Rxe\Factory\LoginForm' => 'Rxe\Factory\LoginFormFactory',
'Rxe\Factory\LoginFilter' => 'Rxe\Factory\LoginFilterFactory',
'Rxe\Factory\CommentForm' => 'Rxe\Factory\CommentFormFactory',
'Rxe\Factory\CommentFilter' => 'Rxe\Factory\CommentFilterFactory',
'Rxe\Factory\PostsTable' => 'Rxe\Factory\PostsTableFactory',
'Rxe\Factory\CategoriesTable' => 'Rxe\Factory\CategoriesTableFactory',
'Rxe\Factory\CommentsTable' => 'Rxe\Factory\CommentsTableFactory',
'Zend\Db\Adapter\AdapterService' => 'Zend\Db\Adapter\AdapterServiceFactory'
)
),
Please, let me know if you need me to show you more codes. Thank you in advance.
EDIT #1
If I remove the line that calls the Form in the ViewControllerFactory.php, I get the following error: Fatal error: Call to a member function prepare() on a non-object in /home/vol12_3/byethost4.com/b4_16354889/htdocs/module/Rxe/view/rxe/view/id.phtml on line 31
The id.phtml is:
<!-- Comment form -->
<div id="comment-form-area" class="col-xs-3">
<?php $this->commentForm->prepare() ?>
<?php echo $this->form()->openTag($this->commentForm); ?>
<div class="form-group comment-area">
<?php echo $this->formRow($this->commentForm->get('comment_content')); ?>
</div>
<div class="form-group">
<?php echo $this->formRow($this->commentForm->get('submit')); ?>
</div>
<?php echo $this->form()->closeTag(); ?>
</div>
<!-- /Comment form -->

Try removing these lines
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
If it doesn't work, have a look at this tutorial how to create proper controller factories and pass dependencies. https://samsonasik.wordpress.com/2015/03/31/zend-framework-2-using-__invokepluginmanager-manager-in-services-factory/
An example how I build my forms:
namespace Admin\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
class ContentForm extends Form implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct("content");
}
public function init()
{
$this->setAttribute('method', 'post');
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'title',
'attributes' => [
'required' => true,
'size' => 40,
'id' => "seo-caption",
'placeholder' => 'Title',
],
'options' => [
'label' => 'Title',
],
]);
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'text',
'attributes' => [
'class' => 'ckeditor',
'rows' => 5,
'cols' => 80,
],
'options' => [
'label' => 'Text',
],
]);
}
public function getInputFilterSpecification()
{
return [
[
"name"=>"title",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 200,
],
],
],
],
[
"name"=>"text",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
],
],
],
],
];
}
}
Than I create a Factory
namespace Admin\Factory\Controller;
use Admin\Controller\ContentController;
use Zend\Mvc\Controller\ControllerManager;
class ContentFormFactory
{
/**
* #{inheritDoc}
*/
public function __invoke(ControllerManager $controllerManager)
{
return new ContentController(
$controllerManager->getServiceLocator()->get('FormElementManager')->get('Admin\Form\ContentForm')
);
}
}
Inside module.config.php I have this code
'controllers' => [
'factories' => [
'Admin\Controller\Content' => "Admin\Factory\Controller\ContentFormFactory",
],
'invokables' => [
...
],
],
Please, show us some more code.

Related

Require at least one element in ZF2 FieldSet

The problem
I have a Form and a FieldSet. I would like to validate that the FieldSet is not empty. Also, I want to validate each field in the FieldSet.
So far, whatever I have tried is validating one or the other, but not both. If elements is present in the Form's input filter specification, then it validates that elements is not empty, but does not validate the bar and baz fields of FieldSet. And, of course, the other way around. Any clue as to how to approach this issue would be much appreciated.
The Form
class FooForm extends Form implements InputFilterProviderInterface
{
public function init()
{
$this->add([
'name' => 'elements',
'type' => Collection::class,
'required' => true,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class
]
]
]);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'elements',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
The FieldSet
class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
public function init()
{
$this->add(['name' => 'bar']);
$this->add(['name' => 'baz']);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'bar',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
[
'name' => 'baz',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
Edit: Added full validation spec.
After getting some hints on Google and digging through the source code, I found a solution. Unfortunately the zend-inputfilter implementation is a little buggy and won't work nicely with getInputFilterSpecification(), but we can just construct our own InputFilter and return that directly:
The Form
class FooForm extends BaseForm
{
public function init()
{
$this->add([
'name' => 'elements',
'type' => Collection::class,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class
]
]
]);
}
public function getInputFilter()
{
if (!$this->filter) {
$this->filter = new InputFilter();
/** #var Collection $elementsCollection */
$elementsCollection = $this->fieldsets['elements'];
/** #var SomeElementFieldSet $elementsFieldSet */
$elementsFieldSet = $elementsCollection->getTargetElement();
$collectionFilter = new CollectionInputFilter();
$collectionFilter->setIsRequired(true);
$collectionFilter->setInputFilter(
$elementsFieldSet->getInputFilterSpecification()
);
$this->filter->add($collectionFilter, 'elements');
}
return $this->filter;
}
}
This will validate that there is at least one element in the collection. And will validate all the elements one by one by the FieldSet's specification.
One problem persists, though. Whenever the collection is empty, the validation will return false, but will not return any messages. This is due to a bug in the zend-inputfilter component. Issues reported here and here. But that is another problem altogether.
Use setValidationGroup() method in the Form object by specifying an array of input fields you want to validate. Please refer to the Doc!
You may give a try this way. Though I have added some extra fields to the form for testing purpose only.
class FooForm extends Form implements InputFilterProviderInterface
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->add(['name' => 'title']);
$this->add([
'name' => 'elements',
'type' => Collection::class,
'required' => true,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class,
],
],
]);
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Post'
],
]);
// I pointed this. Here you can specify fields to be validated
$this->setValidationGroup([
'title',
'elements' => [
'bar',
],
]);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'title',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
];
}
}
And your fieldset class should be
class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
public function init()
{
$this->add(['name' => 'bar']);
$this->add(['name' => 'baz']);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'bar',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
[
'name' => 'baz',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
Hope this would help!

How to get ZF2 fieldset validation working?

I have a simple form currently consisting of a single fieldset. Now I want the fields to be filtered and validated. So I implemented the method getInputFilterSpecification() in my Fieldset class:
...
class FooFieldset extends \Zend\Form\Fieldset
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->setHydrator(new ClassMethods(false));
$this->setObject(new Buz());
$this->setLabel('Baz');
$this->add(array(
'type' => 'text',
'name' => 'bar',
'options' => array(
'label' => _('bar')
)
));
}
public function getInputFilterSpecification()
{
return [
'bar' => [
'required' => true,
'filters' => [
0 => [
'name' => 'Zend\Filter\StringTrim',
'options' => []
]
],
'validators' => [],
'description' => _('bar lorem ipsum'),
'allow_empty' => false,
'continue_if_empty' => false
]
];
}
}
and added the Fieldset to the Form:
...
class BuzForm extends \Zend\Form\Form
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->setAttribute('role', 'form');
$this->add(array(
'name' => 'baz-fieldset',
'type' => 'Buz\Form\BazFieldset'
));
$this->add(array(
'type' => 'submit',
'name' => 'submit',
'attributes' => array(
'value' => 'preview'
)
));
}
}
The problem is, that the InputFilter specifications are completely ignored. I've set a breakpoint into FooFieldset#getInputFilterSpecification() and to be sure even checked it witha die() -- the method is not called.
What is wrong here and how to get it working correctly?
You will need to implement Zend\InputFilter\InputFilterProviderInterface interface in order for the getInputFilterSpecification() method to be called.

Zend Framework 2 Repopulate form using validated values

I have a simple form class setup along with a filter. After submitting the form, if there's a validation error, the validation/filter works and I can dump the filtered values, but the form does not display the cleaned data. In particular, I am testing with StringTrim and StripTags. I can see the trimmed value, but the final form output still shows the original value submitted. How do I use the validated values instead when the form is repopulated?
An example:
Form data submitted string " asdf ".
Dumping form data, $regform->getData() : "asdf"
The above is expected, but the output in the view still shows the spaces: " asdf ".
I appreciate any input. Code is below. Thank you!
Controller code:
public function indexAction ()
{
$this->layout()->pageTitle = "Account Registration";
$regform = new RegForm($data=null);
if($this->request->isPost()){
$data = $this->post;
$regform->setData($data);
$ufilter = new RegFilter();
$regform->setInputFilter($ufilter->getInputFilter());
if($regform->isValid()){
$this->view->result = "ok";
}
else {
$this->view->result = "Not good";
}
var_dump($regform->getData());
}
$this->view->regform = $regform;
return $this->view;
}
RegForm.php
<?php
namespace GWMvc\Form;
use Zend\Form\Form;
use Zend\Form\Element;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Session\Container;
class RegForm extends Form
{
public function __construct($data = null, $args = array())
{
parent::__construct('reg-form');
$this->setAttribute('class', 'form form-inline');
$this->setAttribute('role', 'form');
$this->setAttribute('method', 'post');
$this->setAttribute('action','/app/registration/index');
$this->add(array(
'name' => 'firstname',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'First Name:',
),
'attributes' => array('id' => 'firstname', 'type' => 'text',
'class' => 'regformitem regtextfield')));
$this->add(array(
'name' => 'lastname',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'Last Name:'
),
'attributes' => array('id' => 'lastname', 'type' => 'text',
'required' => true,'class' => 'regformitem regtextfield')));
$this->add(array(
'type' => 'Zend\Form\Element\Csrf',
'name' => 'csrf',
'options' => array(
'csrf_options' => array(
'timeout' => 600
)
)
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Submit',
'class' => 'btn btn-default',
),
));
}
}
RegFilter.php
<?php
namespace GWMvc\Form;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class RegFilter implements InputFilterAwareInterface
{
public $username;
public $password;
protected $inputFilter;
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$this->inputFilter = new InputFilter();
$this->factory = new InputFactory();
$this->inputFilter->add($this->factory->createInput(array(
'name' => 'firstname',
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 50,
),
),
),
)));
$this->inputFilter->add($this->factory->createInput(array(
'name' => 'lastname',
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 50,
),
),
),
)));
}
return $this->inputFilter;
}
}
View Script:
<?php
$form = &$this->regform;
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formElement($form->get('csrf'));?>
<div class="form" gwc="regitem">
<?php echo $this->formRow($form->get('firstname')); ?>
</div>
<div class="form" gwc="regitem">
<?php echo $this->formRow($form->get('lastname')); ?>
</div>
EDIT (SOLUTION)
As per the accepted answer below, it was this easy. Here's what I added.
$valid = $regform->isValid();
$regform->setData($regform->getData());
if($valid){
$this->view->result = "ok";
} else {
// not ok, show form again
}
I guess you have to do it manually:
if($regform->isValid()){
$regform->setData ($regform->getData ())->isValid ();
$this->view->result = "ok";
}

ZF2 file upload doesn't work

I try to upload a file with ZF2, but the file doesn't get uploaded. The form seems to be valid. Is there anything wrong with my code?
If I upload the image with php move_uploaded_files, everything work as expected.
Form:
class LogoUploadForm extends Form {
public function init() {
$this->add([
'type' => 'File',
'name' => 'logo',
'attributes' => array(
'id' => 'logo-input'
),
]);
}
}
InputFilter:
class LogoInputFilter extends InputFilter {
public function init() {
$this->add([
'name' => 'logo',
'required' => true,
'filters' => [
[
'name' => 'File\RenameUpload',
'options' => [
'target' => './data/upload/',
'overwrite' => true,
'randomize' => true,
'use_upload_extension' => true,
]
]
],
'validators' => [
[
'name' => 'File\MimeType',
'options' => [
'magicFile' => false, //Important: https://github.com/zendframework/zf2/issues/6493
'mimeType' => ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']
]
],
[
'name' => 'File\UploadFile',
],
[
'name' => 'File\Size',
'options' => [
'max' => '4MB'
]
]
]
]);
}
}
Controller:
class LogoController extends AbstractActionController {
public function uploadAction() {
$form = $this->logoUploadForm;
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData(array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
));
if ($form->isValid()) {
exit('valid');
} else {
exit('invalid');
}
}
}
}
You should call in the view the prepare function before the form opentag function:
$form->prepare();
echo $this->form()->openTag($form);
The form will detect, at the moment you call the prepare function, the proper form encoding type to be used.

Zend Form Duplicate Entry Email Exception

Having a registration zend form in view looks like this :
<?php
$form = $this->form;
if(isset($form)) $form->prepare();
$form->setAttribute('action', $this->url(NULL,
array('controller' => 'register', 'action' => 'process')));
echo $this->form()->openTag($form);
?>
<dl class="form-signin">
<dd><?php
echo $this->formElement($form->get('name_reg'));
echo $this->formElementErrors($form->get('name_reg'));
?></dd>
<dd><?php
echo $this->formElement($form->get('email_reg'));
echo $this->formElementErrors($form->get('email_reg'));
?></dd>
<dd><?php
echo $this->formElement($form->get('password_reg'));
echo $this->formElementErrors($form->get('password_reg'));
?></dd>
<dd><?php
echo $this->formElement($form->get('confirm_password_reg'));
echo $this->formElementErrors($form->get('confirm_password_reg'));
?></dd>
<br>
<dd><?php
echo $this->formElement($form->get('send_reg'));
echo $this->formElementErrors($form->get('send_reg'));
?></dd>
<?php echo $this->form()->closeTag() ?>
And RegisterController as following.
<?php
namespace Test\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;
use Test\Form\RegisterForm;
use Test\Form\RegisterFilter;
use Test\Form\LoginFormSm;
use Test\Form\LoginFilter;
use Test\Model\User;
use Test\Model\UserTable;
class RegisterController extends AbstractActionController
{
public function indexAction()
{
$this->layout('layout/register');
$form = new RegisterForm();
$form_sm = new LoginFormSm();
$viewModel = new ViewModel(array(
'form' => $form,
'form_sm' =>$form_sm,
));
return $viewModel;
}
public function processAction()
{
$this->layout('layout/register');
if (!$this->request->isPost()) {
return $this->redirect()->toRoute(NULL,
array( 'controller' => 'index'
)
);
}
$form = $this->getServiceLocator()->get('RegisterForm');
$form->setData($this->request->getPost());
if (!$form->isValid()) {
$model = new ViewModel(array(
'form' => $form,
));
$model->setTemplate('test/register/index');
return $model;
}
// Creating New User
$this->createUser($form->getData());
return $this->redirect()->toRoute(NULL, array (
'controller' => 'auth' ,
));
}
protected function createUser(array $data)
{
$userTable = $this->getServiceLocator()->get('UserTable');
$user = new User();
$user->exchangeArray($data);
$userTable->saveUser($user);
return true;
}
}
Also a RegisterForm where are declared all variables shown in index. Also RegisterFilter as following:
<?php
namespace Test\Form;
use Zend\InputFilter\InputFilter;
class RegisterFilter extends InputFilter
{
public function __construct()
{
$this->add(array(
'name' => 'email_reg',
'required' => true,
'filters' => array(
array(
'name' => 'StripTags',
),
array(
'name' => 'StringTrim',
),
),
'validators' => array(
array(
'name' => 'EmailAddress',
'options' => array(
'domain' => true,
'messages' => array(
\Zend\Validator\EmailAddress::INVALID_FORMAT => 'Email address format is invalid'
),
),
),
array(
'name' => 'AbstractDb',
'options' => array(
'domain' => true,
'messages' => array(
\Zend\Validator\Db\AbstractDb::ERROR_RECORD_FOUND => 'Current Email Already registered'
),
),
),
),
));
$this->add(array(
'name' => 'name_reg',
'required' => true,
'filters' => array(
array(
'name' => 'StripTags',
),
array(
'name' => 'StringTrim',
),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 140,
),
),
),
));
$this->add(array(
'name' => 'password_reg',
'required' => true,
'validators' => array(
array(
'name' => 'StringLength',
'options' =>array(
'encoding' => 'UTF-8',
'min' => 6,
'messages' => array(
\Zend\Validator\StringLength::TOO_SHORT => 'Password is too short; it must be at least %min% ' . 'characters'
),
),
),
array(
'name' => 'Regex',
'options' =>array(
'pattern' => '/[A-Z]\d|\d[A-Z]/',
'messages' => array(
\Zend\Validator\Regex::NOT_MATCH => 'Password must contain at least 1 digit and 1 upper-case letter'
),
),
),
),
));
$this->add(array(
'name' => 'confirm_password_reg',
'required' => true,
'validators' => array(
array(
'name' => 'Identical',
'options' => array(
'token' => 'password_reg', // name of first password field
'messages' => array(
\Zend\Validator\Identical::NOT_SAME => "Passwords Doesn't Match"
),
),
),
),
));
}
}
Problem
All i need is to throw a message when somebody tries to register and that e-mail is already registered. Tried with \Zend\Validator\Db\AbstractDb and added following validator to email in RegisterFilter as following
array(
'name' => 'AbstractDb',
'options' => array(
'domain' => true,
'messages' => array(
\Zend\Validator\Db\AbstractDb::ERROR_RECORD_FOUND => 'Current Email Already registered'
),
),
),
But that seems not to work.
Question: Is there a way to implement this validator in RegisterController?
Additional.
I've deleted from RegisterFilert validator and put inside Module.ph
'EmailValidation' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$validator = new RecordExists(
array(
'table' => 'user',
'field' => 'email',
'adapter' => $dbAdapter
)
);
return $validator;
},
And call it from RegisterController
$validator = $this->getServiceLocator()->get('EmailValidation');
if (!$validator->isValid($email)) {
// email address is invalid; print the reasons
$model = new ViewModel(array(
'error' => $validator->getMessages(),
'form' => $form,
));
$model->setTemplate('test/register/index');
return $model;
}
And when i use print_r inside view to check for it shows.
Array ( [noRecordFound] => No record matching the input was found ).
I want just to echo this 'No record matching the input was found'.
Fixed
Modified in RegisterController as following
$validator = $this->getServiceLocator()->get('EmailValidation');
$email_ch = $this->request->getPost('email_reg');
if (!$validator->isValid($email_ch)) {
// email address is invalid; print the reasons
$model = new ViewModel(array(
'error' => 'Following email is already registered please try another one',
'form' => $form,
));
$model->setTemplate('test/register/index');
return $model;
}
I had compared
if (!$validator->isValid($email_ch))
Before with nothing and that's why i needed to add first
$email_ch = $this->request->getPost('email_reg');
You don't have to do that in your controller, just try this in your RegisterFilter class :
First : Add $sm as parameter of the _construct() method :
public function __construct($sm) {....}
Second: Replace e-mail validation by this one :
$this->add ( array (
'name' => 'email_reg',
'required' => true,
'validators' => array(
array(
'name' => 'Zend\Validator\Db\NoRecordExists',
'options' => array(
'table' => 'user',
'field' => 'email',
'adapter' => $sm->get ( 'Zend\Db\Adapter\Adapter' ),
'messages' => array(
NoRecordExists::ERROR_RECORD_FOUND => 'e-mail address already exists'
),
),
),
),
)
);
When you call the RegisterFilter don't forget to pass the serviceLocator as parameter in your controller :
$form->setInputFilter(new RegisterFilter($this->getServiceLocator()));
Supposing you have this in your global.php File (config\autoload\global.php) :
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
To your previous request, ("I want just to echo this 'No record matching the input was found'")
$validator = $this->getServiceLocator()->get('EmailValidation');
$email_ch = $this->request->getPost('email_reg');
if (!$validator->isValid($email_ch)) {
// email address is invalid; print the reasons
foreach ($validator->getMessages() as $message) {
$msg = $message;
}
$model = new ViewModel(array(
'error' => $msg,
'form' => $form,
));
$model->setTemplate('test/register/index');
return $model;
}

Categories