0

I have an issue with private tempstore storage that I wasn't able to solve. I've implemented a webform handler, which populates data in this storage and then I'm creating tokens out of the saved values. This works fine, however, when anonymous user comes to page where token value is used, he/she sees last value saved in to the storage, before his/her session has been created.

This is strange, because setting a value for anonymous user should create a session for user, if it doesn't exist, yet: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21TempStore%21PrivateTempStore.php/function/PrivateTempStore%3A%3Aset/8.6.x Do you have any idea why this happens, please? Should I use module https://www.drupal.org/project/session_based_temp_store? Should I consider using Sessions directly (https://drupal.stackexchange.com/a/246268/7580)?

1
  • 1
    More likely the page where you're using that data has been cached for anonymous users which all share the same cached page content. You'll need to disable anonymous page caching on that page your outputting the data
    – Leigh
    Commented Oct 21, 2020 at 11:23

1 Answer 1

0

Yes, this looks very much like a caching problem. You don't need to disable the anonymous page cache, though, this happens automatically for requests with a session cookie. What you need is a cache context session in render arrays containing session data, no matter whether you serve anonymous or authenticated users:

public function build() {
  $session = \Drupal::request()->getSession();
  $build = [
   '#markup' => $session->get('value'),
  ];
  $build['#cache']['contexts'][] = 'session';
  return $build;
}

The private tempstore is for large amounts of data. See What is the difference between \Drupal::request()->getSession() and \Drupal::service('user.private_tempstore')?

4
  • Thanks. So this basically means that I need to override this part of a block definition of the module? /** * {@inheritdoc} */ public function getCacheContexts() { return Cache::mergeContexts(parent::getCacheContexts(), ['url.path']); } Commented Oct 21, 2020 at 11:56
  • No, add the cache context directly to the build array the block plugin returns. session is a default auto placeholder condition and then the block cache methods no longer work. See drupal.stackexchange.com/questions/288881/…
    – 4uk4
    Commented Oct 21, 2020 at 12:13
  • Thanks. I added following hook implementation to my module: function mymodule_block_build_social_sharing_block_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) { $build['#cache']['contexts'][] = 'session'; } But it didn't help. Am I doing something wrong? Commented Oct 21, 2020 at 19:57
  • My answer is more about that you need to add a cache context, not where. So I've assumed you have a render element in the build array which displays a session value. If you add the session value in a different place I would suggest to add the cache data at the same place. Tokens can also bubble up cache metadata. But there are a lot of things that can go wrong if you have for example a custom token placed in a contrib/custom block rendered via a custom theme.
    – 4uk4
    Commented Oct 22, 2020 at 8:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.