delete an array in list array in laravel session - php

I have a session to save cart info in laravel like this:
$item = [
'id' => 1,
'product_id' => 11
];
$item2 = [
'id' => 2,
'product_id' => 22
];
\Session::push('cart', $item);
\Session::push('cart', $item2);
Now I want delete an Item in array for $id=1:
foreach(\Session::get('cart') as $cart)
{
if($id==$cart['id'])
{
echo 'done';
\Session::forget('cart.' . $i);
}
$i++;
}
It print done but it can not delete that item in list.
what is my wrong?
also I try \Session::pull('card.id', $id);
EDIT
with dd(\Session::get('cart'))
array:4 [▼
2 => array:5 [▼
"id" => 1
"product_id" => "11"
]
3 => array:5 [▶]
4 => array:5 [▶]
5 => array:5 [▶]
]
So I try change the code to this:
foreach(\Session::get('cart') as $key->$cart)
{
if($id==$cart['id'])
{
\Session::forget('cart.' . $key);
}
}
But It can not delete too

I'm pretty sure that cart.{$id} is not a session key, as you're only explicitly setting cart, which is an array. This should work for you instead:
$id = 1; // set from request, etc.
$cartSession = session()->get("cart");
foreach($cartSession AS $index => $cart){
if($index == $id){
unset($cartSession[$index]);
}
}
session()->put("cart", $cartSession);
Essentially, you pull the session to a variable (array), loop that and unset where $index matches $id, then set the remaining array back as "cart".
Note: I'm using session() instead of \Session, which is just Facade vs global function; shouldn't make a difference on which you use, unless below a certain Laravel version (< 5.0 I believe)

Related

Effective way to unset session array in php/symfony

php unset is working but on reload the session data is still there:
I'm building simple addtocart and remove from cart in php/symfony5, but I'm unable to unset the array from multi dimension array in symfony session.
^ array:3 [▼
0 => array:1 [▼
"items" => array:4 [▼
0 => 9
1 => "Dry fruit"
2 => "1234"
3 => "250g"
]
]
1 => array:1 [▼
"items" => array:4 [▼
0 => 8
1 => "Pumpkin"
2 => "123"
3 => "x"
]
]
This is my cart controller:
$basket = $session->get('basket',[]);
dump($basket);
$size = $session->get('size');
if($request->isMethod('POST')){
$id = $request->request->get('0');
foreach($basket as $key => $value){
if($value['items'][0] == $id){
unset($basket[$key]['items']);
dd($basket);
//$session->set('basket',[]);
//return $this->redirectToRoute('cart');
}
}
}
On the above code when I click remove button in twig and when dd($basket) is done the array is empty like below:
^ array:3 [▼
0 => [] //empty
1 => array:1 [▼
"items" => array:4 [▼
0 => 8
1 => "Pumpkin"
2 => "123"
3 => "x"
]
]
But, when I comment dd($basket) and page is reloaded the array is as it is like before(seems reverted idk) and if I uncomment $session->set('basket',[]); everything is empty.
what I want to achieve here is, how to remove array from session multi dimension array?
You simply need to set the session variable to the updated $basket value.
// get a copy of the basket from the session
$basket = $session->get('basket',[]);
// do whatever to update $basket here
// overwrite the basket in the session
$session->set('basket', $basket);
// then return a Response

how to add an item to array in laravel

i have a function that it fills the one array like below :
if (isset($options[$attribute->id][$optionId])) {
foreach ($options[$attribute->id][$optionId] as $item) {
. . . .
$attributeOptionsData[] = [
'id' => $optionId,
'label' => $attributeOption->label ? $attributeOption->label : $attributeOption->admin_name,
'swatch_value' => $attribute->swatch_type == 'image' ? $attributeOption->swatch_value_url : $attributeOption->swatch_value,
'products' => $options[$attribute->id][$optionId],
'images' => $productImage ?? null,
];
dd($attributeOptionsData);
}
the result of this dd is like below :
array:1 [▼
0 => array:5 [▼
"id" => 1
"label" => "black"
"swatch_value" => "#000000"
"products" => array:1 [▶]
"images" => "product/4618/rAkC2aC3QJB6kMiAAzIGk6nUzGHxpdfIS55g3T0P.jpeg"
]
]
now what i want to do is that after the last line add some content to this array and make it like below:
array:1 [▼
0 => array:5 [▼
"id" => 1
"label" => "مشکی"
"swatch_value" => "#000000"
"products" => array:1 [▶]
"images" => "product/4618/rAkC2aC3QJB6kMiAAzIGk6nUzGHxpdfIS55g3T0P.jpeg"
"custom_field" => "some value"
]
]
on the line that i dd the array i want add the customfield to it . how can i do that thanks in advance.
the reason i dont insert like others in that i want to add the custom field in a foreach loop based on 1 field of that array
So, if you simply want to add something at the bottom of an array, just use array_push().
In your case, you would need to retrieve the whole $attributeOptionsData[] in a foreach loop and append the array to the key you're in, during that loop. Be aware that this is somehow inefficient. If you want to add a line based on a value you can retrieve in the first foreach loop, you could've just made an if-statement asking for that value and add it with array_push() afterwards.
Either way, I think this is what you're looking for:
if (isset($options[$attribute->id][$optionId])) {
foreach ($options[$attribute->id][$optionId] as $item) {
$attributeOptionsData[] = [
'id' => $optionId,
'label' => $attributeOption->label ? $attributeOption->label : $attributeOption->admin_name,
'swatch_value' => $attribute->swatch_type == 'image' ? $attributeOption->swatch_value_url : $attributeOption->swatch_value,
'products' => $options[$attribute->id][$optionId],
'images' => $productImage ?? null,
];
}
foreach($attributeOptionsData as $key=>$data){
array_push($attributeOptionsData[$key], ["custom_field" => "some value"])
}
}
$attributeOptionsData is an associative array. You can assign values to it by specifying the array $key:
$attributeOptionsData[$key] = $value;

Undefined index error while key exists in array

I'm pulling my hair on a proble which seems very simple, but I can't find a solution.
I have a simple $row array here :
array:2 [▼
"reference" => "ABCDEF"
"quantity" => "10"
]
I'm trying to parse it and retrieve quantities per reference using :
$line = [
'ref' => strtoupper($row["reference"]),
'quantity' => $row["quantity"]
];
I'm looping through array of lines using this code:
foreach ($rows as $row) {
$line = [
'ref' => strtoupper($row['reference']),
'quantity' => $row['quantity']
];
}
As a test, my main array $rows has 2 lines :
^ array:3 [▼
0 => array:2 [▼
0 => "ABCDEF"
1 => "10"
]
1 => array:2 [▼
0 => "WXCVBN"
1 => "3"
]
2 => array:1 [▼
0 => null
]
]
However, I'm getting the following error :
Undefined index: reference
Strangely enough, if I comment out the
'ref' => strtoupper($row["reference"]),
line, I can get the "quantity" value with no issue...
I know the key is in there, since the debug of the $row object gives the above result.
It must be dead simple... but I can't find the solution...
If anyone could please help ?
So apparently the $row variable a row from a bigger array that is used in a foreach loop.
This might be the solution to your problem.
$array = [
[ "reference" => "ABC", "quantity" => "10"],
[ "reference" => "ABC", "quantity" => "10"],
[ "reference" => "ABC", "quantity" => "10"],
];
$line[] = '';
foreach($array as $row)
{
$line['ref'] = $row['reference'];
$line['quantity'] = $row['quantity'];
}
In this example $array is your bigger array, i use it to test the example.
After that i create a empty array $line to append the "new" data.
Could you try this?
Edit:
After taking a look at your loop and the array i noticed that your array doesnt have a reference key. Can you try strtoupper(row[0])?
Viewing your code seems that you convert $row array to $line without rewrite key in new array.
your code
foreach ($rows as $row) {
$line = [
'ref' => strtoupper($row['reference']),
'quantity' => $row['quantity']
];
}
With your rewrite you can access $line data by index, not by key
array:3 [▼
0 => array:2 [▼
0 => "ABCDEF"
1 => "10"
]
...
]
My solution
If you want to access your $line data by key, you need to rewrite your loop as:
foreach($rows as $rowData) {
foreach($rowData as $rowKey => $rowValue) {
$data = [
'ref' => $rowKey => strtoupper$($rowValue),
'quantity' => $row['quantity']
];
}
$line[] = $data;
}

Laravel swap the position in collection - multidimensional array

Following is the array in the collection:
array:1 [▼
"online" => array:2 [▼
"IS-003" => array:19 [▼
"product" => Product {#831 ▶}
"quantity" => 1
"payment-option" => "online"
]
"HA4" => array:19 [▼
"product" => Product {#822 ▶}
"quantity" => 1
"payment-option" => "online"
]
]
]
Whenever a user changes the payment-option, accordingly the above array should change.
For instance, if HA4['payment-option'] is changed from online to cod, then there should be 2 arrays in parent array.
Following is the array that I want as result.
array:2 [▼
"online" => array:1 [▼
"IS-003" => array:19 [▼
"product" => Product {#831 ▶}
"quantity" => 1
"payment-option" => "online"
]
]
"cod" => array:1 [▼
"HA4" => array:19 [▼
"product" => Product {#822 ▶}
"quantity" => 1
"payment-option" => "cod"
]
]
]
The thing that I have tried so far but couldn't get the desired result:
$paymentOptionCart = collect();
foreach ($cart as $paymentType => &$details) {
foreach ($details as $c => $p) {
if ($c == $code) {
$details[$c]['payment-option'] = $request->option;
$paymentOptionCart->put($paymentType, $details);
unset($details[$c]);
}
}
}
On executing the above code, nothing happens except the payment-option is updated to cod.
I know I am making a silly mistake somewhere, but I am unable to locate where and how.
Can anybody help me out?
This should do your task:
$array = [
"online" => [
"IS-003" => [
"quantity" => 1,
"payment-option" => "online"
],
"HA4" => [
"quantity" => 1,
"payment-option" => "online"
]
]
];
$code = "HA4";
$request_option = "cod";
foreach ($array as $paymentType => $details) {
foreach ($details as $c => $p) {
if ($c == $code) {
$array[$request_option][$c] = $p;
$array[$request_option][$c]["payment-option"] = $request_option;
unset($array[$paymentType][$c]);
}
}
}
unset($details[$c]) seems to be the problem... this punches out the element at index 0, at the end of the first iteration - and index 1 should then become index 0, which subsequently will not be accessible at index 1, during the next iteration of the loop. just run the loop until the exit condition is met and then unset them all, not during the loop... or loop backwards, in order to keep the indexes intact; this would unset the last one element at first and the loop would not exceed the array boundaries.
having two different payment options within a single online order is rather an unlikely example, haven't seen this yet. people might rather post two orders (which implies, not only the business logic is flawed, but the array structure has an unfortunate design, which requires such messing around).
xdebug is great for understanding what is happening. even if my answer might not answer the question in code one can copy & paste (that's not my job), xdebug will tell you exactly what the problem is.

Update the value if same key of array or insert as new value

I am making a minimalist eCommerce web application using laravel framework and I am a newbie.
What I am trying to achieve is when a product exists in the session, I want to update the quantity of that product when Add to Cart button is clicked. And if it doesn't exists in the session, I want to insert it in the session.
Code that I have tried so far:
public function store( $id ) {
$product = Product::findOrFail( $id );
if ( \Session::has( 'cart' ) && is_array( \Session::get('cart') ) ) {
\Session::push('cart', ['product' => (int)$id, 'quantity' => 1 ]);
} else {
\Session::put('cart', ['product' => (int)$id, 'quantity' => 1 ]);
}
\Session::flash('added_product', 'Product Added in the cart');
return \Redirect::back();
}
The result of the above code is:
array:3 [▼
0 => array:2 [▼
"product" => 1
"quantity" => 1
]
1 => array:2 [▼
"product" => 2
"quantity" => 1
]
2 => array:2 [▼
"product" => 1
"quantity" => 1
]
]
Desired Result is:
array:2 [▼
0 => array:2 [▼
"product" => 1
"quantity" => 2
]
1 => array:2 [▼
"product" => 2
"quantity" => 1
]
]
Kindly help me out with this. Thanks.
UPDATE 1:
After Youssef Answer, I got the following result:
array:4 [▼
"product" => 1
"quantity" => 1
0 => array:2 [▼
"product" => 3
"quantity" => 1
]
1 => array:2 [▼
"product" => 2
"quantity" => 1
]
]
I don't know Laravel but i think you can just process the array like this:
public function store( $id ) {
$product = Product::findOrFail( $id );
if ( \Session::has( 'cart' ) && is_array( \Session::get('cart') ) ) {
$cart = \Session::get('cart');
$found = false;
foreach($cart as $i=>$el)
{
if($el['product'] == $id)
{
$cart[$i]['quantity']++;
$found = true;
}
}
if(!$found) {
$cart[] = ['product' => $i, 'quantity' => 1];
}
\Session::put('cart', $cart);
} else {
\Session::put('cart', [['product' => (int)$id, 'quantity' => 1 ]]);
}
\Session::flash('added_product', 'Product Added in the cart');
return \Redirect::back();
}
If the entry exists in the session you are creating and pushing a yet another item to the array which results in a duplicate result. You should probably change the if block to the following:
$value = Session::pull( 'cart', ['product' => int($id), 'quantity' => 0 ]);
$value['quantity'] += 1;
Session::put('cart', $value);
The pull method call will get you the cart value if it exists or create a new one if it doesn't exist (with quantity 0). It increments the quantity, which means it will rise by 1 if it's already there or set to 1 if it's the one you created in the pull call. The value is removed from session when you call pull so you will put back the new value into the session by calling put. Hope this gives a more concise code.
You can add array safety checks to the increment statement as: array_key_exists('quantity')

Categories