stuart: server/kolab-resource-handlers/kolab-resource-handlers/freebusy freebusy.php, 1.9, 1.10

cvs at intevation.de cvs at intevation.de
Thu Jul 15 22:26:05 CEST 2004


Author: stuart

Update of /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy
In directory doto:/tmp/cvs-serv10634

Modified Files:
	freebusy.php 
Log Message:
Support for the new event format, as well as some style fixups.

*** !!!THIS NEEDS TO BE TESTED W/ KONTACT!!! ***


Index: freebusy.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusy.php,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- freebusy.php	13 Jul 2004 07:31:44 -0000	1.9
+++ freebusy.php	15 Jul 2004 20:26:03 -0000	1.10
@@ -91,7 +91,7 @@
     trigger_error( $errortext, E_USER_WARNING );
 
     $err = array_pop($errors);
-    if ( $err == 'Permission denied' || $err == 'Invalid credentials' || $err == 'Login aborted' ) {
+    if ($err == 'Permission denied' || $err == 'Invalid credentials' || $err == 'Login aborted') {
         unauthorized($errortext);
     }
 
@@ -113,6 +113,103 @@
     notFound("LDAP Error $errno: $error");
 }
 
+// Date/Time value parsing, curtesy of the Horde iCalendar library
+function parseTime($text)
+{
+    // There must be a trailing 'Z' on a time
+    if (strlen($text) != 9) {
+        return false;
+    }
+
+    $time['hour']  = intval(substr($text, 0, 2));
+    $time['minute'] = intval(substr($text, 3, 2));
+    $time['second']  = intval(substr($text, 6, 2));
+    return $time;
+}
+
+function parseDate($text)
+{
+    if (strlen($text) != 10) {
+        return false;
+    }
+
+    $date['year']  = intval(substr($text, 0, 4));
+    $date['month'] = intval(substr($text, 5, 2));
+    $date['mday']  = intval(substr($text, 8, 2));
+
+    return $date;
+}
+
+function parseDateTime($text)
+{
+    $dateParts = split('T', $text);
+    if (count($dateParts) != 2 && !empty($text)) {
+        // Not a datetime field but may be just a date field.
+        if (!$date = parseDate($text)) {
+            return $date;
+        }
+        return @gmmktime(0, 0, 0, $date['month'], $date['mday'], $date['year']);
+    }
+
+    if (!$date = parseDate($dateParts[0])) {
+        return $date;
+    }
+    if (!$time = parseTime($dateParts[1])) {
+        return $time;
+    }
+
+    return @gmmktime($time['hour'], $time['minute'], $time['second'],
+                     $date['month'], $date['mday'], $date['year']);
+}
+
+function getEventHash($xml_text)
+{
+    $xmldoc = @domxml_open_mem($xml_text, DOMXML_LOAD_PARSING +
+        DOMXML_LOAD_COMPLETE_ATTRS + DOMXML_LOAD_SUBSTITUTE_ENTITIES +
+        DOMXML_LOAD_DONT_KEEP_BLANKS, $error);
+
+    if (!empty($error)) {
+        // There were errors parsing the XML data - abort
+        return false;
+    }
+
+    $noderoot = $xmldoc->document_element();
+    $childnodes = $noderoot->child_nodes();
+
+    $event_hash = array();
+
+    // Build the event hash
+    foreach ($childnodes as $value) {
+        $event_hash[$value->tagname] = $value->get_content();
+    }
+
+    // Perform some sanity checks on the event
+    if (
+        empty($event_hash['uid']) ||
+        empty($event_hash['start-date']) ||
+        empty($event_hash['end-date'])
+    ) {
+        return false;
+    }
+
+    // Make sure we're allowed to view this event
+    if (!empty($event_hash['sensitivity']) && $event_hash['sensitivity'] != 'public') {
+        return false;
+    }
+
+    // Set the summary if it's not present, so we don't get PHP warnings
+    // about accessing non-present keys
+    if (empty($event_hash['summary'])) {
+        $event_hash['summary'] = '';
+    }
+
+    // Convert our date-time values to timestamps
+    $event_hash['start-date'] = parseDateTime($event_hash['start-date']);
+    $event_hash['end-date'] = parseDateTime($event_hash['end-date']);
+
+    return $event_hash;
+}
+
 function &generateFreeBusy($startstamp = NULL, $endstamp = NULL)
 {
     global $params, $imap, $user, $messages, $extended;
@@ -155,14 +252,13 @@
     $vFb->setAttribute('DTEND', $endstamp);
     $vFb->setAttribute('URL', 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);
 
-    $eventICal= &new Horde_iCalendar();
     foreach ($messages as $msg) {
         // Fetch the message
         $textmsg = @imap_fetchheader($imap, $msg, FT_UID | FT_PREFETCHTEXT);
-	if( imap_last_error() == "Unexpected characters at end of address: <>") {
-	  // We have a message with an empty address from OL,
-	  // just ignore the error
-	  imap_errors();
+        if (imap_last_error() == "Unexpected characters at end of address: <>") {
+            // We have a message with an empty address from OL,
+            // just ignore the error
+            imap_errors();
         }
 
         $textmsg .= @imap_body($imap, $msg, FT_UID);
@@ -170,15 +266,14 @@
 
         $mimemsg = &MIME_Structure::parseTextMIMEMessage($textmsg);
 
-        // Get a text/calendar MIME part
+        // Read in a Kolab event object, if one exists
         $parts = $mimemsg->contentTypeMap();
         $event = false;
         foreach ($parts as $mimeid => $conttype) {
-            if ($conttype == 'text/calendar') {
+            if ($conttype == 'application/x-vnd.kolab.event') {
                 $part = $mimemsg->getPart($mimeid);
 
-                $eventICal->parsevCalendar($part->toString());
-                $event = $eventICal->findComponent('VEVENT');
+                $event = getEventHash($part->toString());
                 if ($event === false) {
                     continue;
                 }
@@ -189,14 +284,14 @@
             continue;
         }
 
-        $uid = $event->getAttributeDefault('UID', 0);
-	$summary = $event->getAttributeDefault('SUMMARY', 0);
+        $uid = $event['uid'];
+        $summary = $event['summary'];
 
-	trigger_error("Looking at message with uid=$uid and summary=$summary", E_USER_NOTICE);
+        trigger_error("Looking at message with uid=$uid and summary=$summary", E_USER_NOTICE);
 
         // Get the events initial start
-        $initial_start = $event->getAttributeDefault('DTSTART', 0);
-        $initial_end = $event->getAttributeDefault('DTEND', 0);
+        $initial_start = $event['start-date'];
+        $initial_end = $event['end-date'];
 
         // Don't bother adding the initial event if it's outside our free/busy window
         if ($initial_start < $startstamp || $initial_end > $endstamp) {
@@ -205,8 +300,10 @@
 
         if ($extended) {
             //error_log("adding event uid $uid");
-            $vFb->addBusyPeriod('BUSY', $initial_start, $initial_end, null, array('X-UID' => base64_encode($uid),
-										  'X-SUMMARY' => $summary ));
+            $vFb->addBusyPeriod('BUSY', $initial_start, $initial_end, null, array(
+                'X-UID'         => base64_encode($uid),
+                'X-SUMMARY'     => base64_encode($summary),
+            ));
         } else {
             $vFb->addBusyPeriod('BUSY', $initial_start, $initial_end);
         }
@@ -218,16 +315,16 @@
     return $vCal->exportvCalendar();
 }
 
-function store_freebusy( $fbdirname, $fbfilename ,$fbdata )
-{  
-  $tmpn = tempnam( $fbdirname,'fb' );
-  $tmpf = fopen( $tmpn, 'w' );
-  fwrite( $tmpf, $fbdata );
-  if( !is_dir( $fbdirname ) ) {
-    mkdir( $fbdirname );
-  }
-  rename( $tmpn, $fbfilename );
-  fclose( $tmpf );      
+function storeFreeBusy($fbdirname, $fbfilename ,$fbdata)
+{
+    $tmpn = tempnam($fbdirname, 'fb');
+    $tmpf = fopen($tmpn, 'w');
+    fwrite($tmpf, $fbdata);
+    if (!is_dir($fbdirname)) {
+        mkdir($fbdirname);
+    }
+    rename($tmpn, $fbfilename);
+    fclose($tmpf);
 }
 
 // ========================================================================== //
@@ -324,68 +421,71 @@
 $imapuser = $_SERVER['PHP_AUTH_USER'];
 $imappw = $_SERVER['PHP_AUTH_PW'];
 
-if( $_SERVER['REQUEST_METHOD'] == 'PUT' ) {
-  // We have a file upload, slurp up the data
-  $vfbupload = file_get_contents( 'php://input' );
+if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
+    // We have a file upload, slurp up the data
+    $vfbupload = file_get_contents('php://input');
 
-  trigger_error( "user=$user, $imapuser=$imapuser, method=PUT", E_USER_NOTICE );
+    trigger_error("PUT user=$user, imapuser=$imapuser", E_USER_NOTICE);
 
-  if( $imapuser == $user ) {
-    // Username OK, Apache should have taken care of authentication
-    store_freebusy( $fbdir, $fbfilename, $vfbupload );
-    exit;
-  } else {
-    unauthorized( "You're not allowed to store a freebusy file with that name"); 
-  }
+    if ($imapuser == $user) {
+        // Username OK, Apache should have taken care of authentication
+        storeFreeBusy($fbdir, $fbfilename, $vfbupload);
+        exit;
+    } else {
+        unauthorized("Unable to store uploaded free/busy file");
+    }
 }
 
-trigger_error( "user=$imapuser, mailbox=$fullmbox, fbfilename=$fbfilename", E_USER_NOTICE );
+trigger_error("user=$imapuser, mailbox=$fullmbox, fbfilename=$fbfilename", E_USER_NOTICE);
 
 $vfb = false;
-if( $_SERVER['REQUEST_METHOD'] != 'PUT' && ($imapuser || $extended) ) {
-  // Open an IMAP connection to the requested users' calendar
-  $imap = @imap_open($fullmbox, $imapuser, $imappw, OP_HALFOPEN );
-  if ( !$imap ) {
-    // Login error, check the cache
-  } else {
-    testIMAPError();
-    trigger_error( "Trying to reopen mailbox $fullmbox", E_USER_NOTICE);
-    @imap_reopen( $imap, $fullmbox );
-    if ( imap_last_error() ) {
-      // Login error, check the cache
-      trigger_error( "IMAP Error trying to open $fullmbox: ".imap_last_error(), E_USER_WARNING );
-    } else {    
-      // Enumerate our calendar events
-      $messages = @imap_sort($imap, SORTDATE, 0, SE_UID);
-      trigger_error("Got ".count($messages)." messages in calendar folder...", E_USER_NOTICE);
-      testIMAPError();
-      
-      // Generate the VFB file
-      $vfb = &generateFreeBusy();
-      $ts = mktime();
-      if( $vfb ) {
-	if( $extended ) {
-	  // Don't cache
-	} else {
-	  store_freebusy( $fbdir, $fbfilename, $vfb );
-	}
-      }
+if ($_SERVER['REQUEST_METHOD'] != 'PUT' && ($imapuser || $extended)) {
+    // Open an IMAP connection to the requested users' calendar
+    $imap = @imap_open($fullmbox, $imapuser, $imappw, OP_HALFOPEN );
+    if (!$imap) {
+        // Login error, check the cache
+    } else {
+        testIMAPError();
+        trigger_error("Trying to reopen mailbox $fullmbox", E_USER_NOTICE);
+        @imap_reopen($imap, $fullmbox);
+        if (imap_last_error()) {
+            // Login error, check the cache
+            testIMAPError();
+            //trigger_error("IMAP Error trying to open $fullmbox: " . imap_last_error(), E_USER_WARNING);
+        } else {
+            // Enumerate our calendar events
+            $messages = @imap_sort($imap, SORTDATE, 0, SE_UID);
+            trigger_error('Calendar folder contains ' . count($messages) . ' messages', E_USER_NOTICE);
+            testIMAPError();
+
+            // Generate the VFB file
+            $vfb = &generateFreeBusy();
+            $ts = mktime();
+            if ($vfb) {
+                if ($extended) {
+                    // Don't cache
+                } else {
+                    // Cache the generated free/busy file
+                    storeFreeBusy($fbdir, $fbfilename, $vfb);
+                }
+            }
+        }
     }
-  }
 }
 
-if( !$vfb ) {
-  if( !file_exists( $fbfilename ) && $imapuser == $user ) {
-    unauthorized("Failed to create freebusy list");
-    exit;
-  }
-  $vfb = file_get_contents( $fbfilename );
-  if( !$vfb && $extended ) {
-    # Check if we have a plain fb list
-    $vfb = file_get_contents( $fbdir.$user.'.ifb' );    
-  }
-  if( !$vfb ) notFound( "File not found on disk" );
-  $ts = filectime( $fbfilename );
+if (!$vfb) {
+    if (!file_exists($fbfilename) && $imapuser == $user) {
+        notFound("Unable to generate free/busy list");
+        exit;
+    }
+
+    $vfb = file_get_contents($fbfilename);
+    if (!$vfb && $extended) {
+        // Check if we have a plain fb list
+        $vfb = file_get_contents("$fbdir$user.ifb");
+    }
+    if (!$vfb) notFound("Unable to locate cached free/busy list");
+    $ts = filectime($fbfilename);
 }
 
 // And finally send it out, ensuring it doesn't get cached along the way





More information about the commits mailing list