How to remove an item from session array in laravel - php

Here is the problem I have a session
session('products')
this is actually an array that contains id
session('products')
array:4 [▼
0 => "1"
1 => "2"
2 => "4"
3 => "1"
]
Now I want to delete lets say 4 How do I do that? I tried method
session()->pull($product, 'products');
But it didn't work!
Other solution
session()->forget('products', $product);
it also didn't work

You AFAIR have to firstly retrieve whole array, edit it and then set it again. If you want to delete by product ID, which is as I assume an array value, you can use this: PHP array delete by value (not key)
$products = session()->pull('products', []); // Second argument is a default value
if(($key = array_search($idToDelete, $products)) !== false) {
unset($products[$key]);
}
session()->put('products', $products);
Misunderstood question
Session::pull takes first parameter as the item do delete and second as the default value to return. You have mistaken the order of arguments. Try:
session()->pull('products'); // You can specify second argument if you need default value
As I can see in source, Session::forget expects string or array, so you should specify only the first parameter:
session()->forget('products');

This method isn't tested:
Session::forget('products.' . $i);
note the dot notation here, its worth the try. If that isnt working, you can always do this:
$products = Session::get('products'); // Get the array
unset($product[$index]); // Unset the index you want
Session::set('products', $products); // Set the array again

You can do it in the following way in case you have a function to delete an item from a cart
public function deleteProductoCart(Producto $producto) {
$cart = \Session::get('products');
unset($cart[$producto->id]);
\Session::put('products', $cart);
return redirect()->route('tu-ruta');
}

Related

Laravel make array and use strtolower

I have data like this:
array:1 [
0 => "No Brand,ddfg"
]
First of all this data is wrong, what I want is to have something like this:
array:2 [
0 => "No Brand"
1 => "ddfg"
]
So now its really an array :)
Then I need my array data transform to lower case like:
array:2 [
0 => "no brand"
1 => "ddfg"
]
Code
$sibarBrandsArray = SidebarManager::first()->pluck('brands')->toArray();
This return data like:
array:1 [
0 => "No Brand,ddfg"
]
And this is how my data looks like in database:
Any idea?
Solved
// get my table row
$sibarBrandsArray = SidebarManager::first();
// get my row column
$getBrandColumn = $sibarBrandsArray->brands;
// separate data in that column with comma
$separateBrands = explode(',', $getBrandColumn);
// lowercase each separated data
$brandsArray = array_map('strtolower', $separateBrands);
// dump the result
dd($brandsArray);
Result
array:2 [
0 => "no brand"
1 => "ddfg"
]
Laravel has a very efficient and easy way to work with arrays. It's called a collection. Click here to learn more. Don't convert your response to the array, use collection directly.
$sibarBrandsCollection = SidebarManager::first()->pluck('brands');
Laravel eloquent by default gives you collection instance when you get a response. so pluck in above call is nothing but calling pluck on collection instance. We can chain method to the collection and do manipulation as needed.
$sibarBrandsCollection = $sibarBrandsCollection->map(function ($name) {
return strtolower($name);
});
Above code will automatically convert all of your values to lowercase. Similarly, you can explode the value to get your intended result. At last, if you have to send data as array to the browser just add toArray() method at the end of your collection.
I would not use core PHP array function unless needed, Laravel collection is great way to work with arrays.
$yourArray = array_map('strtolower', $yourArray);
$yourArray = array_map('nestedLowercase', $yourArray);
function nestedLowercase($value) {
if (is_array($value)) {
return array_map('nestedLowercase', $value);
}
return strtolower($value);
}
or you can use:
$query->whereRaw('LOWER(`newsTitle`) LIKE ? ',[trim(strtolower($newsTitle)).'%']);

How to add to an decoded Json Array from the Database specific selected Values

I am working on a movie WebApp. The User selects Movies and it gets added to the database. the column movie_list is a JSON because
I want that every time a User add a movie it gets added to the Array and if its already in it I want that it doesn't get added to the array
The problem is instead of adding it to the existing array it will sometime overwrite the Array, just add a nested Array or just create a custom key (0,1,2,3).
I tried to function like
array_merge and array_add
// It does overwrite it
array['checkedMovie'] = 3
Also thought about for each, but sadly dont know how to realize it.
My Brain is squeezed up.
public function update(Request $request, TrackMovie $trackMovie)
{
$currentCheckedMoviesArray = DB::table('track_movies')->where('user_id', $trackMovie->user_id)->get('checkedMovie');
$currentCheckedMoviesArray = json_decode($currentCheckedMoviesArray, true)[0];
$newarraychecked=array_add($currentCheckedMoviesArray,$currentCheckedMoviesArray['checkedMovie'], $trackMovie->checkedMovie);
return dd($newarraychecked);
$current_length = DB::table('track_movies')->where('user_id', $trackMovie>user_id)->value('lengthOfMovie');
DB::table('track_movies')->where('user_id', $trackMovie->user_id)->update([
'lengthOfMovie' => $current_length + $trackMovie->lengthOfMovie,
'checkedMovie' => $newarraychecked;
]);
return dd(TrackMovie::all());
}
To make it a bit clearly I edited this because I think its because of my formatting.
$currentCheckedMoviesArray = json_decode($currentCheckedMoviesArray, true)[0];
// DD Result
array:1 [▼
"checkedMovie" => "["1", "2"]"
]
$trackMovie->checkedMovie
//DD Result
array:2 [▼
0 => "2"
1 => "4"
]
$newarraychecked=Arr::collapse($currentCheckedMoviesArray, $trackMovie->checkedMovie);
//DD Result
[]
Actual Result:
This is the result what I get on the above code
array:1 [▼
"checkedMovie" => "["1", "2"]"
]
There some more because I tested many things
array:1 [▼
"checkedMovie" => "["1", "2"]"
1 => "2"
2 => "4"
]
Expected Result:
The User is checking some movies.
// He already has some movies
checkedMovie = ["1","2","3"]
Now the Application Checks if it already existed the movie in the Database.
If it does not contain in the database I want to add it. User selects Movie ID (5,6)
checkedMovie = ["1","2","3","5","6"]
After that, it will overwrite the Database column value
If I have forgotten something to add up to the question, please comment it so I can edit the question!
Try with the following:
$checkedMovie=array(1,2,3);
$selectedMovie=array(3,4,5,6);
$checkedMovie=array_unique(array_merge($checkedMovie,$selectedMovie));
You can just push the new values to the array and then use array_unique to filter out the duplicates
Example:
public function update(Request $request, TrackMovie $trackMovie)
{
//Get Current Array from DB
$currentCheckedMoviesArray = DB::table('track_movies')->where('user_id', $trackMovie->user_id)->get('checkedMovie');
$currentCheckedMoviesArray = json_decode($currentCheckedMoviesArray, true)[0];
//Decode JSON array
$currentCheckedMoviesArray['checkedMovie'] = json_decode($currentCheckedMoviesArray['checkedMovie'])
//Push the new Movie to the array
$currentCheckedMoviesArray['checkedMovie'][] = $trackMovie->checkedMovie;
//Remove duplicates from the array
$newarraychecked = array_unique($currentCheckedMoviesArray['checkedMovie']);
....
}

Adding values to array in a loop

Iam working on a laravel project which stores values to a DB entry in loop on meeting certain conditions.
This first creates an array if the entry is for the first time and adds a value to it. Henceforth, it recalls the array and keeps adding values to it.
if(is_null($lead->shown_to)) {
$a = array();
array_push($a, "lead 1");
$lead->shown_to = serialize($cart);
$lead->save();
} else {
$a=unserialize($lead->shown_to);
array_push($a, "lead 2");
$lead->shown_to = serialize($a);
$lead->save();
}
To be able to create an array and add distinct elements to it repeatedly.
Is there a way to first check if the element exists in it or not. If it does, just move ahead, else add it?
Thanks in advance.
There're a couple of methods you can use.
You can first look for the value on the DB if exists using a column from the database like:
$result = Model::where( 'column', 'value' );
if ( $result ) {
// update already exists
} else {
// create one
}
// Retrieve flight by name, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// Retrieve by name, or instantiate...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
Also it depends what you are looking for as firstOrCreate persists the value into the DB where firstOrNew just creates a new instance where you need to call save()
to check a value exists in an array you can use array_search(). this will return the value if exists. if not it returns false.
if(!array_search('lead 2', $a)) {
// array does't has 'lead 2' so,
array_push('lead 2', $a);
}
In Laravel I would take advantage of the Collections because they have a lot of helpful methods to work with.
I would do something like this:
OPTION 1
//Depending on the value of $lead->show, initialize the cart variable with the serialization of the attribute or and empty array and transform it to a collection.
$cart = collect($lead->shown_to ? unserialize($lead->shown_to) : []);
//Ask if the collection doesn't have the given value. If so, added it.
if (!$cart->contains($your_value)) {
$cart->push($your_value);
}
//Convert to array, serialize and store
$lead->shown_to = serialize($cart->toArray());
$lead->save();
OPTION 2
//Depending on the value of $lead->show, initialize the cart variable with the serialization of the attribute or and empty array and transform it to a collection.
$cart = collect($lead->shown_to ? unserialize($lead->shown_to) : []);
//Always push the value
$cart->push($your_value);
//Get the unique values, convert to an array, serialize and store
$lead->shown_to = serialize($cart->unique()->toArray());
$lead->save();
You can get more creative using the collections and they read better on Laravel
I think you can use updateOrCreate, if not exists it will create now, if exists, it will update it, so you can keep assigning value to shown_to property
$lead= App\Lead::updateOrCreate(
['name' => 'Lead 1'],
['shown_to' => serialize($a)]
);
if you wan to keep the existing shown_to better to use json data, so that you can do like
$lead= App\Lead::updateOrCreate(
['name' => 'Lead 1'],
['shown_to' => json_encode(array_push(json_decode($a), $newData))]
);

Updating previous Session Array Laravel

I have an issue on how can I update my Previous array ?
What currently happening to my code is its just adding new session array instead of updating the declared key here's my code:
foreach ($items_updated as $key => $added)
{
if ($id == $added['item_id'])
{
$newquantity = $added['item_quantity'] - 1;
$update = array(
'item_id' => $items['item_id'],
'item_quantity' => $newquantity,
);
}
}
Session::push('items', $updated);
$items = Session::get('items', []);
foreach ($items as &$item) {
if ($item['item_id'] == $id) {
$item['item_quantity']--;
}
}
Session::set('items', $items);
If you have nested arrays inside your session array. You can use the following way to update the session: $session()->put('user.age',$age);
Example
Supppose you have following array structure inside your session
$user = [
"name" => "Joe",
"age" => 23
]
session()->put('user',$user);
//updating the age in session
session()->put('user.age',49);
if your session array is n-arrays deep then use the dot (.) followed by key names to reach to the nth value or array, like session->put('user.comments.likes',$likes)
I guess this will work for you if you are on laravel 5.0. But also note, that I haven't tested it on laravel 4.x, however, I expect the same result anyway:
//get the array of items (you will want to update) from the session variable
$old_items = \Session::get('items');
//create a new array item with the index or key of the item
//you will want to update, and make the changes you want to
//make on the old item array index.
//In this case I referred to the index or key as quantity to be
//a bit explicit
$new_item[$quantity] = $old_items[$quantity] - 1;
//merge the new array with the old one to make the necessary update
\Session::put('items',array_merge($old_items,$new_item));
You can use Session::forget('key'); to remove the previous array in session.
And use Session::push to add new items to Session.

How to change data of reference passed Array in Closure

I have an Eventbus that takes a filter name as its first parameter and a Closure as second parameter. Like this:
$this->EventBus->subscribe('FilterTestEvent', function(){/*Do Something*/});
It's called like this:
$filteredValue = $this->EventBus->filter('FilterTestEvent', $anyValue);
What I want now is to pass an array as reference to the Closure that then is changed in any way (here: add elements) and then return something as the filtered value:
$item_to_change = array('e1' => 'v1', 'e2' => 'v2');
$this->EventBus->subscribe('FilterTestEvent', function(&$item){
$item['new'] = 'LoremIpsum';
return true;
});
$filtered = $this->EventBus->filter('FilterTestEvent', $item_to_change);
Now I would a print_r($item_to_change) expect to look like the following:
Array
(
[e1] => v1
[e2] => v2
[new] => LoremIpsum
)
But instead it looks like the original array:
Array
(
[e1] => v1
[e2] => v2
)
The eventbus internally stores all closures and calls them if needed through call_user_func_array() with the closure as first argument and the value as the only argument array element.
How can I achieve what it's meant to do?
Source Code to the Eventbus: http://goo.gl/LAAO7B
Probably this line:
$filtered = $this->EventBus->filter('FilterTestEvent', $item_to_change);
is supposed to return a new filtered array, not modify the original one.
So check it:
print_r($filtered);
Passing by reference is possible by modifying a function (adding &):
function filter(&$array){ //Note & mark
$array['new_index'] = "Something new" ;
}
$array = array("a"=> "a");
filter($array); //The function now receives the array by reference, not by value.
var_dump($array); //The array should be modified.
Edit:
Make your callback return the filtered array:
$this->EventBus->subscribe('FilterTestEvent', function(&$item){
$item['new'] = 'LoremIpsum';
return $item ;
});
Passing by reference should not work here, because in the source code that $value variable is swapped with another value and returned after.
Ok. I found the answer. The filter function needs to be changed so that it accepts arrays as value, in which I can save the reference. For details see difference Revision 1 and Revision 2 of the Eventbus source code, here: goo.gl/GBocgl

Categories