One of the latest crazes on the 'net has recently been online calendars.
with the
MCAL library and PHP,
writing calendar applications is now
easy and fully functional. The MCAL library is very similar to the c-client IMAP
library. It offers a common simple interface for accessing calendars that can be stored in
many different formats, both local and remote formats are supported.
In this tutorial, we will use the mstore calendar driver. The mstore calendar driver uses
a local file storage format. Another driver that can be used is the ICAP driver,
which allows access to remote calendar stores.
One things that makes the MCAL library very different than other libraries is that it
does not just handle "simple" calendaring. It is a feature rich calendaring library that
handles dates from year 1 to year 9999, incorporating the Gregorian calendar and extrapolating
back. This calendaring obviously contains events and many event objects. (It essentially uses
icalendar objects and properties).
Some of MCAL's supported object features are:
- Alarms (triggers) which can be set to go off any number of minutes before the event.
- Class values (Public/Private)
- Start and End Dates
- Recurrence (This event should re-occur every Thursday..etc..)
- Calendar sharing.
Enough about the capabilities, lets get coding!
The first thing we'll probably want to do is pull up a users calendar and display the month
view, and the event titles for any of their scheduled events:
To do this, we only need to use just a couple of mcal functions.
The first is mcal_open. mcal_open takes in a calendar string, a username and a password.
In this case, we are using:
<?php mcal_open("{/mstore}","username","password"); ?>
Calendar address strings are currently of the following form:
{servername/protocol}<username>calendar
This is the contents broken down:
- servername - The remote server to connect to.
- protocol - The driver protocol to use.
- username - The users calendar to access. (i.e. john smith could be logged in
and wants to view mary's calendar. If this is left blank, it
means the current user that is logged in.
- calendar - The calendar to access.
Most of these parts can also be left out. For example:
- {icap.chek.com}INBOX - Will open up an ICAP connection to icap.chek.com and open up the default calendar for that user.
- {icap.chek.com/icap}INBOX - Will open up an ICAP connection to icap.chek.com and open up the default calendar for that user.
- {icap.chek.com}<> - Will open up an ICAP connection to icap.chek.com and open up the default calendar for that user.
- {icap.chek.com}<mary> - Will open up an ICAP connection to icap.chek.com and open up the default calendar
for mary, regradless of the logged in
user .
In our case, we are using the mstore driver, (since it's a local filesystem, no hostname is necessary)
This function will return a calendar stream upon success.
The other function we will use is:
<?php mcal_days_in_month($month,$leap_year); ?>
This simply returns the number of days in a given month, taking into account if it is a leap year or not.
To find out what day of the week the first of the month is, because we need to display
the first on the correct weekday when we go to display the calendar, we use:
<?php $startday=mcal_day_of_week($year,$month,1); ?>
The next function is where the majority of the work is done:
<?php $events=mcal_list_events($stream,$year,$month,1,$year,$month,$days); ?>
This function takes in a stream, and beginning and end dates. It returns a list of
event ID's for every event that is scheduled between the two dates.
Once we have this list of ID's, we need to loop through the events and find their actual dates.
while we are at it, we might as well store the title of the events since we will be
printing them out in the month view also:
<?php
for($x=0; $x<count($events); $x++) {
$event=mcal_fetch_event($stream,$events[$x]);
$start=$event->start;
$date_array[$start->mday]=$date_array[$start->mday] . "<br>$event->title";
}
?>
Now that we have all the date and event information, the rest is simple. We just
loop through all the dates, printing out the information we need.
Following is the complete file, index.php3:
<html><head><title>Calendar</title></head><body><center>
<?php
$montharray=array("","January","February","March","April","May","June","July","August","September","October","November","December");
$current_date=getdate();
if(empty($month)) {
$month=$current_date["mon"];
}
if(empty($year)) {
$year=$current_date["year"];
}
$stream=mcal_open("{/mstore}","musone","hi");
$days=mcal_days_in_month($month,mcal_is_leap_year($year));
$startday=mcal_day_of_week($year,$month,1);
$events=mcal_list_events($stream,$year,$month,1,$year,$month,$days);
for($x=0;$x<count($events);$x++) {
$event=mcal_fetch_event($stream,$events[$x]);
$start=$event->start;
$date_array[$start->mday]=$date_array[$start->mday] . "<br>$event->title";
}
?>
<a href="<?php echo $PHP_SELF; ?>?month=<?php echo $month-1; ?>"><</a>
<b><?php echo $montharray[$month] - $year; ?></b>
<a href="<?php echo $PHP_SELF; ?>?month=<?php echo $month+1; ?>">></a>
<table border=1>
<tr><th>Sun</th><th>Mon</th><th>Tue</th><th>Web</th><th>Thu</th><th>Fri</th><th>Sat</th></tr>
<?php
for($i=0;$i<$startday;$i++) {
echo "<td></td>";
}
$dayofweek=$startday;
for($i=1;$i<=$days;$i++) {
if (($dayofweek % 7 == 0) && ($dayofweek !=0)) {
printf("</tr>\n<tr>");
}
echo "<td height=100 width=100>";
echo "<A href=\"addevent.php3?month=$month&year=$year&day=$i\">$i";
echo "</a>";
if ($date_array[$i]) {
echo "<A href=\"viewevent.php3?month=$month&year=$year&day=$i\">";
echo "$date_array[$i]</a>";
}
echo "</td>";
$dayofweek++;
}
?>
</tr></table>
</center></body></html>
Note, one thing we are doing is allowing people to add events by clicking on and day
in the calendar. If there is an event scheduled, it prints out the title, and by clicking
on the title, it displays all of the events information.
to display an events information, we use the same technique as the above, but just pull up the
events for that one day, and print out all information.
viewevent.php3 consists of:
<?php
$stream=mcal_open("{/mstore}","musone","hi");
$events=mcal_list_events($stream,$year,$month,$day,$year,$month,$day);
for($x=0; $x<count($events); $x++) {
$event=mcal_fetch_event($stream,$events[$x]);
$start=$event->start;
$end=$event->end;
echo "Event: $event->id<br>";
echo "Start: ";
echo "$start->year";
echo "$start->month";
echo "$start->mday";
echo "$start->hour";
echo "$start->min";
echo "$start->sec <br>";
echo "End:";
echo "$end->year";
echo "$end->month";
echo "$end->mday";
echo "$end->hour";
echo "$end->min";
echo "$end->sec <br>";
echo "Title: $event->title <br>";
echo "Category: $event->category <br>";
echo "Description: $event->description <br>";
}
?>
<a href="index.php3?month=<?php echo $month; ?>&year=<?php echo $year; ?>">Back</a>
To add an event, it's just as simple, first we print out a form, addevent.php3:
<form action="addeventaction.php3">
<center>Adding event for <?php echo $month; ?>/<?php echo $day; ?>/<?php echo $year; ?></center><br>
Title:<input type="text" name="title"><br>
Category:<input type="text" name="category"><br>
Description<br>
<textarea cols=40 rows=10 name="description"></textarea><br>
<input type="hidden" name="year" value="<?php echo $year; ?>">
<input type="hidden" name="month" value="<?php echo $month; ?>">
<input type="hidden" name="day" value="<?php echo $day; ?>">
<input type="submit">
To do the actual adding of the event after the form is submitted,
we use a couple of new functions.
Every calendar stream has an internal event structure. This event
structure is used for storing and retreiving events.
So we simply set the internal event structure with the proper
information using the mcal_event_set functions.
Finally, we simply call mcal_store_event. This function takes
the current event and adds it to the calendar store.
addeventaction.php3:
<?php
$stream=mcal_open("{/mstore}","musone","hi");
mcal_event_set_title($stream,$title);
mcal_event_set_description($stream,$description);
mcal_event_set_category($stream,$category);
mcal_event_set_start($stream,$year,$month,$day);
mcal_store_event($stream);
Header("Location: index.php3?month=$month&year=$year");
?>
--Mark