Adding values to array in a loop - php

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))]
);

Related

Store array response as object inside array for options

I would like to been appending objects to instagram value instead of overwriting them if there is a new object that isn't repeated.
So I have this piece of code:
if (is_array($api_return)) {
$api_return += ['last_updated' => time()];
$this->instagram->set_user_id($api_return['user_id']);
$this->instagram->set_username($api_return['username']);
$this->instagram->set_access_token($api_return['access_token']);
$this->instagram->set_access_token_expiration($api_return['access_token_expiration']);
$this->instagram->set_last_updated($api_return['last_updated']);
// Show our authenticated message.
$page_content .= $this->get_admin_notice_content('green',
'auth-finished', $this->instagram->get_username());
update_option('instagram', $api_return);
}
What this does, is it takes $api_return which is a array and groups it into an object and saves it inside the database as this:
We have option_name which is instagram and then the value is:
a:5:{s:8:"username";s:16:"saint";s:7:"user_id";i:17841404774727369;s:12:"access_token";s:141:"IGQVJVR1N*****";s:23:"access_token_expiration";i:1650688769;s:12:"last_updated";i:1645536110;}
What I'm attempting to do:
Now I want to be able to save multiple object where the instagram key doesn't get overwritten but each new api_return gets stored as a new object if it's not the same in an array.
Here is an example:
authenticated_users = [
{s:8:"username";s:16:"saint";s:7:"user_id";i:17841404774727369;s:12:"access_token";s:141:"IGQVJVR1N*****";s:23:"access_token_expiration";i:1650688769;s:12:"last_updated";i:1645536110;}
{s:8:"username";s:16:"test3";s:7:"user_id";i:17841404774727369;s:12:"access_token";s:141:"IGQVJVR1N*****";s:23:"access_token_expiration";i:1650688769;s:12:"last_updated";i:1645536110;}
];
What is the best approach on storing the option value as an array with multiple objects?
You have to first load the option an then manually merge the values:
$current = get_option("instagram", []);
$newData = [
$api_return,
];
// Merge array $current and $newData into single array so
// $api_return is appended to $current and the option is updated.
update_option("instagram", array_merge($current, $newData));

Database data field check before Data insertion

I have a data coming from the HTML Page. And i want to check whether the date and the place values already exists. If they exists, it should throw an error saying Data is already present, if those date and place data is not there it should allow the user to save it.
Here is the code which i have written to save it,
public function StoreSampling(Request $request)
{
$date = Carbon::createFromFormat('d-m-Y', $request->input('date'))->format('Y-m-d');
$doctorname = Input::get('doctorselected');
$product = Input::get('product');
$product= implode(',', $product);
$quantity = Input::get('qty');
$quantity =implode(',',$quantity);
$representativeid = Input::get('representativeid');
//Store all the parameters.
$samplingOrder = new SamplingOrder();
$samplingOrder->date = $date;
$samplingOrder->doctorselected = $doctorname;
$samplingOrder->products = $product;
$samplingOrder->quantity = $quantity;
$samplingOrder->representativeid = $representativeid;
$samplingOrder->save();
return redirect()->back()->with('success',true);
}
I searched some of the Stack over flow pages. And came across finding the existence through the ID And here is the sample,
$count = DB::table('teammembersall')
->where('TeamId', $teamNameSelectBoxInTeamMembers)
->where('UserId', $userNameSelectBoxInTeamMembers)
->count();
if ($count > 0){
// This user already in a team
//send error message
} else {
DB::table('teammembersall')->insert($data);
}
But i want to compare the date and the place. And if they are not present, i want to let the user to save it. Basically trying to stop the duplicate entries.
Please help me with this.
There are very good helper functions for this called firstOrNew and firstOrCreate, the latter will directly create it, while the first one you will need to explicitly call save. So I would go with the following:
$order = SamplingOrder::firstOrNew([
'date' => $date,
'place' => $place
], [
'doctorname' => Input::get('doctorselected'),
'product' => implode(',', Input::get('product')),
'quantity' => implode(',',Input::get('qty')),
'representativeid' => Input::get('representativeid')
]);
if($order->exists()) {
// throw error
return;
}
$order->save();
// success
You need to modify your query to something like this:
$userAlreadyInTeam = SamplingOrder::where('date', $date)
->where('place', $place) // I'm not sure what the attribute name is for this as not mentioned in question
// any other conditions
->exists();
if (userAlreadyInTeam) {
// Handle error
} else {
// Create
}
You do not need to use count() as your only trying to determine existence.
Also consider adding a multi column unique attribute to your database, to guarantee that you don't have a member with the same data and place.
The best way is to use the laravel unique validation on multiple columns. Take a look at this.
I'm presuming that id is your primary key and in the sampling_orders table. The validation rule looks like this:
'date' => ['unique:sampling_orders,date,'.$date.',NULL,id,place,'.$place]
p.s: I do not see any place input in your StoreSampling()

Cannot use object of type stdClass as array when looping with array

I'm trying to get Count of a table called TestRunList that has the foreign key the same as another table called Testrun meaning i want to get count of how many testrunlist that single testrun has in the same page i did a forloop to get testrun id for each testrunlist but it didn't seem to work i get this error
Cannot use object of type stdClass as array
heres my Code in the controller
$data = DB::table('TestRun')->get();
$runs=array();
for ($i=0;$i<sizeof($data);$i++)
{
$testrunID=$data[$i]['TestRunID'];
$Testrunlist=TestRunList::where('test_run_id',$testrunID)->count();
$runs[$i]=[
'Countruns'=>$Testrunlist
];
}
return view('management.testrun.testrun-list')
->with('data',$data)
->with('runs', $runs);
$data is a Collection, you can't access using array syntax
$data = DB::table('TestRun')->get();
$runs = [];
$data->each(function ($row) use ($runs) {
$runs[] = [
'Countruns' => TestRunList::where('test_run_id',$row-> TestRunID)->count()
];
});
return view('management.testrun.testrun-list')
->with('data',$data)
->with('runs', $runs);
Always use
print_r($data);
if it's object run echo $data->username if array run echo $data['username'];
So you know what type of data you're dealing with.

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 create php array from mysql result, perform calculation, resort array, present results

I have a photo website on which I am trying to perform a query against a MySQL database. The query is against a concatenated field of 'title' and 'keyword' called 'title_keyword'.
I want to take the search results and sort them by a newly formed variable called 'sort_priority' which is checking to see if the search word is in the 'title' field. If it is in the 'title' field then I want to assign a value of 1 and if not in the title field then a value of 2. The resulting array will be sorted by 'sort_priority' and output to the screen.
Here is the logic I am using with PHP and MySQL:
1) Query the MySQL database and assign variables. (This works just fine)
2) Take the results, assign each field to a variable, create a new variable that performs a calculation on one of the variables returned
$data_array=array();
// get each row
while($row = mysql_fetch_array($result))
{
//get data
$image_id = "{$row['image_id']}";
$title = "{$row['title']}";
$imageurl = "{$row['imageurl']}";
// Create sort_priority to identify if search word is in title field.
//If it is then set to 1 to force this higher in the result list after sorting
$sort_priority = 2;
if(stristr($title,$search))
{ $sort_priority = 1;}
Everything above this point works. Now for the part I'm stumped on. How to create and add data to the array and then sort on my new $sort_priority variable.
Here is what I've written but it just doesn't work**
// Create array and sort by title then keyword (tk_sort)
$data_array = array(
'image_id' => $image_id,
'title' => $title,
'imageurl' => $imageurl,
'sort_priority' => $sort_priority);
// Obtain a list of columns
foreach ($data_array as $key => $row) {
$image_id[$key] = $row['image_id'];
$title[$key] = $row['atitle'];
$imageurl[$key] = $row['imageurl'];
$sort_priority[$key] = $row['sort_priority'];
}
// Sort the data with volume descending, edition ascending
// Add $data as the last parameter, to sort by the common key
array_multisort($sort_priority, SORT_ASC);
// end of array creation and sort
3) Output the newly sorted array to a table
Not sure how to get the data out of it. Do I have to use a loop or something?
You could just let MySQL do the majority of the work. This should work (haven't tried it myself):
SELECT CONCAT_WS('-', `title`, `keyword`) AS search_term,
IF( INSTR(`search_term`, 'your_search_value_here') > 0, 1, 2 ) AS priority_key,
`image_id`, `imageurl`
FROM table_name_here
ORDER BY `priority_key`;
HTH.

Categories