Cant access codeigniter session variable until page refresh - php

Am using codeigniter to build an eCommerce site.
I have a method on controller where users enter their delivery information before checkout, the method saves the delivery information and creates a new session variable called "orderid" which has the value of the orderid as its value. After setting the session variable the method redirects to the checkout controller where i retrieve the "orderid" from the session to retrieve the order from the db for the user to confirm the information before paying.
The problem is, when the user is redirected to the checkout page, they dont see their delivery data.
When do this
echo $this->session->userdata('orderid');
I can see the value
But when i pass it to my method that supposed to return an array of data
$order = $this->orders->get_order($this->session->userdata('orderid'));
print_r($order);
I get an empty array array()
When the checkout page is refreshed it behaves correctly.
What could be the problem

In order for the session to work you have to add $this->load->library('session'); to your __contruct() function
public function __construct() {
parent::__contruct();
$this->load->library('session');
}

You cannot access session value like this
$order = $this->orders->get_order($this->session->userdata('orderid'));
You can use the following method it ll be work fine for you
$orderid=$this->session->userdata('orderid');
$order = $this->orders->get_order($orderid);
**please remembere load session library at constructor or in this function
$this->load->library('session');

Related

Strange behavior of Codeigniter session

I am working on an application built on CodeIgniter. This application extends its controllers using a custom controller CP_Controller which lives in application/core. It looks like this:
class CP_Controller extends CI_Controller {
var $settings;
var $body_classes = array();
var $data = array('theme' => 'cmodule');
public function __construct() {
parent::__construct();
// print_r($_SESSION);
}
...
}
The problem is, print_r($_SESSION);. If I uncomment it, it prints [__ci_last_regenerate] => 1589186369. That's fine. No custom session data.
But for a particular request only, this returns a whole array filled up with session stuff. Even if it is the only request I run in a brand new browser session or private mode.
In this scenario, what's stranger is that business logic has not yet reached execution and no sessions have been set before this point. Then how's it possible that at this point, in a blank browser session, I am getting session data. I am not able to figure out the origin of this session data, where is it being set into the session? It only calls parent::__construct(); before print_r.
Is there really any way a Codeigniter application can hook into session and populate a session at a very initial system bootstrap level (for that particular request only)? Or there could be any other way?
Thanks.

The Auth component still fetching older value of Session?

I am manually modifying some key of Auth session in beforeFilter of AppController.php by this code
public function beforeFilter(Event $event){
//$companyId = $this->Companies->find(.........
$this->request->session()->write('Auth.User.company_id', $companyId);
}
And in various actions of different controller i'm trying to get that stored companyid in session by following way
public function add(){
$companyId = $this->Auth->user('company_id');
debug($companyId); die;
}
When i see the value of $companyId, it is showing older value not updated one in beforeFilter method of AppController. However if i refresh the page and donot modify session again i will get updated $companyId value.
So my question is how can i update the value of Auth session data so that i can get updated value with $this->Auth->user('company_id') code in different places in same request?
The session storage used by the authentication component uses a buffering mechanism, ie the value from the session is usually only read once per request (unless it is being deleted/emptied).
https://github.com/cakephp/cakephp/blob/3.2.8/src/Auth/Storage/SessionStorage.php#L81-L83
So either read the value directly from the session in your controller action, or do not write to the session directly, but to the session storage, something along the lines of
$user = $this->Auth->user();
if (is_array($user) && $user) {
$user['company_id'] = $companyId;
$this->Auth->setUser($user);
}

Codeigniter session generates new session on every page

On every page I see that new session is generated with null userdata
On model constructor
$this->config->set_item('sess_table_name', 'xx_sessions');
Because I want to store this session in another table because the other session table is being used for another login activity
Login function
function login($username,$password)
{
$this->db->where('login',$username);
$this->db->where('pass',$password);
$q=$this->db->get('prof');
// print $this->db->last_query();
if($this->db->count_all_results())
{
$arr=$q->row();
// creating the session
$this->session->set_userdata('login',$arr->id);
$this->session->set_userdata('prof',$arr->profile_id);
// print_r( $arr);
}
else
return FALSE;
}
This login function is on a model. After login and generating the session the page redirects to another page, on that page I see the session builds without any problem but when I move to another page the session losses along with the userdata.
I use the following function to check session data
function print_session()
{
print_r( $this->session->all_userdata());
}
Where I'm wrong ? Tank_auth library and ion_auth library works fine .. I had already used the
Put the session library name into the autoloader configuration, in application/config/autoload.php:
$autoload['libraries'] = array('session');
Then it's available automatically in each controller and everywhere in your application and you get your session data from anywhere:
$session_id = $this->session->userdata('session_id');
And if you don't want to auto load session library then you have to initialize the Session class manually in your controller constructor, use the $this->load->library function:
$this->load->library('session');
For details have a look here:http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
Edit /application/config/config.php and set cookie domain variable
$config['cookie_domain'] = ".yourdomain.com";
It will work!
.yourdomain.com makes the cookie available throughout the domain and its sub-domains.
I have met same problem, and i have searched lots of pages.
I figured out that changing sess_cookie_name solves the problem(new sessions generating issue)
$config['sess_cookie_name'] = 'somenewname'

calling a controller function from a view in codeigniter

I'm a newbie to codeigniter and I'm attempting to write a function that would basically save a name and url to session data whenever you visited a certain page, then report it back in a small widget on the screen.
It's supposed to work as a kind of history function for what pages have been accessed and in what order. So far when working with test data it works great! however I'm trying to figure out how I can call the "add" function on each page that is visited, so we can supply the name and url of that page that was visited. Is there any way to do this? Or is there any way to report back a set of variables such as a name and url for a page after you visit it?
For example: say I visit page1, page2, page3, and page6 and I want each of those to show up in my history function. On each of those pages I would load the history view, and I would want to call the history's controller function "add(name,url)" and fill it in something like this:
add('page1','page1.php')
But I know that you're not supposed to access the controller from the history because that's not the way it's supposed to be done, however I cannot think of any better way to do this. Any help would be appreciated.
I don't know why dont you call this on every controller.
but if you want to call a function of the current controller, you have to get the instance of the current controller this way:
<?php
$CI =& get_instance();
$CI->method($param);
?>
the easiest way to do this would be to put a method in the constructor of your class. that way it will always run first thing, no matter what you are doing. remember that anything you can do in the controller -- sessions, validation, etc -- you can do in a model.
function __construct() {
parent::__construct();
// load model that has page tracker methods
$this->load->model( 'pagetracker_m' );
// call the method to track the pages, and have it return the results
if ( ! $this->history = $this->pagetracker_m->_trackpage(); ) {
echo 'Error getting history ' ; }
} // end construct
function something() {
// pass history to $data, then use echo $history->firstpage, etc in view
$data['history'] = $this->history ;
// call your view etc
}

CakePHP Auth User Information

In my view i am trying to display the current logged in users information and have figured i can do this by using
echo "Welcome back " .$this->Session->read('Auth.User.username'). "
This displays the username and i can use the same approach to display the other fields in that database row, however some of the other fields can update at anytime but does not update on the users page until they logout and login again.
Is this correct way to do it? or can this be done a better way and somehow put some code in the beforeFilter() in AppController to continue to update the variables on each page load?
If the database is updated from outside CakePHP and without calling any controller action it seems the only solution for this is making a query on every loaded page to get the current value.
For this, you should use the beforeFilter method on the AppController:
function beforeFilter(){
$user = $this->User->field('name', array('User.id' => $this->Session->read('Auth.User.id')));
$this->Session->write('Auth.User', $user);
}
Otherwise, you can make use of JavaScript and AJAX to get the data from time to time.
I prefer to get the real time data instead of the session data
var $uses = array('User');
function beforeFilter(){
$id = $this->Auth->user('id'); //Using the session's user id is fine because it doesn't change/update
$user_data = $this->User->findById($id);
$user_fname = $user_data['User']['fname'];
$this->set('fname', $user_fname);
}
//In your view
echo 'Welcome Back '. $fname . '!';
What if you just made an afterSave() on the User model, and in it, set $this->Session->write('Auth.User') = $user;
This is non-tested, but seems like it should work - then your session would always be up to date on any changes.
Edit:
Per your comment, if the data is being pulled from a third-party source that you don't have access to, and you need to make sure it's updated on EVERY page load, then yes, the AppController's beforeFilter() is just fine.
If, however you only need it on certain pages, or certain elements, you can call the update then, or via a requestAction of an element.

Categories