2006-02-20 12:36:30 +01:00
< ? php
/* WARNING: EXPERIMENTAL CODE DO NOT USE FOR PRODUCTION */
/**
* @ file
2006-03-29 21:54:33 +02:00
* IcalsrvNG : Export and Import Egw events and task as ICalendar over http using
* Virtual Calendars
2006-02-20 12:36:30 +01:00
*
2006-03-06 15:25:54 +01:00
* Possible clients include Mozilla Calendar / Sunbird , Korganizer , Apple Ical
2006-02-20 12:36:30 +01:00
* and Evolution .
* @ note < b > THIS IS STILL EXPERIMENTAL CODE </ b > do not use in production .
* @ note this script is supposed to be at : egw - root / icalsrv . php
2006-03-06 15:25:54 +01:00
*
2007-08-27 15:18:32 +02:00
* NEW RalfBecker Aug 2007
* many modifications to improve the support of ( at least ) lightning
* - changed default uid handling to UID2UID ( means keep them unchanged ), as the other
* modes created doublicates on client and server , as the client did not understand
* that the server changes his uid ' s ( against the RFC specs ) .
* - ability to delete events ( not yet InfoLogs ! ), by tracking the id ' s of the GET request
* of the client and deleting the ones NOT send back to the server in PUT requests
* - added etag handling to allow to reject put requests if the calendar is not up to date
* ( HTTP_IF header with etag in client PUT requests ) and to report unmodified calendars
* to the client ( HTTP_IF_NONE_MATCH header with etag gets 304 Not modified response )
* - returning 501 Not implemented response , for WebDAV / CalDAV request ( eg . PROPFIND ), to
* let the client know we dont support it
* - ability to use contacts identified by their mail address as participants ( mail addresses
* which are no contacts still get written to the description ! )
* - support uid for InfoLog ( requires InfoLog version >= 1.5 )
2006-05-22 22:59:57 +02:00
* @ version 0.9 . 37 - ng - a2 added a todo plan for v0 . 9.40
* @ date 20060510
* @ since 0.9 . 37 - ng - a1 removed fixed default domain authentication
2006-04-18 17:38:29 +02:00
* @ since 0.9 . 36 - ng - a1 first version for NAPI - 3.1 ( write in non owner rscs )
2006-02-20 12:36:30 +01:00
* @ author Jan van Lieshout < jvl ( at ) xs4all . nl > Rewrite and extension for egw 1.2 .
2006-03-06 15:25:54 +01:00
* ( see : @ url http :// www . egroupware . org )
2006-04-28 03:20:31 +02:00
* $Id $
2006-02-20 12:36:30 +01:00
* Based on some code from :
* @ author RalfBecker @ outdoor - training . de ( some original code base )
*
2006-03-06 15:25:54 +01:00
* < b > license :</ b >< br >
2006-02-20 12:36:30 +01:00
* 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 .
*
2006-03-06 15:25:54 +01:00
* @ todo make this 'ical-service' enabled / disabled from the egw
* admin interface
2006-03-29 21:54:33 +02:00
* @ todo make the definition of virtual calendars possible from a 'ical-service' web
* user interface user
2006-05-22 22:59:57 +02:00
* @ todo ( for 0.9 . 40 versions ) move much parsing of the vc to class . vcsrv . inc . php
* and add the $vcpath var where pathinfo is parsed to communicate to vc_X class
2006-04-05 17:13:57 +02:00
* @ bug if you dont have enough privilages to access a personal calendar of someone
* icalsrv will not give you an access denied error , but will just return no events
* from this calendar . ( Needed otherwise you cannot collect events from multiple resources
* into a single virtual calendar .
2006-03-29 21:54:33 +02:00
*
* @ todo make code robust against xss attacke etc .
2006-02-20 12:36:30 +01:00
*/
2007-02-15 17:19:06 +01:00
//-------- basic operation configuration variables ----------
2006-02-20 12:36:30 +01:00
2007-02-15 17:19:06 +01:00
$logdir = False ; // set to false for no logging
#$logdir = '/tmp'; // set to a valid (writable) directory to get log file generation
2006-02-20 12:36:30 +01:00
2007-02-15 17:19:06 +01:00
// set to true for debug logging to errorlog
//$isdebug = True;
$isdebug = False ;
2006-02-20 12:36:30 +01:00
2007-02-15 17:19:06 +01:00
/** Disallow users to import in non owned calendars and infologs
* @ var boolean $disable_nonowner_import
*/
$disable_nonowner_import = false ;
2006-04-08 15:46:14 +02:00
2007-02-15 17:19:06 +01:00
// icalsrv variant with session setup modeled after xmlrpc.php
2006-02-20 12:36:30 +01:00
2007-02-15 17:19:06 +01:00
//die(print_r($_COOKIE, true));
$icalsrv = array ();
$GLOBALS [ 'egw_info' ] = array ();
$GLOBALS [ 'egw_info' ][ 'flags' ] = array (
'currentapp' => 'login' ,
'noheader' => True ,
'nonavbar' => True ,
2006-04-08 00:11:25 +02:00
'disable_Template_class' => True
2007-02-15 17:19:06 +01:00
);
include ( 'header.inc.php' );
$ical_login = split ( '\@' , $_SERVER [ 'PHP_AUTH_USER' ]);
if ( $ical_login [ 1 ])
{
$ical_user = $ical_login [ 0 ];
$domain = $ical_login [ 1 ];
unset ( $ical_login );
}
else
{
$ical_user = $_SERVER [ 'PHP_AUTH_USER' ];
$domain = get_var ( 'domain' , array ( 'COOKIE' , 'GET' ));
}
$sessionid = get_var ( 'sessionid' , array ( 'COOKIE' , 'GET' ));
$kp3 = get_var ( 'kp3' , array ( 'COOKIE' , 'GET' ));
$domain = $domain ? $domain : $GLOBALS [ 'egw_info' ][ 'server' ][ 'default_domain' ];
$icalsrv [ 'session_ok' ] = $GLOBALS [ 'egw' ] -> session -> verify ( $sessionid , $kp3 );
if ( $icalsrv [ 'session_ok' ])
{
$icalsrv [ 'authed' ] = True ;
}
if ( ! $icalsrv [ 'session_ok' ] && isset ( $_SERVER [ 'PHP_AUTH_USER' ]) && isset ( $_SERVER [ 'PHP_AUTH_PW' ]))
{
$icalsrv [ 'authed' ] = $GLOBALS [ 'egw' ] -> session -> create ( $ical_user . '@' . $domain , $_SERVER [ 'PHP_AUTH_PW' ], 'text' );
}
if ( $icalsrv [ 'authed' ])
{
$icalsrv [ 'session_ok' ] = True ;
// This may not even be necessary:
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] = 'icalsrv' ;
}
// bad session or bad authentication so please re-authenticate..
if ( ! ( $icalsrv [ 'session_ok' ] && $icalsrv [ 'authed' ]))
{
if ( $isdebug )
{
error_log ( 'line ' . __LINE__ . ': Session: ' . $icalsrv [ 'session_ok' ] . ', Authed: ' . $icalsrv [ 'authed' ]);
2006-04-08 00:11:25 +02:00
}
2007-02-15 17:19:06 +01:00
header ( 'WWW-Authenticate: Basic realm="ICal Server"' );
header ( 'HTTP/1.1 401 Unauthorized' );
exit ;
}
/* Moved after the auth header send. It is normal to save this check until now, similar to how simple eGroupWare access control works for a browser login. (Milosch) */
if ( !@ isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'icalsrv' ]))
{
fail_exit ( 'IcalSRV not enabled' , '403' );
}
// Ok! We have a session and access to icalsrv!
// now set the variables that will control the working mode of icalvircal
2007-02-16 14:13:20 +01:00
// the defines are in the icalsrv_resourcehandler sourcefile
require_once EGW_SERVER_ROOT . '/icalsrv/inc/class.icalsrv_resourcehandler.inc.php' ;
2007-02-15 17:19:06 +01:00
/** uid mapping export configuration switch
* @ var int
* Parameter that determines , a the time of export from Egw ( aka dowload by client ), how
* ical elements ( like VEVENT ' s ) get their uid fields filled , from data in
* the related Egroupware element .
2007-02-16 14:13:20 +01:00
* See further in @ ref secuidmapping in the icalsrv_resourcehandler documentation .
2007-02-15 17:19:06 +01:00
*/
2007-08-27 15:18:32 +02:00
// New RalfBecker Aug 2007
// NOT using UID2UID creates doublicates on the iCal client, as it does NOT understand,
// that posted events get their uid changed by the server.
// I think uid's should be handled as specified in the RFC: the first clients assigns them
// AND noone is supposted to change them after that!
$uid_export_mode = UMM_UID2UID ;
2007-02-15 17:19:06 +01:00
/** uid mapping import configuration switch
* @ var int
* Parameter that determines , at the time of import into Egw ( aka publish by client ), how
* ical elements ( like VEVENT ' s ) will find , based on their uid fields , related egw
* elements , that are then updated with the ical info .
2007-02-16 14:13:20 +01:00
* See further in @ ref secuidmapping in the icalsrv_resourcehandler documentation .
2007-02-15 17:19:06 +01:00
*/
2007-08-27 15:18:32 +02:00
// New RalfBecker Aug 2007
// NOT using UID2UID creates doublicates on the iCal client, see above
$uid_import_mode = UMM_UID2UID ;
2007-02-15 17:19:06 +01:00
/**
* @ section secisuidmapping Basic Possible settings of UID to ID mapping .
*
* @ warning the default setting in icalsrv . php is one of the 3 basic uid mapping modes :
* #The standard mode that allows a published client calendar to add new events and todos
* to the egw calendar , and allows to update already before published ( to egw ) and
* at least once downloaded ( from egw ) events and todos .
* .
* setting : < PRE > $uid_export_mode = UMM_ID2UID ; $uid_import_mode = UMM_UID2ID ; </ PRE > ( default )
* #The fool proof mode that will prevent accidental change or deletion of existing
* egw events or todos . Note that the price to pay is < i > duplication </ i > on republishing or
* re - download !
* .
* setting : < PRE > $uid_export_mode = UMM_NEWUID ; $uid_import_mode = UMM_NEWID ; </ PRE > ( discouraged )
* #The flaky sync mode that in principle would make each event and todo recognizable by
* both the client and egw at each moment . In this mode a once given uid field is both used
* in the client and in egw . Unfortunately there are quite some problems with this , making it
* very unreliable to use !
* .
* setting : < PRE > $uid_export_mode = UMM_UID2UID ; $uid_import_mode = UMM_UID2UID ; </ PRE > ( discouraged ! )
*/
/** allow elements gone ( deleted ) in egw to be imported again from client
* @ var boolean $reimport_missing_elements
*/
$reimport_missing_elements = true ;
//-------- end of basic operation configuration variables ----------
#error_log('_SERVER:' . print_r($_SERVER, true));
// go parse our request uri
$requri = $_SERVER [ 'REQUEST_URI' ];
$reqpath = $_SERVER [ 'PATH_INFO' ];
$reqagent = $_SERVER [ 'HTTP_USER_AGENT' ];
# maybe later also do something with content_type?
# if(!empty($_SERVER['CONTENT_TYPE'])) {
# if(strpos($_SERVER['CONTENT_TYPE'], 'application/vnd....+xml') !== false) {
# ical/ics ???
// ex1: $requri='egroupware/icalsrv.php/demouser/todos.ics'
// then $reqpath='/demouser/todos.ics'
// $rvc_owner='demouser'
// $rvc_basename='/todos.ics'
// ex2:or $recuri ='egroupware/icalsrv.php/uk/holidays.ics'
// then $reqpath='/uk/holidays.ics'
// $rvc_owner = null; // unset
// $rvc_basename=null; // unset
// ex3: $requri='egroupware/icalsrv.php/demouser/todos?pw=mypw01'
// then $reqpath='/demouser/todos.ics'
// $rvc_owner='demouser'
// $rvc_basename='/todos.ics'
// $_GET['pw'] = 'mypw01'
// S-- parse the $reqpath to get $reqvircal names
unset ( $reqvircal_owner );
unset ( $reqvircal_owner_id );
unset ( $reqvircal_basename );
if ( empty ( $_SERVER [ 'PATH_INFO' ]))
{
// no specific calendar requested, so do default.ics
$reqvircal_pathname = '/default.ics' ;
// try owner + base for a personal vircal request
}
elseif ( preg_match ( '#^/([\w]+)(/[^<^>^?]+)$#' , $_SERVER [ 'PATH_INFO' ], $matches ))
{
$reqvircal_pathname = $matches [ 0 ];
$reqvircal_owner = $matches [ 1 ];
$reqvircal_basename = $matches [ 2 ];
if ( ! $reqvircal_owner_id = $GLOBALS [ 'egw' ] -> accounts -> name2id ( $reqvircal_owner ))
{
// owner is unknown, so forget about personal calendar
unset ( $reqvircal_owner );
unset ( $reqvircal_basename );
}
// check for decent non personal path
}
elseif ( preg_match ( '#^(/[^<^>]+)$#' , $_SERVER [ 'PATH_INFO' ], $matches ))
{
$reqvircal_pathname = $matches [ 0 ];
// just default to standard path
}
else
{
$reqvircal_pathname = 'default.ics' ;
2006-04-08 00:11:25 +02:00
}
2007-02-15 17:19:06 +01:00
2006-04-28 03:20:31 +02:00
if ( $isdebug )
2007-02-15 17:19:06 +01:00
{
error_log ( 'http-user-agent:' . $reqagent
. ',pathinfo:' . $reqpath . ',rvc_pathname:' . $reqvircal_pathname
. ',rvc_owner:' . $reqvircal_owner . ',rvc_owner_id:' . $reqvircal_owner_id
. ',rvc_basename:' . $reqvircal_basename );
}
// S1A search for the requested calendar in the vircal_ardb's
if ( is_numeric ( $reqvircal_owner_id ))
{
// check if the requested personal calender is provided by the owner..
/**
* @ todo 1. create somehow the list of available personal vircal arstores
* note : this should be done via preferences and read repository , but how ....
* I have to find out and write it ...
*/
// find personal database of (array stored) virtual calendars
$cnmsg = 'calendar [' . $reqvircal_basename . '] for user [' . $reqvircal_owner . ']' ;
$vo_personal_vircal_ardb =& CreateObject ( 'icalsrv.personal_vircal_ardb' , $reqvircal_owner_id );
if ( ! ( is_object ( $vo_personal_vircal_ardb )))
{
error_log ( 'icalsrv.php: couldnot create personal vircal_ardb for user:' . $reqvircal_owner );
fail_exit ( 'could not access' . $cnmsg , '403' );
}
2006-02-20 12:36:30 +01:00
2007-02-15 17:19:06 +01:00
// check if a /<username>/list.html is requested
if ( $reqvircal_basename == '/list.html' )
{
echo $vo_personal_vircal_ardb -> listing ( 1 );
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
}
2006-02-20 12:36:30 +01:00
2007-02-15 17:19:06 +01:00
error_log ( 'vo_personal_vircal_ardb:' . print_r ( $vo_personal_vircal_ardb -> calendars , true ));
// search our calendar in personal vircal database
if ( ! ( $vircal_arstore = $vo_personal_vircal_ardb -> calendars [ $reqvircal_basename ]))
{
error_log ( 'icalsrv.php: ' . $cnmsg . ' not found.' );
fail_exit ( $cnmsg . ' not found.' , '404' );
}
// oke we have a valid personal vircal in array_storage format!
}
else
{
// check if the requested system calender is provided by system
$cnmsg = 'system calendar [' . $reqvircal_pathname . ']' ;
/**
* @ todo 1. create somehow the list of available system vircal
* arstores note : this should be done via preferences and read
* repository , but how .... I have to find out
*/
// find system database of (array stored) virtual calendars
$system_vircal_ardb = CreateObject ( 'icalsrv.system_vircal_ardb' );
if ( ! ( is_object ( $system_vircal_ardb )))
{
error_log ( 'icalsrv.php: couldnot create system vircal_ardb' );
fail_exit ( 'couldnot access ' . $cnmsg , '403' );
}
2006-02-20 12:36:30 +01:00
2007-02-15 17:19:06 +01:00
// check if a /list.html is requested
if ( $reqvircal_pathname == '/list.html' )
{
echo $system_vircal_ardb -> listing ( 1 );
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
}
// search our calendar in system vircal database
if ( ! ( $vircal_arstore = $system_vircal_ardb -> calendars [ $reqvircal_pathname ]))
{
fail_exit ( $cnmsg . ' not found' , '404' );
}
// oke we have a valid system vircal in array_storage format!
}
//die(print_r($_COOKIE,true). " in ". __FILE__.", line ".__LINE__);
if ( $isdebug )
{
error_log ( 'vircal_arstore:' . print_r ( $vircal_arstore , true ));
}
// build a virtual calendar with ical facilities from the found vircal
// array_storage data
2007-08-27 15:18:32 +02:00
require_once ( EGW_INCLUDE_ROOT . '/icalsrv/inc/class.icalvircal.inc.php' );
$icalvc =& new icalvircal ;
2007-02-16 14:13:20 +01:00
if ( ! $icalvc -> fromArray ( $vircal_arstore ))
2007-02-15 17:19:06 +01:00
{
error_log ( 'icalsrv.php: ' . $cnmsg . ' couldnot restore from repository.' );
fail_exit ( $cnmsg . ' internal problem ' , '403' );
}
// YES: $icalvc created ok! acces rights needs to be checked though!
// HACK: ATM basic auth is always needed!! (JVL) ,so we force icalvc into it
$icalvc -> auth = ':basic' ;
// check if the virtual calendar demands authentication
if ( strpos ( $icalvc -> auth , 'none' ) !== false )
{
// no authentication demanded so continue
}
elseif ( strpos ( $icalvc -> auth , 'basic' ) !== false )
{
//basic http authentication demanded
//so exit on non authenticated http request
//-- As we atm only allow authenticated users the
// actions in the next lines are already done at the begining
// of this file --
// if((!isset($_SERVER['PHP_AUTH_USER'])) ||
// (!$GLOBALS['egw']->auth->authenticate($_SERVER['PHP_AUTH_USER'],
// $_SERVER['PHP_AUTH_PW']))) {
// if($isdebug)
// error_log('SESSION IS SETUP, BUT AUTHENTICATE FAILED'.$_SERVER['PHP_AUTH_USER'] );
// header('WWW-Authenticate: Basic realm="ICal Server"');
// header('HTTP/1.1 401 Unauthorized');
// exit;
// }
// // else, use the active basic authentication to set preferences
// $user_id = $GLOBALS['egw']->accounts->name2id($_SERVER['PHP_AUTH_USER']);
// $GLOBALS['egw_info']['user']['account_id'] = $user_id;
// error_log(' ACCOUNT SETUP FOR'
// . $GLOBALS['egw_info']['user']['account_id']);
}
elseif ( strpos ( $icalvc -> auth , 'ssl' ) !== false )
{
// ssl demanded, check if we are in https authenticated connection
// if not redirect to https
error_log ( 'icalsrv.php:' . $cnmsg . ' demands secure connection' );
fail_exit ( $cnmsg . ' demands secure connection: please use https' , '403' );
}
else
{
error_log ( '*** icalsrv.php:' . $cnmsg . ' requires unknown authentication method:'
2006-03-29 21:54:33 +02:00
. $icalcv -> auth );
2007-02-15 17:19:06 +01:00
fail_exit ( $cnmsg . ' demands unavailable authentication method:'
. $icalcv -> auth , '403' );
2006-04-08 15:46:14 +02:00
}
2007-02-15 17:19:06 +01:00
/**
* @ todo this extra password checkin should , at least for logged - in users ,
* better be incorporated in the ACL checkings . At some time ...
*/
// check if an extra password is needed too
if ( strpos ( $icalvc -> auth , 'passw' ) !== false )
{
//extra parameter password authentication demanded
//so exit if pw parameter is not valid
if (( ! isset ( $_GET [ 'password' ])) ||
( ! $icalvc -> pw !== $_GET [ 'password' ]))
2007-02-16 14:13:20 +01:00
{
2007-02-15 17:19:06 +01:00
error_log ( 'icalsrv.php:' . $cnmsg . ' demands extra password parameter' );
fail_exit ( $cnmsg . ' demands extra password parameter' , '403' );
}
2006-03-29 21:54:33 +02:00
}
2007-02-15 17:19:06 +01:00
// now we are authenticated enough
// go setup import and export mode in our ical virtual calendar
$icalvc -> uid_mapping_export = $uid_export_mode ;
$icalvc -> uid_mapping_import = $uid_import_mode ;
$icalvc -> reimport_missing_elements = $reimport_missing_elements ;
$logmsg = " " ;
2007-08-27 15:18:32 +02:00
// NEW RalfBecker Aug 2007
// We have to handle the request methods different, specially the WebDAV ones we dont support
switch ( $_SERVER [ 'REQUEST_METHOD' ])
2007-02-15 17:19:06 +01:00
{
2007-08-27 15:18:32 +02:00
case 'PUT' :
2007-02-15 17:19:06 +01:00
// *** PUT Request so do an Import *************
2007-08-27 15:18:32 +02:00
2007-02-15 17:19:06 +01:00
if ( $isdebug )
{
error_log ( 'icalsrv.php: importing, by user:' . $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]
. ' for virtual calendar of: ' . $reqvircal_owner_id );
}
// check if importing in not owned calendars is disabled
if ( $reqvircal_owner_id
&& ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ] !== $reqvircal_owner_id ))
2007-02-16 14:13:20 +01:00
{
2007-02-15 17:19:06 +01:00
if ( $disable_nonowner_import )
{
error_log ( 'icalsrv.php: importing in non owner calendars currently disabled' );
fail_exit ( 'importing in non owner calendars currently disabled' , '403' );
}
}
if ( isset ( $reqvircal_owner_id ) && ( $reqvircal_owner_id < 0 ))
{
error_log ( 'icalsrv.php: importing in group calendars not allowed' );
fail_exit ( 'importing in groupcalendars is not allowed' , '403' );
}
2007-08-27 15:18:32 +02:00
// NEW RalfBecker Aug 2007
// for a PUT we have to check if the currently loaded calendar is still up to date
// (not changed eg. by someone else or via the webfrontend).
// This is done by comparing the ETAG given as HTTP_IF with the current ETAG (last modification date)
// of the calendar --> on failure we return 412 Precondition failed, to not overwrite the modifications
if ( isset ( $_SERVER [ 'HTTP_IF' ]) && preg_match ( '/\(\[([0-9]+)\]\)/' , $_SERVER [ 'HTTP_IF' ], $matches ))
{
$etag = $icalvc -> get_etag ();
//error_log("PUT: current etag=$etag, HTTP_IF=$_SERVER[HTTP_IF]");
if ( $matches [ 1 ] != $etag )
{
fail_exit ( 'Precondition Failed' , 412 );
}
}
2007-02-15 17:19:06 +01:00
// I0 read the payload
$logmsg = 'IMPORTING in ' . $importMode . ' mode' ;
$fpput = fopen ( " php://input " , " r " );
$vcalstr = " " ;
while ( $data = fread ( $fpput , 1024 ))
{
$vcalstr .= $data ;
}
fclose ( $fpput );
// import the icaldata into the virtual calendar
// note: ProductType is auto derived from $vcalstr
$import_table =& $icalvc -> import_vcal ( $vcalstr );
// count the successes..
if ( $import_table === false )
{
$msg = 'icalsrv.php: importing ' . $cnmsg . ' ERRORS' ;
fail_exit ( $msg , '403' );
}
else
{
$logmsg .= " \n imported " . $cnmsg . ' : ' ;
foreach ( $import_table as $rsc_class => $vids )
{
$logmsg .= " \n resource: " . $rsc_class . ' : ' . count ( $vids ) . ' elements OK' ;
}
}
// DONE importing
if ( $logdir )
{
log_ical ( $logmsg , " import " , $vcalstr );
}
2007-08-27 15:18:32 +02:00
// NEW RalfBecker Aug 2007
// we have to send a new etag header, as otherwise the client (at least lightning) has a wrong etag,
// if it's not requesting the calendar again via GET
header ( " ETag: " . $icalvc -> get_etag ());
2007-02-15 17:19:06 +01:00
// handle response ...
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
2007-08-27 15:18:32 +02:00
case 'GET' :
// *** GET Request so do an export
2007-02-15 17:19:06 +01:00
$logmsg = 'EXPORTING' ;
// derive a ProductType from our http Agent and set it in icalvc
2007-02-16 14:13:20 +01:00
$icalvc -> deviceType = icalsrv_resourcehandler :: httpUserAgent2deviceType ( $reqagent );
2007-02-15 17:19:06 +01:00
2007-08-27 15:18:32 +02:00
// NEW RalfBecker Aug 2007
// if an IF_NONE_MATCH is given, check if we need to send a new export, or the current one is still up-to-date
if ( isset ( $_SERVER [ 'HTTP_IF_NONE_MATCH' ]))
{
$etag = $icalvc -> get_etag ();
error_log ( " GET: current etag= $etag , HTTP_IF_NONE_MATCH= $_SERVER[HTTP_IF_NONE_MATCH] " );
if ( $_SERVER [ 'HTTP_IF_NONE_MATCH' ] == $etag )
{
fail_exit ( 'Not Modified' , 304 );
}
}
2007-02-15 17:19:06 +01:00
// export the data from the virtual calendar
$vcalstr = $icalvc -> export_vcal ();
// handle response
if ( $vcalstr === false )
{
$msg = 'icalsrv.php: exporting ' . $cnmsg . ' ERRORS' ;
fail_exit ( $msg , '403' );
}
else
{
$logmsg .= " \n exported " . $cnmsg . " : OK " ;
}
// DONE exporting
2007-08-27 15:18:32 +02:00
// NEW RalfBecker Aug 2007
// returnung max modification date of events as etag header
header ( " ETag: " . $icalvc -> export_etag );
2007-02-15 17:19:06 +01:00
if ( $logdir ) log_ical ( $logmsg , " export " , $vcalstr );
// handle response ...
2007-10-13 09:26:33 +02:00
// using fixed text/calendar as content-type, as deviceType2contentType always returns '', which cause php to use text/html
//$content_type = icalsrv_resourcehandler::deviceType2contentType($icalvc->deviceType);
$content_type = 'text/calendar' ;
2007-02-15 17:19:06 +01:00
if ( $content_type )
{
2007-10-25 17:35:39 +02:00
header ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
header ( 'Cache-Control: no-store, no-cache, must-revalidate' ); // HTTP/1.1
header ( 'Cache-Control: pre-check=0, post-check=0, max-age=0' ); // HTTP/1.1
2007-10-13 09:26:33 +02:00
header ( 'Content-Type: ' . $content_type );
2007-02-15 17:19:06 +01:00
}
echo $vcalstr ;
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
2007-08-27 15:18:32 +02:00
default :
case 'PROPFIND' :
// tell the client we do NOT support full WebDAV/CalDAV
fail_exit ( 'Not Implemented' , 501 );
2007-02-15 17:19:06 +01:00
}
// // --- SOME UTILITY FUNCTIONS -------
/**
* Exit with an error message in html
* @ param $msg string
* message that gets return as html error description
*/
function fail_exit ( $msg , $errno = '403' )
{
// log the error in the http server error logging files
error_log ( 'resp: ' . $errno . ' ' . $msg );
// return http error $errno can this be done this way?
header ( 'HTTP/1.1 ' . $errno . ' ' . $msg );
# header('HTTP/1.1 403 ' . $msg);
2007-02-16 14:13:20 +01:00
ob_flush ();
flush ();
2007-02-15 17:19:06 +01:00
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
}
/*
* Log info and data to logfiles if logging is set
*
* @ param $msg string with loginfo
* @ param $data data to be logged
* @ param $icalmethod $string value can be import or export
* @ global $logdir string / boolean log directory . Set to false to disab logging
*/
function log_ical ( $msg , $icalmethod = " data " , $data )
{
global $logdir ;
if ( ! $logdir ) return ; // loggin seems off
// some info used for logging
$logstamp = date ( " U " );
$loguser = $_SERVER [ 'PHP_AUTH_USER' ];
$logdate = date ( " Ymd:His " );
// filename for log info, only used when logging is on
$fnloginfo = " $logdir /ical.log " ;
// log info
$fnlogdata = $logdir . " /ical. " . $icalmethod . '.' . $logstamp . " .ics " ;
$fp = fopen ( " $fnloginfo " , 'a+' );
fwrite ( $fp , " \n \n $loguser on $logdate : $msg , \n data in $fnlogdata " );
fclose ( $fp );
// log data
$fp = fopen ( " $fnlogdata " , " w " );
fputs ( $fp , $data );
fclose ( $fp );
}
?>