Armazenando dados / sessão para usuário anônimo

12

Estou trabalhando em uma loja e, para o carrinho, preciso armazenar itens antes do pagamento.

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

Eu dou uma olhada no serviço ao usuário para:

pivate_tempstore e shared_tempstore

Mas isso funciona apenas para autentica usuários.

O que posso usar para armazenar dados? $ _SESSION? ou Drupal 8 tem um serviço para isso?

Kevin
fonte
Eu estou usando cookies. Tenho um identificador e um cookie de hash que valido e, em seguida, associo o identificador ao que eu preciso. Não uso sessões porque o D8 também parou de usá-las para usuários anônimos.
Ok e por que você não usa $ _SESSION?
Kevin

Respostas:

11

No Drupal 8, as variáveis ​​da sessão podem ser acessadas fora da solicitação:

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

Se você deseja definir algo na sessão, pode fazer o seguinte:

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

Ou para recuperar uma variável de sessão:

$details = $session->get('profile');
Duncanmoo
fonte
1
Vou tentar, para que você possa armazenar uma matriz?
Kevin
1
Sim, você pode armazenar uma matriz, mudei meu código para alinhar com a pergunta, mas a minha está armazenando uma matriz.
Duncanmoo
3
Esforçou-se para conseguir que outras soluções funcionassem - isso é tão simples e parece realmente funcionar #
Nate
como excluir uma variável de sessão?
siddiq
Graças a esse trabalho perfeitamente
Kevin
17

Resposta tardia, mas vale a pena mencionar que você pode usar o tempstore privado para usuários anônimos, desde que o tempstore tenha acesso a uma sessão ativa. Para fazer isso, você precisa injetar sua classe com serviços para o armazenamento temporário, a sessão e o usuário atual, da seguinte maneira:

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')
    );
}

Então, você só precisa garantir que você inicie o gerenciador de sessões se o usuário for anônimo, antes de colocar qualquer coisa no armazenamento temporário:

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

Você pode achar essa abordagem preferível, pois significa que você pode usar um único sistema para armazenamento temporário, independentemente de um usuário estar conectado.

(Meus exemplos de código são extraídos mais ou menos literalmente deste excelente tutorial sobre como criar formulários de várias etapas .)

liserge
fonte
Interessante, eu vou dar uma olhada nele, mas eu gosto desta abordagem
Kevin
Dê uma olhada neste sobre como iniciar uma sessão no Drupal 8 (pós beta6) drupal.org/node/2228871 . Talvez devêssemos revisar o segundo fragmento de código na resposta.
David Riccitelli
Veja também drupal.stackexchange.com/questions/163142/…
David Riccitelli
3

Uma sessão pode ser anônima (uid = 0). Você pode simplesmente usar $ _SESSION e o drupal cuidará disso.

Armazene dados da sessão:

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

Obter dados da sessão:

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

Atualização 1: Objeto de Sessão

Enquanto ainda houver trabalho em andamento no núcleo do D8, consulte este problema. Converter usos de $ _SESSION em sessão symfony recuperada da solicitação , você pode usar o objeto de sessão na solicitação para armazenar dados da sessão. Mas não misture, os dados armazenados com um desses métodos não estão disponíveis no outro. Veja esta resposta para mais detalhes Drupal 8 e Session Management :

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

    return $value;
  }
}

Atualização 2: TempStore

O TempStore parece ser muito popular no D8. Mas é muito complicado armazenar alguns valores, como nesta pergunta. Ele se destina a grandes blocos de dados, como, por exemplo, dados de visualização ou visualizações não salvas. Aqui estão os registros oficiais de alterações:

Acessar dados da sessão através do objeto Request

API TempStore adicionada para armazenamento persistente e expirável de dados sem cache

4k4
fonte
A sessão yes pode ser anônima, mas aparentemente não para o serviço do usuário.
Kevin
No Drupal 8, a melhor prática ditaria que você deveria usar uma Interface para ler e gravar dados em variáveis ​​de sessão. Isso permite armazenamento permutável e um futuro melhor.
George
1

O $this->sessionManager->start();não estava mais funcionando para mim por causa da última atualização. Eu mudei para$this->sessionManager->regenerate();

Dan Poenaru
fonte
Você deve adicionar este como um comentário à resposta original, e não como uma nova resposta
wranvaud
1
@wranvaud, eu não tinha reputação suficiente para poder comentar outra resposta.
Dan Poenaru