Hi

I wrote a wizard using the CTools Framework. The wizard is for registration purpose, so only anonymous user will use the wizard. According to the documentation, I disabled caching of form for the wizard.

But unfortunately CTools Wizard won't work.

I debugged and found the following problem:

1. function ctools_object_cache_set()

- CTools saves the $storage variable in the ctools_object_cache table using the session id of the user.

2. function ctools_object_cache_get($obj, $name, $skip_cache = FALSE) {}

- CTools retrieves the object cache using the session id (session_id()).

Unfortunatly on every page reload, in my case the session id for an anonymous user was different.

Does someone know a solution for this problem? I need some kind of a constant session id for anonymous user.

Comments

merlinofchaos’s picture

I haven't tried this, but a conversation I had at Drupalcon suggested this might come up.

The proposed solution: In the first _submit callback for the wizard, add something to $_SESSION which will force Drupal to keep a permanent session for that anonymous user.

It's entirely possible that the caching system should do this automatically.

ayalon’s picture

I think I figured out the problem. Maybe it's because I'm using Drupal Pressflow.

Anyway, this is an issue that will raise problem with Drupal 7, which has the same session handling mechanism as Pressflow.

I finally found the solution in the mollom issue queue:
http://drupal.org/node/562374

The wrote a patch that saves the session id in the user session to force a session for anonymous user.

I made a path that works exactly the same way and solves the session id problem.

Can anyoune have a look at this and this?

merlinofchaos’s picture

Yeah, that's what I was thinking of. Can we do this *only* for the anonymous user? We don't need to do this for authenticated users, so why waste the bits?

merlinofchaos’s picture

I'm thinking this:

  if (empty($GLOBALS['user']->uid) && empty($_SESSION['ctools_session_id'])) {
ayalon’s picture

You are right, it's necessary for anonymous users only.

But I think your code will not work. Anonymous user have a $user->uid = 0 and not empty.

  // Store the CTools session id in the user session to force a
  // session for anonymous users in Drupal 7 and Drupal 6 Pressflow.
  // see http://drupal.org/node/562374
  if ($GLOBALS['user']->uid == 0 && empty($_SESSION['ctools_session_id'])) {
    $_SESSION['ctools_session_id'] = session_id();
  }

I have implemented the code above and it works well.

merlinofchaos’s picture

  $foo = 0;
  empty($foo) == TRUE;

=)

merlinofchaos’s picture

Also, I'm not sure we really need to even put the session ID there. I'm not sure it matters, but since the information is superfluous, let's put something more meaningful there.

  $_SESSION['ctools_hold_session'] = TRUE;

That's much more descriptive.

ayalon’s picture

Ok, I followed your advice. Attached you find a new patch.

Can you please review and commit it?

merlinofchaos’s picture

Status: Active » Needs review
merlinofchaos’s picture

Status: Needs review » Fixed

Ok, your patch is malformed -- it's a patch against your last patch rather than against current CTools.

It also seems you're placing this in cache_get -- but I'd rather do it in cache_set. There's no point in holding the session ID unless we are actually writing data.

Committed a version that goes in the cache_set function.

function ctools_object_cache_set($obj, $name, $cache) {
  // Store the CTools session id in the user session to force a
  // session for anonymous users in Drupal 7 and Drupal 6 Pressflow.
  // see http://drupal.org/node/562374, http://drupal.org/node/861778
  if (empty($GLOBALS['user']->uid) && empty($_SESSION['ctools_session_id'])) {
    $_SESSION['ctools_hold_session'] = TRUE;
  }

  ctools_object_cache_clear($obj, $name);
  db_query("INSERT INTO {ctools_object_cache} (sid, obj, name, data, updated) VALUES ('%s', '%s', '%s', %b, %d)", session_id(), $obj, $name, serialize($cache), time());
}

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.