I was going to use the object cache for my module (see #1104208: consider using Ctools' object cache instead of our own) but it turns out I don't think I can.

The assumption that the session ID stays the same from the cache setting to the getting is baked into the API functions, and that's not really going to work for my use case.

So I'm going to carry on doing my own thing, but just filing this for consideration for future versions of the object cache system :)

Comments

merlinofchaos’s picture

Status: Active » Postponed

Yeah, I've thought about this somewhat. It's actually a really narrow cache for a very specific use-case, and that may not be quite ideal. The problem is, making it more generic is a pretty big can of worms.

I'll ponder it. There are reasons why I've thought bout changing it...having a wizard that can have temporary data cross multiple sessions is valuable, but removing that automation is tricky. It may need to be a separate system with similar goals.

joachim’s picture

What about just storing the cache ID in the session, so the wizard takes responsibility for knowing the cache ID -- then there's no session assumption within the cache system? That doesn't seem like a huge change to me, but then again I've only glanced at this :)

tema’s picture

Here's my "quick and dirty" solution. Every wizard extends this class to use its own session key. Works for PHP5.3+ only.

/**
 * Ctools object cache with session key.
 */

abstract class SessionCache {

  const KEY = 'undefined';

  protected static function setSession() {
    $c = get_called_class();
    if (!isset($_SESSION[$c::KEY])) {
      $_SESSION[$c::KEY] = user_password(12);
    }
  }

  public static function set($data) {
    $c = get_called_class();
    self::setSession();
    ctools_include('object-cache');
    ctools_object_cache_set($c::KEY, $_SESSION[$c::KEY], $data);
  }

  public static function get() {
    $c = get_called_class();
    if (!isset($_SESSION[$c::KEY])) {
      return;
    }
    ctools_include('object-cache');
    return ctools_object_cache_get($c::KEY, $_SESSION[$c::KEY]);
  }

  public static function clear() {
    $c = get_called_class();
    ctools_include('object-cache');
    ctools_object_cache_clear($c::KEY, $_SESSION[$c::KEY]);
    unset($_SESSION[$c::KEY]);
  }
  // @todo: a method for garbage collection.
}

/**
 * Example
 */
class TestCache extends SessionCache {

  const KEY = 'test_cache';

  public static function get() {
    if (!isset($_SESSION[self::KEY])) {

      // Set defaults.
      parent::setSession();
      $data = 123;
      parent::set($data);
    }
    else {
      ctools_include('object-cache');
      $data = ctools_object_cache_get(self::KEY, $_SESSION[self::KEY]);
    }
    return $data;
  }
}

// Use it without class instantiation:

print TestCache::get(); // 123, $_SESSION['test_cache'] contains a string of 12 random alphanumeric chars.  

TestCache::set(111);

print TestCache::get(); // 111.

TestCache::clear(); // $_SESSION['test_cache'] is not set.

I'm new to Ctools and PHP OOP, so please correct me if I'm doing something wrong.

scottalan’s picture

Issue summary: View changes

Any updates on this one. I'm running into an issue now that I think falls under this same category.

When using ctools to create a multi-step form with the wizard I'm noticing something odd. I'm using ctools_object_cache. When I run the wizard without using a modal (ajax) it uses the same session_id throughout. Meaning, each time session_id() is called it returns the same $sid. When I run the wizard using the modal a new session_id is generated for each step of the wizard. This generates multiple entries in the {ctools_object_cache} table vs just clearing out the same object cache for each step and then rewriting it. I'm confused because there shouldn't be a difference using ajax or not. i've stepped through both the object-cache.inc and session.inc and nothing is standing out as far as why the session is regenerated using ajax and it's not being regenerated without. Thanks

ctools - 7.x-1.4

Open Atrium Profile

japerry’s picture

Status: Postponed » Closed (outdated)

Drupal 7 is no longer supported, closing.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.