/**
  * Publishes the infomation
  * @paam timestamp $starttime Time from which to publish data  (usually now)
  * @paam integer $length Amount of seconds from $starttime we should publish
  */
 function publishFB($starttime, $length)
 {
     $start = $starttime;
     $end = $starttime + $length;
     // Get all the items in the calendar that we need
     $calendaritems = array();
     $restrict = array(RES_OR, array(array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["startdate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["startdate"], VALUE => $end)))), array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["duedate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["duedate"], VALUE => $end)))), array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_LT, ULPROPTAG => $this->proptags["startdate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_GT, ULPROPTAG => $this->proptags["duedate"], VALUE => $end)))), array(RES_OR, array(array(RES_AND, array(array(RES_EXIST, array(ULPROPTAG => $this->proptags["enddate_recurring"])), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->proptags["recurring"], VALUE => true)), array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["enddate_recurring"], VALUE => $start)))), array(RES_AND, array(array(RES_NOT, array(array(RES_EXIST, array(ULPROPTAG => $this->proptags["enddate_recurring"])))), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["startdate"], VALUE => $end)), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->proptags["recurring"], VALUE => true))))))));
     // global OR
     $contents = mapi_folder_getcontentstable($this->calendar);
     mapi_table_restrict($contents, $restrict);
     while (1) {
         $rows = mapi_table_queryrows($contents, array_values($this->proptags), 0, 50);
         if (!is_array($rows)) {
             break;
         }
         if (empty($rows)) {
             break;
         }
         foreach ($rows as $row) {
             $occurrences = array();
             if (isset($row[$this->proptags['recurring']]) && $row[$this->proptags['recurring']]) {
                 $recur = new Recurrence($this->store, $row);
                 $occurrences = $recur->getItems($starttime, $starttime + $length);
             } else {
                 $occurrences[] = $row;
             }
             $calendaritems = array_merge($calendaritems, $occurrences);
         }
     }
     // $calendaritems now contains all the calendar items in the specified time
     // frame. We now need to merge these into a flat array of begin/end/status
     // objects. This also filters out all the 'free' items (status 0)
     $freebusy = $this->mergeItemsFB($calendaritems);
     // $freebusy now contains the start, end and status of all items, merged.
     // Get the FB interface
     try {
         $fbsupport = mapi_freebusysupport_open($this->session, $this->store);
     } catch (MAPIException $e) {
         if ($e->getCode() == MAPI_E_NOT_FOUND) {
             $e->setHandled();
             if (function_exists("dump")) {
                 dump("Error in opening freebusysupport object.");
             }
         }
     }
     // Open updater for this user
     if (isset($fbsupport) && $fbsupport) {
         $updaters = mapi_freebusysupport_loadupdate($fbsupport, array($this->entryid));
         $updater = $updaters[0];
         // Send the data
         mapi_freebusyupdate_reset($updater);
         mapi_freebusyupdate_publish($updater, $freebusy);
         mapi_freebusyupdate_savechanges($updater, $start - 24 * 60 * 60, $end);
         // We're finished
         mapi_freebusysupport_close($fbsupport);
     } else {
         ZLog::Write(LOGLEVEL_WARN, "FreeBusyPublish is not available");
     }
 }
예제 #2
0
 function readFBfromGAL($emailaddress, $starttime, $endtime)
 {
     $rows = $this->readResolveRecipientfromGAL($emailaddress);
     $fbsupport = mapi_freebusysupport_open($this->_session);
     foreach ($rows as $entry) {
         $fbDataArray = mapi_freebusysupport_loaddata($fbsupport, array($entry[PR_ENTRYID]));
         $res['displayname'] = $entry[PR_DISPLAY_NAME];
         $res['emailaddress'] = $entry[PR_SMTP_ADDRESS];
         $res['type'] = 1;
         $res['entries'] = array();
         if ($fbDataArray[0] != NULL) {
             foreach ($fbDataArray as $fbDataUser) {
                 $rangeuser1 = mapi_freebusydata_getpublishrange($fbDataUser);
                 if ($rangeuser1 == NULL) {
                     return $result;
                 }
                 $enumblock = mapi_freebusydata_enumblocks($fbDataUser, $starttime, $endtime);
                 mapi_freebusyenumblock_reset($enumblock);
                 while (true) {
                     $blocks = mapi_freebusyenumblock_next($enumblock, 100);
                     if (!$blocks) {
                         break;
                     }
                     foreach ($blocks as $blockItem) {
                         if ($blockItem['start'] < $starttime) {
                             $blockItem['start'] = $starttime;
                         }
                         if ($blockItem['end'] > $endtime) {
                             $blockItem['end'] = $endtime;
                         }
                         $res['entries'][] = $blockItem;
                     }
                 }
             }
         }
         $result[$emailaddress][] = $res;
     }
     mapi_freebusysupport_close($fbsupport);
     return $result;
 }
 function getFreeBusyInfo($entryID, $start, $end)
 {
     $result = array();
     $fbsupport = mapi_freebusysupport_open($this->session);
     if (mapi_last_hresult() != NOERROR) {
         if (function_exists("dump")) {
             dump("Error in opening freebusysupport object.");
         }
         return $result;
     }
     $fbDataArray = mapi_freebusysupport_loaddata($fbsupport, array($entryID));
     if ($fbDataArray[0] != NULL) {
         foreach ($fbDataArray as $fbDataUser) {
             $rangeuser1 = mapi_freebusydata_getpublishrange($fbDataUser);
             if ($rangeuser1 == NULL) {
                 return $result;
             }
             $enumblock = mapi_freebusydata_enumblocks($fbDataUser, $start, $end);
             mapi_freebusyenumblock_reset($enumblock);
             while (true) {
                 $blocks = mapi_freebusyenumblock_next($enumblock, 100);
                 if (!$blocks) {
                     break;
                 }
                 foreach ($blocks as $blockItem) {
                     $result[] = $blockItem;
                 }
             }
         }
     }
     mapi_freebusysupport_close($fbsupport);
     return $result;
 }
예제 #4
0
 /**
  * Gets the availability of a user for the given time window.
  *
  * @param string $to
  * @param SyncResolveRecipient $resolveRecipient
  * @param SyncResolveRecipientsOptions $resolveRecipientsOptions
  *
  * @access private
  * @return SyncResolveRecipientsAvailability
  */
 private function getAvailability($to, $resolveRecipient, $resolveRecipientsOptions)
 {
     $availability = new SyncResolveRecipientsAvailability();
     $availability->status = SYNC_RESOLVERECIPSSTATUS_AVAILABILITY_SUCCESS;
     if (!isset($resolveRecipient->id)) {
         // TODO this shouldn't happen but try to get the recipient in such a case
     }
     $fbsupport = mapi_freebusysupport_open($this->session);
     if (mapi_last_hresult()) {
         ZLog::Write(LOGLEVEL_WARN, sprintf("Unable to open free busy support (0x%08X)", mapi_last_hresult()));
         $availability->status = SYNC_RESOLVERECIPSSTATUS_AVAILABILITY_FAILED;
         return $availability;
     }
     $fbDataArray = mapi_freebusysupport_loaddata($fbsupport, array($resolveRecipient->id));
     $start = strtotime($resolveRecipientsOptions->availability->starttime);
     $end = strtotime($resolveRecipientsOptions->availability->endtime);
     // Each digit in the MergedFreeBusy indicates the free/busy status for the user for every 30 minute interval.
     $timeslots = intval(ceil(($end - $start) / self::HALFHOURSECONDS));
     if ($timeslots > self::MAXFREEBUSYSLOTS) {
         throw new StatusException("KopanoBackend->getAvailability(): the requested free busy range is too large.", SYNC_RESOLVERECIPSSTATUS_PROTOCOLERROR);
     }
     $mergedFreeBusy = str_pad(fbNoData, $timeslots, fbNoData);
     if (is_array($fbDataArray) && !empty($fbDataArray)) {
         foreach ($fbDataArray as $fbDataUser) {
             if ($fbDataUser == null) {
                 ZLog::Write(LOGLEVEL_INFO, sprintf("KopanoBackend->getAvailability(): freebusy user is null for '%s'. Unable to retrieve his availability.", $resolveRecipient->displayname));
                 continue;
             }
             $rangeuser = mapi_freebusydata_getpublishrange($fbDataUser);
             if ($rangeuser == null) {
                 ZLog::Write(LOGLEVEL_INFO, sprintf("KopanoBackend->getAvailability(): Unable to retrieve mapi_freebusydata_getpublishrange (0x%X) for '%s'", mapi_last_hresult(), $resolveRecipient->displayname));
                 $availability->status = SYNC_RESOLVERECIPSSTATUS_AVAILABILITY_FAILED;
                 return $availability;
             }
             // if free busy information is available for the whole requested period,
             // assume that the user is free for the requested range.
             if ($rangeuser['start'] <= $start && $rangeuser['end'] >= $end) {
                 $mergedFreeBusy = str_pad(fbFree, $timeslots, fbFree);
             } elseif ($rangeuser['end'] <= $start || $rangeuser['start'] >= $end) {
                 $mergedFreeBusy = str_pad(fbNoData, $timeslots, fbNoData);
             } elseif ($rangeuser['start'] > $start && $rangeuser['end'] >= $end) {
                 $missingSlots = intval(ceil(($rangeuser['start'] - $start) / self::HALFHOURSECONDS));
                 $mergedFreeBusy = str_pad(fbNoData, $missingSlots, fbNoData) . str_pad(fbFree, $timeslots - $missingSlots, fbFree);
             } elseif ($rangeuser['start'] <= $start && $rangeuser['end'] < $end) {
                 $missingSlots = intval(ceil(($rangeuser['end'] - $end) / self::HALFHOURSECONDS));
                 $mergedFreeBusy = str_pad(fbFree, $timeslots - $missingSlots, fbFree) . str_pad(fbNoData, $missingSlots, fbNoData);
             } else {
                 $missingBeginSlots = intval(ceil(($rangeuser['start'] - $start) / self::HALFHOURSECONDS));
                 $missingEndSlots = intval(ceil(($rangeuser['end'] - $end) / self::HALFHOURSECONDS));
                 $mergedFreeBusy = str_pad(fbNoData, $missingBeginSlots, fbNoData) . str_pad(fbFree, $timeslots - $missingBeginSlots - $missingEndSlots, fbFree) . str_pad(fbNoData, $missingEndSlots, fbNoData);
             }
             $enumblock = mapi_freebusydata_enumblocks($fbDataUser, $start, $end);
             mapi_freebusyenumblock_reset($enumblock);
             while (true) {
                 $blocks = mapi_freebusyenumblock_next($enumblock, self::FREEBUSYENUMBLOCKS);
                 if (!$blocks) {
                     break;
                 }
                 foreach ($blocks as $blockItem) {
                     // calculate which timeslot of mergedFreeBusy should be replaced.
                     $blockDuration = ($blockItem['end'] - $blockItem['start']) / self::HALFHOURSECONDS;
                     $startSlot = intval(floor(($blockItem['start'] - $start) / self::HALFHOURSECONDS));
                     $endSlot = intval(floor(($blockItem['end'] - $start) / self::HALFHOURSECONDS));
                     // check if the end slot is the exact begin of the next slot from request; in such case it's necessary to reduce the endslot.
                     if ($start + $endSlot * self::HALFHOURSECONDS == $blockItem['end'] && $endSlot > $startSlot) {
                         $endSlot--;
                     }
                     for ($i = $startSlot; $i <= $endSlot; $i++) {
                         // only set the new slot's free busy status if it's higher than the current one
                         if ($blockItem['status'] > $mergedFreeBusy[$i]) {
                             $mergedFreeBusy[$i] = $blockItem['status'];
                         }
                     }
                 }
             }
         }
     }
     mapi_freebusysupport_close($fbsupport);
     $availability->mergedfreebusy = $mergedFreeBusy;
     return $availability;
 }