PHP array_sum multi-dimensional - php

I need to get the array_sum of $product['stars']; so I can use it to find the average. When I try to use it I am not using it on the array somehow? Also I believe this comes in as a string. Does it need to be converted to INT? Thanks so much for any ideas.
<?php
$categories = array();
while ($row_rsCategories = mysqli_fetch_assoc($res)) {
$product_array = array();
$product_array_query = mysqli_query($mysqli,"SELECT id, user_id, client_id, comments, stars FROM reviews WHERE user_id = '".$row_rsCategories['userId']."'");
while($product_array_fetch = mysqli_fetch_array($product_array_query)) {
$product_array[] = array("id"=>$product_array_fetch['user_id'],"comments"=>$product_array_fetch['comments'],"stars"=>$product_array_fetch['stars']);
}
$categories[] = array(
'id' => $row_rsCategories['userId'],
'name' => $row_rsCategories['usersName'],
'products' => $product_array,
);
}
foreach ($categories as $category) {
?>
<div class="col-md-4">
<div id = "user-square">
<div class="avatar">
<img src="<?php echo $avatarDir.$list['usersAvatar']; ?>" class="publicAvatar" />
</div>
<?php
echo $category['name']; ?> </br>
<?php foreach($category['products'] as $product) {
echo $product['stars']; ?> </br>
<?php }
?>

You could do it by combining array_sum with array_map:
$starsum = array_sum(array_map(function($x) { return $x['stars']; }, $product_array));
But you can also just calculate the sum while you're constructing the array of results:
$starsum = 0;
$rowcount = 0;
while($product_array_fetch = mysqli_fetch_array($product_array_query)) {
$product_array[] = array("id"=>$product_array_fetch['user_id'],"comments"=>$product_array_fetch['comments'],"stars"=>$product_array_fetch['stars']);
$starsum += $product_array_fetch['stars'];
$rowcount++;
}
$categories[] = array(
'id' => $row_rsCategories['userId'],
'name' => $row_rsCategories['usersName'],
'products' => $product_array,
'avgstars' => ($rowcount == 0) ? 0 : $starsum / $rowcount
);
There's no need to convert the values to integers, PHP will do that automatically when you use arithmetic functions on them.

Related

2 foreach loops with arrays

What I am trying to do is get my "$ages" array to display a value once per player in order of the array..
However every time I add the extra for loop with that array, it duplicates each player 20 times, with each array value once. I want 20 players, with the 20 different values of the array one each.
Here's the current output, that is duplicating each player 20 times.
http://freerdarts.com/test.php
Here's the code
<link rel="stylesheet" href="https://freerdarts.com/assets/css/main.css" />
<?php
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTML(file_get_contents('https://www.leagueleader.net/sharedreport.php?operatorid=98&code=1166aea7-6e0e-4864-8074-8ebd93311041'));
$doc->strictErrorChecking = false;
$pre = [];
$keys = ['name', 'team', 'ppd', 'games', 'wins', 'hats', '3bd', 'ton80','hton','lton','6do','7do','8do','9do'];
$keys2 = ['name', 'mpr', 'games', 'wins','assists', 'hats','whorse','5mr','6mr','7mr','8mr','9mr'];
foreach ($doc->getElementsByTagName('table') as $k => $table) {
if (strpos($table->getAttribute('class'), 'report') === false) {
continue;
}
foreach ($table->getElementsByTagName('tr') as $i => $tr) {
if ($tr->parentNode->nodeName === 'thead') continue; // skip headers
$row_values = [];
foreach ($tr->childNodes as $td) {
$text = trim($td->nodeValue);
if ($text === '') continue;
$row_values[] = $text;
}
if($k == 1 ){
$row_values = array_combine($keys, $row_values);
}else if($k == 2 ){
unset($row_values[1]);
$row_values = array_combine($keys2, $row_values);
}
$pre[$row_values['name']][] = $row_values;
}
}
$combined = [];
foreach($pre as $name => $row){
$combined[$name] = [
"name"=> $name,
"team"=> $row[0]['team'],
"ppd_01" => $row[0]['ppd'],
"games_01" => $row[0]['games'],
"wins_01" => $row[0]['wins'],
"hats_01" => $row[0]['hats'],
"3bd" => $row[0]['3bd'],
"ton80" => $row[0]['ton80'],
"hton" => $row[0]['hton'],
"lton" => $row[0]['lton'],
"6do" => $row[0]['6do'],
"7do" => $row[0]['7do'],
"8do" => $row[0]['8do'],
"9do" => $row[0]['9do'],
"mpr_crk" => $row[1]['mpr'],
"games_crk" => $row[1]['games'],
"wins_crk" => $row[1]['wins'],
"assists_crk" => $row[1]['assists'],
"hats_crk" => $row[1]['hats'],
"whorse" => $row[1]['whorse'],
"5mr" => $row[1]['5mr'],
"6mr" => $row[1]['6mr'],
"7mr" => $row[1]['7mr'],
"8mr" => $row[1]['8mr'],
"9mr" => $row[1]['9mr']
];
}
//echo '<pre>'.json_encode($combined, JSON_PRETTY_PRINT).'</pre>';
//echo $combined['Ronnie Otto']['ppd_01'];
?>
<?php
// Players Ages
$ages = array(one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty);
sort($combined);
foreach($combined as $row) {
foreach($ages as $age) {
// Name Corrections
if($row['name'] == 'Scott Sandburg'){ $row['name'] = 'Scott Sandberg'; }
// Profile Images
$profile_image = $row['name'];
$profile_image = str_replace(' ', '_', $profile_image);
?>
<div class="profile">
<span class="profile_ext"> <img src="../images/profiles/<?=$profile_image?>.jpg" />
<span class="name"><?=$row['name'];?></span>
<span class="age"><?=$age;?></span>
<span class="gamesplayed"><?=$row['games_01']+$row['games_crk'];?></span>
<span class="blank"></span>
<!-- Cricket Stats -->
<span class="cricketmpr"><?=$row['mpr_crk'];?></span>
<span class="cricket_5mr"><?=$row['5mr'];?></span>
<span class="cricket_6mr"><?=$row['6mr'];?></span>
<span class="cricket_7mr"><?=$row['7mr'];?></span>
<span class="cricket_8mr"><?=$row['8mr'];?></span>
<span class="cricket_9mr"><?=$row['9mr'];?></span>
<span class="cricket_whorse"><?=$row['whorse'];?></span>
<span class="blank"></span>
<!-- 01 Stats -->
<span class="o1ppd"><?=$row['ppd_01'];?></span>
<span class="o1_lton"><?=$row['lton'];?></span>
<span class="o1_hats"><?=$row['hats_01'];?></span>
<span class="o1_hton"><?=$row['hton'];?></span>
</span>
</div>
<?php } } ?>
The problem is that you have an inner foreach() in your display part...
foreach($ages as $age) {
this doesn't seem in any way connected to the data you are displaying as there doesn't seem to be an age in the data.
You should also be getting some warnings as
$ages = array(one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty);
will show
Warning: Use of undefined constant one - assumed 'one' (this will
throw an Error in a future version of PHP)
You should have quotes round the values...
$ages = array('one',...
If you just want the players listed with the corresponding age, you first need to change
foreach($combined as $key => $row) {
// Remove next foreach
// foreach($ages as $age) {
Then to display the age, use the $key from the foreach() to index the $ages array...
<span class="age"><?=$ages[$key];?></span>

PHP - creating a new array through nested arrays while creating a post/image relationship

PHP 7.2
Wordpress 4.9.8
Advanced Custom Fields 5.7.7
I'm interested in creating an array where each item would hold:
post id
post title
array of images belonging to post
I am using an ACF repeater for every post that holds many images, the repeater name is carousel.
There is no connection between the WP post object and the ACF fields.
The issue:
nested foreach pushes all the images into the first post.
Expected:
nested foreach will fill the $randomArray only with images that belong to that post ID.
$workshop_posts_args = array(
'post_type' => 'workshops'
);
$randomArray = [
'post_id' => '',
'post_title' => '',
'post_image_url' => []
];
$post_query = new WP_Query($workshop_posts_args);
if ($post_query->have_posts()) {
while ($post_query->have_posts()) {
$post_query->the_post();
$carousel_array = get_field('carousel', get_the_ID());
echo "<h2>".get_the_title()."</h2>";
if ($carousel_array) {
foreach ($carousel_array as $carousel_images) {
foreach ($carousel_images as $image) {
$randomArray['post_id'] = get_the_ID();
$randomArray['post_title'] = get_the_title();
$randomArray['post_image_url'][] = $image['url'];
echo 'image_url:'.$image['url'].'<br>The array: <pre>'.print_r($randomArray, true).'</pre>';
?>
<?php
}
}
}
}
}
?>
<h1>TOTAL ARRAY</h1>
<pre><?php print_r($randomArray) ?></pre>
You are over-writing array index again and again inside loop and that's you problem.
so do:-
$randomArray = []; //before post_query
And change if block like below:-
if ($post_query->have_posts()) {
while ($post_query->have_posts()) {
$post_query->the_post();
$id = get_the_ID();
$randomArray[$id]['post_id'] = $id;
$randomArray[$id]['post_title'] = get_the_title();
$carousel_array = get_field('carousel', $id);
if ($carousel_array) {
foreach ($carousel_array as $carousel_images) {
foreach ($carousel_images as $image) {
$randomArray[$id]['post_image_url'][] = $image['url'];
?>
<?php
}
}
}
}
}
Note:- rest code will be same
the above code will give you post-id based multi-dimensional array. if you want indexes to be 0,1,2,3..... format then do:-
$randomArray = array_values($randomArray);
Use proper indexing of $randomArray like below:
<?php
$workshop_posts_args = array(
'post_type' => 'workshops'
);
$randomArray = array();
$post_query = new WP_Query($workshop_posts_args);
$index = 0;
if ($post_query->have_posts()) {
while ($post_query->have_posts()) {
$post_query->the_post();
$randomArray[$index]['post_id'] = get_the_ID();
$randomArray[$index]['post_title'] = get_the_title();
$carousel_array = get_field('carousel', get_the_ID());
//echo "<h2>".get_the_title()."</h2>";
if ($carousel_array) {
foreach ($carousel_array as $carousel_images) {
foreach ($carousel_images as $image) {
$randomArray[$index]['post_image_url'][] = $image['url'];
//echo 'image_url:'.$image['url'].'<br>The array: <pre>'.print_r($randomArray, true).'</pre>';
?>
<?php
}
}
}
$index++;
}
}
?>
<h1>TOTAL ARRAY</h1>
<pre><?php print_r($randomArray) ?></pre>

Encode nested JSON array in php

I want to send nested JSON array.Which contain following format.
${"posts":[{
"abc":"123",
"xyz":"123",
"pro":[{
"name":"Brinjal",
"qty":"500 gms"
},
{
"name":"Brinjal",
"qty":"500 gms"
}]
}]
}
Here is my php code:
$rows = $stmt->fetchAll();
if ($rows) {
$order["posts"] = array();
foreach ($rows as $row) {
$post = array();
$post["order_id"] = $row["order_id"];
$post["order_totalamount"] = $row["order_totalamount"];
$post["address"] = $row["address"];
$post["pincode"] = $row["pincode"];
$post["delivery_timeslot"] = $row["delivery_timeslot"];
$post["order_date"] = $row["order_date"];
$query1= "query";
$rows1 = $stmt->fetchAll();
if ($rows1) {
foreach ($rows1 as $row1) {
$query2= "query";
$rows2 = $stmt->fetchAll();
$post["product"] = array();
if ($rows2) {
$products = array();
foreach ($rows2 as $row2) {
$products["product_name"]=$row2["product_name"];
$products["prod_qty"] = $row2["product_minquantity"];
}
array_push($post["product"],$products);
echo json_encode($products);
}
}
}
array_push($order["posts"], $post);
}
echo json_encode($order);
}
From above code I got result:
$ {"posts":
[{
"order_id":"18",
"order_totalamount":"40",
"address":"2, Chetan Society, Vadodara",
"pincode":"390023",
"delivery_timeslot":"Zone wise delivery",
"order_date":"2016-03-18 17:50:53",
"product":[{"product_name":"Brinjal","prod_qty":"500 gms"}]
}]
}
But my actual product array is:
${"product_name":"Banana","prod_qty":"1 Kg"}{"product_name":"Brinjal","prod_qty":"500 gms"}
Kindly help out. I am stuck on it. tried a lot but did not get success.
In
foreach ($rows2 as $row2) {
$products["product_name"]=$row2["product_name"];
$products["prod_qty"] = $row2["product_minquantity"];
}
You overwrite $products["product_name"]and $products["prod_qty"] with the values of the last $row2.
The line {"product_name":"Banana","prod_qty":"1 Kg"}{"product_name":"Brinjal","prod_qty":"500 gms"} actually consists of two echo's:
{"product_name":"Banana","prod_qty":"1 Kg"}
{"product_name":"Brinjal","prod_qty":"500 gms"}
But you don't see the difference. I suggest echoing a string in-between them or use something like var_dump() to see how many values you're echoing.
You should do something like:
for ($i = 0; $i < count($rows2); $i++) {
$products[$i]["product_name"]=$rows2[$i]["product_name"];
$products[$i]["prod_qty"] = $rows2[$i]["product_minquantity"];
}
This will result in: [{"product_name":"Banana","prod_qty":"1 Kg"},{"product_name":"Brinjal","prod_qty":"500 gms"}]
FYI $array[] = has the same rsults as array_push(), but had less overhead of calling array_push().
EDIT:
Below a complete example since it doesn't seem to workout for you:
//Demo $order
$order = array (
'posts' =>
array (
0 =>
array (
'order_id' => '18',
'order_totalamount' => '40',
'address' => '2, Chetan Society, Vadodara',
'pincode' => '390023',
'delivery_timeslot' => 'Zone wise delivery',
'order_date' => '2016-03-18 17:50:53',
),
),
);
//Demo $rows2
$rows2 = array(
array(
'product_name' => 'banana',
'product_minquantity' => '1 Kg'
),
array(
'product_name' => 'Brinjal',
'product_minquantity' => '500 gms'
)
);
$post['product'] = array();
if ($rows2) {
$products = array();
for ($i = 0; $i < count($rows2); $i++) {
$products[$i]['product_name'] = $rows2[$i]['product_name'];
$products[$i]['prod_qty'] = $rows2[$i]['product_minquantity'];
}
$post['product'] = $products;
echo json_encode($products); //[{"product_name":"banana","prod_qty":"1 Kg"},{"product_name":"Brinjal","prod_qty":"500 gms"}]
}
//$order['posts'][] = $post;
$order['posts'][0] = $order['posts'][0] + $post;
//In this example I only have 1 item in $order['posts'] so I know to add to key 0.
//In your case you need to know which key of $rows1 you need to do the adding.
//Change the foreach loop of $rows to a for loop as well so you can define your own keynames ($i).
echo '<br>==================================================================<br>';
echo json_encode($order);
/*
{
"posts":[
{
"order_id":"18",
"order_totalamount":"40",
"address":"2, Chetan Society, Vadodara",
"pincode":"390023",
"delivery_timeslot":"Zone wise delivery",
"order_date":"2016-03-18 17:50:53",
"product":[
{
"product_name":"banana",
"prod_qty":"1 Kg"
},
{
"product_name":"Brinjal",
"prod_qty":"500 gms"
}
]
}
]
}
*/

Organizing results by category Redux

I am trying to expand on my question asked here: Creating a multi-dimensional array from query
I have added a category description to my categories table but I cannot figure out how to add it to the code below and display each category description for each category.
Here is the code I am using to display the items by category:
$itemcategories = array();
while ($row = mysqli_fetch_array($result))
{
$head = $row['category'];
$itemcategories[$head][] = array(
'id' => $row['id'],
'title' => $row['title'],
'itemdesc' => $row['itemdesc'],
'price' => $row['price'],
'special' => $row['special']
);
}
<?php foreach ($itemcategories as $head => $items) { ?>
<h3><?php echo $head; ?></h3>
<table class="chart">
<?php foreach ($items as $item) { ?>
<tr><td><?php echo $item['itemdesc']; ?></td></tr>
<?php } ?>
</table>
<?php } ?>
// to initial variable holder
$categories = $items = array();
// looping mysql result
while ($row = mysqli_fetch_array($result))
{
// to get category name
$head = $row['category'];
// avoid excessive setting of $categories
if (!isset($categories[$head]))
{
$categories[$head] = $row['descrption'];
}
// assign mysql result to $items
$items[$head][] = $row;
}
// free mysql result
mysql_free_result($result);
// loop all $categories
foreach ($categories as $head=>$desc)
{
// this is my example for printing HTML
// you can use heredoc syntax
// or stick to your existing format
echo "<h3>{$head} - {$desc}</h3><table class="chart">";
foreach ($items[$head] as $item)
{
// print item description
echo "<tr><td>{$item['itemdesc']}</td></tr>";
}
echo "</table>";
}

Creating a multi-dimensional array from query

I am using the code below to create a multi-dimensional array from a query so that I can organize the results by category but it only gets me 2 columns (category, agency).
I am not sure how I can alter this so that I can get 4 columns (category, agency, description, website). Any help is greatly appreciated.
$categories = array();
while ($row = mysqli_fetch_array($result))
{
$category = $row['category'];
$categories[$category][] = $row['agency'];
}
<?php
foreach ($categories as $category => $agencies)
{
?>
<h3><?php echo $category; ?></h3>
<table class="chart">
<?php
foreach ($agencies as $agency)
{
?>
<tr><td><?php echo $agency; ?></td></tr>
<?php
}
?>
</table>
<?php
}
?>
You could store the individual row results as an associative array:
$categories[$category][] = array(
'agency' => $row['agency'],
'description' => $row['description'],
'website' => $row['website']
);

Categories