I have a gap in understanding Controllers utilization even after visiting the documentation multiple times. I have the following:
class Membership extends CI_Controller
{
/*Load the login view first assuming user is member*/
public function index()
{
$this->load->view('login');
}
/*if not member, load register view*/
public function register()
{
$this->load->view('register');
}
/*view to recover user credentials*/
public function recover()
{
$this->load->view('recover');
}
public function enroll_user()
{
/*Retrieve post parameters*/
$fullname = $this->input->post('fullname');
$email = $this->input->post('email');
$mobile = $this->input->post('mobile');
$home = $this->input->post('home');
$username = $this->input->post('username');
$password = $this->input->post('password');
$confirmPassword = $this->input->post('cpassword');
}
}
now example when user clicked on Register Now link on the main page, the register() function should load the view. But after he completes the form and submit it, to which function should I submit it? Does this mean I have to create two functions per functionality, one to load the view (register.php) and the second one to handle the operation of that function (enroll_user)?
You can do this in just one shot
public function register()
{
$post = $this->input->post();
if($post){
// do other stuff here
// you can load view here too if validation fails
}else{
$this->load->view('register');
}
}
And in you form use this
echo form_open(current_url());
In your register.php put the action of the form to memebership/enroll_user so when the user submits the registration form the action will be submited to enroll_user function and it will take care of the registration etc.
You need two functions, one for displaying the registration form and other for handling the submitted data. You can do it using one controller but its good practice to do it in two controllers because it will be easier for you to find out which function is doing what later.
Related
Currently if i accessed main/subscriber am able to view page when not logged in I have created a function in Main controller -refer to User role page redirect codeigniter for clarity on code.
public function subscriber() {
$this->load->view('header', $data);
$this->load->view('dashboard/subscriber', $data);
$this->load->view('footer');
}
The simplest way to protect your different routes based on user is logged in or not, use a session variable.
when a user logged in in your app then set a sessio variable like this
$this->session->set_userdata('is_logged_in', TRUE);
and check that variable in constructor of a controller so that user is verified before calling any method.
class Demo_controller extends CI_Controller{
public function __construct(){
parent::__construct();
// check if user is logged in
if(!$this->session->userdata('is_logged_in')){
// user is not logged in then redirect user to any page you want
}
}
}
you can also use hooks for creating such system in Codeigniter
You need to protect your pages. Let's assume that your $_SESSION['email'] variable is only set when the user has logged in. We can use that as a flag to determine if the user is logged in.
Add these functions to your User_model (make sure the model is autoloaded).
public function is_logged() {
if (is_null($this->session->userdata('email')) {
redirect('main/login');
exit; // just in case
}
}
public function is_allowed($perm) {
$roles = $this->session->userdata('roles');
if ($roles !== 'admin' && $perm !== $roles) {
// maybe set flashdata so user knows why they were redirected
redirect('main/' . $roles);
exit; // just in case
}
}
Then controller:
class Subscriber extends CI_Controller {
public function construct() {
parent::__construct();
$this->user_model->is_logged(); // can merge with below func, just make sure it is called first (!imp)
$this->user_model->is_allowed('subscriber');
}
public function subscriber() {
$this->load->view('header', $data);
$this->load->view('dashboard/subscriber', $data);
$this->load->view('footer');
}
}
This is as basic as it gets. You can do it more fancy if you wish. I personally use a database-based ACL system.
Also consider renaming roles to just role in your db and elsewhere, it is confusing considering a user only has 1 role (given your previous question).
If you want to prevent user from accessing certain pages if not logged in codeigniter,
you should first set_userdata when login.
Change the controller as below. When session data are not empty it will redirect you to the specific page. Otherwise, 'write what needs to be done'.
public function subscriber()
{
if($this->session->userdata('id')!="")
{
$this->load->view('header', $data);
$this->load->view('dashboard/subscriber', $data);
$this->load->view('footer');
} else {
//your code here
}
}
I am working on login and search functionality using CodeIgniter.
What Exactly I am doing?
When the user searches something in the search form and on submitting that form I put a check if the user is logged in then it will directly show the result & if the user is not logged in then it redirects the user to the login page and I saved the search data in session as search_session_data.
I have a controller which redirects user regarding the session. If the user came directly to the login page then the user is redirected to the dashboard after login. but if the user is coming from search page then the user is redirected to the search result page after login.
I have mentioned the problem inside the code with a comment.
This is the controller:
public function get_the_search_result() {
$search_session_data = $this->session->userdata('search_session_data');
$this->load->model ('my_model');
$result_data = $this->my_model->find_data_regarding_search_criteria($search_session_data);
$this->load->view ('app/app_statch_result',['result_data' => $result_data,]);
}
public function login_function() {
//necessary login code
if ($this->session->userdata('search_session_data')) {
//Here I want the if `search_session_data` available in session then
// user goest to `get_the_search_result` and view the
//'app/app_statch_result` but it is not working.
$this->get_the_search_result();
} else {
return redirect('dashboard');
}
}
So How do I redirect the user to app_statch_result from
login_function function?
Any suggestion regarding improvement is applicable. Thanks
If I were you, I would do the following:
Create login controller, or better, library and put all login logic inside that class. Then you can load that library from any controller... For example:
Sample library
class User_controll{
private $CI;
public function __construct() {
$this->CI = &get_instance();
}
public function check_user_data($username, $password) {
$tmpId;
// To increase security you can encrypt password
$user = $this->CI->db->from('users')->where(array('username' => $username, 'password' => $password))->get()->result();
if(count($user) == 1){
$this->CI->session->set_userdata('loggedIn', 1);
redirect('user_page');
}
}
protected function logout() {
$this->CI->session->set_userdata('loggedIn', 0);
}
public function isLoggedIn() {
return $this->CI->session->userdata('loggedIn') == 1;
}
}
Sample Controller
class User_page extends CI_Controller{
public function __construct() {
parent::__construct();
$this->load->library('User_controll');
}
public function index() {
if(!$this->user_controll->isLoggedIn()){
redirect('user_page/loginForm');
}
else {
// do whatever you want
}
}
}
I am trying to build a simple login system using CodeIgniter. I have placed all of my functions into one controller and I have also placed a session check function called is_logged_in into the controller. However, the user can still copy and paste the URL once they have logged out and view the main page. It seems like my is logged in function isn't working. Am I missing something? It only works if I place a check in my header every time instead. Here is my code.
Controller file
function index()
{
$this->load->view('login');
}
function checklogin()
{
$this->load->model('user');
$query = $this->user->validate_login();
if($query)
{
redirect('portal/home');
}
else
{
$this->index();
}
}
function logout()
{
$this->session->unset_userdata('username');
$this->session->unset_userdata('is_logged_in');
$this->session->sess_destroy();
redirect($this->index(),'refresh');
}
function is_logged_in()
{
$is_logged_in = $this->session->userdata('is_logged_in');
if(!isset($is_logged_in)||$is_logged_in!=TRUE)
{
$this->index();
}
}
function home()
{
$this->is_logged_in();
$data['main_content'] = 'home';
$this->load->view('includes/template',$data);
}
function statements()
{
$this->is_logged_in();
$data['main_content'] = 'statements';
$this->load->view('includes/template',$data);
}
function about()
{
$this->is_logged_in();
$data['main_content'] = 'about';
$this->load->view('includes/template',$data);
}
}
?>
This is what I place into my headers that actually works instead of the function
<?php
if(!$this->session->userdata('is_logged_in'))
{
redirect('portal/index');
}
?>
User Model
<?php
class User extends CI_Model{
function __construct()
{
parent::__construct();
}
public function validate_login()
{
//$this->form_validation->set_rules('username', 'Username', 'trim|required');
//$this->form_validation->set_rules('password', 'Password', 'trim|required');
$username = $this->security->xss_clean($this->input->post('username'));
$password = $this->security->xss_clean(md5($this->input->post('password')));
$this->db->where('username', $username);
$this->db->where('password', $password);
$query = $this->db->get('accounts');
if($query->num_rows()==1)
{
foreach($query->result() as $row)
{
$sess_data = array(
'username'=>$this->input->post('username'),
'is_logged_in'=>TRUE,
'privilege'=>$row->privilege
);
}
$this->session->set_userdata($sess_data);
return true;
}
else
{
// echo $password;
}
}
}
?>
Also, how can I combine the commented out part in the user model with the next lines? I want an error message to be sent if no input is placed. Hope I can get help with this.
So much wrong in this. Do not, not ever, use a single controller for your application. Things will get pretty big, pretty fast, and then you have one unreadable blob of a file. Keep your application code normalized. That's why you are using MVC. If you then need a method accessible from every, or nearly every controller, then put this function into a base controller(MY_Controller i.e.), or a model, or a library, depending on the functionality of this method. But in your case, this is for a base controller. This wont help with your problem, but just a friendly suggestion.
The problem with your code is, the visitor hits the URL for method "statements" and this is what happens:
statements calls is_logged_in
is_logged_in determines user is not logged in and calls index
index loads the login view
statements method loads the statements view
After you check for log in, and determine that the user is not logged in, you have to prevent further execution of other parts of your code. I would suggest having is_logged_in method returning a bool(false) value, and the statements(and other methods) then stopping execution. But if you would separate your code like you should over multiple controllers, then maybe have the is_logged_in controller to redirect the user to the login page.
I am new to codeigniter. I have a controller users which loads a login view.
class user extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->helper(array('form'));
}
public function login()
{
$this->load->model('user_images');
$data = $this->load->model('login');
$this->load->view('login', $data);
}
}
In the login model I handle all the validation and processing. If there is a validation error or the like I return $data['msg'] = 'some error message'; I pass this data via $data = $this->load->model('login'); to $this->load->view('login', $data); and in view I echo $msg. However upon submission the form processes, if I enter the correct credentials I get logged in, however if I enter some wrong credentials the validation errors do not get passed to the view. I am moving this project over from an non-framework environment, so I am sure that the validation rules work .etc. I am just not sure why the messages are not getting parsed on the view.
It looks like you are getting this wrong
$data = $this->load->model('login');
The load->model() loads the login_model and makes it methods available via
$this->login->youMethodHere().
f there is a validation error or the like I return $data['msg'] = 'some error message'; I pass this data via $data = $this->load->model('login'); to $this->load->view('login', $data);
When you return something from a method/function you do not return the variable. You return the value of the variable.
You should add you method to the login_model (perhaps this should be user_model...) and return ex. an array or mysqli result set from the model. Depeanding on what the models returns you should set the data.
$this->load->model('user_model');
$login_succes = $this->user_model->login($username, $password);
if( $login_success )
{
$data['msg'] = 'hurrah you did it
...
I have
login controller,model and view
url http://mySite/login
Now when i am at http://mySite/controller it shows the login form and then when i submit the form the run method is called so the url change to http://mySite/login/run
how can i stop this :?
P.S // I creat my own MVC following this tut : http://www.youtube.com/watch?v=2Eu0Nkpo6vM
login controller
class Login extends Conroller {
function __construct() {
parent::__construct();
}
function index()
{
$this->view->render('authentication/enter');
}
function run()
{
$this->model->run();
}
}
login model
class Login_Model extends Model
{
public function __construct()
{
parent::__construct();
}
public function run()
{
$sth = $this->dbh->connect()->prepare("SELECT UserID FROM users WHERE
username = :login ");
$sth->execute(array(':login' => $_POST['login']));
$data = $sth->fetch();
$count = $sth->rowCount();
if ($count > 0) {
// login
Session::set('loggedIn', $_POST['login']);
header('location: ../dashboard');
} else {
echo 4;
}
}
}
withour .htacces
the url is
http://mySite/index.php?url={controller name}
or
http://mySite/index.php?url={controller name}/{some method from the contoller}
Without watching that entire video or wondering too hard why you're re-inventing the PHP MVC wheel, here's my best guess.
Change your view's form to submit to the index action
<form method="post" action="login" ...
In your index action, detect a POST request and run the model's run() method from there
function index()
{
if ($this->request->isPost()) { // seriously, I'm just guessing here
$this->model->run();
}
$this->view->render('authentication/enter');
}
A couple of notes...
Don't do controller tasks (ie redirecting) from the model
Always exit; after sending a Location response header
Drop this mess and try a proven and tested MVC framework like Symfony or Zend