I am working on a script for a drivers license website, and I need to make a calendar like table for the students, so they can see when they have which lesson.
Right now we are updating the table manually, but I would like to make a script so it can do it automatically.
The table looks like this: (By the way, its a HTML table).
+----------+--------+---------+-----------+----------+--------+
| Week Nr. | Monday | Tuesday | Wednesday | Thursday | Friday |
+----------+--------+---------+-----------+----------+--------+
| 17 | 14 | 1 | 16 | 2 | |
+----------+--------+---------+-----------+----------+--------+
| 18 | 4 | 1 | 6 | | |
+----------+--------+---------+-----------+----------+--------+
| 19 | 8 | 1 | 11 | | |
+----------+--------+---------+-----------+----------+--------+
| 20 | 14 | 1 | 16 | 2 | |
+----------+--------+---------+-----------+----------+--------+
Lets say its this week (Week 17), it has its own set of lessons for every day, except Friday, which is the same for every week. Then it is the week after, which has its own set of lessons, and then it is 3 weeks after, which again has its own set of lessons. Then the 4th week, it start all over, with the same set as week 17, because its a 3 week program, over and over again.
What i want to do is that it automatically updates the table, so it shows the current week number. Then let us say that it is next week now, the table should have automatically update it self to show the current week and its set of lesson numbers.
The numbers under the column "Week Nr." are the week numbers, and the numbers under the day names are the lesson numbers.
So next week it should look like this:
+----------+--------+---------+-----------+----------+--------+
| Week Nr. | Monday | Tuesday | Wednesday | Thursday | Friday |
+----------+--------+---------+-----------+----------+--------+
| 18 | 4 | 1 | 6 | | |
+----------+--------+---------+-----------+----------+--------+
| 19 | 8 | 1 | 11 | | |
+----------+--------+---------+-----------+----------+--------+
| 20 | 14 | 1 | 16 | 2 | |
+----------+--------+---------+-----------+----------+--------+
| 21 | 4 | 1 | 6 | | |
+----------+--------+---------+-----------+----------+--------+
Is there anybody who could give me a hint on how to do that with PHP. I have tried everything I knkw, but I just cant get it right.
This is not exactly what you want, but it could be a good starting point. Just modify it to print out the HTML tags.
//Set a counter for the lessons
$j = 0;
//Loop through the weeks of the year
for ($i = 1; $i <= 52; $i++) {
echo "Week: ".$i."<br>";
echo "This weeks lessons: " . $j."<br>";
//Incrase counter
$j++;
if ($j % 3 === 0) {
//Reset counter if need
echo "<hr>";
$j = 0;
}
}
Related
I need to get past 30 days sales records from MYSQL database to display in a bar chart how many items sold each day. Also I need to display past 30 days in my chart x axis in my php document. I tried run this code inside a for loop. because I am running some other codes to display some data using this loop. Take a look at the following code and help me how to achieve this.
This is the table I try to get data from
Date format (YYYY-MM-DD)
Products Table
product_id | sold_by | qty | added_date | sold_date
-----------+---------+-----+-------------+-----------
3 | 12 | 7 | 2022-05-05 | 2022-07-28
3 | 12 | 7 | 2022-05-05 | 2022-07-29
3 | 12 | 7 | 2022-05-05 | 2022-07-30
3 | 12 | 1 | 2022-05-05 | 2022-07-30
3 | 12 | 2 | 2022-05-05 | 2022-07-30
6 | 22 | 4 | 2022-06-06 | 2022-07-31
8 | 11 | 6 | 2022-08-05 | 2022-07-31
Deleted Table
product_id | added_date | delete_date
-----------+-------------+-----------
3 | 2022-05-05 | 2022-07-28
3 | 2022-05-05 | 2022-07-29
3 | 2022-05-05 | 2022-07-30
3 | 2022-05-05 | 2022-07-30
3 | 2022-05-05 | 2022-07-30
6 | 2022-06-06 | 2022-07-31
8 | 2022-08-05 | 2022-07-31
As you can see for some days I have multiple records.
<?php
//for loop to run 30 times to get 30 days results
for ($i = 30; $i >= 0; $i--) {
$sold_products_count = mysqli_num_rows(mysqli_query($conn, "SELECT * FROM products WHERE sold_date = CURRENT_DATE - $i"));
$deleted_count = mysqli_num_rows(mysqli_query($conn, "SELECT * FROM deleted WHERE delete_date = CURRENT_DATE - $i"));
?>
{
<?php
$current_date = date("Y-m-d");
$new_date = date_create($current_date);
date_sub($new_date, date_interval_create_from_date_string("$i day"));
?>
x: '<?php echo date_format($new_date, "Y-m-d"); ?>',
a: <?php echo $deleted_count; ?>,
s: <?php echo $sold_products_count; ?>,
},
<?php
}
?>
x- X axis data in the chart
a - number of products deleted in specific date
s - number of products sold in specific date
With the above code I was able to print the x axis data. I am not sure how to get past 30 days data from the SQL database. I think the problem is in the $i part in the SQL query.
In your query, if you use INTERVAL, you can use some days for adding/reducing from the current or specific date.
For example in your case, if you always want to get the last 30 days data, you can use your WHERE like this:
sold_date >= CURDATE() - INTERVAL 30 DAY
I have a leave date data in one month with various types of dates I try to match the data by date this month. when I make it based on row data only one date appears. I am a little less aware of the logic if it is an array.
My table
| ID | id | start_date | end_date |
| ____|________|______________|______________|
| 1 | x1 | 2018-11-05 | 2018-11-05 |
| 1 | x1 | 2018-11-12 | 2018-11-15 |
| 3 | x1 | 2018-11-19 | 2018-11-21 |
My script
$timesheet = $this->db->select('*')
->where('MONTH(start_date)', 11)
->where('YEAR(start_date)', 2018)
->where('id', 'x1')
->get();
$result = $timesheet->row_array();
$day_start=date_create($result['start_date']);
$day_end=date_create($result['end_date']);
for ($x = 1; $x <= 30; $x++) {
if($x >=$day_start->format('d') and $x <= $day_end->format('d')){
echo "<td class='bg-warning'>Y</td>";
}else{
echo "<td>N</td>";
}
}
/** MY result data **/
| Date | ... | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ... |
----------------------------------------------------------------
| Result| ... | N | N | N | Y | Y | N | N | N | N | ... |
/** the results I expected **/
| Date | ... | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ... |
----------------------------------------------------------------
| Result| ... | N | Y | N | Y | Y | N | Y | Y | Y | ... |
If you want to merge all of the records together, you will need to build up an array of the days (I create it using array_fill() and set each one to "N" to start).
You then iterate over each result row and add in the Y's to the appropriate elements. You then loop over from the start to end day using a for() loop to fill in the days with a 'Y'.
Finally you can output the $dates array which has all of the various rows added into it.
$dates = array_fill(1, 30, "N");
foreach ($timesheet->result_array() as $result) {
$start = (int)$result['start_date']->format('d');
$end = (int)$result['end_date']->format('d');
for ( $i = $start; $i <= $end; $i++ ) {
$dates[$i] = "Y";
}
}
foreach ( $dates as $day ) {
if($day == "Y") {
echo "<td class='bg-warning'>Y</td>";
}else{
echo "<td>N</td>";
}
}
You will probably want to change the array_fill() to have the correct number of days for the month you are working with, but this is something you can sort out as and when you need it.
Say we have a posts table that has the columns: id, title, expires_at. We want to show how many posts where not "expired" in each week of every year.
Maybe a simpler way of putting it would be: "a count of posts grouped by weeks of the year where the expires_at date is great then the start of each week"
For example:
-------------------------------------------------
| Year | Week | posts_not_expired |
------------|-----------|-----------------------|
| 2017 | 01 | 22 |
| 2017 | 02 | 103 |
| 2017 | 03 | 7 |
| ... | ... | ... |
| 2009 | 52 | 63 |
|-----------|-----------|-----------------------|
What we have so far:
SELECT
COUNT(id) as posts_not_expired,
YEAR(expires_at) * 100 as Year,
YEARWEEK(expires_at) as Week,
FROM posts
GROUP BY Year, Week
You can use DAYOFWEEK to count non-expired posts for a given week. (where 1 = Sunday,2=Monday,..7=Saturday)
SELECT
YEAR(expires_at) as `Year`,
WEEKOFYEAR(expires_at) as `Week`,
SUM(DAYOFWEEK(expires_at) > 2) as `posts_not_expired`
FROM posts
GROUP BY YEAR(expires_at), WEEKOFYEAR(expires_at)
I need to synchronize two different booking calendars, beacause both calendars book the same room (or the same event).
So, if a client book a day (and hours) in calendar_01, this value (booked day and hours) will be automatically updated in calendars_02 (and vice versa).
It's important to update (and rewrite the new value) in order of the last time (most recent booking) without a continuous loop.
MySql DB
I'm using a plugin for this and in "calendars" database there is a table called "days", in this table I can see this:
+--------------+-------------+------------+------+----------------------------------------------------------+
| unique_key | calendar_id | day | year | data |
+--------------+-------------+------------+------+----------------------------------------------------------+
| 1_2014-08-20 | 1 | 2014-08-20 | 2014 | available h10-12; booked h12-14; in pending h14-16; |
| 2_2014-08-20 | 2 | 2014-08-20 | 2014 | available h 10 - 12; available h12-14; available h14-16; |
| 1_2014-08-21 | 1 | 2014-08-21 | 2014 | available h10-12; available-14; available h14-16; |
| 2_2014-08-21 | 2 | 2014-08-21 | 2014 | booked h10-12; booked h12-14; in pending h14-16; |
+--------------+-------------+------------+------+----------------------------------------------------------+
Simplification: column "data" contains the values (TEXT type) that record every rebooking, so:
+--------------+-------------+------------+------+--------------+
| unique_key | calendar_id | day | year | data |
+--------------+-------------+------------+------+--------------+
| 1_2014-08-20 | 1 | 2014-08-20 | 2014 | text value A |
| 2_2014-08-20 | 2 | 2014-08-20 | 2014 | text value B |
| 1_2014-08-21 | 1 | 2014-08-21 | 2014 | text value C |
| 2_2014-08-21 | 2 | 2014-08-21 | 2014 | text value D |
+--------------+-------------+------------+------+--------------+
I need to update the values of the same column "data", like this:
+--------------+-------------+------------+------+--------------+
| unique_key | calendar_id | day | year | data |
+--------------+-------------+------------+------+--------------+
| 1_2014-08-20 | 1 | 2014-08-20 | 2014 | text value A |
| 2_2014-08-20 | 2 | 2014-08-20 | 2014 | text value A |
| 1_2014-08-21 | 1 | 2014-08-21 | 2014 | text value D |
| 2_2014-08-21 | 2 | 2014-08-21 | 2014 | text value D |
| 1_2014-08-22 | 1 | 2014-08-22 | 2014 | text value X |
| 2_2014-08-22 | 2 | 2014-08-22 | 2014 | text value X |
| 1_2014-08-23 | 1 | 2014-08-23 | 2014 | text value Y |
| 2_2014-08-23 | 2 | 2014-08-23 | 2014 | text value Y |
+--------------+-------------+------------+------+--------------+
Many thanks in advance for any help!
I would strongly advice against syncing/Data Replication. You'd need to run a deamon 24/7, the risk of running into issues is much higher, it's also less eficient since It has to keep checking for new data in both tables which also means a delay for people to see their new bookings on the site. And it not so easy to debug when something does go wrong with the deamon.
The following solution is much easier to debug, more efficient. I would suggest you write abstract CRUD code for the data: Create, Read, Update and Delete. Create and Update are probably the ones you're most interested in, what you would do is something like this:
<?php
function create($id, $data)
{
$id = mysql_real_escape_string($id);
$data = mysql_real_escape_string($data['data']);
mysqL_query("INSERT INTO calendars (unique_key,data) VALUES('".$id."','".$data."')");
mysqL_query("INSERT INTO days (unique_key,data) VALUES('".$id."','".$data."')");
}
function update($id, $data)
{
$id = mysql_real_escape_string($id);
$data = mysql_real_escape_string($data['data']);
mysqL_query("UPDATE calendars SET data = '".$data."' WHERE unique_key = '".$id."'");
mysqL_query("UPDATE days SET data = '".$data."' WHERE unique_key = '".$id."'");
}
create('1_2014-08-20', array(
'data' => 'data here'
));
update('1_2014-08-20', array(
'data' => 'data here'
));
This is as simple as passing data into it. If you ever modify the SQL structure you can create a new abstraction set of functions/classes that follows the new database structure and it's as easy as swapping out an include.
Currently we store hours in a table that has a percentage field to distribute data across the week.
eg.
| dayint | daytext | hours | percent |
+--------+---------+-------+---------+
| 1 | mon | 9 | 0.14 |
| 2 | tue | 15 | 0.23 |
| 3 | wed | 9 | 0.14 |
| 4 | thu | 9 | 0.14 |
| 5 | fri | 0 | 0.00 |
| 6 | sat | 23 | 0.35 |
We are now adding a monthly distribution as well as weekly, so to calculate this I am:
Getting number of weeks in a month.
$weeks = $days_in_month/7
Iterating through each day's percent and dividing it by number of weeks.
$percent = $day['percent'] / $weeks
If my assumption is correct, this should distribute data across the month evenly. The problem is that it is consistently about 1ish % extra for the month.
If I enter 1000, I get 1013. If I enter 200, I get 202. Maybe I am just going about it wrong mathematically, any help is appreciated.
If your percent column stores data that has been rounded and is used in your monthly calculation as opposed to displaying rounded results that are stored accurately elsewhere then you will get rounding errors.
The example below shows the results for three weeks and the tables afterwards show the results using the actual data and the rounded data.
|Hours|Actual |Rounded| |Hours|Actual |Rounded| |Hours|Actual |Rounded|
| 9|0.13846153846154| 0.14| | 10|0.15625000| 0.16| | 8|0.135593220339| 0.14|
| 15|0.23076923076923| 0.23| | 14|0.21875000| 0.22| | 13|0.220338983051| 0.22|
| 9|0.13846153846154| 0.14| | 8|0.12500000| 0.13| | 11|0.186440677966| 0.19|
| 9|0.13846153846154| 0.14| | 10|0.15625000| 0.16| | 7|0.118644067797| 0.12|
| 0|0.00000000000000| 0| | 1|0.01562500| 0.02| | 2|0.033898305085| 0.03|
| 23|0.35384615384615| 0.35| | 21|0.32812500| 0.33| | 18|0.305084745763| 0.31|
| 65|1.00000000000000| 1.00| | 64|1.00000000| 1.02| | 59|1.000000000000| 1.01|
Over the three weeks iterating with
$percent = $day['percent'] / $weeks
actual column gives the results
0.14343
0.22329
0.14997
0.13779
0.01651
0.32902
1.00000
whereas rounded column gives
0.146666667
0.223333333
0.153333333
0.14
0.016666667
0.33
1.01
Remember rounded results always go up or stay the same never downwards, so the error will always be slightly more than you expect.
I decided to change my approach and go about it like this:
Get the total hours for the month by looping through:
$total = $total + $day['hours'];
Use the stored hours instead of the percent to calculate a new percent using:
$percent = $v['hours']/$total;
This approach returns the correct data.