i've set the validation rules in application/config/validation_rules.php and it looks like this
(short version)
$config = array(
'member/register' => array(
'field' => 'language',
'label' => 'language',
'rules' => 'required|min_length[5]|max_length[12]'
),
array(
'field' => 'email',
'label' => 'email',
'rules' => 'required|valid_email'
),
array(
'field' => 'password',
'label' => 'password',
'rules' => 'required|min_length[8]'
),
array(
'field' => 'verify_password',
'label' => 'password',
'rules' => 'required|min_length[8]|matches[password]'
));
and i'm calling it like this:
$this->config->load('validation_rules');
$this->form_validation->set_rules($config);
if($this->form_validation->run('member/register') == FALSE)
{
$page = array(
'meta_title' => 'member registration',
'load_page' => 'front/register_view'
);
$this->load->view('front/template', $page);
}
not only is the validation_errors() function not showing anything but i'm also getting this error:
Message: Undefined variable: config
update: (here is my controller)
class register extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->library('form_validation');
}
function index()
{
$this->config->load('validation_rules', TRUE);
$this->form_validation->set_rules($this->config->item('config', 'validation_rules'));
if($this->form_validation->run('member/register') == FALSE)
{
//validation doesnt pass, load view
$page = array(
'meta_title' => 'member registration',
'load_page' => 'front/register_view'
);
$this->load->view('front/template', $page);
}
else
{
$register_data = array(
'language' => $this->input->post('language'),
'email' => $this->input->post('email'),
'password' => md5($this->input->post('password')),
'fname' => $this->input->post('fname'),
'lname' => $this->input->post('lname'),
'phone' => $this->input->post('phone'),
'address' => $this->input->post('address'),
'address2' => $this->input->post('address2'),
'city' => $this->input->post('city'),
'state' => $this->input->post('state'),
'zipcode' => $this->input->post('zipcode'),
'gfname' => $this->input->post('gfname'),
'glname' => $this->input->post('glname'),
'gphone' => $this->input->post('gphone')
);
$this->session->set_userdata($register_data);
}
}
function package()
{
$page = array(
'meta_title' => 'Register Package',
'load_page' => 'register_package_view'
);
$this->load->view('includes/template', $page);
}
}
I encountered same problem but I managed to fix it by using following configuration:
In my application/config/form_validation.php:
$config = array(
"register" => array(
array(
"field" => "username",
"label" => "Username",
"rules" => "required"
)
)
);
Auto-load the custom config file "form_validation.php" inside application/config/autoload.php:
$autoload['config'] = array('form_validation');
In my controller:
// manually set rules by taking $config["register"] from form_validation.php
$this->form_validation->set_rules($this->config->item("register"));
// call run() without parameter
if ($this->form_validation->run() == FALSE) {
$this->load->view("user/register_test");
} else {
echo "Form content is correct";
}
I've tried calling the validator using $this->form_validation->run("register"), without using $this->form_validation->set_rules() function, but I got no luck. Setting the rules manually by retrieving it from config array in form_validation.php make my day.
In case you are extending the form_validation library, you need to pass the $config array to the parent constructor:
class MY_Form_validation extends CI_Form_validation {
/**
* constuctoooor
*/
function MY_Form_validation($config){
parent::__construct($config);
}
http://ellislab.com/forums/viewthread/181937/
It's also cleaner using the method outlined in the docs: http://ellislab.com/codeigniter%20/user-guide/libraries/form_validation.html#savingtoconfig to avoid calling $this->form_validation->set_rules(...);
/**
* This is the POST target for the password reset form above
* #return null
*/
public function submit(){
// perform validation //
if($this->form_validation->run() == FALSE){
// display error on sign-up page //
$this->session->set_flashdata("system_validation_errors", validation_errors());
redirect('member/forgot/password');
}
// more awesome code
}
$this->config->load('validation_rules');
$this->form_validation->set_rules($config);
should be:
$this->config->load('validation_rules', TRUE);
$this->form_validation->set_rules($this->config->item('validation_rules', 'validation_rules'));
Per the documentation:
// Loads a config file named blog_settings.php and assigns it to an index named "blog_settings"
$this->config->load('blog_settings', TRUE);
// Retrieve a config item named site_name contained within the blog_settings array
$site_name = $this->config->item('site_name', 'blog_settings');
Your rules are wrong, you forgot to put the validation group in an array:
$config['validation_rules'] = array(
'member/register' => array(
array(
'field' => 'language',
'label' => 'language',
'rules' => 'required|min_length[5]|max_length[12]'
),
array(
'field' => 'email',
'label' => 'email',
'rules' => 'required|valid_email'
),
array(
'field' => 'password',
'label' => 'password',
'rules' => 'required|min_length[8]'
),
array(
'field' => 'verify_password',
'label' => 'password',
'rules' => 'required|min_length[8]|matches[password]'
)
)
);
Related
I'm using codeigniter 3, and I'm trying to use the form_validation library.
Basically, if validation fails, I'm catching the input data and then sending it back to the form.
So I'm sticking all form data in an array, like so:
// add input data to array
$org_data = array(
'org_id' => $this->input->post('org_id'),
'p_org_id' => $this->input->post('p_org_id'),
'account_ref' => $this->input->post('account_ref'),
'org_name' => $this->input->post('org_name'),
'address1' => $this->input->post('address1'),
'address2' => $this->input->post('address2'),
'address3' => $this->input->post('address3'),
'town' => $this->input->post('town'),
'county' => $this->input->post('county'),
'pcode' => $this->input->post('pcode'),
'phone' => $this->input->post('phone'),
'support_email' => $this->input->post('support_email'),
'notify_return' => $this->input->post('notify_return'),
'notify_email' => $this->input->post('notify_email'),
'email_interval' => $this->input->post('email_interval'),
'renewal_date' => $this->input->post('renewal_date'),
'login_reminder' => $this->input->post('login_reminder'),
'default_fireaware' => $this->input->post('default_fireaware'),
'open_training_url' => $this->input->post('open_training_url'),
);
All fine!
Now, to send the data back to the form, I am using the below.
$this->data['org_id'] = array(
'name' => 'org_id',
'id' => 'org_id',
'type' => 'text',
'value' => $this->form_validation->set_value('org_id'),
);
BUT
I don't want to create one of these for every input, so ideally I'd like to use a loop to create these. But I cant get it to work, I am getting undefined variable errors.
This is the loop in progress:
foreach($org_data as $key => $value){
$this->data['$key'] = array(
'name' => '$key',
'id' => '$key',
'type' => 'text',
'value' => $this->form_validation->set_value('$value'),
);
}
Can I use a loop to do this?
What are your thoughts?
use validation like this
$config = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'required'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'required'
),
array(
'field' => 'passconf',
'label' => 'Password Confirmation',
'rules' => 'required'
),
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'required'
)
);
$this->form_validation->set_rules($config);
if ($this->form_validation->run() == FALSE) {
$data['errors'] = validation_errors();
$this->load->view('yourview', $data);
} else {
$userData = $this->input->post();
$this->load->view('yourview', $data);
}
Basically, if validation fails, I'm catching the input data and then
sending it back to the form.
yeah i think this is the part to clarify - you don't need to do that at all -- thats the advantage of using set_value('fieldName'), it automatically echoes out the value. Same - on the form - with form_error( 'fieldName' ) it will display the field specific error message.
I'm trying to do an email validation whereby the domain of the email would be #abc123.com. I've separated my form validation rules into another file in the application/config folder called form_validation.php. One of my rules consists of a callback_email_check.
Where should I put the function? In the main controller or together with the form_validation.php file where all my form validation rules are? I've tried putting at both options but at where I display my error message I'm getting an output saying Unable to access an error message corresponding to your field name Email.(email_check).
function email_check($email)
{
if( strpos($email, '#abc123.com') !== FALSE ) return TRUE;
$this->form_validation->set_message('email', 'Please use abc123 email only.');
return FALSE;
}
form_validation.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/* Form Validation Rules */
$config = array(
'login' => array(
array(
'field' => 'user_id',
'label' => 'User ID',
'rules' => 'trim|required'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|required'
)
),
'sign_up' => array(
array(
'field' => 'user_id',
'label' => 'User ID',
'rules' => 'trim|required'
),
array(
'field' => 'name',
'label' => 'Name',
'rules' => 'trim|required'
),
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'trim|required|valid_email|callback_email_check'
),
array(
'field' => 'department',
'label' => 'Department',
'rules' => 'trim|required'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|required'
),
array(
'field' => 'cfm_password',
'label' => 'Re-type Password',
'rules' => 'trim|required|matches[password]'
)
),
'edit_profile' => array(
array(
'field' => 'new_password',
'label' => 'New Password',
'rules' => 'trim|required'
),
array(
'field' => 'retype_password',
'label' => 'Re-type Password',
'rules' => 'trim|required|matches[new_password]'
)
),
'forgot_password' => array(
array(
'field' => 'user_id',
'label' => 'User ID',
'rules' => 'trim|required'
),
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'trim|required|valid_email|callback_email_check'
)
)
);
?>
On your function email_check, the set_message is not correct it should be the same name as the function.
Change this
$this->form_validation->set_message('email', 'Please use abc123 email only.');
To
$this->form_validation->set_message('email_check', 'Please use abc123 email only.');
Call backs http://www.codeigniter.com/userguide2/libraries/form_validation.html#callbacks
I am also facing the same problem and this is how i resolved it...
You can put email_check function in same controller. In case you are not getting the error message in callback then pass $this in your run()
if ($this->form_validation->run($this)) { ...}
and associating a Controller Method with a Rule Group -
$config = array(
'controller/method' => array(...));
view link for more : [associating a Controller Method with a Rule Group][1]
cheers !!
Just add this line in your config:
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'trim|required|valid_email|callback_email_check',
**'errors' => array('email_check' => 'Your Error Message')**
),
I have a very simple method that is meant to add validation rules from a form (if no ID, password is required otherwise not - New user vs update user).
public function edit($id = NULL){
$rules = $this->user_m->rules;
$id || $rules['password'] .= '|required';
$this->form_validation->set_rules($rules);
$this->load->view('_layout_admin_main',$this->data);
}
$rules is set in the model as (although I can't see how it's relevant):
public $rules = array(
'name' => array(
'field' => 'name',
'label' => 'Name',
'rules' => 'trim|required|xss_clean'
),
'email' => array(
'field' => 'email',
'label' => 'Email',
'rules' => 'trim|required|valid_email|callback__unique_email|xss_clean'
),
'password' => array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|matches[password_c]'
),
'password_c' => array(
'field' => 'password_c',
'label' => 'Password Confirmation',
'rules' => 'trim|matches[password]'
),
'username' => array(
'field' => 'username',
'label' => 'Username',
'rules' => 'trim|is_unique|xss_clean|required'
)
);
The error is Message: Array to string conversion ... Line Number: 27, the $id reference is causing it specifically when $id is NULL. When $id is set, it is fine and dandy. $id is definitely not an array.
I know this is vague but this literally is it. Please ask questions if you have any ideas and I'll post any more that you need.
I think there is a small issue with the way you concatenate required to the rules, try this instead :
public function edit($id = NULL){
$rules = $this->user_m->rules;
$id || $rules['password']['rules'] .= '|required'; // issue was here
$this->form_validation->set_rules($rules);
$this->load->view('_layout_admin_main',$this->data);
}
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;
}
I'd like some help please.
This is the array that holds all the validation on a contact form
class Contact_Form extends CI_Controller
{
private $_validation = array(
'fullname' => array(
'field' => 'fullname',
'label' => 'Fullname',
'rules' => 'trim|required|max_length[255]'
),
'email' => array(
'field' => 'email',
'label' => 'Email Address',
'rules' => 'trim|required|max_length[255]|valid_email'
),
'phone' => array(
'field' => 'phone',
'label' => 'Phone',
'rules' => 'trim|max_length[10]|integer'
),
'message' => array(
'field' => 'message',
'label' => 'Message',
'rules' => 'trim|required'
),
'captcha' => array(
'field' => 'captcha',
'label' => 'Security Code',
'rules' => 'trim|required|callback_validate_captcha'
)
);
// This is the part where I validate my contact form inside a method
$this->load->library('form_validation');
$this->form_validation->set_rules($this->_validation);
if ($this->form_validation->run() === true) {
echo 'works!';
}
This is the callback function that validates the captcha
public function callback_validate_captcha($str) {
$post_captcha = $this->input->post('captcha');
$set_captcha = $this->session->userdata('captcha');
if (strcmp($set_captcha, $post_captcha) !== 0) {
$this->form_validation->set_message('validate_captcha', '%s is wrong');
return false;
}
return true;
}
If i hit submit on an empty form I get the error that idicates that captcha is a required field, but if i submit a wrong code i don't get any error at all, which means that the callback is being ignored.
I tried to change my if statement
// change this (althought i feel its more correct)
if (strcmp($set_captcha, $post_captcha) !== 0)
// to this
if ($set_captcha != $post_captcha)
but the problem remains. Any ideas what's wrong?
you are making major mistake you have to make function validate_captcha instead of callback_validate_captcha.
Because callback is form keyword to call a function just try and bingo