Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unset session in SilverStripe

I am building a pretty simple online shop in SilverStripe. I am writing a function to remove an item from the cart (order in my case).

My setup:

My endpoint is returning JSON to the view for use in ajax.

public function remove() {

    // Get existing order from SESSION
    $sessionOrder = Session::get('order');

    // Get the product id from POST
    $productId = $_POST['product'];

    // Remove the product from order object
    unset($sessionOrder[$productId]);

    // Set the order session value to the updated order
    Session::set('order', $sessionOrder);

    // Save the session (don't think this is needed, but thought I would try)
    Session::save();

    // Return object to view
    return json_encode(Session::get('order'));
}

My issue:

When I post data to this route, the product gets removed but only temporarily, then next time remove is called, the previous item is back.

Example:

Order object:

{
  product-1: {
    name: 'Product One'
  },
  product-2: {
    name: 'Product Two'
  }
}

When I post to remove product-1 I get the following:

{
  product-2: {
    name: 'Product Two'
  }
}

Which appears to have worked but then I try and remove product-2 with and get this:

{
  product-1: {
    name: 'Product One'
  }
}

The SON OF A B is back! When I retrieve the entire cart, it still contains both.

How do I get the order to stick?

like image 921
nickspiel Avatar asked Oct 19 '22 07:10

nickspiel


1 Answers

Your expectation is correct, and it should work with the code you wrote. However, the way the session data is managed doesn't work well with data being deleted, because it is not seen as a change of state. Only existing data being edited is seen as such. See Session::recursivelyApply() if you want to know more. Only way I know is to (unfortunately) emphasized textmanipulate $_SESSION directly before you set the new value for 'order'

public function remove() {

  // Get existing order from SESSION
  $sessionOrder = Session::get('order');

  // Get the product id from POST
  $productId = $_POST['product'];

  // Remove the product from order object
  unset($sessionOrder[$productId]);
  if (isset($_SESSION['order'])){
    unset($_SESSION['order']);
  }
  // Set the order session value to the updated order
  Session::set('order', $sessionOrder);

  // Return object to view
  return json_encode(Session::get('order'));
}
like image 77
jfbarrois Avatar answered Oct 22 '22 21:10

jfbarrois