I have a small PHP page which takes data from MySQL and displays it via PHP in a monthly calendar. I'm having trouble arranging the data properly within an array to get the desired output.
First, I will describe what I would like to happen:
students come to classes on regular days of the week
they can also make or cancel reservations
the calendar also displays days when the school is not open
In order to display this data on the calendar, I use MySQL to output data from a variety of sources, and then input that into an array with PHP, which I sort by date and output.
My issue is, I would like to be able to handle more than one row of data per day, but because I am using the date as the key, I am limited on only displaying one result per day. If I use a loop to append the date with a counter in the key, I get overlapping results in situations where someone made a reservation and then cancelled that reservation on the same day.
As for my code...
First, I check to see if the student is registered in a weekly class, then input that class into the array.
$sql = "SELECT StudentDB.studentid, ClassDB.classID, ClassDB.class_level, ClassDB.class_title, ClassDB.time, ClassDB.teacher, StudentDB.first_name, StudentDB.last_name, StudentDB.payment_amount, ClassDB.day
FROM ClassDB
INNER JOIN RegDB ON ClassDB.classID = RegDB.classid
INNER JOIN StudentDB ON StudentDB.studentID = RegDB.studentid
WHERE StudentDB.studentid = '$studentid'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) { // DISPLAY REGULAR CLASS DATA
$dayofclass = $row['day'];
$class_level = $row['class_level'];
$class_title = $row["class_title"];
$day = $row["day"];
$class_time = $row["class_time"];
$time = $row["time"];
// check which dates match the days of the week and store in an array
for ($i=1;$i<=$n;$i++){
if ($i<10) {
$i = "0" . $i;
}
$day=date("l",strtotime($yearmonth.$i)); //find weekdays
if($day==$dayofclass){
$time = date("H:i",strtotime($row['time']));
$dates[]=$yearmonth.$i;
$datesdata[$yearmonth.$i] = "0";
$timedata[$yearmonth.$i] = $time;
$classiddate[$yearmonth.$i] = $row['classID'];
}
}
}
echo "</table>";
$conn->close();
}
After that, I check for specific reservations (cancelations, irregular reservations, waitlists) and input them into the array:
$lowerlimit = $yearmonth . "01";
$upperlimit = $yearmonth . "31";
$sql = "SELECT AttendanceDB.*, ClassDB.*
FROM StudentDB
INNER JOIN AttendanceDB ON StudentDB.studentid = AttendanceDB.studentid
INNER JOIN ClassDB ON AttendanceDB.classid = ClassDB.classID
WHERE StudentDB.studentid = '$studentid'
AND AttendanceDB.class_time >= '$lowerlimit'
AND AttendanceDB.class_time <= '$upperlimit'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$loopcount = 0;
// store furikae data in the array
while($row = $result->fetch_assoc()) {
$phpdate = strtotime( $row["class_time"] );
$time = date("H:i",strtotime($row['time']));
$mysqldate = date( 'Y-m-d', $phpdate );
$loopcount++;
$mysqldate = $mysqldate . "+" . $loopcount;
// $loopcount++;
// $mysqldate = $mysqldate . "+" . $loopcount;
$previousdate = $mysqldate;
$previousfurikae = $row['furikae'];
if ($row["furikae"] == 3){
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "1";
$timedata[$mysqldate] = $time;
$classiddate[$mysqldate] = $row['classID'];
} elseif ($row["furikae"] == 8 OR $row["furikae"] == 7) {
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "3";
$timedata[$mysqldate] = $time;
} elseif ($row["furikae"] == 2) {
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "2";
$timedata[$mysqldate] = $time;
}
}
}
$conn->close();
Then finally I check the school calendar and input the days off into the array:
$sql = "SELECT *
FROM SchoolScheduleDB
WHERE date >= '$lowerlimit'
AND date <= '$upperlimit'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// store furikae data in the array
while($row = $result->fetch_assoc()) {
$phpdate = strtotime( $row["date"] );
// $time = date("H:i",strtotime($row['time']));
// $mysqldate = date( 'Y-m-d', $phpdate ) . " " . $time;
$mysqldate = date( 'Y-m-d', $phpdate );
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "666";
}
}
$conn->close();
The way I intended it to work was that:
First the regular classes would be input
Then any reservations would overwrite the original plans
And finally the school calendar would overwrite everything
Currently, this functions as it should, but it is limited to displaying 1 result per day, but I would like to be able to display more than 1 result per day for students who come to multiple classes.
Thank you for your help. If I made any mistakes in my question or my question is unclear I will do my best to revise it.
You can make a Sub-Array for each date by using edged brackets:
$data[20180528][] = 'aa';
$data[20180528][] = 'bb';
$data[20180529][] = 'cc';
$data[20180529][] = 'dd';
$data[20180529][] = 'ee';
will give you an Array like this:
20180528 => aa
=> bb
20180529 => cc
=> dd
=> ee
Related
I am currently trying to get the nearest match of 2 sets of dates (d-m-Y) against a SQL database and then out put the matched InterestRate column name.
I have an example of my current code, this is mostly pseudo code and trying a few things out. If that helps.
//$XSS_BLOCK2 = "05-05-2016";
$XSS_BLOCK3 = "20-05-2016"; //By the way The '2016-05-20' is user input so it will not be '2016-05-20' all the time, so it could be anything '2014-08-15'.
$today = date('d-m-Y');
$interest = 0;
$securesqlstring = $secureconn->prepare("SELECT * FROM LatePaymentRates");
$securesqlstring->execute();
while($row=$securesqlstring->fetch())
{
echo $row['StartDate'];
echo $row['EndDate'];
echo $row['InterestRate'];
$varsin = array($XSS_BLOCK3, $today);
$DateRange = new DateTime($varsin);
$databasein = array($row['StartDate'], $row['EndDate']);
$DateRanges = new DateTime($databasein);
if(($DateRange >= $DateRanges) && ($DateRange >= $DateRanges)) {
$dayrate = $row['InterestRate'] * $XSS_BLOCK3 / 36500;
$start_date = new DateTime($DateRange);
$end_date = new DateTime($DateRanges);
$dd = date_diff($end_date, $start_date) * $dayrate;
$interest += $dayrate;
}
}
$LatePaymentInterest = $interest;
if (!$securesqlstring) // If there is an error it will show this message.
{exit("Error in the SQL");}
Do we really need to spell this one out? I feel like I must be missing something...
SELECT * FROM my_table WHERE '2016-05-20' BETWEEN startdate AND enddate;
I can't figure it out! I've created an array of months in "Slovenian language" and now, I would want to display my month's name instead of the number. Instead of working, it writes out - 32014vEurope/Berlin11bEurope/BerlinWed and some more weird stuff, it should obviously print out November in my case. I would like to solve this problem with arrays, but It just wouldn0t convert the number of 'n' to the requested month.
function kliknjena($link, $mojster)
{
$meseci[1] = "Januar";
$meseci[2] = "Februar";
$meseci[3] = "Marec";
$meseci[4] = "April";
$meseci[5] = "Maj";
$meseci[6] = "Junij";
$meseci[7] = "Julij";
$meseci[8] = "Avgust";
$meseci[9] = "September";
$meseci[10] = "Oktober";
$meseci[11] = "November";
$meseci[12] = "December";
$sql = "SELECT naslov, podnaslov, vsebina, ustvarjeno, slug FROM novica
where slug = '$mojster'
limit 1";
$result = mysqli_query($link, $sql);
if (mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_assoc($result))
{
echo "<h1>".$row["naslov"]."</h1>";
$timestamp = strtotime($row["ustvarjeno"]);
$m = date("n", $timestamp);
echo date("d. $meseci[$m]; Y, H:i:s", $timestamp);
echo "<p>".$row["podnaslov"]."</p>"."<br>";
echo "<p>".$row["vsebina"]."</p>"."<br>";
}
}
else
{
echo "0 results";
}
}
Use:
echo date('d. ', $timestamp) . $meseci[$m] . date('; Y, H:i:s', $timestamp);
What's happening is that the month name is being substituted into the date() argument, and then all the letters in the month are being treated as formatting characters, so they get replaced with the corresponding fields from the date and time.
$sqlStr = "SELECT name, datescheduled
FROM table
WHERE datescheduled > NOW()
ORDER BY datescheduled DESC";
I would like to echo a table with the results above. I would like a row for each day for the next 90 days regardless of whether or not the MySQL table has an entry for that day. How can I do this?
Add:
$query1 = mysql_query($sqlStr);
echo "<table><tr>";
echo "<th>Name</th><th>Date Scheduled</th>";
while ($rows = mysql_fetch_assoc($query1)) {
echo "<td>" .$rows['name']. "</td>";
echo "<td>" .$rows['datescheduled']. "</td>";
}
echo "</tr><table>";
//select rows for next 90 days and read them into $rows
//use datescheduled as the key
//assumes there will only be 1 row per date and datescheduled is in Y-m-d format
$sqlStr = "SELECT name, datescheduled
FROM table
WHERE datescheduled > NOW()
AND datescheduled < date_add(now(),INTERVAL 90 DAY)
ORDER BY datescheduled DESC";
$rs = mysql_query($sqlStr);
$rows = array();
while($r = mysql_fetch_assoc($rs)) {
$rows[$r['datescheduled']] = $r;
}
//add missing dates to $rows with name = false
$begin = new DateTime();
$end = new DateTime();
$end->modify('+90 day');
$interval = new DateInterval('P1D');
$period = new DatePeriod($begin, $interval, $end);
//iterate through the next 90 days
foreach ($period as $dt) {
$date_key = $dt->format( "Y-m-d" );
if(!isset($rows[$date_key])) {
//table doesn't contain a row for this date, so add it
$rows[$date_key] = array('datescheduled' => $date_key, 'name' => false);
}
}
//do something with $rows
So you can use this basic setup. I assume based on your wording that there would only be one entry per row, but it would be easy to adjust accordingly.
//Get the current date
$date = date('Y-m-d');
//Set the table header
$str = '<table><thead><tr><th>Name</th><th>Date</th></tr></thead><tbody>';
//START THE WHILE LOOP GETTING THE FETCH ASSOC
//Go through for 90 days
for ( $i = 0; $i < 90; $i++ ) {
$str .= '<tr>';
if ( $row['date'] == date('Y-m-d', strtotime('-'.$i.' day', $date)) {
$str .= '<td>'.$row['name'].'</td><td>'.$row['date'].'</td>';
} else {
$str .= '<td></td><td></td>';
}
$str .= '</tr>';
}
//END WHILE LOOP NOT INCLUDED
$str .= '</table>';
echo $str;
Hi firstly heres my code.
<?php
function getDatesBetween2Dates($startTime, $endTime) {
$day = 86400;
$format = 'd-m-Y';
$startTime = strtotime($startTime);
$endTime = strtotime($endTime);
$numDays = round(($endTime - $startTime) / $day) + 1;
$days = array();
for ($i = 0; $i < $numDays; $i++) {
$days[] = date($format, ($startTime + ($i * $day)));
}
return $days;
}
///
$days = getDatesBetween2Dates(date('d-m-Y', strtotime('-3 weeks Monday')),date('d-m-Y', strtotime('+2 weeks Sunday')));
foreach($days as $key => $value){
$dayNumber = date('d', strtotime($value));
//echo $value;
echo "<div id=\"day\">
<div id=\"number\">$dayNumber</div>";
////////////sql seearch//\\\/////////
//Connect to db
include("../djwbt.php");
$sql = "SELECT * FROM daysummary WHERE date='$value'";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
$place = $row['place'];
$invoicedate = $row['date'];
}
/////////////end sql search//////////
echo "<div id=\"event\">$place</div>
</div><!-- end day -->";
}
?>
What i am trying to do is show all dates between two points and for each of the dates search my db using the date as a where clause. i have tried putting the search in a few places but im not getting the right results.
this gives me the same result in each date.
e.g. 17th = (empty) as in my db, 18TH = HOME (as in my db), 19th = HOME (not as in my db), 20th = HOME (this continues all the way through fore each)
the link in each fore each works perfectly?
Any help would be amazing.
I would make one statement that gets all the needed data from your database:
SELECT column_name(s)
FROM table_name
WHERE column_name BETWEEN value1 AND value2;
then use the foreach loop for the results
Note that mysql_ functions are deprecated, Try switching to mysqli_ or PDO
Upon running the below SQL statement (which works perfectly) I've found that all tables in my database are flushed white.
Any idea as to why this happening?
// check database for necessary updates
$update = mysql_query("SELECT * FROM rent WHERE colour='3C0'");
while($row_update = mysql_fetch_array( $update )) {
$datetime_lower = DateTime::createFromFormat('d/m/Y', $min);
$datetime_upper = DateTime::createFromFormat('d/m/Y', $max);
$datetime_compare = DateTime::createFromFormat('d/m/Y g:i a', $row_update['pDate']);
if ($datetime_lower < $datetime_compare && $datetime_upper > $datetime_compare) {
// date is between do nothing
mysql_close($update);
} else {
// date is not between so update
echo "date is not between";
$update_result = mysql_query("UPDATE rent SET colour='F0F0F0' WHERE substr(pDate, 0, 10) NOT BETWEEN $min AND $max && colour='3C0'");
mysql_close($update_result);
}
}
I've included a few pictures.
This is how it is meant to look like (above code omitted):
http://i51.tinypic.com/143gpef.jpg
This is how it currently looks like (above code present):
http://i54.tinypic.com/2lwm4xg.jpg
Your while loop appears to go through all the results from your table. It appears that on each iteration of the loop, you check the date first in PHP, then you check the date again in your update query, and update all matching rows to F0F0F0.
I don't know why your code is changing the colour to white instead of #F0F0F0, since there is no white or fff in your code, so all I can do is suggest something to make your code more efficient.
Instead of updating all rows on each iteration of the while loop, if you have an id column (Primary Key with Auto-increment) in your rent table, you can use this value in your while loop instead of having to test the date a second time.
$update = mysql_query("SELECT * FROM rent WHERE colour='3C0'");
while($row_update = mysql_fetch_array( $update )) {
$datetime_lower = DateTime::createFromFormat('d/m/Y', $min);
$datetime_upper = DateTime::createFromFormat('d/m/Y', $max);
$datetime_compare = DateTime::createFromFormat('d/m/Y g:i a', $row_update['pDate']);
if ($datetime_lower < $datetime_compare && $datetime_upper > $datetime_compare) {
// date is between do nothing
mysql_close($update);
} else {
// date is not between so update
echo "date is not between";
$update_result = mysql_query("UPDATE rent SET colour='F0F0F0' WHERE id=" . $row_update['id'] . " && colour='3C0'");
mysql_close($update_result);
}
}