I need a way to store temporary data for anonymous users.
Apparently this is not possible with:
\Drupal::service('user.private_tempstore')
Unless you write a custom constructor for the session management and stuff, which seems a little far-fetched to me?
I tried using
\Drupal::service('user.shared_tempstore')
But that saves the temp data for all anonymous users. So it's not linked to a single user.
Using raw $_SESSION['data'] works fine, but I'm not sure if I'm supposed to be doing this in Drupal and how safe/unsafe it is to do this?
Sessions (Drupal 8) are used via the simple Session implementation of SessionInterface interface. See Complete Tutorial of Sessions (Drupal 8).
Example:
use Symfony\Component\HttpFoundation\Session\Session;
$session = new Session();
$session->start();
// set and get session attributes
$session->set('name', 'Yash');
$session->get('name');
// set flash messages
$session->getFlashBag()->add('notice', 'Profile updated');
// retrieve messages
foreach ($session->getFlashBag()->get('notice', array()) as $message) {
echo '<div class="flash-notice">'.$message.'</div>';
}
I am not answering your specific question (regarding $_SESSION) because I have successfully used:
$session = \Drupal::service('user.private_tempstore')->get('your_module');
$session->set('whatever', $whatever);
from within procedural code (i.e. hooks, themes) without problems.
Pay attention that this private tempstore has to be assigned to a module (for the lack of a better way of saying this) which is the purpose of this line
$session = \Drupal::service('user.private_tempstore')->get('your_module')
After you get the private tempostore you can now set and get the session values:
$session->get('whatever');
$session->set('whatever', $whatever);
EDIT
Sorry, you explained correctly. I didn't get the critical part 100% ;)
You can always access the Session object from the request.
$session = \Drupal::request()->getSession();
$session->set('whatever', 'hello');
$value = $session->get('whatever', 'default');
I've been using plain PHP $_SESSION variables for a while now.
Did some research on them and they should be perfectly safe to use.
They're working correctly everywhere I use them and they have been working correctly for a while.
Don't think there's any issue using them in Drupal 8.
Related
case:
When using kohana driven site from 2 different devices I randomly get both session data on each device. I'm using native sessions to store few objects, but they should be private on each device. What am I doing wrong?
for example:
public function load()
{
$session = Session::instance();
$this->dialog = $session->get('dialog');
}
public function save()
{
$session = Session::instance();
$session->set('dialog', $this->dialog);
}
it looks like some kind of caching problem. I tried to regenerate session id every time. I've got 1st id, then 2nd, then 3rd and when i clicked a link a got 1st id again.
Make sure caching is turned off in your bootstrap file. And the cookie variables are set correctly, especially the Cookie::$domain.
Also verify your session config file too. You can find more info here: http://kohanaframework.org/3.2/guide/kohana/sessions
I don't know much about joomla. I found this:
JFactory::getSession();
Here I found that there is an expire date, but I can't make it work.
http://www.techportal.co.za/joomla/joomla-tutorials/304
Could you give an working example?
Just want when a user reopen the browser the data stored in the last session to be available. Also have to say that I'm using an outside domain to login, so in this case I don't care about internal ways of joomla handling users.
The 4 sections you can see in the documentation you're using there need to be passed through in an array (called $options in the API)
So you'd need to pass
$time=99; //time in minutes
$options = array(
"expire" => $time,
);
$session =& JFactory::getSession($options);
Note by default this is handled by a param in the config area of Joomla in 2.5 upwards! This might well also be the case in 1.5 - I don't have a copy of 1.5 to hand.
Does anyone have any experience using this plugin? i've acquired the client library for php, and setup the appropriate functions in my controller. i get a valid response when i click "test" from the plugin settings page in vanilla, but now i'm stuck... where do i go from here?
to be more clear about the issue, i dont know what my next step is. What I mean is, I know I must be missing something... heres the controller function (or page) i'm using as the endpoint for the plugin :
// 1. Get your client ID and secret here.
$clientID = "1234";
$secret = "1234";
// 2. Grab the current user from your session management system or database here.
//so i check to see if the user is logged in to my codeigniter's auth
//all works fine
// 3. Fill in the user information in a way that Vanilla can understand.
$user = array();
if ($signedIn) {
// i then set these according to the user info of the logged in user
$user['uniqueid'] = '123';
$user['name'] = 'John PHP';
$user['email'] = 'john.php#anonymous.com';
$user['photourl'] = '';
}
// 4. Generate the jsConnect string.
$secure = true;
WriteJsConnect($user, $_GET, $clientID, $secret, $secure);
http://vanillaforums.org/docs/jsconnect is the docs site, which makes no mention of what to do past my current point.
I had to figure this out for myself as well, and did so finally last night. I have written up the files and put them into a github repo so that other people with CodeIgniter can enjoy the JsConnect features with their sites more easily. I really like it now that it is working!
You can download the code and just follow the readme here:
https://github.com/mandersondesign/JSConnect-Codeigniter
If there are any issues that you have, let me know and I will help you out!
I'm using the latest version of Codeigniter and tank_auth 1.0.9 on a site I'm building.
When using set_flashdata() and flashdata() respectivly, nothing is being returned on redirect but if I set sess_use_database to FALSE in the config it works.
I've searched around and couldn't find an answer -- Has anyone else run into this issue and fixed it?
I was having the same issue and figured out the problem. If you're storing sessions in the database, it will not work.
Tank Auth runs this code from the main library ( $this->tank_auth->logout() ):
$this->delete_autologin();
// See http://codeigniter.com/forums/viewreply/662369/ as the reason for the next line
$this->ci->session->set_userdata(array('user_id' => '', 'username' => '', 'status' => ''));
$this->ci->session->sess_destroy();
Then it runs this code from the auth controller ( $this->_show_message() ):
$this->session->set_flashdata('message', $message);
redirect('/auth/');
The problem is that since sess_destroy() was run prior to setting the flashdata, there is no database row to add the flashdata to, so the flashdata never gets set.
At this point there are a few solutions:
Option 1:
Add $this->ci->session->sess_create(); immediately after $this->ci->session->sess_destroy(); in function logout() in application/libraries/Tank_auth.php
This works because you are creating a new blank session where flashdata can be stored. A potential con for this is that you are performing more operations on the database (delete+insert).
Option 2:
Comment out/delete $this->ci->session->sess_destroy(); in function logout() in application/libraries/Tank_auth.php
This works because the session is not destroyed, allowing CI to perform only an update query to add flashdata. This is probably better than option 1 unless you absolutely need to destroy the session.
Option 3:
Set $config['sess_use_database'] to FALSE.
This works because a session is automatically created when it is requested again, as opposed to how it works when you store sessions in the database. Potentially less secure.
In the end, it is up to you to decide which option is best for your application.
if tank_auth does any internal redirects then you may lose the flash data on that redirect request.
Exactly.
CodeIgniter documentation specifies here:
http://codeigniter.com/user_guide/libraries/sessions.html
=============================
Destroying a Session
To clear the current session:
$this->session->sess_destroy();
Note: This function should be the last one called,
and **even flash variables will no longer be available**.
If you only want some items destroyed and not all, use unset_userdata().
=============================
I've digged into the system/libraries/Session.php file and saving flashdata triggers the sess_write() method which only UPDATES the database as you said.
To me a better fix is checking to make sure the session exist before setting the flashdata in show_message().
function _show_message($message)
{
// Patch for show_message() after logout(). Make sure the session exist before set_flashdata().
if(!$this->session->sess_read())
{
$this->session->sess_create();
}
$this->session->set_flashdata('message', $message);
redirect('/auth/');
}
Although I can tentatively see a solution to this, I was wondering if there may be a glaringly obvious simpler approach.
My aim is to use the first segment of a given URI to query the DB as to which controller should be run.
I assume I would have to reform the URI with the resultant controller name in segment 1, then allow the system to continue processing as normal (hence a pre_system hook).
Although not essential I would also like to hold a couple of other variables from the same DB request to be used later in the call stack, and assume this would have to be done using global variables?
Any better suggestions would be gladly received.
Thanks.
Should it be of use to anyone else, here is the code to acheive the desired result. This does however not take into account passing additional variables because I can live without them.
function set_controller()
{
include_once APPPATH.'config/database.php'; //Gather the DB connection settings
$link = mysql_connect($db[$active_group]['hostname'], $db[$active_group]['username'], $db[$active_group]['password']) or die('Could not connect to server.' ); //Connect to the DB server
mysql_select_db($db[$active_group]['database'], $link) or die('Could not select database.'); //Select the DB
$URI = explode('/',key($_GET)); //Break apart the URL variable
$query = 'SELECT * FROM theDomainTable WHERE domainName = "'.$URI[1].'"'; //Query the DB with the URI segment
if($results = mysql_fetch_array(mysql_query($query))){ //Only deal with controller requests that exist in the database
$URI[1] = $results['controllerName']; //Replace the controller segment
$_GET = array(implode('/',$URI)=>NULL); //Reconstruct and replace the GET variable
}
mysql_close($link); //Close the DB link
}
I wouldn't use global variables, Id prefer to store it in a library for retrieval later if possible. Global variables are kind of messy in the context of CI.
Although at pre_system Only the benchmark and hooks class have been loaded at this point. This means you're pretty-much stuck with global variables unless you can find a way to select the controller on pre_controller as all the base-classes are loaded and you can put the data somewhere more logical.