calendar with sql - php

PHP+SQL question:
I have table for assignments
one of the field is "progTargetDate" -> linux time (eg: 1348185600 )
I also built calender and I want to check if I have any assignment for each day I print
so - I wrote the query that bring me all the assignment for the current month
$query = mysql_query("SELECT ass.id, ass.title, ass.des, ass.progTargetDate
FROM pro_assignments AS ass, pro_progs2assignments AS pr
WHERE (ass.progTargetDate >= $ChoosenMonth_start) AND
(ass.progTargetDate <= $ChoosenMonth_end)
ORDER BY ass.progTargetDate ASC
");
(I delete part of the SQL query))
and I have the loop that build the calendar cell
for ($i = 1 ; $i <= $total_days_in_month ; $i++)
{
}
$i = each day in the month
I tried to build IF condition without success
I want to check for each day if it found inside the array (that I got from the first query)
(this code goes inside the FOR loop:)
echo "<td>$i";
while($index = mysql_fetch_array($query))
{
$progTargetDate = $index['progTargetDate'];
if ((mktime(0, 0, 0, date($ChoosenMonth) , $i, date($ChoosenYear)) == $progTargetDate))
echo "<p>found</p>";
else
echo "<p>not</p>";
}
echo "</td>";
What do I do wrong?
for 31 days I should have 31 cell with "found" or "not" in each one. but for some reason only in the first cell I see this result

Related

How to display the serial number of the table rows in descending order in php?

I am looking way to sort the serial number of the table in descending order. I am using a here simple while loop, with a counter variable inside it.
Code sample:
$i= 0;
while(condition)
{
$i++;
echo "<td>".$i."</td>";
}
Output:
I am not using an autoincrement column here. I just want it with a simple counter, but in descending order.
example:
#
10
9
8
7
6
5
4
3
2
1
Any help is highly appreciated.
If you already have loop outputting the 1-10 version, you could simple change the output to show 11 minus the current count...
echo "<td>".(11-$i)."</td>";
Or to change the whole code, you could start at 11 and decrement the counter each time and output it that way
$i= 11;
while($i>0)
{
$i--;
echo "<td>".$i."</td>";
}
count first and after do a loop in reverse order
$i= 0;
while(condition)
{
$i++;
}
for ( cnt= $i, $i>= 0, $i--){
echo "<td>".$cnt."</td>";
}
If you are fetching from MYSQL Database and you're using PDO to connect to Database
//COUNT THE TOTAL NUMBER OF ROWS RETURNED
$sql = "SELECT COUNT(*) FROM all_tnxs ORDER BY id DESC";
$stmt = $con->query($sql);
$stmt_num_rows = $stmt->fetch();
$tot_rows = array_shift($stmt_num_rows);
$sn = $tot_rows
while(){
$sn--;
echo '<td>' . $sn . '</td>';
}
So whatever the total number of rows you have - fetching from the database it'll countdown to '0'using the while loop.
I have been looking for this for long but later figured it out myself so I decided to drop it here for anyone it might be helpful to...

Combining while in foreach in PHP

I have been working for a while to combine a "foreach loop" and a "while loop". I would like my foreach to run 30 times. This is indicated by $counter. Now the problem is that my "while" again starts the "foreach" every time. But it hears 30 times turning the "while" each time again.
If I get the while part away and use static code, it will work completely. But I need to link my DB for the information. Perhaps an option is to make a "foreach" a "for" or a whole different option. But I have no idea how to set him up.
$counter = days in a month
$index = foreach time for running. Max $counter
$NUM = unique number of 1 people
The $ index together with $ cut_startday together indicate when a box is to be red or green.
Here's the code for the none working foreach:
foreach(range(1,$counter) as $index) {/*open foreach*/
$get_data = "
SELECT *
FROM core";
$result1 = $conn->query($get_data) or die($conn ->error);
//Start query 1
if($result1) {
while($row = $result1->fetch_assoc()) {
// Get NUM, START DATE and END DATE
$NUM = ($row['c_m_num']);
$startdate = ($row['e_date_s']);
$enddate = ($row['e_date_e']);
// Cut strings for date
$sort_year = substr($startdate, 6, 4); // START YEAR -> 2017
$sort_month = substr($startdate, 0, 2); // START MONTH -> 09
$cut_startday = substr($startdate, 3, 2); // START DAY -> 17
$cut_endday = substr($enddate, 3, 2); // END DAY -> 19
if($load_m_NUM == "$NUM" and $index >= $cut_startday && $index <= $cut_endday ){
echo"<td style='background-color:red;'>x</td>";
}
else{
echo"<td style='background-color:green;'></td>";
}
}
}
/*end foreach*/ }
What the idea is of the code. I want a calendar with a top row de days of a month and on the left side al the people. If the core find a match between days and 1 men, color the td red if not color green.
Any help greatly appreciated!
You could change the foreach statement to for ($index = 0; $index < 30; $index++). To improve your code I suggest putting the for loop inside the while loop instead. That way you only query the database once instead of 30 times.

do-while in php resulting a non-stop page loading

I want to have a $startdate counting 3 days backward from an input date by user, where those 3 days are not holidays.
So if the input date by user is October 22, the $startdate would be October 17 instead of October 19. Because October 19 and 20 are holidays
$i = 1;
do{
//some code to produce the $startdate
//...
//end
//check if $startdate is holiday or not
$this->db->where('hl_date',$startdate);
$query = $this->db->get('php_ms_holiday');
//if $startdate = holiday, it doesn't count
if($query->result_array()){
}
else{
$i++;
}
}while($i <= 3);
But, with that code I have a non-stop loading on the browser when a $startdate captured inside the if($query->result_array()) statement. And the browser can only returning results when I put something like this code below, inside the if($query->result_array()) statement:
$i = $i + n; //n is a number starting from 1, or
$i++;
but not:
$i = $i; //or
$i = $i + 0;
Why is that?
You just make a DB query which result interprets as TRUE. Maybe I wrong but it seems you are make the same db query in each loop iteration.
So, check your query, for example add specific date for holiday checking.
if($query->result_array()) will always evaluate to true, if your query is correctly formulated. So also if the number of rows returned is 0. This means that you never ever go to the else. You if-statement should check the number of results returned instead; Furthermore, I personally would prefer a normal for-loop:
for($i = 0; $i < 3)
{
//some code to produce the $startdate
//...
//end
//check if $startdate is holiday or not
$this->db->where('hl_date',$startdate);
$query = $this->db->get('php_ms_holiday');
//if $startdate = holiday, it doesn't count
if [num_rows equals 0] // test num_rows here; Not sure what your class offers here
{
$i++; // increment counter
// do whatever else you want to do
}
}
If this is always true:
if($query->result_array()){
}
Then this will always be true:
}while($i <= 3); //$i is never adjusted, so it will always be less than 3
Since you say that you want to display data from with the last 3 days but if there are holidays in between, you don't want to count them. To get around this I think you should not use the literal "3" since it can be adjusted, it should be a variable too.
A possible solution would be to have a variable such as:
$days_back = 3;
Then try to count the amount of holidays within the last 3 days(or something like that):
//You can make the holidays to be zero by default
$holidays = someWayToCountHolidays($startDate, $endDate); //You'll obviously have to code this
Then you can make make the variable your while loop will work agains
$num_days = $days_back + $holidays; //$holidays can be zero by default
Then something like below for you do while loop:
if($query->result_array()){
//Then do what ever you want to do here
} else {
//Then do what ever you want to do here
}
$i++; //Adjust $i
}while($i <= $num_days);

Adding rows to an array in PHP

I have loaded an associative array of records from a MySQL database table.
The array consists of 1 to 7 rows representing one week of entries,
which might not have been entered for each day.
How can I insert blank rows into the array for the missing days
so that I can easily display the data in a table?
I don't need to update the database with the blanks.
Example:
Field1 Field2 Field3 Field4 .... Field#
Record[0]
Record[1]
Record[2]
Record[3]
Record[4]
Record[5]
Record[6]
Field4 is the date as yyyy-mm-dd
I load the array automatically using a start date and end date
Some weeks there will be a Sun, Tue, and Fri or Mon, Tue, Wed, Fri & Sat.
this is simple:
Do you know how many "Fields" you have for each day? let's say it's "num of fields"
$records = array_fill(0, 7, array_fill(0, <num of fields>, ''));
what this does is it creates a blank array from [0] to [6] and for each array element it inserts another array of "Fields", with "num of fields", each of which is set to an empty string ''.
Now that you have this, you read your data from the mysql table and if you selectively assign $records by index (i'm assuming), the rest of them will stay blank.
Keep in mind that you can reassign an element of $records array by using something like
$records[5] = array('New value', 'Field2 value');
which is what you do when you read data from mysql table.
Do you use some kind of index in your mysql table to correspond to the numbered day in a week?
comment here if you get stuck with mysql part.
If your array is associative, then when constructing the table why not just check for and skip the empty rows? As an example:
Example 1:
if ($row['Monday'] == '')
{
// draw blank template
}
else
{
// draw using live data
}
Based on added example (untested; for php 5.1 and above):
Example 2:
for($i = 0; $i < count($Record); $i++)
{
$recordDate = strtotime($Record[$i][field4]);
$dayOfWeek = $date('N', $recordDate);
switch ($dayOfWeek)
{
case '1':
// Monday
break;
case '2':
// Tuesday
break;
// and so on...
}
}
Edit
The above code assumed that your rows are in weekday order, with possible omissions. The problem with the first example, is that the array is not associative quite like the example. The problem with the second example, is that a missing weekday row results in a completely skipped output, which could provide a table like MTWFS (skipped Thursday).
So, you need to build a loop that draws each day of the week, and checks all of the rows for the appropriate day to draw. If the day is not found, an empty day is drawn:
Example 3:
$dayNames = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'};
// Loop that walks the days of the week:
for($d = 1; $d < 7; $d++)
{
// Loop that checks each record for the matching day of week:
$dayFound = false;
for($i = 0; $i < count($Record); $i++)
{
$recordDate = strtotime($Record[$i][field4]);
$dayOfWeek = $date('N', $recordDate);
// output this day name in your own formatting, table, etc.
echo $dayNames[$i];
if ($dayOfWeek == $d)
{
// output this day's data
$dayFound = true;
break;
}
if (!$dayFound)
{
// output a blank template
}
}
}
Edit 2
Ok it seems you are more interested in having a fully populated array of weekdays than an output routine (I was assuming you would just want to draw the tables in php or something). So this is my example of how to arrive at a 7-day array with no gaps:
Example 4:
$weekData = array(); // create a new array to hold the final result
// Loop that walks the days of the week, note 0-based index
for($d = 0; $d < 6; $d++)
{
// Loop that checks each record for the matching day of week:
$dayFound = false;
for($i = 0; $i < count($Record); $i++)
{
$recordDate = strtotime($Record[$i][field4]);
$dayOfWeek = $date('N', $recordDate);
// Add one to $d because $date('N',...) is a 1-based index, Mon - Sun
if ($dayOfWeek == $d + 1)
{
// Assign whatever fields you need to the new array at this index
$weekData[$d][field1] = $Record[$i][field1];
$weekData[$d][field2] = $Record[$i][field2];
$weekData[$d][field3] = $Record[$i][field3];
$weekData[$d][field4] = $Record[$i][field4];
// ...
break;
}
if (!$dayFound)
{
// Assign whatever default values you need to the new array at this index
$weekData[$d][field1] = "Field 1 Default";
// ...
}
}
}
Without having seen your current code (as requested in the comments by Felix Kling), my guess is that you will need to loop through your array, passing it to a function (or passing the array to the function) which checks Field4 and keeps track of which days of that week have data and fills in those missing days. This would be easier if the array was in order to start with (as you would only need to track the previous 'entry' rather than the entire week).
I'm a bit busy currently, here's some pseduo-code that will need to be expanded etc.
$formattedWeek = getFormattedWeek($inputArray);
function getFormattedWeek($input) {
$nextDay = 'Sunday';
foreach ($input as $entry) {
if (date-call-that-returns-day-of-the-week !== $nextDay) {
$output[] = 'add whatever you need to your array';
} else {
$output[] = $entry;
}
$nextDay = call-to-increase-the-day-or-loop-back-to-Sunday();
}
return $output;
}
You should get the picture.

How to break up reports by month with php and mysql?

I'm trying to do something relatively simple here. Basically I have a table with a bunch of rows in it marked with a timestamp (format: 2009-05-30 00:14:57).
What I'm wanting to is do is a query which pulls out all of the rows, and splits them by the month so I'm left with a final result like:
February
rowID name order date
rowID name order date
rowID name order date
January
rowID name order date
rowID name order date
rowID name order date
etc.
I have a few vague ideas how to do this - they just seem long winded.
One of the ways would be to do a query for each month. I'd derive what the current month is in PHP then construct a for() which goes back a certain number of months.
like:
$currentmonth = 8;
$last6months = $currentmonth - 6;
for($i = $currentmonth; $i == $last6months; $i--) {
$sql = 'SELECT * FROM reports WHERE MONTH(reports.when) = $currentmonth ';
$res = mysql_query($sql);
// something would go here to convert the month numeral into a month name $currentmonthname
echo $currentmonthname;
while($row = mysql_fetch_array($res)) {
// print out the rows for this month here
}
}
Is there a better way to do this?
It's better to fetch all data once,ordered by month..
Then while fetching with php you can store your current month in a variable (for example $curMonth) and if there is a change in the month, you echo "New Month"...
Executing a query is slow, it's better to minimize your "conversations" with the db..
Don't forget that you have to deal with years aswell. If you have two records, one for January '09 and one for January '08, your results may be skewed.
Best to follow Svetlozar's advice and fetch all data at once. Once you have it in memory, use PHP to segment it into something usefull:
$monthData = array();
$queryResult = mysql_query("
SELECT
*,
DATE_FORMAT('%m-%Y', when) AS monthID
FROM
reports
WHERE
YEAR(when) = 2009 AND
MONTH(when) BETWEEN 5 and 11
");
while ($row = mysql_fetch_assoc($queryResult))
{
if (!isset($monthData[$row['monthID']]))
$monthData[$row['monthID']] = array();
$monthData[$row['monthID']][] = $row;
}
mysql_free_result($queryResult);
foreach($monthData as $monthID => $rows)
{
echo '<h2>Data for ', $monthID, '</h2>';
echo '<ul>';
foreach($rows as $row)
{
echo '<li>', $row['someColumn'], '</li>';
}
echo '</ul>';
}
You could change your SQL query to get your entire report. This is much more efficient than querying the database in a loop.
select
monthname(reports.when) as currentmonth,
other,
fields,
go,
here
from reports
order by
reports.when asc
You could then use this loop to created a nested report:
var $currentMonth = '';
while($row = mysql_fetch_array($res)) {
if($currentMonth !== $row['currentMonth']) {
$currentMonth = $row['currentMonth']);
echo('Month: ' . $currentMonth);
}
//Display report detail for month here
}
*Note: Untested, but you get the general gist of it I'm sure.
This is the SQL script:
SELECT*, DATE_FORMAT(fieldname,'%Y-%m') AS report FROM bukukecil_soval WHERE MONTH(fieldname) = 11 AND YEAR(fieldname)=2011
I hope you know where you should put this code :D

Categories