Foreach loop "Group By" Key in PHP Array - php

I am so close to figuring this out, this is using Wordpress and Gravity Forms Plugin:
<?php
$form_id = '1'; // The registration form's ID
$entries = GFAPI::get_entries( $form_id ); // Get all entries
$html = "<table class='ent'>"; // Create an HTML table
$html .= "<tr><th>Name</th><th>Organization</th><th>Event</th><th>Date</th><th>Number Attending</th></tr>";
$list = array(); // Array to store the original fields
$used = array(); // Array to stored the "used" fields
// Loop through array of entries,each element
foreach($entries as $entry){
// Get datepart from datetime of event and today's date
$date = date_format(new DateTime($entry['8']), 'Y-m-d');
$today = date("Y-m-d");
// Compare event's date with current date
if ( $date >= $today ) {
$list[] = $entry;
if (!empty($used[$entry['6']])) // If used[event name] not null then sum associated numattend
{
$used[$entry['6']] += $entry['5'];
}
else // return associated numattend
{
$used[$entry['6']] = $entry['5'];
}
}
}
unset($entry);
foreach ($used as $key => $value) {
foreach ($list as $key1 => $value1) {
$html .= "<tr><td>" . $value1['1'] . " " . $value1['2'] . "</td><td>" . $value1['93'] . "</td><td>" . $value1['6'] . "</td><td>" . $value1['8'] . "</td><td>" . $value1['5'] . "</td></tr>";
}
$html .= "<tr class='ent_sum_rw'><td>" . " " . "</td><td>" . " " . "</td><td>" . " " . "</td><td class='ent_sum'>" . "Total Attending:" . "</td><td>" . $value . "</td></tr>";
}
unset($value);
$html .= "</table>";
return $html;
?>
Result:
I want the loop to end the entry list on the corresponding "Event Name", Like "Test Event 22" should not show up on the top entry list.

The trick is to populate an Array that meets your demands and after that convert it to html. I haven't tested the code, but it should be clear how it works.
$aEventList = Array();
foreach($entries as $entry){
if (!isset($aEventList[$entry['7']])){ //7 is id of event
//if this event is not made, create it and add name and the date, enter the right numeral
$aEventList[$entry['7']]['name'] = $entry['6'];
$aEventList[$entry['7']]['date'] = $entry['90'];
$aEventList[$entry['7']]['users'] = Array();
}
$aEventList[$entry['7']]['users'][] = Array('name' => $entry['1'] . ' '. $entry['2'],
'org' => $entry['93'],
'num' => $entry['5']);
}
//now you've populated every event and you can loop through it on your desired way:
foreach ($aEventList as $iEvent => $aEvent){
echo $aEvent['name']; //event name
echo $aEvent['date']; // event date
foreach ($aEvent['users'] as $aEventUser){
echo $aEventUser['name']; // user name
echo $aEventUser['org']; // user organisation
echo $aEventUser['num']; // num attendees
}
}

Related

Why is my for loop displaying the same item twice?

I am trying to display each item in a JSON array of reviews. There are two reviews in the array, but instead of displaying both of them, this code displays same one twice.
Why is this happening?
$response = curl_exec($curl);
$data = json_decode($response, true);
// Setup the Review for posting to the Mysql Database
// Loop through Reviews
for ($i=0; $i<count($data['reviews']); $i++) {
$id = $data['reviews']['0']['id']; // good
$stars = $data['reviews']['0']['stars']; //good
$title = $data['reviews']['0']['title'];
$text = $data['reviews']['0']['text'];
$createdAt = $data['reviews']['0']['createdAt'];
$companyReply = $data['reviews']['0']['companyReply']['text'];
$companyReplyDate = $data['reviews']['0']['companyReply']['createdAt'];
// Do Mysql insert for each row
// show this
echo "id: " . $id . "</br>";
echo "stars: " . $stars . "</br>";
echo "title: " . $title . "</br>";
echo "text: " . $text . "</br>";
echo "Created: " . $createdAt . "</br>";
echo "Reply: " . $companyReply . "</br>";
echo "Reply Date: " . $companyReplyDate . "</br> </br>";
}
curl_close($curl);
It is because you aren't actually using your loop increment variable to get different array keys. You're just selecting the ['0'] index repeatedly. Instead, use $i as the array key like this:
for ($i=0; $i<count($data['reviews']); $i++) {
$id = $data['reviews'][$i]['id']; // good
$stars = $data['reviews'][$i]['stars']; //good
$title = $data['reviews'][$i]['title'];
$text = $data['reviews'][$i]['text'];
$createdAt = $data['reviews'][$i]['createdAt'];
$companyReply = $data['reviews'][$i]['companyReply']['text'];
$companyReplyDate = $data['reviews'][$i]['companyReply']['createdAt'];
// ... etc.

php array , how to display array data in email

$qua1 = "5";
$queryNotification= "SELECT * from stock where stockQty <= :qua1 ";
$stmt3 = $conn->prepare($queryNotification);
$stmt3->bindParam(':qua1',$qua1);
$stmt3->execute();
while ($queryNotRow = $stmt3->fetch()){
$a=array("Qty"=>$queryNotRow['stockQty'],"name "=>$queryNotRow['stockName'],"cb "=>$queryNotRow['stockPrice']);
// $array[$queryNotRow['stockQty']] = $queryNotRow['stockName'];
foreach( $a as $row ):
$b = "stockqty = " . $queryNotRow['stockQty'] . " and StockName = " . $queryNotRow['stockName'] . "<br>";
endforeach;
echo $b;
}
If I add send email code inside the foreach loop , the system will send many email according on how many data. How can I only send all the data by ONE EMAIL??
$a=array("Qty"=>$queryNotRow['stockQty'],"name "=>$queryNotRow['stockName']);
foreach($a as $key=>$data){
echo 'stock'.$key.'='.$data.'<br/>';
}
foreach( $a as $row ):
echo "stockqty = " . $row['Qty'] . " and StockName = " . $row['name'] . "<br>";
endforeach;
try this,
$a[] = array(
"Qty" => 1,
"name " => 2
);
foreach ($a as $row) {
echo $row['Qty']."===".$row['name'];
}

php add random array not repeating most recent 5

I'm trying to re-write this code so that it goes with the columns that are going to be user-defined. With this, my challenge consists of
a) Needs to select random starting item from array
b) Select the next random color from the original array that is not equivalent to the most recent items selected based the number: $intNotesColumn + 1
I was thinking a do-while statement nested inside another was appropriate for this but am unsure how to go about this. Here is my code so far:
$metroUIcolors = array( "#A30061", "#8200CC", "008987", "#A05000", "#B85A93", "#C07807", "#E51400", "#297A29" );
$metroUIcolorsLength = count($metroUIcolors);
$intNotesColumn = 3; // This will be user-defined later
// Now I query the SQL database to get my base-code
if ($result->num_rows > 0) {
// output data of each row
echo '<table border=0 valign=top>'
. '<tr>'
. '<td colspan=' . $intNotesColumn . '>' . '<h1>header</h1>' . '</td>'
. '</tr>'
. '<tr>';
$counterRank = 1;
while($row = $result->fetch_assoc()) {
echo "<td bgcolor=" . $metroUIcolors[rand(0, $metroUIcolorsLength - 1)]. ">"
. "<h2>" . $row["username"] . '</h2><br />'
. "<p class='notes'>" . $row["notes"] . "</p>"
. "<p class='footnotes'>"
. "<br />Last Reset: " . $row["lastReset"]
. '<br />Last Update: ' . $row['lastUpdate']
. '<br />SessionID: ' . $row["sessionID"]
. "<br />Counter = " . $counterRank . "</td>". '</p>';
if ($counterRank % $intNotesColumn == 0)
{
echo '</tr><tr>';
}
$counterRank++;
}
echo '</tr></table>';
} else{
echo "No Notes Found in databases";
}
Then, why don't you do it order picking one color at a time. You could use shuffle() so that there will be a different starting color everytime.
<?php
$counterRank = 1;
// shuffle the array
shuffle($metroUIcolors);
while($row = $result->fetch_assoc()) {
$rand_color = $counterRank % $metroUIcolorsLength;
echo "<td bgcolor=" . $metroUIcolors[$rand_color]. ">";
// everything else
$counterRank++;
}
?>
If you insist on doing the way you said, you may create an array $colorCount which has color codes as keys and count as values.
<?php
$counterRank = 1;
$colorCount = array_fill_keys($metroUIcolors, 0);
while($row = $result->fetch_assoc()) {
do {
$rand_color = $metroUIcolors[rand(0, $metroUIcolorsLength - 1)];
} while ($colorCount[$rand_color] > 5);
echo "<td bgcolor=" . $rand_color. ">";
// everything else
$counterRank++;
$colorCount[$rand_color] += 1;
}
?>

Applying array_map recursively (array_walk_recursive?)

I have an associative array that is I am creating from an ODBC query with the following code:
while ($row=odbc_fetch_array($oexec)) {
if(empty($group[$row['gmm']])) {
$group[$row['gmm']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']] = array();
}
if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']])) {
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']] = array();
}
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_ty_yest_sales'] = $row['total_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_wo_dotcom_ty_yest_sales'] = $row['total_wo_dotcom_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['east_ty_yest_sales'] = $row['east_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['central_ty_yest_sales'] = $row['central_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['west_ty_yest_sales'] = $row['west_ty_yest_sales'];
$group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['dotcom_ty_yest_sales'] = $row['dotcom_ty_yest_sales'];
}
This gives me an array where:
$myArray = Array(GMM => Array(acctg_dept_nbr => Array(dept_category_desc => Array(dept_subcatg_desc => Array(value1,value2,value3)))))
I want to sum the values at every level. So for every acctg_dept_nbr[dept_category_desc][dept_subcatg_desc] I want to sum value1,value2,value3. Same for the GMM level and down to the dept_subcatg_desc level. Summing the dept_subcatg_desc level wasn't a problem. I dug around and found how to sum the dept_category_desc level, but am having trouble applying that method recursively.
Here is the code that puts the values into a table:
foreach($group as $gmm => $acctg_dept_nbrs) {
echo "<tr class=\"header\">
<td>" . $gmm . "</td>\n";
foreach ($acctg_dept_nbrs as $acctg_dept_nbr => $dept_catg_grp_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 1em;\">" . $acctg_dept_nbr . "</td>\n";
foreach($dept_catg_grp_descs as $dept_catg_grp_desc => $dept_category_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 2em;\">" . $dept_catg_grp_desc . "</td>\n";
//echo "<td>" . array_sum(array_walk_recursive($dept_category_descs,function($item) {return $item['total_ty_yest_sales'];})) . "</td>";
foreach($dept_category_descs as $dept_category_desc => $dept_subcatg_descs) {
echo "<tr class=\"header\">\n
<td style=\"padding-left: 3em;\">" . $dept_category_desc . "</td>\n";
echo "<td>" . array_sum(array_map(function($item) {return $item['total_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['east_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['central_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
echo "<td>" . array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
foreach($dept_subcatg_descs as $dept_subcatg_desc => $values) {
echo "<tr>\n
<td style=\"padding-left: 4em;\">" . $dept_subcatg_desc . "</td>\n";
$sum = $values['total_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['east_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['central_ty_yest_sales'];
echo "<td>".$sum."</td>";
$sum = $values['west_ty_yest_sales'];
echo "<td>".$sum."</td>";
}
}
}
}
}
The commented out line is the problem for me now. This:
array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs))
works fine at that level, but not at the higher levels. I have also tried to tweak this function to no avail:
function array_map_recursive($callback, $array) {
foreach ($array as $key => $value) {
if (is_array($array[$key])) {
$array[$key] = array_map_recursive($callback, $array[$key]);
}
else {
$array[$key] = call_user_func($callback, $array[$key]);
}
}
return $array;
}
How can I make this work so that regardless of level it will dig down and sum the values for that portion of the array?
function array_map_recursive($callback, $array)
{
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
function array_map_recursive($callback, $array)
{
if(is_array($callback)){
foreach ($callback as $function){
$array = array_map_recursive($function, $array);
}
return $array;
}
$func = function ($item) use (&$func, &$callback) {
return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
};
return array_map($func, $array);
}
This way you can call the function passing more functions.. ex:
$rowData = array_map_recursive(['utf8_decode', 'trim'], $rowData);
Or simple call just one:
$rowData = array_map_recursive('trim', $rowData);
It can be a little difficult if we add multiple arrays to the function. But with only one, there is no problem at all.
function array_map_recursive(&$arr, $fn) {
return array_map(function($item) use($fn){
return is_array($item) ? array_map_recursive($item, $fn) : $fn($item);
}, $arr);
}
$array = array_map_recursive($array, function($item){
//TODO logic here
});
filter_var can essentially be used to accomplish this
function array_map_recursive(callable $func, array $array) {
return filter_var($array, FILTER_CALLBACK, ['options' => $func]);
}
There is one big drawback...
The callback will receive the value as a string.
and the leafs can't be objects

How to use mysql to find a field name of a record?

PDO sql codes :
while($r = $q->fetch(PDO::FETCH_ASSOC)){
$gg = join('</td><td>', $r);
echo "<tr><td>" . $no_count . "</td><td>" . $gg . "</td></tr>";
$no_count = $no_count + 1;
}
variable $r is the record, how can I echo the field name of $r?
Let's say $r carry records from 2 different fields "product" and "price". The value of $r is "apple", "130". How can I add "usd" into "130"?
I need something like.... if $field_name == "$r['price']" { $r = join('usd', $r); };
Thanks to Mike B, I almost there :
while($r = $q->fetch(PDO::FETCH_ASSOC)){
foreach ($r as $name => $value) {
if ($name == "price"){
$r = "usd" . $value; // this line got problem, how to change the value in an array variable $r?
}
}
$gg = join('</td><td>', $r);
echo "<tr><td>" . $no_count . "</td><td>" . $gg . "</td></tr>";
$no_count = $no_count + 1;
}
array_keys($r) will get you a list of fields from the table since you're fetching an associative array.
You can also loop through $r:
foreach ($r as $name => $value) {
print "$name: " . $value;
}
Update
// this line got problem, how to change the value in an array variable $r?
$r[$name] = 'usd' . $value;
Make the edit to the original name. Since you have the key in the $name variable from the foreach loop you can set it directly.

Categories