foreach() Loop Outputting Data and Creating Layout - php

I am currently trying to create a class schedule which I pull from my Sql Server database with PHP and I am trying to get the layout output as well as the data as I am grouping the resources.
These groupings are nested such as:
-DAY
--TIME
---CLASS
----STUDENTS
And should output like this:
However, I am getting this:
My current output is working, however, it is only on the first loop, then everything goes haywire. I am assuming there is an erroneous </div> tag somewhere in my code yet I cannot for the life of me find it.
My php code is a function that is delcare as such:
<div class="mainScheduleWrapper">
<?php daySchedule(); ?>
</div>
My php code is as such:
function daySchedule() {
global $conn;
$dayScheduleQuery = 'SET DATEFIRST 1
SELECT [DAY].[DAY] AS [DAY], CLASS.CLASSTIME AS CLASSTIME, CLASSLEVEL.CLASSLEVEL AS CLASSLEVEL, CLASS.MAXSTUDENT AS MAXSTUDENT, INSTRUCTOR.FIRSTNAME AS INSTRUCTOR, STUDENT.FIRSTNAME AS STUDENTFIRST, STUDENT.SURNAME AS STUDENTLAST, STUDENT.DOB AS STUDENTDOB
FROM STUDENT JOIN BOOKING ON STUDENT.ID = BOOKING.STUDENTID JOIN CLASS ON CLASS.ID = BOOKING.CLASSID JOIN CLASSLEVEL ON CLASS.CLASSLEVELID = CLASSLEVEL.ID JOIN [DAY] ON CLASS.CLASSDAY = [DAY].ID JOIN INSTRUCTOR ON CLASS.INSTRUCTORID = INSTRUCTOR.ID
WHERE [DAY].ID = (DATEPART(dw, GETUTCDATE() AT TIME ZONE \'AUS Eastern Standard Time\'))
ORDER BY CLASS.CLASSTIME ASC, INSTRUCTOR.FIRSTNAME ASC, CLASSLEVEL.CLASSLEVEL ASC';
// COUNTERS
$t = 0;
$i = 0;
//VARIABLES FOR DAY SCHEDULE
$classDay = NULL;
$classTime = NULL;
$classInstructor = NULL;
$closeClass = false;
$closeAll = false;
$queryConnector = $conn->query($dayScheduleQuery);
foreach ($queryConnector as $schedule) {
// CLASS DAY HEADER
if ($classDay != $schedule['DAY']) {
echo '<div class="grid-1">';
echo '<h1>' . $schedule['DAY'] . '</h1>';
echo '</div><!-- Day closed! -->';
$classDay = $schedule['DAY'];
}
// CLASS TIME HEADER
if ($classTime != $schedule['CLASSTIME']) {
if($classTime != $schedule['CLASSTIME'] && $t > 0) {
$closeAll = true;
goto closeAll;
}
echo '<div class="grid-12-noGutter scheduleContainer">'; //NON-CLOSED
echo '<h1>' . 'T = ' . $t . '</h1>';
echo '<div class="grid-middle-center col scheduleTimeTab">';
// FIX 3 DIGIT MILITARY TIME
if (strlen($schedule['CLASSTIME']) < 4) {
$classScheduleTime = '0' . $schedule['CLASSTIME'];
} else {
$classScheduleTime = $schedule['CLASSTIME'];
}
echo '<p>' . date('g:i A', strtotime($classScheduleTime)) . '</p>';
echo '</div>'; //CLOSE TIME TAB
echo '<div class="innerSchedule">'; // NON-CLOSED
$classTime = $schedule['CLASSTIME'];
$t += 100;
}
// INSTRUCTOR HEADER
if ($classInstructor != $schedule['INSTRUCTOR']) {
if ($classInstructor != $schedule['INSTRUCTOR'] && $i > 0) {
$closeClass = true;
goto closeClassWrapper;
}
echo '<div class="classWrapper">';
echo '<h1>' . 'I =' . $i . 'T = ' . $t . '</h1>';
echo '<div class="grid-3-middle classHeader">';
echo '<div class="col classHeaderCell' . classLevelColour($schedule['CLASSLEVEL']) . '">' . $schedule['CLASSLEVEL'] . '</div>';
echo '<div class="col classHeaderCell">' . $schedule['INSTRUCTOR'] . '</div>';
echo '<div class="col classHeaderCell">Max' . ' ' . $schedule['MAXSTUDENT'] . '</div>';
echo '</div>';
echo '<div class="grid-4-middle" id="studentHeaders">';
echo '<div class="col"><h6>Student Name</h6></div>';
echo '<div class="col"><h6>Student Birthday</h6></div>';
echo '<div class="col"><h6>Class Level</h6></div>';
echo '<div class="col"><h6>Attendance</h6></div>';
echo '</div>';
$classInstructor = $schedule['INSTRUCTOR'];
$i += 100;
}
echo '<div class="grid-4 studentRow">';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['STUDENTFIRST'] . ' ' . $schedule['STUDENTLAST'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['STUDENTDOB'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['CLASSLEVEL'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">--</span>';
echo '</div>';
echo '</div>';
// GOTO TAGS
closeClassWrapper: {
if ($closeClass === true) {
echo '</div>';
$closeClass = false;
$i = 0;
}
}
closeAll: {
if ($closeAll === true) {
echo '</div>';
echo '</div>';
echo '</div>';
$closeAll = false;
$t = 0;
$i = 0;
}
}
}
}
Any help would be greatly appreciated - even if it's to tell me I'm going about it the completely wrong way.
Kindest Regards
Michael Z

I wouldn't say you're going about it the completely wrong way, but a few red flags jumped out at me in your code.
The use of goto jumping is bad practice. It butchers your program flow and forces you to segregate tasks that shouldn't be kept apart. You marked the sections of code "// NON CLOSED" when there was a </div> missing, is there any purpose for that? How do you know the goto sections are reliable?
When you echo something like <div class="col">, without escaping the double-quotes (as in \" for every " character), it can be problematic. Your code can get mangled or misinterpreted, both on the PHP end or on the HTML end.
Like others have said, the use of PHP may be overkill here. Besides just sending the JSON, the rest could be handled with JavaScript.

Related

Swapping between two div classes in foreach

I am currently coding a page based on a json query.
Here is a snippet of the code, I don't want to give the top half as that is grabbing the remote json with id's and passwords, but here is the main snippet:
$content_size = 'one_half';
foreach ( $json_decoded['fixtures-results']['matches'] as $match ){
display_match($match);
}
function display_match($match){
global $content_size;
if (strtotime($match['date']) < time()) { goto skip; }
$home_team_name = strtolower($match['home-team']['name']);
$home_team_name = preg_replace('/\s+/', '_',$home_team_name);
$away_team_name = strtolower($match['away-team']['name']);
$away_team_name = preg_replace('/\s+/', '_',$away_team_name);
$match_date = date("M jS, Y", strtotime($match['date']));
echo '<div class="'.$content_size.'">';
echo '<div class="latest_results" style="background:#ffffff">';
echo '<h6>'.$match_date.', '.$match['status']['full'].'</h6>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$home_team_name.'.png"><span>'.$match['home-team']['name'].'</span></div>';
echo '<div class="latest_results_col goalscore2">vs</div>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$away_team_name.'.png"><span>'.$match['away-team']['name'].'</span></div>';
echo '<div class="clear">';
echo '<span>Location:'.$match['venue'].'</span>';
echo '</div>';
echo '</div>';
echo '</div>';
if ($content_size == "one_half") { $content_size = "one_half_last"; goto skip; }else{ $content_size = "one_half"; goto skip; }
skip:
}
What i want is the first div class to be one_half then the next one as one_half_last then back to one_half and so on.
The result is the first div has the class one_half but the second has no class, then the third has one_half and so on, so you see it seems to be working, except its missing the second, fourth, sixth ect class.
Any help would be greatly received.
Kind Regards,
Adam
I am not sure what happened, and why it corrected itself, but here is the code i ended up using.
$content_size = 'one_half';
foreach ( $json_decoded['fixtures-results']['matches'] as $match ){
display_match($match);
}
function display_match($match){
global $content_size;
if(!$content_size){ $content_size = "one_half"; }
if (strtotime($match['date']) < time()) { goto skip; }
$home_team_name = strtolower($match['home-team']['name']);
$home_team_name = preg_replace('/\s+/', '_',$home_team_name);
$away_team_name = strtolower($match['away-team']['name']);
$away_team_name = preg_replace('/\s+/', '_',$away_team_name);
$match_date = date("M jS, Y", strtotime($match['date']));
$home_team_name_2 = team_name_2($match['home-team']['name']);
$away_team_name_2 = team_name_2($match['away-team']['name']);
echo '<div class="'.$content_size.'">';
echo '<div class="latest_results" style="background:#ffffff">';
echo '<h6>'.$match_date.', '.$match['status']['full'].'</h6>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$home_team_name.'.png"><span>'.$home_team_name_2.'</span></div>';
echo '<div class="latest_results_col goalscore2">vs</div>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$away_team_name.'.png"><span>'.$away_team_name_2.'</span></div>';
echo '<div class="clear">';
echo '<span>Location:'.$match['venue'].'</span>';
echo '</div>';
echo '</div>';
echo '</div>';
if ($content_size == "one_half") { $content_size = "one_half last_column"; goto skip; }else{ $content_size = "one_half"; goto skip; }
skip:
}
If anyone has any idea what I did differently I am happy to hear as I am not sure what i did.

Array: Compare values from API with values from own database

I have built a list (moviesSeen) where people can save their seen movies.
Now I want to get the director for each movie from an API and then compare which movies have already been seen. The output of the movies works without problems, but I can't get the result from the database (moviesSeen) to match the movies of the director. How can I achieve this?
The goal of the script is to show all movies of a director and mark all the ones you have already seen.
function getCrewDetails() {
global $apiKey;
global $language;
$personID = htmlspecialchars($_GET['personID']);
$url = "https://api.themoviedb.org/3/person/" . $personID . "?api_key=" . $apiKey . "&" . $language . "";// path to your JSON file
$data = file_get_contents($url); // put the contents of the file into a variable
$personPrivate = json_decode($data); // decode the JSON feed
echo '<div class="row">';
echo '<div class="col">';
echo '<img src="https://image.tmdb.org/t/p/w300/' . $personPrivate->profile_path . '" class="img-thumbnail">';
echo '</div>'; // end div col
echo '<div class="col-8">';
echo '<h1>' . $personPrivate->name . '</h1>';
if (!empty($personPrivate->biography)) {
echo $personPrivate->biography;
} else {
echo '<p>Verdammmt! Zu dieser Person liegen keine biographischen Details vor.</p>';
echo '<p>Dabei hätte sie es doch so verdient :(</p>';
}
echo '</div>'; // end div col
echo '</div>'; // end div row
// echo '<pre>';
// print_r($person);
$url = "https://api.themoviedb.org/3/person/" . $personID . "/movie_credits?api_key=" . $apiKey . "&" . $language . "";// path to your JSON file
$data = file_get_contents($url); // put the contents of the file into a variable
$personCareer = json_decode($data); // decode the JSON feed
echo '<div class="container mt-4">';
echo "<h2>Filmographie</h2>";
echo '<table class="table table-striped table-sm">';
echo '<thead>';
echo '<tr>';
echo '<th scope="col">Film</th>';
echo '<th scope="col">Gesehen</th>';
echo '<th scope="col">Funktion</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM movieSeen WHERE user_id = '" . $_SESSION['id'] . "'");
$stmt->execute();
foreach ($stmt as $row ) {
echo $row['movie_id'] . ', ';
} // output of the saved IDs in movieSeen
foreach ($personCareer->crew as $showCrewDetails) { //Output of the movies
echo '<tr>';
echo '<td>' . $showCrewDetails->title . ' ' . $showCrewDetails->id . ' (' . substr($showCrewDetails->release_date, 0, 4) . ')</td>';
echo '<td><span class="badge badge-danger">Movie Seen</span></td>';
echo '<td>' . $showCrewDetails->job . '</td>';
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
echo '</div>';
//echo '<pre>';
//var_dump($personCareer);
}
I know that I have to edit the last foreach loop, but I just can't get it to work :(

different get_rows from the database

This is the function im using to show results in the index.php with the style.css correctly done with the li´s and the div´s all that i just want to show in every li the price or the service i want. EXAMPLE: ($_GET_ROW['ID'] = '1', $_GET_ROW['ID'] = '2').
function products() { $get = mysql_query('SELECT id, servico, preco FROM loja');
if (mysql_num_rows($get)==0) {
echo "Não existem produtos a serem mostrados!";
} else {
while ($get_row = mysql_fetch_assoc($get)) {
echo '<li class="l1 i1 column1">';
echo '<h2>'.**$get_row["servico"]**. '</h2>';
echo '<div class="basket">Adicionar</p></div>';
echo '<div class="preco"><em>Preco:</em><strong>'.number_format($get_row['preco'], 2).'</strong><span>EUR</span>';
echo '</div>';
echo '<li class="l2 i0 column0">';
echo '<h2>'**.$get_row["servico"].**'</h2>';
echo '<div class="basket">Adicionar</p></div>';
echo '<div class="preco"><em>Preco:</em><strong>'.number_format($get_row['preco'], 2).'</strong><span>EUR</span>';
echo '</div>';
My database:
-----------------------------------
id servico preco
-----------------------------------
1 Servico Normal 29.5
-----------------------------------
2 Servico Rapido 32.5
-----------------------------------
It seems like you need a while loop to iterate through the rows like so:
if (mysql_num_rows($get)==0) {
echo "Não existem produtos a serem mostrados!";
} else {
while($get_row = mysql_fetch_assoc($get)) {
**echo '<li class="l1 i1 column1">';
echo '<h2>'.$get_row["servico_normal"].'</h2>';
echo '<div class="basket">Adicionar</p></div>';
echo '<div class="preco"><em>Preco:</em <strong>'.number_format($get_row['preco'], 2).'</strong><span>EUR</span>';
echo '</div>';**
}
}
However, you should immediately stop using mysql_ functions as they are being deprecated and vulnerable to SQL injection; and use mysqli_ or PDO instead.
Update 1
mysql_ functions are officially deprecated.
The principle of my initial answer still remains. You have two rows in your database and you want to iterate through them.
while ($get_row = mysql_fetch_assoc($get)) {
$liClass = 'l' . $get_row[id];
echo '<li class="' . $liClass . ' i1 column1">';
echo '<h2>' . $get_row[servico] . '</h2>';
echo '<div class="basket"><p>Adicionar</p></div>';
echo '<div class="preco"><em>Preco:</em><strong>' . number_format($get_row['preco'], 2) . '</strong><span>EUR</span>';
echo '</div>';
}
For the first row, the output would be:
<li class="l1 i1 column1">
<h2>Servico Normal</h2>
<div class="basket"><p>Adicionar</p></div>
<div class="preco"><em>Preco:</em><strong>29.50</strong><span>EUR</span></div>

PHP while loop split into two

I'm running a while loop which is taking rows from mySQL and echo'ing them out. Pretty standard. However, there needs to be different HTML markup for the first item, next two items, then it continues as normal into the while loop.
Currently, my while loop looking something like this:
while( ( $row = mysql_fetch_object( $result ) ) !== false )
{
// Places ad based of predefined variable frequency
if ($ad == $adFrequency){
echo '<div class="one-advertisement-article clearfix">';
echo '<div class="grid_9 suffix_2"><img src="http://placehold.it/263x75/000000/ffffff"></div>';
echo '<div class="grid_1"><a class="navigate-right-icon ss-icon" href="#">navigateright</a></div>';
echo '</div>';
$ad = 0;
}
echo '<div class="one-news-article clearfix">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="grid_4"><img src="'.$image_url.'"></div>';
}
else {
echo '<div class="grid_4"><div class="news-placeholder"><span class="ss-icon">ellipsischat</span></div></div>';
}
echo '<div class="grid_7">';
echo '<h2>'.$row->title.'</h2>';
$published_date = date('D, d M Y', strtotime($row->datein));
echo '<p class="published-date">'.$published_date.'</p>';
echo '</div>';
echo '<div class="grid_1">';
echo '<div class="news-item-vertical-sep"> </div>';
echo '<p></p>';
echo '</div>';
echo '</div>';
$ad++;
}
This works fine, but I need to take the first three news items and use this:
echo ' <div class="one-news-featured-article clearfix">';
echo ' <div class="grid_12">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="large-featured-image-container"><img src="'.$image_url.'">/div>';
}
echo ' <div>';
echo ' <h2>'.$row->title.'</h2>';
echo ' </div>';
echo ' </div>';
echo ' </div>';
echo ' <div class="grid_6">';
Any help? Essentially, it needs to apply the second code to the first three items in the query, then follow through with the code included in the current while loop - like an offset I guess.
Thanks,
R
This is quite simple. I hope I understood your question correctly:
$i = 0;
while ( ( $row = mysql_fetch_object( $result ) ) !== false ) {
if ($i < 3) {
// First code
} else {
// Second code
}
$i += 1;
}
Firstly, you should avoid using any mysql_ functions as they are all deprecated and will be removed from future versions of PHP. I'd recommend using PDO instead. See this tutorial to get started.
Then, it'll simply be a case of doing something like this:
foreach($db->query($query) as $index => $row) {
if ($index < 3) {
// first 3 items
} else {
// other items
}
}
You can do it easaly with an simple counter and an if statement:
$count = 0;
while(fetching) {
if($count < 3) {
// items 1, 2 and 3
} else {
// do normal
}
$count++;
}

PHP looping problem?

I'm trying to display the first row in one color and the second row in another color but my code displays the result twice in both colors for example lets say I have 5 results my code will double the results by displaying 10 results. How can I fix this problem?
Here is the php code.
while ($row = mysqli_fetch_assoc($dbc)) {
//first row
echo '<h3 class="title">' . $row['title'] .'</h3>';
echo '<div class="summary">' . substr($row['content'],0,255) . '</div>';
//second row
echo '<h3 class="title-2">' . $row['title'] .'</h3>';
echo '<div class="summary-2">' . substr($row['content'],0,255) . '</div>';
}
You need to change the class on each row:
$count = 0;
while ($row = mysqli_fetch_assoc($dbc)) {
if( $count % 2 == 0 ) {
$classMod = '';
} else {
$classMod = '-2';
}
//first row
echo '<h3 class="title' . $classMod . '">' . $row['title'] .'</h3>';
echo '<div class="summary' . $classMod . '">' . substr($row['content'],0,255) . '</div>';
$count++;
}
your code should be like this
CSS
.odd { background: #CCC }
.event { background: #666 }
PHP
$c = true;
while ($row = mysqli_fetch_assoc($dbc)) {
$style = (($c = !$c)?' odd':' even');
echo '<h3 class="title '.$style.'">' . $row['title'] .'</h3>';
echo '<div class="summary '.$style.'">' .substr($row['content'],0,255) . '</div>';
}
Here's a solution with minimal repetition:
$count = 0;
while (($row = mysqli_fetch_assoc($dbc)) && ++$count) {
printf(
'<h3 class="title%1$s">%2$s</h3>'
. '<div class="summary%1$s">%3$s</div>'
, $count % 2 ? "" : "-2"
, $row['title'] // might want to use htmlentities() here...
, substr($row['content'], 0, 255) // and here...
);
}
$i = 0;
while ($row = mysqli_fetch_assoc($dbc)) {
$color =$i % 2;
echo '<h3 class="title-' .$color . '">' . $row['title'] .'</h3>';
echo '<div class="summary">' . substr($row['content'],0,255) . '</div>';
$i++;
}
Your code just displays every result twice. Use a conditional (e.g. an integer or a boolean) to switch between rows (like: if true, then green; if false, then red).
For a boolean you could change the current value like so:
bool = !bool;
Couple of extra points:
You don't (normally) need so many classes. If you have <div class="stripe"> as your container, you can target the items with e.g. .stripe h3 in CSS.
If you target the odd and even items in CSS with .stripe h3, you can then overwrite just the odd items.
In a perfect world, you should keep presentation in the CSS. All browsers but IE7 and below support div:odd to target any odd child of a parent. This may require changing the structure of your HTML slightly. For IE7 and below, I'd add classes with JavaScript instead of PHP. When IE7 is no more then you can just remove the JS.
By the way, you could do this code too:
while ($row = mysqli_fetch_assoc($dbc)) {
echo '<h3 class="title">' . $row['title'] .'</h3>';
echo '<div class="summary">' . substr($row['content'],0,255) . '</div>';
if($row = mysqli_fetch_assoc($dbc)){
echo '<h3 class="title-2">' . $row['title'] .'</h3>';
echo '<div class="summary-2">' . substr($row['content'],0,255) . '</div>';
}
}
IMO, there is no excuse for not delegating this kind of non-critical, presentation layer decoration to client side code.
Just use a library like jQuery and access the odd and even rows like so:
<script>
$(document).ready(function()
{
//for your table rows
$("tr:even").css("background-color", "#F4F4F0");
$("tr:odd").css("background-color", "#EFF1F2");
});
</script>
You'll have us generating font tags next.

Categories