Przechowywanie danych / sesji dla anonimowego użytkownika

12

Pracuję w sklepie, a do koszyka muszę przechowywać przedmioty przed dokonaniem płatności.

  $tempstore = \Drupal::service('user.private_tempstore')->get('boutique');
  $tempstore->set('poids', $form_state->getValue('poids'));

Patrzę na usługę użytkownika dla:

pivate_tempstore i shared_tempstore

Ale to działa tylko w przypadku uwierzytelnienia użytkowników.

Czego mogę użyć do przechowywania danych? $ _SESSION? czy Drupal 8 ma na to usługę?

Kevin
źródło
Używam ciasteczek. Mam identyfikator i hash cookie, które sprawdzam, a następnie łączę identyfikator z tym, czego potrzebuję. Nie używam sesji, ponieważ D8 przestał ich używać również dla anonimowych użytkowników.
Ok i dlaczego nie używasz $ _SESSION?
Kevin

Odpowiedzi:

11

W Drupal 8 do zmiennych sesji można uzyskać dostęp poza żądaniem:

$session = \Drupal::request()->getSession();

Jeśli chcesz ustawić coś w sesji, możesz wykonać następujące czynności:

$profile = 'Person';
$session->set('profile', $profile);

Lub, aby pobrać zmienną sesji:

$details = $session->get('profile');
Duncanmoo
źródło
1
Spróbuję, żebyś mógł zapisać tablicę?
Kevin,
1
Tak, możesz przechowywać tablicę. Zmieniłem kod, aby dopasować go do pytania, ale mój tak naprawdę przechowuje tablicę.
Duncanmoo,
3
Walczyłem o uruchomienie innych rozwiązań - jest to tak proste i wydaje się, że faktycznie działa
Nate
jak usunąć zmienną sesji?
siddiq
Dzięki tej pracy doskonale
Kevin
17

Późne odpowiadanie, ale warto wspomnieć, że możesz korzystać z prywatnej przechowalni danych dla anonimowych użytkowników, o ile będzie ona mieć dostęp do aktywnej sesji. Aby to zrobić, musisz wstrzyknąć swojej klasie usługi dla magazynu tymczasowego, sesji i bieżącego użytkownika, takie jak:

public function __construct(PrivateTempStoreFactory $temp_store_factory, SessionManagerInterface $session_manager, AccountInterface $current_user) {
    $this->tempStoreFactory = $temp_store_factory;
    $this->sessionManager = $session_manager;
    $this->currentUser = $current_user;

    $this->store = $this->tempStoreFactory->get('myclass.storename');
}

public static function create(ContainerInterface $container) {
    return new static(
        $container->get('user.private_tempstore'),
        $container->get('session_manager'),
        $container->get('current_user')
    );
}

Musisz tylko upewnić się, że uruchamiasz menedżera sesji, jeśli użytkownik jest anonimowy, zanim będziesz musiał umieścić cokolwiek w magazynie tymczasowym:

if ($this->currentUser->isAnonymous() && !isset($_SESSION['session_started'])) {
    $_SESSION['session_started'] = true;
    $this->sessionManager->start();
}

Takie podejście może być preferowane, ponieważ oznacza, że ​​możesz użyć jednego systemu do tymczasowego przechowywania, niezależnie od tego, czy użytkownik jest zalogowany.

(Moje przykłady kodu są mniej więcej dosłownie z tego doskonałego samouczka na temat budowania formularzy wieloetapowych ).

lyserge
źródło
Co ciekawe, przyjrzę się temu, ale podoba mi się to podejście
Kevin
Zobacz, jak rozpocząć sesję w Drupal 8 (post beta6) drupal.org/node/2228871 . Może powinniśmy poprawić drugi fragment kodu w odpowiedzi.
David Riccitelli,
Zobacz także drupal.stackexchange.com/questions/163142/…
David Riccitelli,
3

Sesja może być anonimowa (uid = 0). Możesz po prostu użyć $ _SESSION, a Drupal zajmie się tym.

Przechowuj dane sesji:

$_SESSION['mymodule']['variablename'] = $tempdata;

Uzyskaj dane sesji:

$tempdata = $_SESSION['mymodule']['variablename'];

Aktualizacja 1: Obiekt sesji

Chociaż w rdzeniu D8 nadal trwają prace, zobacz ten problem Konwertuj zastosowania $ _SESSION na sesję symfony pobraną z żądania , możesz użyć obiektu sesji w żądaniu do przechowywania danych sesji. Ale nie mieszaj tego, dane przechowywane za pomocą jednej z tych metod nie są dostępne w drugiej. Zobacz tę odpowiedź, aby uzyskać więcej informacji Drupal 8 i zarządzanie sesjami :

class MymoduleSessionCounter {
  function increment(Request $request) {
    $session = $request->getSession();
    $value = $session->get('mymodule_count', 0);
    $session->set('mymodule_count', $value + 1);

    return $value;
  }
}

Aktualizacja 2: TempStore

TempStore wydaje się być bardzo popularny w D8. Ale przechowywanie niektórych wartości jak w tym pytaniu jest zbyt skomplikowane. Jest przeznaczony do dużych fragmentów danych, takich jak na przykład podgląd danych lub niezapisane widoki. Oto oficjalne zapisy zmian:

Uzyskaj dostęp do danych sesji za pośrednictwem obiektu Request

Dodano interfejs API TempStore do trwałego, przewidywalnego przechowywania danych bez pamięci podręcznej

4k4
źródło
tak, sesja może być anonimowa, ale najwyraźniej nie dla usługi użytkownika.
Kevin
W Drupal 8 najlepsza praktyka dyktuje, że powinieneś używać interfejsu do odczytu i zapisu danych do zmiennych sesji. Pozwala to na wymianę pamięci i lepszą przyszłość.
George
1

To $this->sessionManager->start();nie działało już dla mnie z powodu ostatniej aktualizacji. Zmieniłem to na$this->sessionManager->regenerate();

Dan Poenaru
źródło
Powinieneś dodać to jako komentarz do oryginalnej odpowiedzi, a nie jako nową odpowiedź
wranvaud,
1
@wranvaud, nie miałem wystarczającej reputacji, aby móc skomentować inną odpowiedź.
Dan Poenaru,