Add the subtracted value from previous user value in laravel - php

I have run into an issue where i am adding the point for a user with the previous point already stored in the table via laravel. Now I have an issue where i need to loop all the points of a specific user and I need to add in a new column for each entry the difference between the old previous point and the current point.
From the table i have first entry point is 1 , second entry point is 11, third is 21 and 4th is 22. Here what I need is, I need to loop all these data and for the first record i need to add the difference as 1 in new column and for second the difference between 1st and 2nd row are 10 and for 3rd the difference between 2nd and 3rd are again 10 and for 4th record th diff between the 3rd and 4th are 1.
Please someone provide me with a function which will help me to update new column with the difference in points based on previous and the current point

I assume you are using model
You can try this.
// $id is equal to user_id
function difference($id) {
// First get all your data
$data = YourModel::where('user_id', $id)->get();
// Loop all your data
foreach($data as $d) {
//get previous data
$last = YourModel::where('user_id',$id)->where('created_at', '<', $d->created_at)->first();
// if null then return zero else get the point
$last = isset($last) ? $last->points : 0;
// get the difference from the last
$dif = $d->points - $last;
// putting the difference to the data
$d->difference = $dif;
$d->save();
}
}
Hope this will help you...

Related

php how to navigate to previous and next value in an array

I have an array of blog_ids and i want to navigate to the previous and next blog_id in that array.
foreach($blog_ids as $blog_id) {
echo $blog_id.'<br />';
}
// output:
id_20200523214047
id_20200523003107
id_20200521125410
id_20200521123813
id_20200514222532
From the current page, i grab the id with $_GET['page'];
echo $_GET['page'];
// ouput
id_20200521125410 (3rd value of array)
How can i now navigate to the previous and next value in that array, from the current id i am?
Previous should be: id_20200523003107 and next should be id_20200521123813
If your array has sequential integer keys, then get the current key and then add or subtract one. If it is already at the first position then return the last one or if it is at the last position return the first one. That may not be the behavior you want, so just change what's after the ?? to whatever you want if next or previous don't exist:
$key = array_search($_GET['page'], $blog_ids);
$prev = $blog_ids[$key-1] ?? end($blog_ids);
$next = $blog_ids[$key+1] ?? reset($blog_ids);
For other arrays just re-index first with:
$blog_ids = array_values($blog_ids);
Also, after re-indexing and searching you could get all 3 with:
list($prev, $curr, $next) = array_slice($blog_ids, $key-1, 3);
PHP has functions for this:
https://www.php.net/manual/en/function.prev.php
https://www.php.net/manual/en/function.next.php
hth

How to sort foreach items from SQL by date (Today, Yesterday, 29 Aug, 28, etc.) in PHP?

Sorry, I couldn't explain it more in the title but here's the deal.
I have a SQL table with items which have a classic date column where I ordered them by date in the loop. Now I want to add an echo into an existing loop to display a row in the looped table which will show Items added today, Items added yesterday and so forth.
This is how I'd like it to look when looped. (The closest I got was it looped by every second and added echoed part per every item which was a total mess)
PS: Reading on google maybe it should be included as usort with if inside existing foreach?
----------------------------
Table
----------------------------
echoed `<tr><td>Added: today<td></tr>`
---------------------------
Item 1
Item 2
Item 3
---------------------------
echoed `<tr><td>Added: yesterday<td></tr>`
---------------------------
Item 4
Item 5
Item 6
Item 7
---------------------------
echoed `<tr><td>Added: 29 Aug<td></tr>`
---------------------------
Item 9
Item 10
Item 11
etc
Edit: Date format doesn't have to be 29 Aug. It's just for the reference I'll tweak it myself. I just need a help with the logic of how to implement this.
you should sort them first in the database!
then when looping through the items you essentially remember which section you last displayed, and before outputting the first row of a new section, you output the section title instead:
$current = null;
foreach($rows as $row) {
$display = date_create($row['timestamp'])->format('Ymd'); // or whatever!
// it must consistently return something that makes the following consistent:
if($display != $current) {
// add separator that contains "today" or "yesterday" or the date
echo '<tr><td>'.$display.'</td></tr>';
$current = $display;
}
// display the actual row here
}
the problem gets harder, if you want to also show separator rows for dates that don't exist in database. then, you would have to create a date object first, and subtract one day at a time until the date matches the rows date, outputting separators accordingly.
update: special displays (please note, that $today and $yesterday must be simple types like string or int or something for this to work):
// before the loop!
$today = date_create()->format('Ymd');
$yesterday = date_create("-1 day")->format('Ymd');
$replacements = [
$today => 'today', // or whatever
$yesterday => 'yesterday', // or whatever
];
in the loop when echoing the $display:
echo '<tr><td>'.($replacements[$display] ?? $display).'</td></tr>';
this will look, if the formatted date should be replaced.
You have mentioned that you have already got the data sorted on the basis of days i.e. the field "added".
What you can do next is to loop through the retrieved result set. This is how you can proceed.
$dtPrevDate = null;
The above variable is going to be useful for the purpose of comparison of the dates i.e. "added".
Now loop through the retrieved data:
foreach($data as $datum){
if($dtPrevDate == $datum['added']){
// Keep printing item
}
else{
echo "Item added on: $datum['added']";
}
$dtPrevDate = $datum['added'];
}
The essence of the above code is dependent on the sorting that you have already managed to do using MySQL.

PHP get key value OR max lower

I'v got this array:
$by_date = array(
"2018-10-05"=>54,
"2018-10-07"=>20,
"2018-10-08"=>31,
"2018-10-12"=>52
);
I want to get value by date, but if the date doesn't exist get the lowest date value
for example:
if the date is "2018-10-07" I'll get 20
and if the date is "2018-10-10" I'll get 31
that can go to bigger differences between the date and the last key in the array
For example, if the date is "2019-01-25" I'll get 52 because "2018-10-12" is the last key in the array.
Thanks for the help :)
You guys where right the previews answer wasn't good enough
I'v made a work around that works for me, not sure about efficiency
if (!isset($by_date[$testVal])){
$by_date[$testVal] = null;
ksort($by_date);
$date_key = array_search($price_date,array_keys($by_date));
$by_date[$testVal] = (array_values($by_date)[$date_key-1]);
}
$by_date_price = $by_date[$testVal];
Thank you for the help and comments
You can do it with a simple if condition that uses isset() to check for your input as a key on the array. If the condition is met, you return the matched value, otherwise, use max() and array_keys() to return the value with the highest key.
$by_date = array(
"2018-10-05"=>54,
"2018-10-07"=>20,
"2018-10-08"=>31,
"2018-10-12"=>52
);
$testVal = '2018-10-12'
if (isset($by_date[$testVal]))
return $by_date[$testVal];
else
return $by_date[max(array_keys($by_date))];

Reduce a Value from Each Iteration of Foreach in PHP

I am trying to redeem a value from the array. For example I have 20 Points and I am going to redeem from the list of earned points.
Here is my array structure which will shown as follows
$newstructure = array(
array('earnedpoints'=>'10','usedpoints'=>'0'),
array('earnedpoints'=>'25','usedpoints'=>'0'),
);
which has n number of data's(array).
I am trying to reduce the values from the earned points
Points to redeem : 20. In a foreach statement i am just
$remainingpoints=20; // Redeeming Points is named as in variable of $remainingpoints
foreach ($newstructure as $keys => $newone) {
if ($remainingpoints > $newone['earnedpoint']) {
$remainingpoints = $remainingpoints - $newone['earnedpoint'];
} else {
$remainingpoints = $newone['earnedpoint'] - $remainingpoints;
}
}
For the Point Redeeming for the first iteration of foreach earned point is 10, remaining point is 10 (based on above code) and used point is 10
For the second iteration the earned point is 25 but i want to redeem only 10 so i want to stop the loop once the redeeming values are finished (Previous Iteration 10 and Current Iteration 10)
I trying to get the result as (Redeem Point 20)
First Iteration Used Points 10 and Remaining Points is 10.
Second Iteration Used Points 10 and Remaining Points is 0.
Also I am trying to store the information as in the form of array too.
$newstructure = array(
array('earnedpoints'=>'10','usedpoints'=>'10','remainingpoints'=>'10'),
array('earnedpoints'=>'25','usedpoints'=>'10','remainingpoints'=>'0'),
);
Can anyone point me a right direction inorder to get this desired result?
First thing, in one place you use earnedpoints as your table key, and in loop you use earnedpoint.
This code should work for you:
<?php
$newstructure = array(
array('earnedpoints'=>'10','usedpoints'=>'0'),
array('earnedpoints'=>'25','usedpoints'=>'0'),
);
$remainingpoints=25; // Redeeming Points is named as in variable of $remainingpoints
foreach ($newstructure as $keys => $newone) {
if ($remainingpoints > $newone['earnedpoints']) {
$toRedeem = $newone['earnedpoints'];
}
else {
$toRedeem = $remainingpoints;
}
$remainingpoints -= $toRedeem;
$newstructure[$keys]['usedpoints'] = $toRedeem;
$newstructure[$keys]['remainingpoints'] = $remainingpoints;
/*
if ( $remainingpoints == 0 ) {
break;
}
*/
}
var_dump($newstructure);
In comment I put code where you could break your loop but when you break it, you won't have set used_points and remainingpoints for the following array values

Percentage Difference Loop Array

First time poster so I hope you can help me with what I think is a simple task but can't figure out.
I have a table called exports which among other things has a year and value field. I currently have data for the years from 1992 to 2011.
What I want to be able to do is extract this data from the database and then calculate the year on year percentage difference and store the results in an array so the data can be passed to a view file.
For example: ((1993-1992)/1992)*100) then ((1994-1993)/1993)*100) then ((1995-1994)/1994)*100) etc etc.
I need it to be flexible so I can add future data. For example I will eventually add data for the year 2012.
I'm really stuck as how to progress this. Help would be greatly appreciated.
If I'm understanding that correctly, the solution wouldn't have to be that complicated. A simple SELECT query to fetch the year and value, which you could then go through using a loop in PHP and calculate the percentages. Something like this:
<?php
// Get all the data from the database.
$sql = "SELECT year, value FROM exports";
$stmt = $pdo->query($sql);
// An array to store the precentages.
$percentages = [];
// A variable to keep the value for the last year, to be
// used to calculate the percentage for the current year.
$lastValue = null;
foreach ($stmt as $row) {
// If there is no last value, the current year is the first one.
if ($lastValue == null) {
// The first year would always be 100%
$percentages[$row["year"]] = 1.0;
}
else {
// Store the percentage for the current year, based on the last year.
$percentages[$row["year"]] = (float)$row["value"] / $lastValue;
}
// Overwrite the last year value with the current year value
// to prepare for the next year.
$lastValue = (float)$row["value"];
}
The resulting array would look like this:
array (
[1992] = 1.0,
[1993] = 1.2,
[1994] = 0.95
... etc ...
)

Categories