Codeigniter view executed twice when calling a function from constructor - php

I followed a tutorial on how to set up a login system for php apps in codeigniter. The logic when the user has session data is working great, but I have a problem when the user isn't logged in (f.ex. refreshes the page after a while). The view of "not_logged_in" gets executed twice when I were to call for the functin from constructor.
The following code works, but it means I gotta add the code for every function I add after.
class App extends CI_Controller {
function __construct()
{
parent::__construct();
}
private function logged_in()
{
$is_logged_in = $this->session->userdata('is_logged_in');
if (isset($is_logged_in) OR $is_logged_in)
{
return TRUE;
}
else
{
$data['title'] = 'Chyba přihlášení';
$data['main_content'] = 'not_logged_in';
$this->load->view('includes/template', $data);
return FALSE;
}
}
function index()
{
if($this->logged_in())
{
$data['title'] = 'APLIKACE';
$data['main_content'] = 'app_view';
$data['userid'] = $this->session->userdata('userid'); //get userid from session
$this->session->unset_userdata('userid'); //destroy the data
$this->load->view('includes/template' , $data);
}
}
function logout()
{
$this->session->sess_destroy();
redirect('login');
}
}
Now the real question, how would I go about putting the whole logic into a constructor without having to check for it in every function?

Make APPPATH.'core/MY_Controller.php' file and put authentication logic in constructor there. Than extend that class from every controller (you need auth logic).
class MY_Controller extends CI_Controller
{
public function __construct();
{
parent::__construct();
$this->check_login();
}
protected function check_login()
{
$is_logged_in = $this->session->userdata('is_logged_in');
//here should be *AND* instead *OR* logic
if (isset($is_logged_in) && !empty($is_logged_in))
{
return TRUE;
}
else
{
redirect('login/index');
exit();
}
}
}
Login.php controller:
class Login extends CI_Controller//NOT extending MY_Controller to avoid infinite loop
{
public function __construct();
{
parent::__construct();
}
public function index()
{
//here is login view
//and logic of preserving session
//with redirect to 'app/index' after successful login
}
public function logout()
{
$this->session->sess_destroy();
redirect('login');
}
}
App.php controller:
class App extends MY_Controller//extending MY_Controller to check login status
{
public function __construct();
{
parent::__construct();
}
public function index()
{
//here is app dashboard view
}
public function statistics()
{
//here is some other method that requires logged in user
}
}
I also would recommend you to check Ion_auth authentication system to see if suitable for you.

Related

which function should i use in place of redirect() in codeignitor?

I want user not to jump on my welcome page through URL so. I added session user data in the constructor but redirect is not working showing "ERR_TOO_MANY_REDIRECTS".. so I use header() and site_url and base_url too but not of these are working...
class Admin extends MY_Controller
{
public function __construct()
{
parent::__construct();
if (!$this->session->userdata('userId'))
return redirect('admin/index');
}
public function index()
{
$this->form_validation->set_rules('username', 'Username', 'required|alpha');
$this->form_validation->set_rules('pass', 'password', 'required|max_length[12]');
$this->form_validation->set_error_delimiters("<div class='text-danger'>","</div>");
if($this->form_validation->run())
{
$user=$this->input->post('username');
$pass=$this->input->post('pass');
$this->load->model('loginmodel');
$id=$this->loginmodel->isvalidate($user,$pass);
if($id)
{
$this->load->library('session');
$this->session->set_userdata('userId',$id);
return redirect('admin/welcome');
}
else
{
$this->session->set_flashdata('loginFailed','Invalid Username/password');
return redirect('admin/login');
}
}
else
{
$this->load->view('admin/login');
}
}
}
?>
A constructor allows you to initialize an object's properties upon creation of the object.
If you create a __construct() function, PHP will automatically call this function when you create an object from a class. (source)
In your code, admin redirect to admin (when the admin initialize, __construct() runs which causes to redirect to admin again.)
My suggestion: check sessions from the index method
public function index(){
if(!$this->session->userdata('userId')){
//code
}else{
$this->load->view('admin/login');
}
}
Edit: Thanks to TimBrownlaw
You can redirect to another controller.
redirect('accounts/admin_login');
class Accounts extends MY_Controller {
public function admin_login(){
if($this->session->userdata('userId')){
redirect('admin/index');
}else{
$this->load->view('admin/login');
}
}
}

Codeigniter redirect not working in __construct method

I am checking whether the user is logged in or not in constructor method, if not logged in then redirect to login method but it is looping infinite time.login method is defined in same controller.
issue:
1)For testing purpose just now I wrote same(login) method in 'Welcome' controller in that case it is working fine and redirect perfectly,after that I commented method in 'Welcome' controller and now login method is uncommented in user controller now it is not working
class User extends CI_Controller {
function __construct() {
parent::__construct();
is_logged_in(); // defined in custom helper
if (!is_logged_in()) {
redirect(base_url().'User/Login');
}
}
public function login(){
$this->load->view('loginpage');
}
}
//code in custom helper
function is_logged_in() {
$CI =& get_instance();
$user = $CI->session->userdata('id');
if (!isset($user)) {
return false;
}
else {
return true;
}
}
if your helper returns false your code never reaches the login function of the controller, it always passes by the constructor, which redirects and so on...
change this:
if (!is_logged_in()) {
$this->login();
}
now it calls the login function, if not logged_in(), otherwise it continues with the controller's index() function
Please Use Helper In Controller.
class User extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->helper('name');
$checkLogin = $this->helperName->is_logged_in(); // defined in custom helper
if (!$checkLogin) {
redirect(base_url().'User/Login');
}
}
I guess you autoload your helper.
Maybe your helper function need to changed
function is_logged_in() {
$CI =& get_instance();
$user = $CI->session->userdata('id');
if (!isset($user) || is_null($user)|| empty($user)) {
return false;
}else {
return true;
}
}
Try this way. This is working fine.
Controller
function __construct(){
parent::__construct();
if(!is_login()){
redirect(site_url().'/User/login');
}
}
Helper
function is_login(){
//Your Logic
return false;
}
autoload.php
$autoload['helper'] = array('your_helper_class_name');

How to redirect from view to controller in codeigniter?

In my header view I wrote this code:
<?php
if($this->session->userdata('logged_in')) {
$query = $this->db->get_where('instructors', array('id' => $this->session->userdata('id')));
$insdatacheck = $query->row_array();
if($insdatacheck['name'] == '') {
redirect(base_url().'user/continueregistration');
} else { ?>
<script type="text/javascript">alert('test');</script>
<?php
}
}
?>
But it does not redirect to the following page. However, if I write this in the controller, it works properly. I wrote it in header view because I want to check it in every page where enters the user. How can I improve it and write in a proper way? Thanks in advance
I think instead of your header you should put your check inside your controller constructor.
class Test extends CI_Controller {
function __construct() {
parent::__construct();
// if not logged-in redirect to login page
if ($this->session->userdata('logged_in') == false) {
redirect('login'); // where you want to redirect
}
}
}
Another option is to create a base controller. Place the function in the base controller and then inherit from this.
To achieve this in CodeIgniter, create a file called MY_Controller.php in the libraries folder of your application.
class MY_Controller extends Controller
{
public function __construct()
{
parent::__construct();
}
public function is_logged_in()
{
$user = $this->session->userdata('user_data');
return isset($user);
}
}
Then make your controller inherit from this base controller.
class X extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function do_something()
{
if ($this->is_logged_in())
{
// User is logged in. Do something.
}
}
}
First create session in the controller only,
Then we access session in any page,
$this->load->library('session');
$user=$this->session->userdata('logged_in');
if (!isset($user)) {
redirect(base_url().'user/continueregistration');
}
else {
<script type="text/javascript">alert('test');</script>
}

codeigniter check for user session in every controller

I have this private session in one of my controllers that checks if a user is logged in:
function _is_logged_in() {
$user = $this->session->userdata('user_data');
if (!isset($user)) {
return false;
}
else {
return true;
}
}
Problem is that I have more than one Controller. How can I use this function in those other controllers? Redefining the function in every Controller isn't very 'DRY'.
Any ideas?
Another option is to create a base controller. Place the function in the base controller and then inherit from this.
To achieve this in CodeIgniter, create a file called MY_Controller.php in the libraries folder of your application.
class MY_Controller extends Controller
{
public function __construct()
{
parent::__construct();
}
public function is_logged_in()
{
$user = $this->session->userdata('user_data');
return isset($user);
}
}
Then make your controller inherit from this base controller.
class X extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function do_something()
{
if ($this->is_logged_in())
{
// User is logged in. Do something.
}
}
}
Put it in a helper and autoload it.
helpers/login_helper.php:
function is_logged_in() {
// Get current CodeIgniter instance
$CI =& get_instance();
// We need to use $CI->session instead of $this->session
$user = $CI->session->userdata('user_data');
if (!isset($user)) { return false; } else { return true; }
}
config/autoload.php:
$autoload['helper'] = array('login');
Then in your controller you can call:
is_logged_in();
You can achieve this using helper and CodeIgniter constructor.
You can create custom helper my_helper.php in that write your function
function is_logged_in() {
$user = $this->session->userdata('user_data');
if (!isset($user)) {
return false;
}
else {
return true;
}
}
In controller if its login.php
class Login extends CI_Controller {
public function __construct()
{
parent::__construct();
if(!is_logged_in()) // if you add in constructor no need write each function in above controller.
{
//redirect you login view
}
}
I think using hooks is pretty easy. Just create a hook to check $this->session->user. It will be called in every request.
Get all user's data from session.
In the Controller,
$userData = $this->session->all_userdata();
In the View,
print_r($userData);
I coded like this according to above answers.. And this is running for me
Create file my_helper.php
<?php
function _is_logged_in() {
if(isset($_SESSION['username'])){
return true;
} else {
return false;
}
}
?>
Edit in autoload.php file
$autoload['helper'] = array('my');
In your Controller file
class Welcome extends CI_Controller {
public function __construct(){
parent::__construct();
if(!_is_logged_in())
{
redirect("Login");
}
}
}
Just add this on your folder core file ci_controller at function __construct() to check all controller ():
function __construct()
{
parent::__construct();
if(! $user = $this->session->userdata('user_data');)
{
return false;
}
}

How i can use a __construct function in my other CodeIgniter controller

I have a controller called member within this a construct function
function __construct()
{
parent::Controller();
$this->is_logged_in();
}
I want to check in my other controller that user is logged in how I can use this function in my other controller called profile and others
This is my First project with CodeIgniter
Your authentication checks should be in a library:
The is an excerpt from a basic codigniter authentcation script:
class Site_sentry
{
function Site_sentry()
{
$this->obj =& get_instance();
}
function is_logged_in()
{
if ($this->obj->session)
{
if ($this->obj->session->userdata('session_logged_in'))
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
function login_routine()
{
//do login here (enter into session)
}
}
This library is stored in application/libraries under a filename named after its class with the .php suffix.
Then you can either add this to your autoload config file application/conig/config.php:
$autoload['libraries'] = array('database', 'site_sentry', 'session');
or load it manually in each controller:
$this->load->library('Site_sentry);
Then you can check your session from within controllers, like so:
class Class extends Controller{
function Class()
{
parent::Controller();
if( $this->site_sentry->is_logged_in() == FALSE){
redirect('managerlogin/');
}
}
}
Also check this documentation page http://codeigniter.com/user_guide/libraries/sessions.html; of particular interest is the storing the session into the database section.
I don't think that doing it with the class is the best idea. If the user is logged in, you should check for a flag (value or whatever) inside the session, so you don't need to work with the other controller.
The advantage would be that the session can be accessed more easily and it is the more common approach.
Example with session:
class SomeClass extends Controller {
function __construct()
{
parent::Controller();
$this->is_logged_in();
}
function is_logged_in()
{
$is_logged_in = $this->session->userdata('is_logged_in');
if(!isset($is_logged_in) || $is_logged_in != TRUE)
{
redirect('login');
}
}

Categories