Revision [2788]
This is an old revision of JwCalendarWithPageCreation made by ChristianBarthelemy on 2004-12-02 21:27:34.
JW Calendar action reviewed
Last edited by ChristianBarthelemy
Thu, 02 Dec 2004 21:27 UTC
Thu, 02 Dec 2004 21:27 UTC
I like the idea of WikiCalendar, but I would like to get more from this.
I have been reworking this code to trigger the opening/creation of a dedicated WikiPage when you click on any day.
The idea is to be able to use personal calendars as well as project type calendars. So you can allocate a calendar name (must be a CameCase name) and call the action like this:
{{calendar month="11" year="2004" calendarname="MyProject"}}
The optional calendarname is defaulted to the user WikiName.
When you then click on the 30th of November, the system will open a page named MyProject20041130. It would be a good idea to group such pages under a dedicated category like CategoryCalendarMyProject.
I would like to improve this further on by checking if a page already exists for each day and have a different style or an icon pointing this.
I would also allow as an option to include the page of the selected day close to the calendar itself.
Added in the header:
* @input string $calendarname optional: prefix for the calendar pages to be created - Must be a CamelCase word;
* default: WikiName from the user
* default: WikiName from the user
Added in the constants section:
Added in the PARAMETERS Interface
$calendarname = USER_NAME;
Added a few lines after in the PARAMETERS Interface part 1)
$uCalendarname = $vars['calendarname'];
if ($uCalendarname) $calendarname = $uCalendarname;
//ToDo: check that it is a CamelCase word
if ($uCalendarname) $calendarname = $uCalendarname;
//ToDo: check that it is a CamelCase word
Changed in the output section
Old:
// handle markup for current day or any other day
$calday = sprintf('%4d:%02d:%02d',$year,$month,$day);
if ($calday == $today)
{
echo ' <td title="'.TODAY.'" class="currentday">'.$day."</td>\n";
}
else
{
echo ' <td>'.$day."</td>\n";
}
// end week row
New:
// handle markup for current day or any other day
$calday = sprintf('%4d:%02d:%02d',$year,$month,$day);
$pagename = $calendarname;
if($day<10) {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."0"."$day";
} else {
$pagename = $pagename."$year"."$month"."0"."$day";
}
} else {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."$day";
} else {
$pagename = $pagename."$year"."$month"."$day";
}
}
$pagename = BASE_URL.$pagename."/edit";
if ($calday == $today)
{
echo ' <td title="'.TODAY.'" class="currentday">'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
else
{
echo ' <td>'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
// end week row
// handle markup for current day or any other day
$calday = sprintf('%4d:%02d:%02d',$year,$month,$day);
if ($calday == $today)
{
echo ' <td title="'.TODAY.'" class="currentday">'.$day."</td>\n";
}
else
{
echo ' <td>'.$day."</td>\n";
}
// end week row
New:
// handle markup for current day or any other day
$calday = sprintf('%4d:%02d:%02d',$year,$month,$day);
$pagename = $calendarname;
if($day<10) {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."0"."$day";
} else {
$pagename = $pagename."$year"."$month"."0"."$day";
}
} else {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."$day";
} else {
$pagename = $pagename."$year"."$month"."$day";
}
}
$pagename = BASE_URL.$pagename."/edit";
if ($calday == $today)
{
echo ' <td title="'.TODAY.'" class="currentday">'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
else
{
echo ' <td>'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
// end week row
In case you just want the full code after modification:
<?php
/**
* Display a calendar face for a specified or the current month.
*
* Specifying a month and/or year in the action itself results in a "static" calendar face without
* navigation; conversely, providing no parameters in the action results in a calendar face with
* navigation links to previous, current and next month, with URL parameters determining which
* month is shown (with the current month as default).
*
* You can have one "dynamic" (navigable) calendar on a page (multiple ones would just be the same)
* and any number of "static" calendars.
*
* The current date (if visible) gets a special class to allow a different styling with CSS.
*
* Credit:
* This action was inspired mainly by the "Calendar Menu" code written by
* {@link http://www.blazonry.com/about.php Marcus Kazmierczak}
* (© 1998-2002 Astonish Inc.) which we traced back as being the ultimate origin of this code
* although our starting point was actually a (probably second-hand) variant found on the web which
* did not contain any attribution.
* However, not much of the original code is left in this version. Nevertheless, credit to
* Marcus Kazmierczak for the original that inspired this, however indirectly: Thanks!
*
* @package Actions
* @subpackage Date and Time
* @name Calendar
*
* @author {@link http://wikka.jsnx.com/GmBowen GmBowen} (first draft)
* @author {@link http://wikka.jsnx.com/JavaWoman JavaWoman} (more modifications)
* @version 0.8
* @since Wikka 1.1.6.0
*
* @input integer $year optional: 4-digit year of the month to be displayed;
* default: current year
* the default can be overridden by providing a URL parameter 'year'
* @input integer $month optional: number of month (1 or 2 digits) to be displayed;
* default: current month
* the default can be overridden by providing a URL parameter 'month'
* @input string $calendarname optional: prefix for the calendar pages to be created - Must be a CamelCase word;
* default: WikiName from the user
* @output data table for specified or current month
*
* @todo - take care we don't go over date limits for PHP with navigation links
* - configurable first day of week
*/
// ***** CONSTANTS section *****
define('MIN_DATETIME', strtotime('1970-01-01 00:00:00 GMT')); # earliest timestamp PHP can handle (Windows and some others - to be safe)
define('MAX_DATETIME', strtotime('2038-01-19 03:04:07 GMT')); # latest timestamp PHP can handle
define('MIN_YEAR', date('Y',MIN_DATETIME));
define('MAX_YEAR', date('Y',MAX_DATETIME)-1); # don't include partial January 2038
// not-quite-constants
$daysInMonth = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
define('CUR_YEAR', date('Y',mktime()));
define('CUR_MONTH', date('n',mktime()));
// format string for locale-specific month (%B) + 4-digit year (%Y) used for caption and title attributes
// NOTE: monthname is locale-specific but order of month and year may need to be switched: hence the double quotes!
define('LOC_MON_YEAR', "%B %Y"); # i18n
define('FMT_SUMMARY', "Calendar for %s"); # i18n
define('TODAY', "today");
define ('USER_NAME',$this->GetUserName());
define ('BASE_URL',$this->config['base_url']); # i18n
// ***** END CONSTANTS section *****
// ***** (ACTION) PARAMETERS Interface *****
// set parameter defaults: current year and month
$year = CUR_YEAR;
$month = CUR_MONTH;
$calendarname = USER_NAME;
// get and interpret parameters
// 1) overrride defaults with parameters provided in URL (accept only valid values)
if (isset($_GET['year']))
{
$uYear = (int)$_GET['year'];
if ($uYear >= MIN_YEAR && $uYear <= MAX_YEAR) $year = $uYear;
}
if (isset($_GET['month']))
{
$uMonth = (int)$_GET['month'];
if ($uMonth >= 1 && $uMonth <= 12) $month = $uMonth;
}
$uCalendarname = $vars['calendarname'];
if ($uCalendarname) $calendarname = $uCalendarname;
//ToDo: check that it is a CamelCase word
// 2) override with parameters provided in action itself (accept only valid values)
$hasActionParams = FALSE;
if (is_array($vars))
{
foreach ($vars as $param => $value)
{
switch ($param)
{
case 'year':
$uYear = (int)trim($value);
if ($uYear >= MIN_YEAR && $uYear <= MAX_YEAR)
{
$year = $uYear;
$hasActionParams = TRUE;
}
break;
case 'month':
$uMonth = (int)trim($value);
if ($uMonth >= 1 && $uMonth <= 12)
{
$month = $uMonth;
$hasActionParams = TRUE;
}
break;
}
}
}
// ***** (ACTION) PARAMETERS Interface *****
// ***** DERIVED VARIABLES *****
// derive which weekday the first is on
$datemonthfirst = sprintf('%4d-%02d-%02d',$year,$month,1);
$firstwday = strftime('%w',strtotime($datemonthfirst)); # i18n
// derive (locale-specific) caption text
$monthYear = strftime(LOC_MON_YEAR,strtotime($datemonthfirst)); # i18n
$summary = sprintf(FMT_SUMMARY, $monthYear); # i18n
// derive last day of month
$lastmday = $daysInMonth[$month - 1];
if (2 == $month) # correct for leap year if necessary
{
if (1 == date('L',strtotime(sprintf('%4d-%02d-%02d',$year,1,1)))) $lastmday++;
}
// derive "today" to detect when to mark this up in the calendar face
$today = date("Y:m:d",mktime());
// build navigation variables - locale-specific (%B gets full month name)
// FIXME: @@@ take care we don't go over date limits for PHP
if (!$hasActionParams)
{
// previous month
$monthPrev = ($month-1 < 1) ? 12 : $month-1;
$yearPrev = ($month-1 < 1) ? $year-1 : $year;
$parPrev = "month=$monthPrev&year=$yearPrev";
$urlPrev = $this->Href('', '', $parPrev);
$titlePrev = strftime(LOC_MON_YEAR,strtotime(sprintf('%4d-%02d-%02d',$yearPrev,$monthPrev,1)));# i18n
// current month
$parCur = 'month='.CUR_MONTH.'&year='.CUR_YEAR;
$urlCur = $this->Href('', '', $parCur);
$titleCur = strftime(LOC_MON_YEAR,strtotime(sprintf('%4d-%02d-%02d',CUR_YEAR,CUR_MONTH,1))); # i18n
// next month
$monthNext = ($month+1 > 12) ? 1 : $month+1;
$yearNext = ($month+1 > 12) ? $year+1 : $year;
$parNext = "month=$monthNext&year=$yearNext";
$urlNext = $this->Href('', '', $parNext);
$titleNext = strftime(LOC_MON_YEAR,strtotime(sprintf('%4d-%02d-%02d',$yearNext,$monthNext,1)));# i18n
}
// build array with names of weekdays (locale-specific)
$tmpTime = strtotime("this Sunday"); # get a starting date that is a Sunday
$tmpDate = date('d',$tmpTime);
$tmpMonth = date('m',$tmpTime);
$tmpYear = date('Y',$tmpTime);
for ($i=0; $i<=6; $i++)
{
$aWeekdaysShort[$i] = strftime('%a',mktime(0,0,0,$tmpMonth,$tmpDate+$i,$tmpYear));
$aWeekdaysLong[$i] = strftime('%A',mktime(0,0,0,$tmpMonth,$tmpDate+$i,$tmpYear));
}
// ***** END DERIVED VARIABLES *****
// ***** OUTPUT SECTION *****
?>
<table cellpadding="2" cellspacing="1" class="calendar" summary="<?php echo $summary;?>">
<caption><?php echo $monthYear;?></caption>
<thead>
<tr>
<?php
for ($i=0; $i<=6; $i++)
{
?>
<th scope="col" width="26" abbr="<?php echo $aWeekdaysLong[$i];?>"><?php echo $aWeekdaysShort[$i];?></th>
<?php
}
?>
</tr>
</thead>
<tbody class="face">
<?php
// start row for first week (if it doesn't start on Sunday)
if ($firstwday > 0)
{
echo " <tr>\n";
}
// fill start of first week with blank cells before start of month
for ($i=1; $i<=$firstwday; $i++)
{
echo ' <td> </td>'."\n";
}
// loop through all the days of the month
$day = 1;
$wday = $firstwday;
while ($day <= $lastmday)
{
// start week row
if ($wday == 0)
{
echo " <tr>\n";
}
// handle markup for current day or any other day
$calday = sprintf('%4d:%02d:%02d',$year,$month,$day);
$pagename = $calendarname;
if($day<10) {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."0"."$day";
} else {
$pagename = $pagename."$year"."$month"."0"."$day";
}
} else {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."$day";
} else {
$pagename = $pagename."$year"."$month"."$day";
}
}
$pagename = BASE_URL.$pagename."/edit";
if ($calday == $today)
{
echo ' <td title="'.TODAY.'" class="currentday">'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
else
{
echo ' <td>'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
// end week row
if ($wday == 6)
{
echo " </tr>\n";
}
// next day
$wday = ++$wday % 7;
$day++;
}
// fill week with blank cells after end of month
if ($wday > 0)
{
for ($i=$wday; $i<=6; $i++)
{
echo ' <td> </td>'."\n";
}
}
// end row for last week
if ($wday < 6)
{
echo " </tr>\n";
}
?>
</tbody>
<?php
// generate navigation only for calendar without (valid) action parameters!
// FIXME: @@@ take care we don't go over date limits for PHP
if ($hasActionParams === FALSE)
{
?>
<tbody class="calnav">
<tr>
<td colspan="3" align="left" class="prevmonth"><a href="<?php echo $urlPrev;?>" title="<?php echo $titlePrev;?>"><<</a></td>
<td align="center" class="curmonth"><a href="<?php echo $urlCur;?>" title="<?php echo $titleCur;?>">=</a></td>
<td colspan="3" align="right" class="nextmonth"><a href="<?php echo $urlNext;?>" title="<?php echo $titleNext;?>">>></a></td>
</tr>
</tbody>
<?php
}
?>
</table>
<?php
// ***** END OUTPUT SECTION *****
?>
/**
* Display a calendar face for a specified or the current month.
*
* Specifying a month and/or year in the action itself results in a "static" calendar face without
* navigation; conversely, providing no parameters in the action results in a calendar face with
* navigation links to previous, current and next month, with URL parameters determining which
* month is shown (with the current month as default).
*
* You can have one "dynamic" (navigable) calendar on a page (multiple ones would just be the same)
* and any number of "static" calendars.
*
* The current date (if visible) gets a special class to allow a different styling with CSS.
*
* Credit:
* This action was inspired mainly by the "Calendar Menu" code written by
* {@link http://www.blazonry.com/about.php Marcus Kazmierczak}
* (© 1998-2002 Astonish Inc.) which we traced back as being the ultimate origin of this code
* although our starting point was actually a (probably second-hand) variant found on the web which
* did not contain any attribution.
* However, not much of the original code is left in this version. Nevertheless, credit to
* Marcus Kazmierczak for the original that inspired this, however indirectly: Thanks!
*
* @package Actions
* @subpackage Date and Time
* @name Calendar
*
* @author {@link http://wikka.jsnx.com/GmBowen GmBowen} (first draft)
* @author {@link http://wikka.jsnx.com/JavaWoman JavaWoman} (more modifications)
* @version 0.8
* @since Wikka 1.1.6.0
*
* @input integer $year optional: 4-digit year of the month to be displayed;
* default: current year
* the default can be overridden by providing a URL parameter 'year'
* @input integer $month optional: number of month (1 or 2 digits) to be displayed;
* default: current month
* the default can be overridden by providing a URL parameter 'month'
* @input string $calendarname optional: prefix for the calendar pages to be created - Must be a CamelCase word;
* default: WikiName from the user
* @output data table for specified or current month
*
* @todo - take care we don't go over date limits for PHP with navigation links
* - configurable first day of week
*/
// ***** CONSTANTS section *****
define('MIN_DATETIME', strtotime('1970-01-01 00:00:00 GMT')); # earliest timestamp PHP can handle (Windows and some others - to be safe)
define('MAX_DATETIME', strtotime('2038-01-19 03:04:07 GMT')); # latest timestamp PHP can handle
define('MIN_YEAR', date('Y',MIN_DATETIME));
define('MAX_YEAR', date('Y',MAX_DATETIME)-1); # don't include partial January 2038
// not-quite-constants
$daysInMonth = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
define('CUR_YEAR', date('Y',mktime()));
define('CUR_MONTH', date('n',mktime()));
// format string for locale-specific month (%B) + 4-digit year (%Y) used for caption and title attributes
// NOTE: monthname is locale-specific but order of month and year may need to be switched: hence the double quotes!
define('LOC_MON_YEAR', "%B %Y"); # i18n
define('FMT_SUMMARY', "Calendar for %s"); # i18n
define('TODAY', "today");
define ('USER_NAME',$this->GetUserName());
define ('BASE_URL',$this->config['base_url']); # i18n
// ***** END CONSTANTS section *****
// ***** (ACTION) PARAMETERS Interface *****
// set parameter defaults: current year and month
$year = CUR_YEAR;
$month = CUR_MONTH;
$calendarname = USER_NAME;
// get and interpret parameters
// 1) overrride defaults with parameters provided in URL (accept only valid values)
if (isset($_GET['year']))
{
$uYear = (int)$_GET['year'];
if ($uYear >= MIN_YEAR && $uYear <= MAX_YEAR) $year = $uYear;
}
if (isset($_GET['month']))
{
$uMonth = (int)$_GET['month'];
if ($uMonth >= 1 && $uMonth <= 12) $month = $uMonth;
}
$uCalendarname = $vars['calendarname'];
if ($uCalendarname) $calendarname = $uCalendarname;
//ToDo: check that it is a CamelCase word
// 2) override with parameters provided in action itself (accept only valid values)
$hasActionParams = FALSE;
if (is_array($vars))
{
foreach ($vars as $param => $value)
{
switch ($param)
{
case 'year':
$uYear = (int)trim($value);
if ($uYear >= MIN_YEAR && $uYear <= MAX_YEAR)
{
$year = $uYear;
$hasActionParams = TRUE;
}
break;
case 'month':
$uMonth = (int)trim($value);
if ($uMonth >= 1 && $uMonth <= 12)
{
$month = $uMonth;
$hasActionParams = TRUE;
}
break;
}
}
}
// ***** (ACTION) PARAMETERS Interface *****
// ***** DERIVED VARIABLES *****
// derive which weekday the first is on
$datemonthfirst = sprintf('%4d-%02d-%02d',$year,$month,1);
$firstwday = strftime('%w',strtotime($datemonthfirst)); # i18n
// derive (locale-specific) caption text
$monthYear = strftime(LOC_MON_YEAR,strtotime($datemonthfirst)); # i18n
$summary = sprintf(FMT_SUMMARY, $monthYear); # i18n
// derive last day of month
$lastmday = $daysInMonth[$month - 1];
if (2 == $month) # correct for leap year if necessary
{
if (1 == date('L',strtotime(sprintf('%4d-%02d-%02d',$year,1,1)))) $lastmday++;
}
// derive "today" to detect when to mark this up in the calendar face
$today = date("Y:m:d",mktime());
// build navigation variables - locale-specific (%B gets full month name)
// FIXME: @@@ take care we don't go over date limits for PHP
if (!$hasActionParams)
{
// previous month
$monthPrev = ($month-1 < 1) ? 12 : $month-1;
$yearPrev = ($month-1 < 1) ? $year-1 : $year;
$parPrev = "month=$monthPrev&year=$yearPrev";
$urlPrev = $this->Href('', '', $parPrev);
$titlePrev = strftime(LOC_MON_YEAR,strtotime(sprintf('%4d-%02d-%02d',$yearPrev,$monthPrev,1)));# i18n
// current month
$parCur = 'month='.CUR_MONTH.'&year='.CUR_YEAR;
$urlCur = $this->Href('', '', $parCur);
$titleCur = strftime(LOC_MON_YEAR,strtotime(sprintf('%4d-%02d-%02d',CUR_YEAR,CUR_MONTH,1))); # i18n
// next month
$monthNext = ($month+1 > 12) ? 1 : $month+1;
$yearNext = ($month+1 > 12) ? $year+1 : $year;
$parNext = "month=$monthNext&year=$yearNext";
$urlNext = $this->Href('', '', $parNext);
$titleNext = strftime(LOC_MON_YEAR,strtotime(sprintf('%4d-%02d-%02d',$yearNext,$monthNext,1)));# i18n
}
// build array with names of weekdays (locale-specific)
$tmpTime = strtotime("this Sunday"); # get a starting date that is a Sunday
$tmpDate = date('d',$tmpTime);
$tmpMonth = date('m',$tmpTime);
$tmpYear = date('Y',$tmpTime);
for ($i=0; $i<=6; $i++)
{
$aWeekdaysShort[$i] = strftime('%a',mktime(0,0,0,$tmpMonth,$tmpDate+$i,$tmpYear));
$aWeekdaysLong[$i] = strftime('%A',mktime(0,0,0,$tmpMonth,$tmpDate+$i,$tmpYear));
}
// ***** END DERIVED VARIABLES *****
// ***** OUTPUT SECTION *****
?>
<table cellpadding="2" cellspacing="1" class="calendar" summary="<?php echo $summary;?>">
<caption><?php echo $monthYear;?></caption>
<thead>
<tr>
<?php
for ($i=0; $i<=6; $i++)
{
?>
<th scope="col" width="26" abbr="<?php echo $aWeekdaysLong[$i];?>"><?php echo $aWeekdaysShort[$i];?></th>
<?php
}
?>
</tr>
</thead>
<tbody class="face">
<?php
// start row for first week (if it doesn't start on Sunday)
if ($firstwday > 0)
{
echo " <tr>\n";
}
// fill start of first week with blank cells before start of month
for ($i=1; $i<=$firstwday; $i++)
{
echo ' <td> </td>'."\n";
}
// loop through all the days of the month
$day = 1;
$wday = $firstwday;
while ($day <= $lastmday)
{
// start week row
if ($wday == 0)
{
echo " <tr>\n";
}
// handle markup for current day or any other day
$calday = sprintf('%4d:%02d:%02d',$year,$month,$day);
$pagename = $calendarname;
if($day<10) {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."0"."$day";
} else {
$pagename = $pagename."$year"."$month"."0"."$day";
}
} else {
if($month<10) {
$pagename = $pagename."$year"."0"."$month"."$day";
} else {
$pagename = $pagename."$year"."$month"."$day";
}
}
$pagename = BASE_URL.$pagename."/edit";
if ($calday == $today)
{
echo ' <td title="'.TODAY.'" class="currentday">'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
else
{
echo ' <td>'.'<a href='.$pagename.'>'.$day."</a></td>\n";
}
// end week row
if ($wday == 6)
{
echo " </tr>\n";
}
// next day
$wday = ++$wday % 7;
$day++;
}
// fill week with blank cells after end of month
if ($wday > 0)
{
for ($i=$wday; $i<=6; $i++)
{
echo ' <td> </td>'."\n";
}
}
// end row for last week
if ($wday < 6)
{
echo " </tr>\n";
}
?>
</tbody>
<?php
// generate navigation only for calendar without (valid) action parameters!
// FIXME: @@@ take care we don't go over date limits for PHP
if ($hasActionParams === FALSE)
{
?>
<tbody class="calnav">
<tr>
<td colspan="3" align="left" class="prevmonth"><a href="<?php echo $urlPrev;?>" title="<?php echo $titlePrev;?>"><<</a></td>
<td align="center" class="curmonth"><a href="<?php echo $urlCur;?>" title="<?php echo $titleCur;?>">=</a></td>
<td colspan="3" align="right" class="nextmonth"><a href="<?php echo $urlNext;?>" title="<?php echo $titleNext;?>">>></a></td>
</tr>
</tbody>
<?php
}
?>
</table>
<?php
// ***** END OUTPUT SECTION *****
?>