web-dev-qa-db-fra.com

Comment stocker les valeurs soumises dans un formulaire dans la session?

Je souhaite soumettre un formulaire et stocker les valeurs soumises dans la session. Dans Drupal 7 je viens d'utiliser $_SESSION['key'] = $value; mais comment puis-je l'implémenter correctement dans Drupal 8?

7
Robin

Drupal 8 utilise Symfony's HttpFoundation Session Management , c'est donc là que l'API est documentée.

Si vous regardez dans core.services.yml vous pouvez trouver que le wrapper de Drupal est dedans.

session_manager:
  class: Drupal\Core\Session\SessionManager
5
Letharion

En D8, les données de session sont fournies par un objet de session symfony, qui est attaché à la demande. Voir cette comparaison de D7 contre D8:

Drupal 7:

function mymodule_session_counter_increment() {
  if (!isset($_SESSION['mymodule_count'])) {
    $_SESSION['mymodule_count'] = 0;
  }

  return $_SESSION['mymodule_count']++;
}

Drupal 8:

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

    return $value;
  }
}

Modifier l'enregistrement: Accéder aux données de session via l'objet Request

La gestion de session n'a pas changé. Vous n'avez rien à faire, car Drupal démarre automatiquement une session pour chaque demande et vous pouvez l'utiliser immédiatement.

Exemples comment obtenir la session:

Procédure

Dans le code procédural, obtenez la demande à partir de l'encapsuleur statique \Drupal:

$request = \Drupal::request();
$session = $request->getSession();
$session->set('mymodule_value', $value);

Contrôleur

Dans un contrôleur, vous pouvez extraire la demande de la pile d'arguments de route en incluant un paramètre de demande typé. Un exemple de UserController:

  public function resetPass(Request $request, $uid, $timestamp, $hash) {          
    ...
    $session = $request->getSession();
    $session->set('pass_reset_hash', $hash);
    $session->set('pass_reset_timeout', $timestamp);
    ...
  }

Il n'est pas nécessaire de définir le paramètre d'itinéraire dans la définition d'itinéraire. La demande est toujours disponible.

Formulaire

Dans une méthode de formulaire, obtenez la demande de getRequest():

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $session = $this->getRequest()->getSession();
    $session->set('mymodule_form_value', $form_state->getValue('value'));
  }

Magasin temporaire privé

Le magasin temporaire privé ne remplace pas les sessions. Cela dépend de l'ID de session et il n'est pas possible de l'utiliser sans session. Vous pouvez donc également stocker les valeurs directement dans la session. Drupal core utilise le magasin temporaire privé pour une grande quantité de données et uniquement pour les utilisateurs authentifiés qui ont déjà une session. Pour les utilisateurs anonymes, il n'est pas facile de démarrer un magasin temporaire privé, car drupal utilise des identifiants de session factices jusqu'à ce qu'il démarre une session réelle. Si vous démarrez un magasin temporaire privé dans du code personnalisé, il a le mauvais identifiant de session.

9
4k4

Voici un article sur la façon d'utiliser le service approprié pour stocker des données dans la session: http://atendesigngroup.com/blog/storing-session-data-drupal-8

Il existe deux méthodes décrites dans l'article, voici la première qui n'utilise pas l'injection de dépendance. (le code n'est pas le mien)

Pour définir des données temporaires:

// For "mymodule_name," any unique namespace will do.
// I'd probably use "mymodule_name" most of the time.
$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$tempstore->set('my_variable_name', $some_data);

Pour lire des données temporaires:

$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$some_data = $tempstore->get('my_variable_name');
2
cambraca

Pour stocker temporairement des données dans la session, dans Drupal 8.5 et supérieur, il y a le tempstore.private service qui, par exemple, est utilisé à partir du formulaire de modification de nœud pour stocker temporairement l'aperçu du nœud.

  public function form(array $form, FormStateInterface $form_state) {

    // Try to restore from temp store, this must be done before calling
    // parent::form().
    $store = $this->tempStoreFactory
      ->get('node_preview');

    // Attempt to load from preview when the uuid is present unless we are
    // rebuilding the form.
    $request_uuid = \Drupal::request()->query
      ->get('uuid');
    if (!$form_state
      ->isRebuilding() && $request_uuid && ($preview = $store
      ->get($request_uuid))) {

      /** @var $preview \Drupal\Core\Form\FormStateInterface */
      $form_state
        ->setStorage($preview
        ->getStorage());
      $form_state
        ->setUserInput($preview
        ->getUserInput());

      // Rebuild the form.
      $form_state
        ->setRebuild();

      // The combination of having user input and rebuilding the form means
      // that it will attempt to cache the form state which will fail if it is
      // a GET request.
      $form_state
        ->setRequestMethod('POST');
      $this->entity = $preview
        ->getFormObject()
        ->getEntity();
      $this->entity->in_preview = NULL;
      $form_state
        ->set('has_been_previewed', TRUE);
    }

    /** @var \Drupal\node\NodeInterface $node */
    $node = $this->entity;
    if ($this->operation == 'edit') {
      $form['#title'] = $this
        ->t('<em>Edit @type</em> @title', [
        '@type' => node_get_type_label($node),
        '@title' => $node
          ->label(),
      ]);
    }

    // ...

  }

  /**
   * Form submission handler for the 'preview' action.
   *
   * @param $form
   *   An associative array containing the structure of the form.
   * @param $form_state
   *   The current state of the form.
   */
  public function preview(array $form, FormStateInterface $form_state) {
    $store = $this->tempStoreFactory
      ->get('node_preview');
    $this->entity->in_preview = TRUE;
    $store
      ->set($this->entity
      ->uuid(), $form_state);
    $route_parameters = [
      'node_preview' => $this->entity
        ->uuid(),
      'view_mode_id' => 'full',
    ];
    $options = [];
    $query = $this
      ->getRequest()->query;
    if ($query
      ->has('destination')) {
      $options['query']['destination'] = $query
        ->get('destination');
      $query
        ->remove('destination');
    }
    $form_state
      ->setRedirect('entity.node.preview', $route_parameters, $options);
  } 

Avant Drupal 8.5, le service est user.private_tempstore , qui sera supprimé dans Drupal 9.0.

Étant donné que vous souhaitez stocker les valeurs soumises, qui, je suppose, ne sont utilisées que pour une période de temps limitée et ne sont plus nécessaires après la connexion ou la déconnexion de l'utilisateur, j'utiliserais la même approche que celle utilisée à partir de Drupal core pour afficher un aperçu d'un nœud avant qu'il ne soit créé/enregistré. Il a également le pro que la suppression des données se fasse automatiquement.

2
kiamlaluno

Avant de lancer le vôtre, voyez si le module Session Node Access fait ce dont vous avez besoin.

1
Rubix05

Les sessions (Drupal 8) sont utilisées via l'implémentation de session simple de l'interface SessionInterface.

Les sessions Symfony sont conçues pour remplacer plusieurs fonctions natives PHP. Les applications doivent éviter d'utiliser session_start (), session_regenerate_id (), session_id (), session_name () et session_destroy () et utiliser à la place les API dans la section suivante.

Sessions Drupal 8

Exemple:

use Symfony\Component\HttpFoundation\Session\Session;

$session = new Session();
$session->start();

// set and get session attributes
$session->set('name', 'Yash');
$session->get('name');

// set flash messages
$session->getFlashBag()->add('notice', 'Profile updated');

// retrieve messages
foreach ($session->getFlashBag()->get('notice', array()) as $message) {
    echo '<div class="flash-notice">'.$message.'</div>';
}
1
Yash Khandelwal

Vous pouvez utiliser "\ Drupal :: service ()".

Pour définir des données temporaires:

$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$tempstore->set('my_variable_name', $some_data);

Pour lire des données temporaires:

$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$some_data = $tempstore->get('my_variable_name');

Vous pouvez vous référer à ce tutoriel pour plus de détails.

1
Tim Kariuki

que diriez-vous ? :

    $session = new Session();
    $session->set('key', 'value');

    $key= $session->get("key");
    var_dump($key);
0
Matoeil