From a5a0a790c97e9a00aa514072110a6f581a54c991 Mon Sep 17 00:00:00 2001 From: Jo Rhett Date: Thu, 2 Nov 2006 08:36:44 +0000 Subject: Updated combined publish.php --- calendars/publish.php | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 calendars/publish.php (limited to 'calendars') diff --git a/calendars/publish.php b/calendars/publish.php new file mode 100644 index 0000000..be0a19c --- /dev/null +++ b/calendars/publish.php @@ -0,0 +1,264 @@ + +RewriteEngine on +RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] + + +Usage (Apple iCal): +1. Open iCal, select a calendar for publishing +2. Select "Publish" from the "Calendar" menu +3. Configure to your liking, and set the URL to (eg): http://example.com/path/to/publish.php +4. Click the "Publish" button +5. Some PHP versions require a '?' at the end of the URL (eg): http://localhost/~dietricha/calendar/calendars/publish.php? + +Usage (Sunbird Calendar): +1. Create a new calendar in Sunbird + Type Remote + Location http://example.com/path/to/publish.php/calendarname.ics + calendarname.ics should be a unique filename and must end with .ics + Username: either your web server username, or auth_internal_username + Password: either your web server password, or auth_internal_password + +Hints: +1. PHP 4.3.0 or greater is required +2. Your version of php and apache MUST support $_SERVER['PATH_INFO'] +3. Depending on your web server environment, you may need to set safe_mode = Off + (this won't be necessary if you are using a wrapper like cgiwrap or suexec) + +Troubleshooting: +You can turn on logging by setting the PHPICALENDAR_LOG_PUBLISHING constant to 1 below. +This will write out a log file to the same directory as this script. +Don't forget to turn off logging when done!! +*/ + +// include PHP iCalendar configuration variables +include('../config.inc.php'); + +// set calendar path, or just use current directory...make sure there's a trailing slash +if (isset($calendar_path) && $calendar_path != '') { + if (substr($calendar_path, -1, 1) !='/') $calendar_path = $calendar_path.'/'; +} else { + $calendar_path = ''; +} +// allow/disallow publishing + +$phpicalendar_publishing = isset($phpicalendar_publishing) ? $phpicalendar_publishing : 0; +define( 'PHPICALENDAR_PUBLISHING', $phpicalendar_publishing ); + +// toggle logging +define( 'PHPICALENDAR_LOG_PUBLISHING', 1 ); +if(defined('PHPICALENDAR_LOG_PUBLISHING') && PHPICALENDAR_LOG_PUBLISHING == 1) { + if( ! $logfile = fopen('publish_log.txt','a+') ) { + header('HTTP/1.1 401 Unauthorized'); + header('WWW-Authenticate: Basic realm="ERROR: Unable to open log file"'); + echo 'Unable to open log file.'; + exit; + } +} + +// Require authentication +if (!isset($_SERVER['REMOTE_USER'])) { + + // Require authentication + if (!isset($_SERVER['HTTP_AUTHORIZATION'])) { + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) + = explode( ':', base64_decode( substr($_SERVER['HTTP_AUTHORIZATION'], 6) ) ); + } + + if (!isset($_SERVER['PHP_AUTH_USER'])) { + header('WWW-Authenticate: Basic realm="phpICalendar"'); + header('HTTP/1.1 401 Unauthorized'); + echo 'You must be authorized!'; + exit; + } else { + if ($_SERVER['PHP_AUTH_USER'] != $auth_internal_username || $_SERVER['PHP_AUTH_PW'] != $auth_internal_password) { + header('WWW-Authenticate: Basic realm="phpICalendar"'); + header('HTTP/1.1 401 Unauthorized'); + echo 'You must be authorized!'; + exit; + } + } +} + +// only allow publishing if explicitly enabled +if(PHPICALENDAR_PUBLISHING != 1) { + header('WWW-Authenticate: Basic realm="ERROR: Calendar Publishing is disabled on this server"'); + header('HTTP/1.1 401 Unauthorized'); + echo 'You must be authorized!'; + exit; +} + +// unpublishing +if($_SERVER['REQUEST_METHOD'] == 'DELETE') { + // get calendar filename + $calendar_file = $calendar_path.substr($_SERVER['REQUEST_URI'] , ( strrpos($_SERVER['REQUEST_URI'], '/') + 1) ) ; + + $calendar_file = urldecode($calendar_file); + + logmsg('received request to delete '.$calendar_file); + + // remove calendar file + if(!unlink($calendar_file)) + { + logmsg('unable to delete the calendar file'); + } + else + { + logmsg('deleted'); + } + return; +} + +// publishing +elseif($_SERVER['REQUEST_METHOD'] == 'PUT'){ + logmsg('PUT request'); + + // get calendar data + if($datain = fopen('php://input','r')){ + while(!@feof($datain)){ + $data .= fgets($datain,4096); + } + + @fclose($datain); + }else{ + logmsg('unable to read input data'); + } + + if(isset($data)){ + if (isset($_SERVER['PATH_INFO'])) { + preg_match("/\/([\w\-\.\+ ]*).ics/i",$_SERVER['PATH_INFO'],$matches); + $calendar_name = urldecode($matches[1]); + } + + // If we don't have it from path info, use the supplied calendar name + if( ! isset($calendar_name) ) { + + $cal_arr = explode("\n",$data); + + foreach($cal_arr as $k => $v){ + if(strstr($v,'X-WR-CALNAME:')){ + $arr = explode(':',$v); + $calendar_name = trim($arr[1]); + break; + } + } + } + + logmsg('Received request to update: ' . $calendar_name); + + // Remove any invalid characters from the filename + $calendar_name = preg_replace( "/[^\w\.\- ]/", '', $calendar_name ); + + if( ( ! isset($calendar_name) ) || ( $calendar_name == '' ) ) { + header('HTTP/1.1 401 Invalid calendar name'); + header('WWW-Authenticate: Basic realm="ERROR: Invalid calendar name."'); + echo 'Invalid calendar name.'; + } + + // If we don't have a name, assume default + $calendar_name = isset($calendar_name) ? $calendar_name : 'default'; + + logmsg('Updating calendar: ' . $calendar_name); + + // If this is Apple iCal, an event with a blank summary is private - mark as such + if( preg_match( "/Apple.*iCal/", $_SERVER['HTTP_USER_AGENT'] ) ) { + $data = preg_replace( + "/^\s*SUMMARY:\s*$/m", + "SUMMARY: **PRIVATE**\nCLASS:PRIVATE", + $data + ); + } + + // write to file + if($dataout = fopen($calendar_path.$calendar_name.'.ics','w+')){ + fputs($dataout, $data, strlen($data) ); + @fclose($dataout); + }else{ + logmsg( 'could not open file '.$calendar_path.$calendar_name.'.ics' ); + } + } + else { + logmsg('PUT ERROR - No data supplied.'); + } +} +elseif ($_SERVER['REQUEST_METHOD'] == 'GET') { + if (isset($_SERVER['PATH_INFO'])) { + preg_match("/\/([ A-Za-z0-9._]*).ics/i",$_SERVER['PATH_INFO'],$matches); + $icsfile = urldecode($matches[1]); + + // get calendar data + if (file_exists($calendar_path . $icsfile . '.ics') && + is_readable($calendar_path . $icsfile . '.ics') && + is_file($calendar_path . $icsfile . '.ics') + ) { + echo file_get_contents($calendar_path . $icsfile . '.ics'); + logmsg('downloaded calendar ' . $icsfile); + } + } +} + +if(defined('PHPICALENDAR_LOG_PUBLISHING') && PHPICALENDAR_LOG_PUBLISHING == 1) { + fclose($logfile); +} + +header('HTTP/1.1 204 Successful.'); +exit; + + +// for logging +function logmsg($str){ + global $logfile; + + if(defined('PHPICALENDAR_LOG_PUBLISHING') && PHPICALENDAR_LOG_PUBLISHING == 1) { + if( $_SERVER['PHP_AUTH_USER'] ) + $user = $_SERVER['PHP_AUTH_USER']; + else + $user = $_SERVER['REMOTE_USER']; + + $logline = date('Y-m-d H:i:s ') . $_SERVER['REMOTE_ADDR'] . ' ' . $user . ' ' . ${str} . "\n"; + + fputs($logfile, $logline, strlen($logline) ); + } +} +?> -- cgit v1.2.3