Hi Leute
die Idee mit dem Webcalender fand ich klasse und habe mich gleich an eine eigene Umsetzung gemacht, da ich bereits einige FHT-Steuerscripte am laufen habe, wollte ich nicht alles übernehmen und habe mir die Funktionen vereinfacht.
Vll. kann es ja jemand gebrauchen
Ich habe mit den Webcalender auf meinen Server aufgesetzt (IIS7) und ein paar Anpassungen in der RSS-Ausgabe vorgenommen.
Es werden nun im Feed gleich alle ausgewählten Kategorien (bei mir Räume) angezeigt. Ebenso der Start/Ende eines Events.
Das nachfolgende Script ist das modiizierte rss.php aus dem Hauptverzeichnis vom Webcalender.
Macht bitte vorher von der originalen eine Kopie und ersetzt es dann mit dem Inhalt.
<?php
/* $Id: rss.php,v 1.46.2.8 2008/04/04 17:56:14 umcesrjones Exp $
*
* Description:
* This script is intended to be used outside of normal WebCalendar use,
* as an RSS 2.0 feed to a RSS client.
*
* You must have "Enable RSS feed" set to "Yes"
* in both System Settings and in the specific user's Preferences.
*
* Simply use the URL of this file as the feed address in the client.
* For public user access:
* http://xxxxx/aaa/rss.php
* For any other user (where "joe" is the user login):
* http:/xxxxxx/aaa/rss.php?user=joe
*
* By default (if you do not edit this file), events
* will be loaded for either:
* - the next 30 days
* - the next 10 events
*
* Input parameters:
* You can override settings by changing the URL parameters:
* - days: number of days ahead to look for events
* - cat_id: specify a category id to filter on
* - repeats: output all events including all repeat instances
* repeats=0 do not output repeating events (default)
* repeats=1 outputs repeating events
* repeats=2 outputs repeating events but suppresses display of
* 2nd & subsequent occurences of daily events
* - user: login name of calendar to display (instead of public user).
* You must have the following System Settings configured for this:
* Allow viewing other user's calendars: Yes
* Public access can view others: Yes
* - showdate: put the date and time (if specified in the title
* of the item) in the title
*
* Security:
* $RSS_ENABLED must be set true
* $USER_RSS_ENABLED must be set true unless this is for the public user
* $USER_REMOTE_ACCESS can be set as follows in pref.php
* 0 = Public entries only
* 1 = Public & Confidential entries only
* 2 = All entries are included in the feed *USE WITH CARE
*
* We do not include unapproved events in the RSS feed.
*
*
* TODO
* Add other RSS 2.0 options such as media.
* Add <managingEditor>: dan@spam_me.com (Dan Deletekey)
*/
$debug = false;
include_once 'includes/translate.php';
require_once 'includes/classes/WebCalendar.class';
require_once 'includes/classes/Event.class';
require_once 'includes/classes/RptEvent.class';
$WebCalendar =& new WebCalendar ( __FILE__ );
include 'includes/formvars.php';
include 'includes/functions.php';
include 'includes/config.php';
include 'includes/dbi4php.php';
$WebCalendar->initializeFirstPhase ();
include 'includes/' . $user_inc;
include_once 'includes/validate.php';
include 'includes/site_extras.php';
include_once 'includes/xcal.php';
$WebCalendar->initializeSecondPhase ();
load_global_settings ();
$WebCalendar->setLanguage ();
if ( empty ( $RSS_ENABLED ) || $RSS_ENABLED != 'Y' ) {
header ( 'Content-Type: text/plain' );
echo print_not_auth (28);
exit;
}
/* Configurable settings for this file. You may change the settings below to
* change the default settings. These settings will likely move into the System
* Settings in the web admin interface in a future release.
*/
// Show the date in the title and how to format it.
$date_in_title = false; //Can override with "rss.php?showdate=1|true".
$showdate = getValue ( 'showdate' );
if ( ! empty ( $showdate ) )
$date_in_title = ( $showdate == 'true' || $showdate == 1 ? true : false );
$date_format = 'M jS'; //Aug 10th, 8/10
$time_format = 'g:ia'; //4:30pm, 16:30
$time_separator = ', '; //Aug 10th @ 4:30pm, Aug 10th, 4:30pm
// Default time window of events to load.
// Can override with "rss.php?days=60".
$numDays = 30;
// Max number of events to display.
// Can override with "rss.php?max=20".
$maxEvents = 10;
// Login of calendar user to use.
// '__public__' is the login name for the public user.
$username = '__public__';
// Allow the URL to override the user setting such as "rss.php?user=craig".
$allow_user_override = true;
// Load layers.
$load_layers = false;
// Load just a specified category (by its id).
// Leave blank to not filter on category (unless specified in URL).
// Can override in URL with "rss.php?cat_id=4".
$cat_id = '';
// Load all repeating events.
// Can override with "rss.php?repeats=1".
$allow_repeats = false;
// Load show only first occurence within the given time span of daily repeating events.
// Can override with "rss.php?repeats=2".
$show_daily_events_only_once = false;
// End configurable settings...
// Set for use elsewhere as a global.
$login = $username;
if ( $allow_user_override ) {
$u = getValue ( 'user', '[A-Za-z0-9_\.=@,\-]+', true );
if ( ! empty ( $u ) ) {
if ( $u == 'public' )
$u = '__public__';
// We also set $login since some functions assume that it is set..
$login = $username = $u;
}
}
load_user_preferences ();
// public entries only
$allow_access = array ( 'P' );
// .
// Determine what remote access has been set up by user.
// This will only be used if $username is not __public__.
if ( isset ( $USER_REMOTE_ACCESS ) && $username != '__public__' ) {
if ( $USER_REMOTE_ACCESS > 0 ) // plus confidential
$allow_access[] = 'C';
if ( $USER_REMOTE_ACCESS == 2 ) // plus private
$allow_access[] = 'R';
}
user_load_variables ( $login, 'rss_' );
$creator = ( $username == '__public__' ) ? 'Public' : $rss_fullname;
if ( $username != '__public__' &&
( empty ( $USER_RSS_ENABLED ) || $USER_RSS_ENABLED != 'Y' ) ) {
header ( 'Content-Type: text/plain' );
echo print_not_auth (29);
exit;
}
$cat_id = '';
if ( $CATEGORIES_ENABLED == 'Y' ) {
$x = getValue ( 'cat_id', '-?[0-9]+', true );
if ( ! empty ( $x ) ) {
load_user_categories ();
$cat_id = $x;
$category = $categories[$cat_id]['cat_name'];
}
}
if ( $load_layers )
load_user_layers ( $username );
// Calculate date range.
$date = getValue ( 'date', '-?[0-9]+', true );
if ( empty ( $date ) || strlen ( $date ) != 8 )
// If no date specified, start with today.
$date = date ( 'Ymd' );
$thisyear = substr ( $date, 0, 4 );
$thismonth = substr ( $date, 4, 2 );
$thisday = substr ( $date, 6, 2 );
$startTime = mktime ( 0, 0, 0, $thismonth, $thisday, $thisyear );
$x = getValue ( 'days', '-?[0-9]+', true );
if ( ! empty ( $x ) )
$numDays = $x;
// Don't let a malicious user specify more than 365 days.
if ( $numDays > 365 )
$numDays = 365;
$x = getValue ( 'max', '-?[0-9]+', true );
if ( ! empty ( $x ) )
$maxEvents = $x;
// Don't let a malicious user specify more than 100 events.
if ( $maxEvents > 100 )
$maxEvents = 100;
$x = getValue ( 'repeats', '-?[0-9]+', true );
if ( ! empty ( $x ) ) {
$allow_repeats = $x;
if ( $x == 2 )
$show_daily_events_only_once = true;
}
$endTime = mktime ( 0, 0, 0, $thismonth, $thisday + $numDays -1, $thisyear );
$endDate = date ( 'Ymd', $endTime );
/* Pre-Load the repeated events for quicker access */
if ( $allow_repeats == true )
$repeated_events = read_repeated_events ( $username, $startTime, $endTime, $cat_id );
/* Pre-load the non-repeating events for quicker access */
$events = read_events ( $username, $startTime, $endTime, $cat_id );
$charset = ( empty ( $LANGUAGE ) ? 'iso-8859-1' : translate ( 'charset' ) );
// This should work ok with RSS, may need to hardcode fallback value.
$lang = languageToAbbrev ( $LANGUAGE == 'Browser-defined' || $LANGUAGE == 'none'
? $lang : $LANGUAGE );
if ( $lang == 'en' )
$lang = 'en-us'; //the RSS 2.0 default.
$appStr = generate_application_name ();
ob_start ();
// header ( 'Content-type: application/rss+xml');
header ( 'Content-type: text/xml' );
echo '<?xml version="1.0" encoding="' . $charset . '"?>
<rss version="2.0" xml:lang="' . $lang . '">
<channel>
<title><![CDATA[' . $appStr . ']]></title>
<link>' . $SERVER_URL . '</link>
<description><![CDATA[' . $appStr . ']]></description>
<language>' . $lang . '</language>
<generator>"http://www.k5n.us/webcalendar.php?v=' . $PROGRAM_VERSION
. '"</generator>
<image>
<title><![CDATA[' . $appStr . ']]></title>
<link>' . $SERVER_URL . '</link>
<url>http://www.k5n.us/k5n_small.gif</url>
</image>';
$endtimeYmd = date ( 'Ymd', $endTime );
$numEvents = 0;
$reventIds = array ();
for ( $i = $startTime; date ( 'Ymd', $i ) <= $endtimeYmd && $numEvents < $maxEvents;
$i += 86400 ) {
$d = date ( 'Ymd', $i );
$eventIds = array ();
$pubDate = gmdate ( 'D, d M Y', $i );
$pubDateEnd = gmdate ( 'D, d M Y', $i );
$specialDate = gmdate ( 'd.m.Y', $i );
$specialDateEnd = gmdate ( 'd.m.Y', $i );
$entries = get_entries ( $d, false );
$rentries = get_repeating_entries ( $username, $d );
$entrycnt = count ( $entries );
$rentrycnt = count ( $rentries );
if ( $debug )
echo '
countentries==' . $entrycnt . ' ' . $rentrycnt . '
';
if ( $entrycnt > 0 || $rentrycnt > 0 ) {
for ( $j = 0; $j < $entrycnt && $numEvents < $maxEvents; $j++ ) {
// Prevent non-Public events from feeding
if ( in_array ( $entries[$j]->getAccess (), $allow_access ) ) {
$eventIds[] = $entries[$j]->getID ();
$unixtimeStart = $entries[$j]->getDateTimeTS ();
$unixtimeEnd = $entries[$j]->getEndDateTimeTS ();
$dateinfo = ( $date_in_title
? date ( $date_format, $unixtime )
. ( $entries[$j]->isTimed () ? $time_separator
. date ( $time_format, $unixtime ) : '' ) . ' ' : '' );
if ($unixtimeStart == $unixtimeEnd) {
echo '
<item type="note">';
} else {
echo '
<item type="static">';
}
load_user_categories ();
$res = dbi_execute ( 'SELECT cat_id FROM webcal_entry_categories WHERE cal_id = '. $entries[$j]->getID () );
if ( $res ) {
while ( $row = dbi_fetch_row ( $res ) ) {
$cat_IDList = $cat_IDList.strval($row[0].',');
}
dbi_free_result ( $res );
$cat_IDList = explode(',', $cat_IDList);
}
echo '
<entryID>' . $entries[$j]->getID () . '</entryID>
<title><![CDATA[' . $dateinfo . $entries[$j]->getName () . ']]></title>
<link>' . $SERVER_URL . 'view_entry.php?id=' . $entries[$j]->getID ()
. '&friendly=1&rssuser=' . $login . '&date=' . $d . '</link>
<description><![CDATA[' . $entries[$j]->getDescription () . ']]></description>
<categories>';
foreach($cat_IDList as $cat_ID)
{
if ($cat_ID)
{
echo '
<category ID="' . $cat_ID . '"><![CDATA[' . $categories[$cat_ID]['cat_name'] . ']]></category>';
}
}
echo '
</categories>';
if ($unixtimeStart == $unixtimeEnd) {
echo '
<startDate>' . $specialDate . '</startDate>';
} else {
echo '
<startRSSStamp>' . gmdate ( 'D, d M Y H:i:s', $unixtimeStart ) . ' GMT</startRSSStamp>
<startTime>' . gmdate ( 'H:i:s', $unixtimeStart ) . '</startTime>
<startDate>' . $specialDate . '</startDate>
<endRSSStamp>' . gmdate ( 'D, d M Y H:i:s', $unixtimeEnd ) . ' GMT</endRSSStamp>
<endTime>' . gmdate ( 'H:i:s', $unixtimeEnd ) . '</endTime>
<endDate>' . gmdate ( 'd.m.Y', $unixtimeEnd ) . '</endDate>';
}
echo '
<guid>' . $SERVER_URL . 'view_entry.php?id=' . $entries[$j]->getID ()
. '&friendly=1&rssuser=' . $login . '&date=' . $d . '</guid>
</item>';
$numEvents++;
}
}
for ( $j = 0; $j < $rentrycnt && $numEvents < $maxEvents; $j++ ) {
// To allow repeated daily entries to be suppressed. Step below is
// necessary because 1st occurence of repeating events shows up in
// $entries AND $rentries & we suppress display of it in $rentries.
if ( in_array ( $rentries[$j]->getID (),
$eventIds ) && $rentries[$j]->getrepeatType () == 'daily' )
$reventIds[] = $rentries[$j]->getID ();
// Prevent non-Public events from feeding.
// Prevent a repeating event from displaying if the original event has
// already been displayed; prevent 2nd & later recurrence of daily events
// from displaying if that option has been selected.
if ( ! in_array ( $rentries[$j]->getID (), $eventIds ) &&
( ! $show_daily_events_only_once || ! in_array ( $rentries[$j]->getID (),
$reventIds ) ) &&
( in_array ( $rentries[$j]->getAccess (), $allow_access ) ) ) {
// Show repeating events only once.
if ( $rentries[$j]->getrepeatType () == 'daily' )
$reventIds[] = $rentries[$j]->getID ();
echo '
<item type="interval">';
$unixtimeStart = $rentries[$j]->getDateTimeTS ();
$unixtimeEnd = $rentries[$j]->getEndDateTimeTS ();
$dateinfo = ( $date_in_title == true
? date ( $date_format, $i )
. ( $rentries[$j]->isAllDay () || $rentries[$j]->isUntimed ()
? $time_separator . date ( $time_format, $unixtimeStart ) : '' ) . ' '
: '' );
$timeStart = gmdate ( 'H:i:s', $unixtimeStart );
$timeEnd = gmdate ( 'H:i:s', $unixtimeEnd );
if ($timeStart == $timeEnd) {
$specialDateEnd = gmdate ( 'd.m.Y', $i + 86400 );
$pubDateEnd = gmdate ( 'D, d M Y', $i + 86400 );
} else {
$specialDateEnd = gmdate ( 'd.m.Y', $i );
$pubDateEnd = gmdate ( 'D, d M Y', $i );
}
error_reporting(E_ALL);
ini_set('display_errors', 1);
load_user_categories ();
$res = dbi_execute ( 'SELECT cat_id FROM webcal_entry_categories WHERE cal_id = '. $rentries[$j]->getID () );
$cat_IDList = '';
if ( $res ) {
while ( $row = dbi_fetch_row ( $res ) ) {
$cat_IDList = $cat_IDList.strval($row[0].',');
}
dbi_free_result ( $res );
$cat_IDList = explode(',', $cat_IDList);
}
echo '
<entryID>' . $rentries[$j]->getID () . '</entryID>
<title><![CDATA[' . $dateinfo . $rentries[$j]->getName () . ']]></title>
<link>' . $SERVER_URL . "view_entry.php?id=" . $rentries[$j]->getID ()
. '&friendly=1&rssuser=' . $login . '&date=' . $d . '</link>
<description><![CDATA[' . $rentries[$j]->getDescription () . ']]></description>
<categories>';
foreach($cat_IDList as $cat_ID)
{
if ($cat_ID)
{
echo '
<category ID="' . $cat_ID . '"><![CDATA[' . $categories[$cat_ID]['cat_name'] . ']]></category>';
}
}
echo '
</categories>
<startRSSStamp>' . $pubDate . ' ' . gmdate ( 'H:i:s', $unixtimeStart ) . ' GMT</startRSSStamp>
<startTime>' . gmdate ( 'H:i:s', $unixtimeStart ) . '</startTime>
<startDate>' . $specialDate . '</startDate>
<endRSSStamp>' . $pubDateEnd . ' ' . gmdate ( 'H:i:s', $unixtimeEnd ) . ' GMT</endRSSStamp>
<endTime>' . gmdate ( 'H:i:s', $unixtimeEnd ) . '</endTime>
<endDate>' . $specialDateEnd . '</endDate>
<guid>' . $SERVER_URL . 'view_entry.php?id=' . $rentries[$j]->getID ()
. '&friendly=1&rssuser=' . $login . '&date=' . $d . '</guid>
</item>';
$numEvents++;
}
}
}
}
echo '
</channel>
</rss>';
ob_end_flush ();
// Clear login...just in case.
$login = '';
exit;
?>
Als kleines Script für das IPS habe ich hier eine Funktion die alle Werte ausliest und im Moment als Debugmeldung ausgibt.
Ihr müsst nur den Link zum Kalender anpassen.
Den Usernamen welcher Zugriff hat muss angepasst werden.
Wichtig, RSS muss freigeschaltet sein und der User muss seine Einträge zur Veröffentlichung erlauben.
<?
/*------------------------------------------------------------------------------
FHT - Kalendersteuerung v0.5
(c) 2010 by Adrian Krug
last change: 06.01.2010
------------------------------------------------------------------------------*/
$debug = true;
/*------------------------------------------------------------------------------
Location of RSS-Feed
--------------------------------------------------------------------------------
Parameters:
- days: number of days ahead to look for events
- cat_id: specify a category id to filter on (0=all)
- repeats: output all events including all repeat instances
repeats=0 do not output repeating events (default)
repeats=1 outputs repeating events (recommended)
repeats=2 outputs repeating events but suppresses display of
2nd & subsequent occurences of daily events
- user: login name of calendar to display (instead of public user).
You must have the following System Settings configured for this:
Allow viewing other user's calendars: Yes
Public access can view others: Yes */
$calender_xml = simplexml_load_file("http://kalender.zuhause/rss.php"
."?user=heizung"
."&days=1"
."&repeats=1"
."&cat_id=0");
/*----------------------------------------------------------------------------*/
// Rooms
// -ID- -Name-
$roomIDs = array ( 9 => "Bad - (unten)",
10 => "Bad - (oben)",
11 => "Arbeitsbereich",
12 => "Vorraum - (oben)",
13 => "Küche",
14 => "Schlafbereich",
15 => "Wohnbereich",
50 => "Test");
/*----------------------------------------------------------------------------*/
// FHT's
// -ID- -FHT-ID-
$fhtVariables = array ( 9 => "12345", //Bad - (unten)
10 => "12345", //Bad - (oben)
11 => "12345", //Arbeitsbereich
12 => "12345", //Vorraum - (oben)
13 => "12345", //Küche
14 => "12345", //Schlafbereich
15 => "12345", //Wohnbereich
50 => "12345"); //Test
/*----------------------------------------------------------------------------*/
// Profiles
$profiles = array ("Heizen","Schnelles Aufheizen","Abwesend","Ausgeschaltet");
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Do NOT change anything below this line --> it's your own risk ;-) */
/*----------------------------------------------------------------------------*/
$items = $calender_xml->channel->item; // <------------------------------------- Select all available items
$itemIndex = 1;
if ($debug) {echo "FHT-Calendar DEBUGMODE
----------------------
";}
if ($debug) {echo count($items)," calendar entrys are available to proceed
";}
foreach ($items as $item) // <-------------------------------------------------- Read each entry
{
$categories = $item->categories->category; // <------------------------------ Select all available categories
$itemType = $item['type']; // <---------------------------------------------- Read type of entry (note,static,interval)
$itemTitle = $item->title; // <---------------------------------------------- Read out title / action
if ($debug) {echo "
Dataset - ",$itemIndex++," - (",$itemType,")
",
"Action | ",$itemTitle;}
if (in_array($itemTitle,$profiles)) {if ($debug) {echo " - (OK - regognized)
";}
} else {if ($debug) {echo " - (!not known!)
";}} // <----------------------- Check if action is known in profiles
$startDate = $item->startDate; // <------------------------------------------ Read start date
if ($debug) {echo "Start | Date: ",$startDate;}
switch ($itemType) { // <---------------------------------------------------- Check item type
case "note": // <--------------------------------------------------------- it's only a note
if ($debug) {echo "
";}
break;
default: // <------------------------------------------------------------- Check if it's static or interval
$startTime = $item->startTime; // <------------------------------------ Read start time
$endDate = $item->endDate; // <---------------------------------------- Read end date
$endTime = $item->endTime; // <---------------------------------------- Read end time
if ($debug) {echo " - Time: ",$startTime,"
","End | Date: ",
$endDate," - Time: ",$endTime,"
";}
break;
}
if ($debug) {echo "Rooms | ",count($categories),"
";}
for ($categoryIndex=0; $categoryIndex <= count($categories)-1; // <---------- Check category mapping
$categoryIndex++)
{
foreach ($categories[$categoryIndex]->attributes() as $categoryID) // <--- Read category ID from associative array
{
$roomID = $categoryID; // <-------------------------------------------- ID of actual parsed room
$roomName = $roomIDs[''.$categoryID.'']; // <-------------------------- Name of actual parsed room
if ($debug) {echo $categoryIndex+1,". Room | ID: ",$roomID,
" - Name: ",$roomName,"
";}
if ($debug) {echo $categoryIndex+1,". Room | Send XYZ to FHT-Variable 12345
";}
}
}
}
if ($debug) {echo "
SCRIPT - READY
";}
?>
Der RSS-XML Syntax der ausgegeben sieht nun wie folgt aus:
<item type="note">
<entryID>14</entryID>
<title><![CDATA[Schnelles Aufheizen]]></title>
<link></link>
<description><![CDATA[Test]]></description>
<categories>
<category ID="11"><![CDATA[Arbeitsbereich]]></category>
<category ID="9"><![CDATA[Bad - (unten)]]></category>
<category ID="12"><![CDATA[Vorraum - (oben)]]></category>
<category ID="10"><![CDATA[Bad - (oben)]]></category>
<category ID="13"><![CDATA[Küche]]></category>
<category ID="14"><![CDATA[Schlafbereich]]></category>
<category ID="15"><![CDATA[Wohnbereich]]></category>
</categories>
<startDate>00.00.0000</startDate>
<guid></guid>
</item>
<item type="static">
<entryID>13</entryID>
<title><![CDATA[Ausgeschaltet]]></title>
<link></link>
<description><![CDATA[Ungenutzt]]></description>
<categories>
<category ID="11"><![CDATA[Raum 0]]></category>
</categories>
<startRSSStamp></startRSSStamp>
<startTime>00:00:00</startTime>
<startDate>00.00.0000</startDate>
<endRSSStamp></endRSSStamp>
<endTime>00:00:00</endTime>
<endDate>00.00.0000</endDate>
<guid></guid>
</item>
<item type="interval">
<entryID>5</entryID>
<title><![CDATA[Heizen]]></title>
<link></link>
<description><![CDATA[Heizen]]></description>
<categories>
<category ID="10"><![CDATA[Raum 1]]></category>
</categories>
<startRSSStamp></startRSSStamp>
<startTime>00:00:00</startTime>
<startDate>00.00.0000</startDate>
<endRSSStamp></endRSSStamp>
<endTime>00:00:00</endTime>
<endDate>00.00.0000</endDate>
<guid></guid>
</item>
Es können nun die Kategorien recht simpel als Räume anwenden, das ergibt nen übersichtlichen Kalender, welcher dann die Räume über die Kategorien anzeigen kann.
Desweiteren habe ich die „items“ in Typen unterteilt:
[ul]
[li]note - Termin ohne Zeitangabe[/li][li]static - Fixtermin ohne Wiederholung (Achtung der erste Termin eines Intervalls ist auch ein Static)[/li][li]interval - Wiederkehrende Termine[/li][/ul]
Abschliessend bin ich nun dabei die Datenübergabe zu realisieren, und diverse neue Funktionen in den Kalender zu integrieren, im Moment habe ich mir z.B. die Räume im Popup sichtbargemacht, und beim Termineintrag ein Dropdownfeld realisiert, welches mir die „Profile“ auflistet, so genügt ein Klick, und jeder der die Codes nicht weiß hats einfacher --> Thema WAF
Wenns so weitergeht optimiere ich den Kalender voll auf FHT Funktionalität
So nun noch ein paar Screeshots.
Bei Fragen, Fehler und Co, hier einfach melden.
Grüßle
Addy