Extension:SpecialCalendar

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual - list
Crystal Clear action run.png

Release status: beta

Implementation Special page
Description Easily create a calendar of iCal format in MediaWiki.
Author(s) user:sbrunner
Latest version 2007.01 (2007-01)
MediaWiki 1.9.0
License No license specified
Download see below

Translate the SpecialCalendar extension if possible

Check usage and version matrix; code metrics

The goal[edit | edit source]

The goal is to have (edit and view) a calendar on MediaWiki that can be downloaded in the iCal format.

Install[edit | edit source]

  • copy the source on a file named SpecialCalendar.php.
  • copy this file in the extensions directory.
  • add in the LocalSettings.php file.
include_once('extensions/SpecialCalendar.php');
  • in the LocalSettings.php file define for example
$wgICalenarVersion = '2.0';
$wgICalenarPerodID = '-//Fabricants de Joie//NONSGML mediawiki//FR';
$wgICalenarDefaultPage = 'Calendar';

How to use[edit | edit source]

<title|Horaire>
<dateformat|G:i>

introductions

=== Event1 ===
<start|20060414T133000Z>
  <end|20060414T140000Z>
<categories|Sport>
comments

=== Event2 ===
<start|20060414T143000Z>
  <end|20060414T150000Z>
<categories|Camp>
comments


License[edit | edit source]

GNU General Public License (GPL)

Author: user:sbrunner

Code[edit | edit source]

<?php
if (!defined('MEDIAWIKI')) die();
/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * @author sbrunner
 *
 */
 
$wgExtensionCredits['specialpage'][] = array(
    'name' => 'SpecialICalendar',
    'url' => 'http://www.mediawiki.org/wiki/Extension:SpecialICalendar',
    'author' => 'Stéphane Brunner'
);
 
$wgExtensionFunctions[] = "wfiCalExtension";
 
require_once( "$IP/includes/SpecialPage.php" );
 
function wfiCalExtension() {
	global $IP, $wgMessageCache, $myForm, $wgICalenarDefaultPage;
 
	$wgMessageCache->addMessages(array('calendar' => 'Calendar'));
	$wgMessageCache->addMessages(array('calendardate' => ' From $1 to $2'));
//	$wgMessageCache->addMessages(array('calendardateformat' => 'D j M Y G:i:s'));
	$wgMessageCache->addMessages(array('calendardateformat' => 'l j F Y'));
//	$wgMessageCache->addMessages(array('calendardateformat' => '%A %d %B %Y %H:%M'));
	$wgMessageCache->addMessages(array('calendardownload' => '<p style="text-align:right;"><a href="$1">Gets the calendar as iCal format.</a></p>'));
 
	$wgMessageCache->addMessages(array('mon' => 'Mon'));
	$wgMessageCache->addMessages(array('tue' => 'Tue'));
	$wgMessageCache->addMessages(array('wed' => 'Wed'));
	$wgMessageCache->addMessages(array('thu' => 'Thu'));
	$wgMessageCache->addMessages(array('fri' => 'Fri'));
	$wgMessageCache->addMessages(array('sat' => 'Sat'));
	$wgMessageCache->addMessages(array('sun' => 'Sun'));
 
 
	if (isset($wgICalenarDefaultPage)) {
		$wgMessageCache->addMessages(array($wgICalenarDefaultPage => '=== Event ===  <start|19970714T170000Z> <end|19970715T035959Z>'));
	}
 
	SpecialPage::addPage( new iCalSpecialPage() );
}
 
class iCalSpecialPage extends SpecialPage {
 
	// Day and mounth to display
	var $langueDate = array();
	var $dateformat;
 
	function iCalSpecialPage() {
		SpecialPage::SpecialPage( 'Calendar' );
 
		$this->dateformat = wfMsg('calendardateformat');
 
		$this->langueDate['Mon'] = wfMsg('mon');
		$this->langueDate['Tue'] = wfMsg('tue');
		$this->langueDate['Wed'] = wfMsg('wed');
		$this->langueDate['Thu'] = wfMsg('thu');
		$this->langueDate['Fri'] = wfMsg('fri');
		$this->langueDate['Sat'] = wfMsg('sat');
		$this->langueDate['Sun'] = wfMsg('sun');
 
		$this->langueDate['Monday'] = wfMsg('monday');
		$this->langueDate['Tuesday'] = wfMsg('tuesday');
		$this->langueDate['Wednesday'] = wfMsg('wednesday');
		$this->langueDate['Thursday'] = wfMsg('thursday');
		$this->langueDate['Friday'] = wfMsg('friday');
		$this->langueDate['Saturday'] = wfMsg('saturday');
		$this->langueDate['Sunday'] = wfMsg('sunday');
 
		$this->langueDate['Jan'] = wfMsg('jan');
		$this->langueDate['Feb'] = wfMsg('feb');
		$this->langueDate['Mar'] = wfMsg('mar');
		$this->langueDate['Apr'] = wfMsg('apr');
		$this->langueDate['May'] = wfMsg('may');
		$this->langueDate['Jun'] = wfMsg('jun');
		$this->langueDate['Jul'] = wfMsg('jul');
		$this->langueDate['Aug'] = wfMsg('aug');
		$this->langueDate['Sep'] = wfMsg('sep');
		$this->langueDate['Oct'] = wfMsg('oct');
		$this->langueDate['Nov'] = wfMsg('nov');
		$this->langueDate['Dec'] = wfMsg('dec');
 
		$this->langueDate['January'] = wfMsg('january');
		$this->langueDate['February'] = wfMsg('february');
		$this->langueDate['March'] = wfMsg('march');
		$this->langueDate['April'] = wfMsg('april');
		$this->langueDate['May'] = wfMsg('may');
		$this->langueDate['June'] = wfMsg('june');
		$this->langueDate['July'] = wfMsg('july');
		$this->langueDate['August'] = wfMsg('august');
		$this->langueDate['September'] = wfMsg('septembre');
		$this->langueDate['October'] = wfMsg('octobre');
		$this->langueDate['November'] = wfMsg('novembre');
		$this->langueDate['December'] = wfMsg('decembre');
	}
 
	function execute( $par ) {
		global $wgRequest, $wgOut, $wgUser, $wgICalenarVersion, $wgICalenarPerodID, $wgICalenarDefaultPage, $wgTitle, $wgInputEncoding;
 
		$this->setHeaders();
 
		if ( $this->userCanExecute( $wgUser ) ) {
			$action = $wgRequest->getVal( 'action' );
			$cal = isset($par) ? $par : $wgRequest->getVal( 'cal' );
			if ($cal == null) {
				$cal = $wgICalenarDefaultPage;
			}
			$text = wfMsg($cal);
			if ( "raw" == $action ) {
				$wgOut->disable();
				header( 'Content-type: text/calendar; charset='.$wgInputEncoding );
 
				echo 'BEGIN:VCALENDAR'."\n";
				echo 'VERSION:'.$wgICalenarVersion."\n";//'2.0';
				echo 'PRODID:'.$wgICalenarPerodID."\n"; //'-//Fabricants de Joie//NONSGML mediawiki//FR';
				$this->parce('doical', $text."\n", $cal);
				echo 'END:VCALENDAR'."\n";
			}
			else {
				$titleObj = Title::makeTitle( NS_SPECIAL, "Calendar" );
				$action = $titleObj->escapeLocalURL( "cal=".urlencode( $cal ) );
				$wgOut->addHTML(wfMsg('calendardownload', $titleObj->escapeLocalURL( "cal=".urlencode( $cal ).'&action=raw' )));
 
				$titleObj = Title::makeTitle( NS_MEDIAWIKI, $cal );
				$action = $titleObj->escapeLocalURL( "action=edit" );
				$wgOut->addHTML('<div class="editsection" style="float: right; margin-left: 5px;">[<a href="'.$action.'">'.wfMsg('editsection').'</a>]</div>');
 
 
				$index = strpos($text, '<title|');
				$end = false;
				if ($index !== false) {
					$index = $index + 7;
					$end = strpos($text, '>', $index);
				}
				if ($end !== false) {
					$wgOut->setPagetitle(substr($text, $index , $end - $index));
					$text = substr($text, $end +1);
				}
 
				$index = strpos($text, '<dateformat|');
				$end = false;
				if ($index !== false) {
					$index = $index + 12;
					$end = strpos($text, '>', $index);
				}
				if ($end !== false) {
					$this->dateformat = substr($text, $index , $end - $index);
					$text = substr($text, $end +1);
				}
 
 
				$this->parce('dodisplay', $text, $cal);
			}
		} else {
			$this->displayRestrictionError();
		}
	}
 
	function parce($func, $text, $cal) {
		global $wgOut;
 
		$oldindex = 0;
		$index = strpos($text, '===');
		while ($index !== false) {
			if ($func == 'dodisplay' && $oldindex < $index) {
				$wgOut->addWikiText(substr($text, $oldindex, $index - $oldindex));
			}
			$index = $index + 3;
			$end = strpos($text, '===', $index);
			$title = null;
			$startDate = null;
			$endDate = null;
			$categories = null;
			if ($end !== false) {
				$title = substr($text, $index, $end - $index);
				$index = strpos($text, '<start|', $end);
				if ($index !== false) {
					$index = $index + 7;
					$end = strpos($text, '>', $index);
					if ($end !== false) {
						$startDate = substr($text, $index , $end - $index);
					}
				}
			}
			if ($end !== false) {
				$index = strpos($text, '<end|', $end);
				if ($index !== false) {
					$index = $index + 5;
					$end = strpos($text, '>', $index);
					if ($end !== false) {
						$endDate = substr($text, $index , $end - $index);
					}
				}
				else {
					$end = false;
				}
			}
			if ($end !== false) {
				$index = strpos($text, '===', $end);
 
				if ($end !== false) {
					$cindex = strpos($text, '<categories|', $end);
					if ($cindex !== false && ($index == false || $cindex < $index)) {
						$cindex = $cindex + 12;
						$end = strpos($text, '>', $cindex);
						if ($end !== false) {
							$categories = substr($text, $cindex , $end - $cindex);
						}
					}
				}
				$oldindex = $end + 1;
				$titleObj = Title::makeTitle( NS_SPECIAL, "Calendar/".$cal );
				$this->$func($title, $categories, $titleObj->escapeFullURL().'#'.str_replace('%', '.', urlencode(str_replace(' ', '_', $title))), $startDate, $endDate);
			}
			else {
				$index = -1;
			}
		}
		if ($func == 'dodisplay' && $oldindex < strlen($text)) {
			$wgOut->addWikiText(substr($text, $oldindex));
		}
	}
 
	function doical($title, $categories, $url, $startDate, $endDate) {
		if (strlen($startDate) == 16 && strlen($endDate) == 16) {
			echo 'BEGIN:VEVENT'."\n";
			$sts = $this->getdate($startDate);
			echo 'DTSTART:'.gmdate('Ymd', $sts).'T'.gmdate('His', $sts)."Z\n";//19970714T170000Z;
			$ets = $this->getdate($endDate);
			echo 'DTEND:'.gmdate('Ymd', $ets).'T'.gmdate('His', $ets)."Z\n";
			echo 'SUMMARY:'.$title."\n";
			echo 'URL:'.$url."\n";
			if ($categories != null) {
				echo 'CATEGORIES:'.$categories."\n";
			}
			echo 'END:VEVENT'."\n";
		}
	}
 
	function dodisplay($title, $categories, $url, $startDate, $endDate) {
		global $wgOut;
 
		$wgOut->addHTML('<div class="'.$categories.'">'); // TODO multi !
		$wgOut->addWikiText('=== '.$title.' ===');
		if (strlen($startDate) == 16 && strlen($endDate) == 16) {
			$wgOut->addWikiText(wfMsg('calendardate', 
				strtr(date($this->dateformat, $this->getdate($startDate)), $this->langueDate), 
				strtr(date($this->dateformat, $this->getdate($endDate)), $this->langueDate)));
		}
		else {
			$wgOut->addWikiText('parce error');
		}
		$wgOut->addHTML('</div>');
	}
 
	function getdate($date) {
		$result = mktime(substr($date, 9, 2), substr($date, 11, 2), substr($date, 13, 2), substr($date, 4, 2), substr($date, 6, 2), substr($date, 0, 4));
		return $result;
	}
}
?>