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; }
/** * 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; }