Question

I am trying to store data entered in the drupal custom form in order to display it in next page using session.

For the first time it is running perfectly, but for the second time it contains the same value in session which was entered previously.

After clearing caches (admin/config/development/performance/clear caches) it is working for the first time, retains the same problem.

/**
 * @file
 * Contains \Drupal\resume\Form\PaymentForm.
 */
namespace Drupal\resume\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\SessionManager;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\SessionManagerInterface;
use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;


class PaymentForm extends FormBase {

    /**
* @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;

/**
* @var \Drupal\Core\Session\SessionManagerInterface
*/
private $sessionManager;

/**
* @var \Drupal\Core\Session\AccountInterface
*/
private $currentUser;

/**
* @var \Drupal\user\PrivateTempStore
*/
protected $store;

public function getFormId() {
    return 'payment_form';
}

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('mymodule.storename');
}

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

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

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


$form['pay_first_name'] = array(
    '#type' => 'textfield',
    '#title' => ('First Name'),
);

$form['pay_last_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Last Name'),
);

$form['address'] = array(
    '#type' => 'textfield',
    '#title' => ('address'),
);


$form['email_id'] = array(
    '#type' => 'textfield',
    '#title' => t('email_id'),
);

$form['actions']['#type'] = 'actions';
$form['actions']['payment_submit'] = array(
  '#type' => 'submit',
  '#value' => $this->t('payment'),
  '#button_type' => 'primary',
);
return $form;
}


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

  $payment_array['first_name'] = $form_state->getValue('pay_first_name');
  $payment_array['last_name'] = $form_state->getValue('pay_last_name');
  $payment_array['line1'] = $form_state->getValue('address');
  $payment_array['email'] = $form_state->getValue('email_id');

  $session = \Drupal::service('user.private_tempstore')->get('resume');
  $session->set('payment_details', $payment_array);
    $form_state->setRedirect('payment_redirect.form');
    return;
  }
}
Was it helpful?

Solution

What you store in $session is not a session. A private tempstore is a different kind of storage for large amount of data, too big to have it preloaded in memory.

If you want to store a small amount of data, that does not exceed a few Megabytes, then use a session. You find the session attached to the request object:

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

In a form you can get the session from the injected request stack. Use $session->set() and $session->get() to store:

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

    $session = $this->getRequest()->getSession();
    $session->set('payment_details', $payment_array);

  }

and retrieve the data:

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

    $session = $this->getRequest()->getSession();
    $payment_array = $session->get('payment_details', []);

    // make sure the form is not cached and this code is run on every request
    $form['#cache']['max-age'] = 0;

  }

You don't need to start the session. This is done by Drupal in the background for each request:

When finishing the response, Drupal checks if there is new session data and then starts a session to store the data (which implies setting a cookie). When the user with the session cookie comes back, then the session is restored from the database and is attached to the request.

More info Drupal 8 and Session Management

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top