Nested For Each - php

I'm trying to make a php page that gets receipts entered into a database and sorts them by category. Each entry has a store name, an amount, and a category.
I have successfully been able to total up the receipt totals by store and display them.
I'm now trying to make a nested for each loop where I list those stores and totals by category but I have not been successful.
This is my code so far:
<html>
<body>
<?php
error_reporting(E_ALL ^ E_NOTICE);
//$startDate = $_POST["startdate"];
//$endDate = $_POST["enddate"];
$startDate = "2023-01-01";
$endDate = "2023-01-31";
require_once 'loginDB.php';
$conn = new mysqli($hn, $un, $pw, $db);
if ($conn->connect_error) die($conn->connect_error);
$RECEIPTTOTAL=0;
$names= array();
$totals =array();
$tipseach =array();
$arrayID = 0;
$categories = array();
$result=$conn->query("SELECT * FROM CEREAL_HEADERS WHERE ( RECEIPT_DATE>='$startDate' AND RECEIPT_DATE <='$endDate')");
while ($rows = $result->fetch_assoc() ) {
$RECEIPTTOTAL=$RECEIPTTOTAL+$rows['AMOUNT'];
echo $rows['RECEIPT_DATE'];
echo '&nbsp&nbsp&nbsp&nbsp ';
echo '$';
echo $rows['AMOUNT'];
echo '&nbsp&nbsp&nbsp&nbsp ';
echo $rows['STORE_NAME'];
echo '&nbsp&nbsp&nbsp&nbsp ';
echo $rows['CATEGORY'];
echo '<br>';
//-------------------Get amounts per store-------------
if(array_search($rows['STORE_NAME'], $names) === false)
//if(array_search($rows['Employee'], $names) ?? false)
{
$names[]= $rows['STORE_NAME'];
}
$arrayID= array_search($rows['STORE_NAME'],$names);
$tipseach[$arrayID]=$tipseach[$arrayID]+$rows['AMOUNT'];
//--------------------Get amounts per category----------
if(array_search($rows['CATEGORY'], $categories) === false)
//if(array_search($rows['Employee'], $names) ?? false)
{
$categories[]= $rows['CATEGORY'];
}
$arrayID2= array_search($rows['CATEGORY'],$categories);
$tipseachcategory[$arrayID2]=$tipseachcategory[$arrayID2]+$rows['AMOUNT'];
}
echo "<br><b>Total Expenses: $";
echo $RECEIPTTOTAL;
echo "</b><br><br>";
//$combinecategories = array_combine($categories, $names);
$combine = array_combine($names, $tipseach);
$html = "<table>";
$html .= "<tr><td>Count</td><td>&nbsp&nbsp&nbsp&nbsp</td><td>Name</td><td>&nbsp&nbsp&nbsp&nbsp</td><td>Tips</td></tr>";
$i = 1;
foreach ($combine as $names => $tipseach):
$html .= "<tr>";
$html .= "<td>".$i."</td>";
$html .="<td>&nbsp&nbsp&nbsp&nbsp</td>";
$html .= "<td>".$names."</td>";
$html .="<td>&nbsp&nbsp&nbsp&nbsp</td>";
$html .= "<td>".$tipseach."</td>";
$html .= "</tr>";
$i++;
endforeach;
$html .= "</table>";
echo $html;
?>
</body>
</html>
All of the categories are stored in an array.
The table successfully lists the stores and the total spent at each. I'm trying to get it to list a category, then the stores and totals under each category. Basically like a profit/loss sheet.
Any suggestions on how to proceed would be appreciated.

Related

Creating pages from a csv file

I've created a page that grabs data from a CSV (http://liamjken.com/aim-parse/aim-websites-new.csv) and displays it on this page http://www.liamjken.com/aim-parse/parse.php?17
?17 references the row in the csv file. so if I change that to ?10 it pulls the info from a different row.
What I would like to do instead of using the row number is use the $vin_num value. so if I put ?1FMCU9GD9KUC40413 at the end of the URL it would display the row that contains that Number.
here is the code I have currently, its basically cobbled together from multiple different trends I found so if you notice other potential problems id be happy to hear about them.
<?php
$qstring = $_SERVER['QUERY_STRING'];
$row = $qstring; // The row that will be returned.
$data = get_row('aim-websites-new.csv', $row);
'<pre>'.print_r($data).'</pre>';
function get_row($csv, $row) {
$handle = fopen("$csv", 'r');
$counter = 0;
$result = '';
while ( ($data = fgetcsv($handle)) !== FALSE ) {
$counter++;
if ( $row == $counter ) {
$vin_num="$data[12]";
$model="$data[10]";
$make="$data[9]";
$year="$data[8]";
ob_start();
?>
<h1>VIN: <?php echo $vin_num; ?></h1>
<h1>Year: <?php echo $year; ?></h1>
<h1>Make: <?php echo $make; ?></h1>
<h1>Model: <?php echo $model; ?></h1>
<?php
$output = ob_get_clean();
ob_flush();
return $output;
}
}
}
?>
<?php
function extract_data($file)
{
$raw = file($file); // file() puts each line of file as string in array
$keys = str_getcsv(array_shift($raw)); // extract the first line and convert into an array
// Look through the rest of the lines and combine them with the header
$data = [];
foreach ($raw as $line) {
$row = str_getcsv($line);
$data[] = array_combine($keys, $row);
}
return $data;
}
function get_record($data, $vin)
{
foreach ($data as $record) {
if ($record['VIN'] === $vin)
return $record;
}
return null;
}
$data = extract_data('aim-websites-new.csv');
$vin = $_SERVER['QUERY_STRING'];
if (empty($vin)) {
echo '<h1>No VIN provided</h1>';
exit;
}
$record = get_record($data, $vin);
if ($record === null) {
echo '<h1>No record found</h1>';
exit;
}
echo '<h1>' . $record['VIN'] . '</h1>';
echo '<h1>' . $record['Year'] . '</h1>';
echo '<h1>' . $record['Make'] . '</h1>';
echo '<h1>' . $record['Model'] . '</h1>';
echo '<pre>' . print_r($record, true) . '</pre>';
If you don't trust that the records will have valid VINs, you can use the code posted here to validate: How to validate a VIN number?

Iterating values fetched from mysqli

So I am creating a dynamic menu. Where I have stored the main categories of the menu in a separate table and subcategories in another table.
They are stored in this way
Categories Table
id cat_name
1 HOME,
2 PRODUCTS,
3 SOLUTIONS,
4 NEWS & GALLERY,
5 DOWNLOADS,
6 CONTACT
Right Now I am running a query
$sql="SELECT * FROM categories";
$query = mysqli_query($con, $sql);
while($row = mysqli_fetch_assoc($query)) {
$row['cat_name'];
$cat=explode(",",$row['cat_name']);
}
Then wherever needed I am printing the values like this
<?php echo $cat[0]; .. echo $cat[1]; //and so on ?>
It looks like this right now. And it is supposed to look likethis
But the problem with this solution is that I have to define the index of the array to print it.
I am developing the admin panel for this one and I want that if the admin adds a new menu item then it should automatically fetch it and display it.
But with this solution it is not possible.
I am thinking of iterating the values with a for loop but cannot get it right.
Use foreach ($query as $rows)
or
Use for ($i=0; $i < count($query); $i++)
Probably You can try this also
$sql="SELECT * FROM categories";
$query = mysqli_query($con, $sql);
while($row = mysqli_fetch_assoc($query))
{
$row['cat_name'];
$cat=explode(",",$row['cat_name']);
foreach($cat as $catss)
{
$cat = trim($catss);
$categories .= "<category>" . $cat . "</category>\n";
}
}
You can try this way may be you wish like this for dynamic menu:
$sql="SELECT * FROM categories";
$query = mysqli_query($con, $sql);
$menu = '';
$menu .= '<ul>';
while($row = mysqli_fetch_assoc($query))
{
$menu .= '<li>' . $row['cat_name'] . '</li>';
}
$menu .= '</ul>';
echo $menu;
When you are fetching data from table then you can directly print that value using field name. if you want to further use that so, you have to add in one array like:
$cat[] = $row['cat_name'];
then you can use this value in that manner using for or while:
foreach ($cat as $value) {
echo $value;
}
echo '<ul>';
foreach ($cat as $val) {
echo "<li>{$val}</li>";
}
echo '</ul>';
Instead of the index. Also this should be faster and readable than for loop.
You can save it in array then later access the values.
$sql="SELECT * FROM categories";
$query = mysqli_query($con, $sql);
$cat = array();
while($row = mysqli_fetch_assoc($query)) {
$cat[]=$row['cat_name']
}
Now:
foreach ($cat as $category) {
$cate_gory = explode("," , $category);
foreach ($cate_gory as $categories) {
echo $categories . "<br>";
}
}
Foreach Loop
foreach($cats as $cat)
{
echo $cat;
}
Basic For Loop
for ($i=0; $i<count($cats); $i++)
{
echo $cats[$i];
}
Simple Use Case
<?php
$cats = 'Stack overflow PHP questions';
$cats = explode(' ',$cats);
$html = '<ul>';
foreach($cats as $cat)
{
$html .= '<li>' . $cat . '</li>';
}
$html .= '</ul>';
echo $html;
?>
Your Code
In this case the while loop you are using will iterate over all the values returned from the sql statement, so there is no need to add more complexity. I would remove the commas from the field names and echo out the html this way.
$sql="SELECT * FROM categories";
$query = mysqli_query($con, $sql);
$html = '<ul>';
while($row = mysqli_fetch_assoc($query)) {
$html .= '<li>' . $row['cat_name'] . '</li>';
}
$html .= '</ul>';
echo $html;
?>

PHP While Loop/Foreach Loops

I have a question on a different way to wright this code because its not doing what I want it to do..
I am creating a forum list that will display the section under that category. Well this is the issue as you can see that I have an If () {}Else {} statement that is being used to put the information in that list I want. The problem is that I need to add a special class to the last section under that category that will be called last-tr. Now my issue that I have is all the information is making it to the screen but the class is only applied to the last row and now the last row of all the category's which is what i'm looking for.
So something like this,
Welcome Center
Introduce Yourself
Say Hello To our Admins (last-tr)
Game
COD
BF4 (last-tr)
Code
PHP
Java
PDO (last-tr)
but what my code is giving me is
Welcome Center
Introduce Yourself
Say Hello To our Admins
Game
COD
BF4
Code
PHP
Java
PDO (last-tr) <- Just that one.
Here is the code
<?php
include '../../core/init.php';
include '../../includes/head.php';
//Getting Categories under Welcome
$db = DB::getInstance();
$user = New User();
$forum = New Forum();
$list = '';
$category = $db->query('SELECT * FROM forum_categories');
foreach ($category->results() as $category) {
$list .= '<thead>';
$list .= '<tr>';
$list .= '<th class="titles">' . $category->title . '</th>';
$list .= '<th>Last Post</th>';
$list .= '<th>Topics</th>';
$list .= '<th>Replies</th>';
$list .= '</tr>';
$list .= '</thead>';
$list .= '<tbody>';
$sections = $db->query("SELECT * FROM forum_section WHERE category_id = '$category->id'");
foreach ($sections->results() as $section) {
$x = 0;
if ($x < $sections->count()) {
$list .= '<tr>';
$list .= '<td>';
$list .= '<a href="/category.php?id='. $section->id .'">';
$list .= '<img scr="/images/icons/iconmonstr/intro.png">';
$list .= '</a>';
$list .= '' . $section->title . '';
$list .= '<span>' . $section->desc . '</span>';
$list .= '</td>';
$list .= '<td> Nasty </td>';
$list .= '<td> 0 </td>';
$list .= '<td> 0 </td>';
$list .= '</tr>';
$x++;
}else {
$list .= '<tr class="last-tr">';
$list .= '<td>';
$list .= '' . $section->title . '';
$list .= '</td>';
$list .= '<td> Nasty </td>';
$list .= '<td> 0 </td>';
$list .= '<td> 0 </td>';
$list .= '</tr>';
}
}
$list .= '</tbody>';
}
?>
<link rel="stylesheet" href="/css/fourms.css">
<title>Forums</title>
</head>
<body>
<?php include '../../includes/header.php'; ?>
<section id="main_section">
<section id="main_content">
<div id="forum-section">
<table class="forumlist">
<?php echo $list; ?>
</table>
</div>
</section>
</section>
<?php include('../../includes/footer.php'); ?>
Your if-statement should be if ($x < $sections->count()-1) because the last index of an array is always count-1 due to starting at 0.
OR
You could also fix it here by starting $x at 1, since you are using a foreach with the counter on the side, so its not like you'll get an out of index error. In other words:
foreach ($sections->results() as $section) {
$x = 1;
if ($x < $sections->count()) {
...
$x++;
}else {
...
}
}
But going with the first option is probably more straight-forward.
You are testing against your overall class not the data within the class.
$sections->count() is counting all of the sections not the entries in teh one section you are dealing with.
You need to test the count of the singular section
So if you had
$sectionsAll = array(
sectionOne = array( 1, 2, 3),
sectionTwo = array( 1, 2, 3),
sectionThree = array( 1, 2, 3)
);
You are currently testing on $sectionsAll, you need to check against sectionOne, sectionTwo, sectionThree

Group PHP arrays by key value

Basically I'm trying to group my arrays like this:
Shopping
Amazon
Social
Amoeblo
American express
By using below PHP code:
<?php
echo '<ul id="list"><h2 class="searchresults"></h2>';
foreach($records as $catval) {
$sitechar = $catval->site_category;
echo '<h3 id="disappear">'. strtoupper($sitechar) .'</h3>';
echo '<li class="siteli"><a href="#" class="add">';
echo '<p id="text-site">'.$catval->site_name. '</p></a>';
echo '</li>';
}
echo '</ul>';
?>
But I'm getting values only like below.
Shopping
Amazon
Social
Amoeblo
Social
American express
I'm not getting the exact PHP sorting to use for this.
I would create a new array with categories as keys for arrays with the sites.
<?php
$arr = array();
// First create multidimensional array with categories as keys for site arrays
foreach($records as $catval) {
$sitechar = $catval->site_category;
if (!array_key_exists($sitechar, $arr)) {
// Set new array for a category if it does not exist
$arr[$sitechar] = array();
}
// Add site to category
$arr[$sitechar][] = array(
"name"=>$catval->site_name,
"image"=>$catval->site_img
);
}
// Then iterate the new array of categories
echo ("<ul>");
foreach($arr as $category => $sites) {
echo("<h3>" . $site_category "</h3>");
// Iterate array of sites
foreach($sites as $site) {
echo("<li>" . $site["name"] . "-" , $site["image"] . "</li>");
}
}
echo("</ul>");
?>
You can do it using a foreach and ksort
Let $your_array be the array you mentioned above
$res_array = array();
foreach($your_array as $val){
$res_array[$val->site_category][] = $val->site_name;
}
ksort($res_array);
print_r($res_array);
OR search for multisort in php which will solve your problem :)
$tmp = null;
echo '<ul id="list"><h2 class="searchresults"></h2>';
foreach($records as $catval) {
$myHtml = makeHtml($catval,$tmp);
echo $myHtml;
$tmp = $catval->site_category;
}
echo '</ul>';
function makeHtml($catval,$tmp){
if($tmp != $catval->site_category){ $html .= '<h3 id="disappear">'. strtoupper($catval->site_category) .'</h3>';}
$html .='<li class="siteli"><p id="text-site">'.$catval->site_name. '</p></li>';
return $html;
}

Google Analytics API v3 how to extract values?

I'm a newbie at GA API so I have no clue how to extract results the correct way in this case.
e.g. I'm trying to extract avgTimeOnPage values based on filtering from ga:pagePath = ...
But each one is returning a single digit value on ga:pagePath.. so I'm thinking the ga:pagePath and ga:avgTimeOnPage results are not being displayed correctly. Maybe I'm not extracting the right way.
Anyone who can help would be greatly appreciated.
$ids = 'ga:123456789';
// $start_date $end_date already defined
$filter = 'ga:pagePath==/folder/somepage.html';
$metrics = 'ga:avgTimeOnPage';
$optParams = array('dimensions' => 'ga:pagePath', 'filters' => $filter);
$data = $service->data_ga->
get($ids, $start_date, $end_date, $metrics, $optParams);
foreach($data['totalsForAllResults'] as $rows) :
echo $rows['ga:pagePath']; // why returning a single digit value?
echo $rows['ga:avgTimeOnPage']; // also returns a single digit
endforeach;
$data['totalsForAllResults'] will return a single row that is the total row. You are looking for the values not the totals. so you should use:
foreach ($data->getRows() as $row) :
And then you can iterate $rows for every cell.
Check this full example:
private printDataTable(&$results) {
if (count($results->getRows()) > 0) {
$table .= '<table>';
// Print headers.
$table .= '<tr>';
foreach ($results->getColumnHeaders() as $header) {
$table .= '<th>' . $header->name . '</th>';
}
$table .= '</tr>';
// Print table rows.
foreach ($results->getRows() as $row) {
$table .= '<tr>';
foreach ($row as $cell) {
$table .= '<td>'
. htmlspecialchars($cell, ENT_NOQUOTES)
. '</td>';
}
$table .= '</tr>';
}
$table .= '</table>';
} else {
$table .= '<p>No Results Found.</p>';
}
print $table;
}
source: https://developers.google.com/analytics/devguides/reporting/core/v3/coreDevguide#working

Categories