Link to home
Create AccountLog in
Avatar of Nathan Riley
Nathan RileyFlag for United States of America

asked on

Calendar php/mysql

I'm using the following code to show a calendar for the current month.  It should also be pulling and putting the events on the correct day if there is an event in the database.  For some reason the events are not getting put into the calendar.

<?php

?>
<link rel="stylesheet" href="css/style.css">
<section id="content">
<?php
/* draws a calendar */
function draw_calendar($month,$year,$events = array()){

	/* draw table */
	$calendar = '<table cellpadding="0" cellspacing="0" class="calendar">';

	/* table headings */
	$headings = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
	$calendar.= '<tr class="calendar-row"><td class="calendar-day-head">'.implode('</td><td class="calendar-day-head">',$headings).'</td></tr>';

	/* days and weeks vars now ... */
	$running_day = date('w',mktime(0,0,0,$month,1,$year));
	$days_in_month = date('t',mktime(0,0,0,$month,1,$year));
	$days_in_this_week = 1;
	$day_counter = 0;
	$dates_array = array();

	/* row for week one */
	$calendar.= '<tr class="calendar-row">';

	/* print "blank" days until the first of the current week */
	for($x = 0; $x < $running_day; $x++):
		$calendar.= '<td class="calendar-day-np">&nbsp;</td>';
		$days_in_this_week++;
	endfor;

	/* keep going with days.... */
	for($list_day = 1; $list_day <= $days_in_month; $list_day++):
		$calendar.= '<td class="calendar-day"><div style="position:relative;height:100px;">';
			/* add in the day number */
			$calendar.= '<div class="day-number">'.$list_day.'</div>';
			
			$event_day = $year.'-'.$month.'-'.$list_day;
			if(isset($events[$event_day])) {
				foreach($events[$event_day] as $event) {
					$calendar.= '<div class="event">'.$event['title'].'</div>';
				}
			}
			else {
				$calendar.= str_repeat('<p>&nbsp;</p>',2);
			}
		$calendar.= '</div></td>';
		if($running_day == 6):
			$calendar.= '</tr>';
			if(($day_counter+1) != $days_in_month):
				$calendar.= '<tr class="calendar-row">';
			endif;
			$running_day = -1;
			$days_in_this_week = 0;
		endif;
		$days_in_this_week++; $running_day++; $day_counter++;
	endfor;

	/* finish the rest of the days in the week */
	if($days_in_this_week < 8):
		for($x = 1; $x <= (8 - $days_in_this_week); $x++):
			$calendar.= '<td class="calendar-day-np">&nbsp;</td>';
		endfor;
	endif;

	/* final row */
	$calendar.= '</tr>';
	

	/* end the table */
	$calendar.= '</table>';

	/** DEBUG **/
	$calendar = str_replace('</td>','</td>'."\n",$calendar);
	$calendar = str_replace('</tr>','</tr>'."\n",$calendar);
	
	/* all done, return result */
	return $calendar;
}

function random_number() {
	srand(time());
	return (rand() % 7);
}

/* date settings */
$month = (int) ($_GET['month'] ? $_GET['month'] : date('m'));
$year = (int)  ($_GET['year'] ? $_GET['year'] : date('Y'));

/* select month control */
$select_month_control = '<select name="month" id="month">';
for($x = 1; $x <= 12; $x++) {
	$select_month_control.= '<option value="'.$x.'"'.($x != $month ? '' : ' selected="selected"').'>'.date('F',mktime(0,0,0,$x,1,$year)).'</option>';
}
$select_month_control.= '</select>';

/* select year control */
$year_range = 7;
$select_year_control = '<select name="year" id="year">';
for($x = ($year-floor($year_range/2)); $x <= ($year+floor($year_range/2)); $x++) {
	$select_year_control.= '<option value="'.$x.'"'.($x != $year ? '' : ' selected="selected"').'>'.$x.'</option>';
}
$select_year_control.= '</select>';

/* "next month" control */
$next_month_link = '<a href="?month='.($month != 12 ? $month + 1 : 1).'&year='.($month != 12 ? $year : $year + 1).'" class="control">Next Month &gt;&gt;</a>';

/* "previous month" control */
$previous_month_link = '<a href="?month='.($month != 1 ? $month - 1 : 12).'&year='.($month != 1 ? $year : $year - 1).'" class="control">&lt;&lt; 	Previous Month</a>';


/* bringing the controls together */
$controls = '<form method="get">'.$select_month_control.$select_year_control.'&nbsp;<input type="submit" name="submit" value="Go" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$previous_month_link.'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$next_month_link.' </form>';

//Connect to DB
			require_once("config.php");
			$connect = mysql_connect($host,$username,$password);
			mysql_select_db($database, $connect);
			
/* get all events for the given month */
$events = array();
$query = "SELECT title, DATE_FORMAT(event_date,'%Y-%m-%D') AS event_date FROM events WHERE event_date LIKE '$year-$month%'";
$result = mysql_query($query) or die('cannot get results!');
while($row = mysql_fetch_assoc($result)) {
	$events[$row['event_date']][] = $row;
}

echo '<h2 style="float:left; padding-right:30px;">'.date('F',mktime(0,0,0,$month,1,$year)).' '.$year.'</h2>';
echo '<div style="float:left;">'.$controls.'</div>';
echo '<div style="clear:both;"></div>';
echo draw_calendar($month,$year,$events);
echo '<br /><br />';
?>
</section>
<?php include 'footer.php'; ?>

Open in new window

Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Please read this article over -- it has some examples that may be helpful.
https://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html

I think the general design I would use would be to SELECT the calendar items from the calendar table WHERE the dates are BETWEEN the first and last of the month you want to draw out.  Retrieve all the rows into an array of events with the index equal to the ISO-8601 DATE value of the event.  Then as you render dach day of the calendar table, check the array of events for a matching index.  If the index is present in the array, make the day a link to a script that checks for all events on one particular day.  If the index is not present, just render the day in clear text (not a link).

Does that make sense for your needs?
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
SOLUTION
Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
I would also change the way you are retrieving month. The way you are doing it is problematic.

Try this instead
$month = empty($_GET['month']) ? date('n'): (int)$_GET['month'] ;

Open in new window

Your code below assumes that month is defined in the $_GET array but then has a contingency for when it doesn't. If it is not defined the interpreter is going to throw a wobbly - so you need to check if the $_GET['month'] index is defined by using the empty (or isset) call and then acting on that.

Secondly you don't need to get a leading 0 month with date as you don't wan't to use use leading 0 in your query so use 'n' instead of 'm' in the date call.

Finally we can either case the entire result to int or just the last part because we know date('n') will return an unpadded value - your choice.

Do a similar approach for the year

$year = empty($_GET['year'] ? date('Y'): (int) $_GET['year'];

Open in new window

That combined with the query submitted earlier should see you through.
Avatar of Nathan Riley

ASKER

Yeah turned out it was the preceding 0's on months that were messing it up.  Fixed now, thanks guys!
Thanks for the points. ~Ray