Codeigniter helper function to validation rules - php

I created a helper for checking if a user id exists in my user database table:
if ( ! function_exists('valid_user'))
{
function valid_user($user_id)
{
$ci=& get_instance();
$ci->load->database();
$ci->db->select('id');
$ci->db->where('id', $user_id);
$ci->db->where('activated', 1);
$ci->db->where('banned', 0);
$ci->db->limit(1);
$query = $ci->db->get('users');
if ($query->num_rows() > 0) //if user exists
{
return TRUE;
}
else
{
return FALSE;
}
}
}
I added the function to my validation rule like so
$this->form_validation->set_rules('user_id', 'User ID', 'required|xss_clean|max_length[11]|is_natural_no_zero|valid_user');
It does not perform the valid_user function. What am I doing wrong here?

In my previous experience, I usually added a validation function (in your case, valid_user) in the same place where the callback is called.
For example, I would put valid_user method in a users_controller where one of the registration methods will invoke the valid_user method.
Also, it seems that, in your set_rules, you have to set callback_valid_user not valid_user according to the Codeigniter user guides.
http://codeigniter.com/user_guide/libraries/form_validation.html#callbacks

$this->form_validation->set_rules('user_id', 'User ID',
'required|xss_clean|max_length[11]|is_natural_no_zero|callback_valid_user');
//note the callback_ ↑

Related

getting the query from database - Codeigniter

I wanted to check whether the username exists in the database,
but Codeigniter is throwing an
Error: Can't use method return value in write context.
The code is as follows:
public function check_username_exists($username){
$query = $this->db->get_where('users', array('username' => $username));
if(empty($query->row_array())){
return true;
}else{
return false;
}
}
$result = $query->row_array();
if(empty($result)){
return true;
}else{
return false;
}
try using below code
public function check_username_exists($username){
$query = $this->db->get_where('users', array('username' => $username));
if($query->num_rows() > 0){
return true;
}else{
return false;
}
}
It looks like you are trying to validate a form for user registration. If this is the case, then you would be far better off using the built-in form_validation library (https://codeigniter.com/user_guide/libraries/form_validation.html). There is already a built in method that would help you make sure you have unique records (such as the username). So basically, once the form_validation library is loaded, you would need to set the rules for validation. Once rules are set, you can call the run() method, which will produce a bool true/false whether it passes validation or not.
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', "trim|required|is_unique[users.username]");
if($this->form_validation->run() === true) {
//Do something when posted form is validated
} else {
// There were errors or this is the first time
if(validation_errors())
$data['error_message'] = validation_errors();
}
You should use the form validation library to validate any (and usually all) of your forms throughout your application
Hope that helps
First Understand the Error: Can't use method return value in write context.
empty() needs to access the value by reference (in order to check whether that reference points to something that exists).
However, the real problem you have is that you use empty() at all, mistakenly believing that "empty" value is any different from "false".
Empty is just an alias for !isset($thing) || !$thing. When the thing you're checking always exists (in PHP results of function calls always exist), the empty() function is nothing but a negation operator.
Not Coming to your problem, As Scott Miller suggest you can use CodeIgniter validation. And if you want a little advance solution then you can put your validation in the config folder with creating form_validation.php for more detail visit CodeIgniter documentation for validation.
$config = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'required|is_unique[users.username]'
)
);
And If you want to do it with the query then here is the query:
public function check_username_exists($username){
$query = $this->db->get_where('users', array('username' => $username));
if ($query->num_rows() > 0){
return true;
}
else{
return false;
}
}
You can use num_rows to get the username exist or not.

php cake Auth inside class

I need to check if a user is existing in the mgrUser table. now the propblem is the controller is in the adminController while the model is in the mgrUserModel. how do i use Auth for this? Thats the reason why I made a generic login code.
public function login() {
// if ($this->Auth->login()) {
// return $this->redirect($this->Auth->redirectUrl());
// }
// $this->Flash->error(
// __('Username ou password incorrect')
// );
//since the model is in a different view, I needed to includ the mgrModel and create a generic login
//will revamp the code to fit the built in Aut code for php cake
if(isset($_POST['submit'])) {
$User_ID = htmlspecialchars($_POST['user_id']);
$Pass = htmlspecialchars($_POST['pass']);
try {
$mgrUserModel = new MgrUser();
$isValid = $mgrUserModel->find('first', array(
'conditions' => array("user_id" => $User_ID)
));
if($isValid != null){
if (($isValid['MgrUser']['pass']) == $Pass) {
//this doesnot work
$this->Auth->allow();
$this->redirect($this->Auth->redirectUrl());
}
else{
}
}
} catch (Exception $e) {
//echo "not logged in";
}
// this echo will show the id and pass that was taken based on the user_id and pass that the user will input
//for testing only
// echo $isValid2['MgrUser']['id'];
// echo $isValid2['MgrUser']['pass'];
}
}
You need double == to compare things,
function checkMe()
{
if($user == 'me'){
$this->Auth->allow('detail');
}
}
what you did was assign "me" string to variable $user which always returns true because assignment was possible
Anyway you should use it in beforeFilter which is running before every action from this controller, which makes much more sense
public function beforeFilter() {
parent::beforeFilter();
if($user == 'me'){
$this->Auth->allow('detail');
}
}
the Auth component could be configured to read the user information via another userModel (The model name of the users table). It defaults to Users.
please consult the book for appropriate cakephp version: https://book.cakephp.org/3.0/en/controllers/components/authentication.html#configuring-authentication-handlers

Protecting routes in laravel with filters

how can I secure routes so that user can access only those departments that he belongs to?
my current filter:
Route::filter('department', function ($route, $request) {
// Check to see if the current user belongs to the department:
if (!Request::isMethod('post'))
{
if($request->segment(2) != "create")
{
if (!Auth::user()->canAccessDepartment($request->segment(2))) {
// The user shouldn't be allowed to access the department! Redirect them
return Redirect::to('/')->with( 'notice', 'Error!' );;
}
}
}
});
And this is my method in user model
public function canAccessDepartment($department_id) {
$user = Confide::user();
if ($user->departments()->where('department_id', $department_id)->count() < 1)
{
return false;
}
else{ return true; }
}
In the code you have, the filter is applied to all the routes, and then checks to see if we have a matching method/action. My preference would be to only apply the filter when it's needed. So
[Warning - untested code follows]
Route::resource('department', 'DepartmentController',
array('except' => array('create','store', 'update', 'destroy')));
Route::resource('department','DepartmentController',array('only'=>array('create','store', 'update', 'destroy'),'before'=>'departmentFilter'));
Route::filter('department', function ($route, $request) {
// should this be Confide::user() ?
if (!Auth::user()->canAccessDepartment($request->segment(2))) {
// The user shouldn't be allowed to access the department! Redirect them
return Redirect::to('/')->with( 'notice', 'Error!' );
}
});
I think that this should be done in the database/model level. Since the data that you need to compare is in a database, its better if you do this transaction in a database level.

Codeigniter Form Validation in Model

Hello all, this is my first CI project.
I have a simple form validation function in my model.
function verify_login()
{
//This method will have the credentials validation
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|callback_check_database');
var_dump($this->form_validation->run());
die;
if ($this->form_validation->run() == FALSE) {
//Field validation failed. User redirected to login page
$this->load->view('login_view');
} else {
//Go to private area
redirect('home', 'refresh');
}
}
This only works when it's in a controller but not in a model. When I try passing the variables from the controller to the function in the model, the variables get received but won't process.
Can someone enlighten me? Thank you.
its fine to do your form validation in a model. But you want to have the validation return True or False to your controller. Not call a view. So like
// in your Model lets call it Users
function verify_login()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|callback_check_database');
if ($this->form_validation->run() == FALSE) {
return FALSE ;
} else {
return TRUE;
}
}
// Your callback function
// in Controller
function verify(){
if( $this->users->verify_login() == FALSE ){
// $this->errormessage will be available in any view that is called from this controller
$this-errormessage = "There was an error with your Log In. Please try again." ;
$this->showLogin() ; }
else {
// set a session so you can confirm they are logged in on other pages
$this->setLoginSession($this->input->post('username', TRUE)) ;
$this->showUserHome(); }
}
Another thing to think about -- often people know their user name but mess up their password. So if you check for them separately you can adjust the error message accordingly. And if you check for user name and there are no results -- you don't need to check for password and in the error message you can tell them there is no user by that name.
My biggest recommendation to you is to not do validations like this in your model. If you're validating in your model it needs to be against a database value directly and not a form.
Please let me know if that solves your problem, if not please comment and I'll edit my answer.
UPDATE: Please ignore some of the above, as I was going off theory and not fact :)
I'll have to dig deeper into the CI core to get a good idea of what's wrong with this. Your code itself looks ok. Only thing I can see is that your callback may not exist in your model and only in your controller. Echoing the below I do not consider this a good use of the model.
The docs on validations
class Data_model extends CI_Model
{
public function rules()
{
return [
['field' => 'pertanyaan',
'label' => 'pertanyaan',
'rules' => 'required|is_unique[data.pertanyaan]'],
['field' => 'jawaban',
'label' => 'jawaban',
'rules' => 'required']
];
}
}
class Datas extends CI_Controller
{
public function add()
{
$data = $this->data_model;
$validation = $this->form_validation;
$validation->set_rules($data->rules());
if ($validation->run()) {
$data->save();
$this->session->set_flashdata('success', 'Berhasil disimpan');
}
$this->load->view("admin/data/new_form");
}
}

Codeigniter form validation error message

I have a form on my website header where i allow the user to log in with his username/password... then i POST to /signin page and check if the username exists to allow the user to log in.. if there is a problem upon login i output these errors...
i tried using the following code to show a custom error but with no luck
if ($this->form_validation->run() == false){
$this->load->view("login/index", $data);
}else{
$return = $this->_submitLogin();
if ($return == true){
//success
}else{
$this->form_validation->set_message('new_error', 'error goes here');
//error
}
$this->load->view("login/index", $data);
}
how does set_message work and if this is the wrong method, which one allow me to show a custom error in this case?
EDIT :
validation rules:
private $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' => 'password',
'label' => 'Password',
'rules' => 'trim|required|min_length[6]|max_length[32]'
),
);
The set_message method allows you to set your own error messages on the fly. But one thing you should notice is that the key name has to match the function name that it corresponds to.
If you need to modify your custom rule, which is _check_valid_username, you can do so by perform set_message within this function:
function _check_valid_username($str)
{
// Your validation code
// ...
// Put this in condition where you want to return FALSE
$this->form_validation->set_message('_check_valid_username', 'Error Message');
//
}
If you want to change the default error message for a specific rule, you can do so by invoking set_message with the first parameter as the rule name and the second parameter as your custom error. E.g., if you want to change the required error :
$this->form_validation->set_message('required', 'Oops this %s is required');
If by any chance you need to change the language instead of the error statement itself, create your own form_validation_lang.php and put it into the proper language folder inside your system language directory.
As you can see here, you can display the custom error in your view in the following way:
<?php echo form_error('new_error'); ?>
PS: If this isn't your problem, post your corresponding view code and any other error message that you're getting.
The problem is that your form is already validated in your IF part! You can fix the problem by this way:
if ($this->form_validation->run() == false){
$this->load->view("login/index", $data);
}else{
$return = $this->_submitLogin();
if ($return == true){
//success
}else{
$data['error'] = 'Your error message here';
//error
}
$this->load->view("login/index", $data);
}
In the view:
echo $error;
The CI way to check user credentials is to use callbacks:
$this->form_validation->set_rules('username', 'Username', 'callback_username_check');
...
public function username_check($str) {
// your code here
}
I recommend you to read CI documentation: http://codeigniter.com/user_guide/libraries/form_validation.html
The way I did this was to add another validation rule and run the validation again. That way, I could keep the validation error display in the view consistent.
The following code is an edited excerpt from my working code.
public function login() {
$this->form_validation->set_rules('email', 'Email', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
$data['content'] = 'login';
if($this->form_validation->run()) {
$sql = "select * from users where email = ? and password = ?";
$query = $this->db->query($sql, array($this->input->post('email'), $this->input->post('password')));
if($query->num_rows()==0) {
// user not found
$this->form_validation->set_rules('account', 'Account', 'callback__noaccount');
$this->form_validation->run();
$this->load->view('template', $data);
} else {
$this->session->set_userdata('userid', $query->id);
redirect('/home');
}
} else {
$this->load->view('template', $data);
}
}
public function _noaccount() {
$this->form_validation->set_message('_noaccount', 'Account must exist');
return FALSE;
}
Require Codeigniter 3.0
Using callback_ method;
class My_controller extends CI_Controller {
function __construct() {
parent::__construct();
$this->form_validation->set_message('date_control', '%s Date Special Error');
}
public function date_control($val, $field) { // for special validate
if (preg_match("/^[0-9]{2}.[0-9]{2}.[0-9]{4}$/", $val)) {
return true;
} else {
return false;
}
}
public function my_controller_test() {
if ($this->input->post()) {
$this->form_validation->set_rules('date_field', 'Date Field', 'trim|callback_date_control[date_field]|xss_clean');
if ($this->form_validation->run() == FALSE) {
$data['errors']=validation_errors();
$this->load->view('my_view',$data);
}
}
}
}
Result:
if date = '14.07.2017' no error
if date = '14-7-2017' Date Field Date Special Error

Categories