I am developing an application in CI supported Grocery CRUD , but at the time of validation is not recognized , what I need is that a field is validated to accept only alphabetic characters , plus points , comma and space but does not work:
Function in controller
Lines of code in the function of Grocery CRUD in what I call the function solo_letras:
Lines of code in method of Grocery CRUD
What would be a validation that could take?
Use the built in form validation in CodeIgniter.
I do it like this.
At the beginning of your function set all the rules for your form inputs like this:
$this->form_validation->set_rules('inputFirstName', 'First Name', required|min_length[4]|max_length[16]|is_unique[users.username]');
This is a sample for a user name field. The first parameter is the form input name='inputFirstName', The second is a readable version of the first and is used for error reporting, then comes your validations which are separated by the pipe character. There is a validation for matching regex; regex_match[/regex/].
Place all your validations then use:
if($this->form_validation->run() == false) {
Do something here if validation fails
return false;
}
To test for validation.
Then continue on with the code if validation passes.
Here is a full sample of a simple registration function:
public function register()
{
$this->output->set_content_type('application_json');
$this->form_validation->set_rules('inputUsername', 'User Name', 'required|min_length[4]|max_length[16]|is_unique[users.username]');
$this->form_validation->set_rules('inputEmail', 'Email', 'required|valid_email|is_unique[users.email]');
$this->form_validation->set_rules('inputFirstname', 'First Name', 'required|max_length[20]');
$this->form_validation->set_rules('inputLastname', 'Last Name', 'required|max_length[20]');
$this->form_validation->set_rules('inputPassword', 'Password', 'required|min_length[6]|max_length[16]|matches[inputPasswordConfirm]');
$this->form_validation->set_rules('inputPasswordConfirm', 'Password Confirmation', 'required');
if($this->form_validation->run() == false) {
$this->output->set_output(json_encode(['result' => 0, 'error' => $this->form_validation->error_array()]));
return false;
}
$username = $this->input->post('inputUsername');
$email = $this->input->post('inputEmail');
$firstName = $this->input->post('inputFirstname');
$lastName = $this->input->post('inputLastname');
$password = $this->input->post('inputPassword');
$passwordConfirm = $this->input->post('inputPasswordConfirm');
$this->load->model('user_model');
$user_id = $this->user_model->insert([
'username' => $username,
'email' => $email,
'firstName' => $firstName,
'lastName' => $lastName,
'password' => hash('sha256', $password . PASSWORD_SALT)
]);
if($user_id) {
$this->session->set_userdata(['user_id' => $user_id]);
$this->output->set_output(json_encode(['result' => 1]));
return false;
}
$this->output->set_output(json_encode(['result' => 0, 'error' => "User not created."]));
}
Related
How to retrieve data from a session array with only one value for the registration session data only and how the example logic code implementation of the page contains sessions, the user is required to register first, so if the user tries to access by refreshing the page, there is no text output in the form of being required to register first with the following code
<?php
class Auth extends CI_Controller
{
public function index()
{
$variabelInpUtusername = $this->input->post("email");
$variabelInputPass = password_hash($this->input->post("password"), PASSWORD_DEFAULT);
$this->form_validation->set_rules(
'email',
'Email',
'required|is_unique[tb_register.username]',
array('is_unique' => 'Ini %s sudah terdaftar', 'required' => 'Anda harus input email')
);
$this->form_validation->set_rules('password', 'Password', 'required', array('required' => 'Anda harus input password'));
if ($this->form_validation->run() == FALSE) {
$this->load->view('templates/header');
$this->load->view('register');
$this->load->view('templates/footer');
} else {
$data = array('username' => $variabelInpUtusername, 'password' => $variabelInputPass);
// print_r($data);
// $this->modeluser->register($data);
$datasession['sessi'] = array('username' => $variabelInpUtusername, 'password' => $variabelInputPass);
$this->session->set_userdata($datasession);
// print_r($datasession);
$this->load->view('templates/header');
$this->load->view('sukses_register', $datasession);
// $this->session->set_userdata($datasession);
// print_r($datasession);
// var_dump($datasession);
}
}
So what I'm trying to do:
Pull User data from database, including email address, username etc.
Edit it
Save it
But I want to keep username and email unique.
And for this I'm setting validation rules like this:
$this->form_validation->set_rules('firstname', 'First Name', 'required|min_length[2]|max_length[15]');
$this->form_validation->set_rules('lastname', 'Last Name', 'required|min_length[2]|max_length[15]');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[users.email]');
$this->form_validation->set_rules('username', 'Username', 'required|min_length[4]|max_length[12]|is_unique[users.username]');
$this->form_validation->set_rules('password1', 'Password', 'required|matches[password2]');
$this->form_validation->set_rules('password2', 'Password Confirmation', 'required');
$this->form_validation->set_rules('group', 'User Group', 'required');
And as you can see I have is_unique[users.username] and is_unique[users.email] rules. But it doesn't let me update my entry using this rules.
So the question is, how can I update database entry, and keep those 2 fields unique(username and email)?
use the call back validation function
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|callback_check_user_email');
function check_user_email($email) {
if($this->input->post('id'))
$id = $this->input->post('id');
else
$id = '';
$result = $this->user_model->check_unique_user_email($id, $email);
if($result == 0)
$response = true;
else {
$this->form_validation->set_message('check_user_email', 'Email must be unique');
$response = false;
}
return $response;
}
in model
function check_unique_user_email($id = '', $email) {
$this->db->where('email', $email);
if($id) {
$this->db->where_not_in('id', $id);
}
return $this->db->get('user')->num_rows();
}
use same for the user name....
In Codeigniter 4
// is_unique[table.field,ignore_field,ignore_value]
$validation->setRules([
'name' => "is_unique[supplier.name,uuid, $uuid]", // is not ok
'name' => "is_unique[supplier.name,uuid,$uuid ]", // is not ok
'name' => "is_unique[supplier.name,uuid,$uuid]", // is ok
'name' => "is_unique[supplier.name,uuid,{uuid}]", // is ok - see "Validation Placeholders"
]);
Eg.
$validation->setRules(['email' => 'required|valid_email|is_unique[users.email,id,4]']);
// 'id' = ignore table field name (users table 'id' field)
// '4' = ignore field value(currnet user id)
codeigniter 4 validation
For Codeigniter 3
Add following helper class (edit_unique_helper.php)
function edit_unique($value, $params) {
$CI =& get_instance();
$CI->load->database();
$CI->form_validation->set_message('edit_unique', "Sorry, that %s is already being used.");
list($table, $field, $current_id) = explode(".", $params);
$query = $CI->db->select()->from($table)->where($field, $value)->limit(1)->get();
if ($query->row() && $query->row()->id != $current_id)
{
return FALSE;
} else {
return TRUE;
}
}
Add to autoload ()
Use edit_unique where you pass an extra parameter which is the id of the row you're editing
eg. $this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|edit_unique[users.user_name.'.$id.']');
Source
I have used codeigniter code in the below when I create a user if it is already exist it should display a message duplicate value but it displays 1062 error. Pls help to solve the issue.
Controller
function create_member()
{
$this->load->library('form_validation');
// field name, error message, validation rules
$this->form_validation->set_rules('first_name', 'Name', 'trim|required');
$this->form_validation->set_rules('last_name', 'Last Name', 'trim|required');
$this->form_validation->set_rules('email_address', 'Email Address', 'trim|required|valid_email');
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[4]');
$this->form_validation->set_rules('password', 'Password', 'trim|required|min_length[4]|max_length[32]');
$this->form_validation->set_rules('password2', 'Password Confirmation', 'trim|required|matches[password]');
if($this->form_validation->run() == FALSE)
{
$this->load->view('signup_form');
}
else
{
$this->load->model('membership_model');
if($query = $this->membership_model->create_member())
{
$data['main_content'] = 'signup_successful';
$this->load->view('includes/template', $data);
}
else
{
$this->load->view('signup_form');
}
}
}
Model
function create_member()
{
$new_member_insert_data = array(
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'email_address' => $this->input->post('email_address'),
'username' => $this->input->post('username'),
'password' => md5($this->input->post('password'))
);
$insert = $this->db->insert('membership', $new_member_insert_data);
if ($this->db->_error_number() == 1062)
{
$this->session->set_flashdata('duplicate_email', 'Duplicate value');
redirect('login');
}
return $insert;
}
It seems that your error is because your database is not allowing to add multiple entries with same username/email, for this you need to add codeigniter is_unique validation on that particular field. Below is example for codeigniter unique validation : $this->form_validation->set_rules('username', 'Username', 'required|min_length[5]|max_length[12]|is_unique[membership.username]');
Try to use $this->db->query instead of insert and create a SQL statement using INSERT IGNORE and you can handle the duplicates silently.
Why just not do a previous query to check if the email exists aleady ?
Anyway, you can do something like that:
$query_string = $this->db->insert_string('users', $data);
$this->db->query($query_string.' ON DUPLICATE KEY UPDATE id=id');
// or
$this->db->query(str_replace("INSERT INTO", "INSERT IGNORE INTO", $query_string));
if( $this->db->affected_rows() == 0 ) {
//duplicate email
}
I followed the tutorial for making a registration form with validation, with 2 views and 1 controller.
I wrote this in the controller:
function index()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[3]|max_length[16]|xss_clean|callback_username_check');
$this->form_validation->set_rules('password', 'Password', 'trim|required|matches[passconf]|md5');
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'trim|required');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('register_form');
}
else
{
$this->load->view('register_success');
$data = array(
'IDUser' => NULL ,
'Username' => "$username" ,
'Password' => 'password' ,
'Email' => 'email' ,
'Gender' => 'gender' ,
'Birthday' => 'bday' ,
);
$this->db->insert('Accounts', $data);
}
}
First it is executes a working sql insert. After, a validation. Nevertheless, the values loaded from the database are not those from the validation. Instead, they are the same plain text in the array.
I don't want to get the values directly from the form/view with POST; that's pointless. What do i do? I'm new to Codeigniter and not that familiar with OOP PHP.
You just have to use Codeigniter Input class : http://ellislab.com/codeigniter/user-guide/libraries/input.html
So in your case:
$username = $this->input->post('username');
$password = $this->input->post('password');
$passconf = $this->input->post('passconf');
$email = $this->input->post('email');
dragu is correct but please use this format:
$username = $this->input->post('username', TRUE);
the TRUE tells codeigniter to XSS clean which is a security feature you definitely want. Thats also why you put XSS clean in the form validation. from yr example:
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[3]|max_length[16]|xss_clean|callback_username_check');
If the form fails validation, then CI can display the results in the form again. having xss_clean in the validation cleans those values.
I just started using a MVC framework, especially Codeigniter and i am having some trouble maintaining my code and where to place my functions(controller or model).
For now i am building a sign up system and i have a controller with the name signup.php
This is my code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Class Signup extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->form_validation->set_rules('username', 'Username', 'trim|required|callback_check_valid_username|min_length[6]|max_length[20]|xss_clean');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'trim|required|min_length[6]|max_length[32]');
if ($this->form_validation->run() == false){
$this->load->view("register/index");
}else{
$this->submitRegistration();
}
}
public function ajaxup(){
if ($this->input->isAjaxRequest()){
header('Content-type: application/json');
$error = false;
$message = '';
$this->form_validation->set_rules('username', 'Username', 'trim|required|callback_check_valid_username|min_length[6]|max_length[20]|xss_clean');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'trim|required|min_length[6]|max_length[32]');
if ($this->form_validation->run() == false){
$message = validation_errors();
$error = true;
}else{
$this->_submitRegistration();
$message = 'Successfully registered.';
}
$return = array(
'error' => $error,
'message' => $message
);
$return = json_encode($return);
echo $return;
}
}
public function _submitRegistration(){
$username = $this->input->post('username');
$email = $this->input->post('email');
$password = $this->input->post('password');
$data = array(
'username' => $username,
'email' => $email,
'password' => $password
);
$this->load->model('users_model');
$this->users_model->register_user($data);
}
public function check_valid_username($username){
$this->load->model('users_model');
if (!$this->users_model->is_valid_username($username)){
$this->form_validation->set_message('check_valid_username', 'The %s field should contain only letters, numbers or periods');
return false;
}
return true;
}
}
Is there anything i could write better to maintain my code and be readable?
*NOTE:*the function ajaxup is used when a user clicks the button and does an ajax call.
Thanks
Looks pretty good to me. Here are few ideas/suggestions for future improvements:
In index() you are calling $this->submitRegistration() but I think you want to be calling $this->_submitRegistration().
Since you are using the same validation rules in both the index() and ajaxup() methods you could pull pull them out into an array and either make them a property of your controller or put them into a config file.
For documentation see here and here.
$validation_rules = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'trim|required|callback_check_valid_username|min_length[6]|max_length[20]|xss_clean'
),
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'trim|required|valid_email'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|required|min_length[6]|max_length[32]'
),
);
Then in your methods you would do something similar to $this->form_validation->set_rules($validation_rules).
Think about reordering your validation rules. For example, let's take a look at the rules for the username field. If check_valid_username() is making a call to the database (through the user model) then it would probably be better to validate the length requirements before. There's no use making an expensive call to the database if we can determine if the username is invalid.
Make your callback methods private. Right now check_valid_username() is a public method and could potentially be accessed through the URL. Prefix it with an underscore (_check_valid_username()) and then in your validation rules use callback__check_valid_username. Note the two underscores.
If you find yourself needing to use check_valid_username() in multiple controllers you could extend the native form validation library and put it there.
This looks fine to me. You seem to have all the relevant functions located in the user model and you are using the controller to access them. All I can suggest is read up on MVC theory if you feel unsure.
This is a good article:
http://www.codinghorror.com/blog/2008/05/understanding-model-view-controller.html