123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- <?php
- /*
- * Copyright 2005 - 2016 Zarafa and its licensors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- ?>
- <?php
- include_once('class.recurrence.php');
- class FreeBusyPublish {
- var $session;
- var $calendar;
- var $entryid;
- var $starttime;
- var $length;
- var $store;
- var $proptags;
- /**
- * @param mapi_session $session MAPI Session
- * @param mapi_folder $calendar Calendar to publish
- * @param string $entryid AddressBook Entry ID for the user we're publishing for
- */
-
-
- function __construct($session, $store, $calendar, $entryid)
- {
- $properties["entryid"] = PR_ENTRYID;
- $properties["parent_entryid"] = PR_PARENT_ENTRYID;
- $properties["message_class"] = PR_MESSAGE_CLASS;
- $properties["icon_index"] = PR_ICON_INDEX;
- $properties["subject"] = PR_SUBJECT;
- $properties["display_to"] = PR_DISPLAY_TO;
- $properties["importance"] = PR_IMPORTANCE;
- $properties["sensitivity"] = PR_SENSITIVITY;
- $properties["startdate"] = "PT_SYSTIME:PSETID_Appointment:0x820d";
- $properties["duedate"] = "PT_SYSTIME:PSETID_Appointment:0x820e";
- $properties["recurring"] = "PT_BOOLEAN:PSETID_Appointment:0x8223";
- $properties["recurring_data"] = "PT_BINARY:PSETID_Appointment:0x8216";
- $properties["busystatus"] = "PT_LONG:PSETID_Appointment:0x8205";
- $properties["label"] = "PT_LONG:PSETID_Appointment:0x8214";
- $properties["alldayevent"] = "PT_BOOLEAN:PSETID_Appointment:0x8215";
- $properties["private"] = "PT_BOOLEAN:PSETID_Common:0x8506";
- $properties["meeting"] = "PT_LONG:PSETID_Appointment:0x8217";
- $properties["startdate_recurring"] = "PT_SYSTIME:PSETID_Appointment:0x8235";
- $properties["enddate_recurring"] = "PT_SYSTIME:PSETID_Appointment:0x8236";
- $properties["location"] = "PT_STRING8:PSETID_Appointment:0x8208";
- $properties["duration"] = "PT_LONG:PSETID_Appointment:0x8213";
- $properties["responsestatus"] = "PT_LONG:PSETID_Appointment:0x8218";
- $properties["reminder"] = "PT_BOOLEAN:PSETID_Common:0x8503";
- $properties["reminder_minutes"] = "PT_LONG:PSETID_Common:0x8501";
- $properties["contacts"] = "PT_MV_STRING8:PSETID_Common:0x853a";
- $properties["contacts_string"] = "PT_STRING8:PSETID_Common:0x8586";
- $properties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords";
- $properties["reminder_time"] = "PT_SYSTIME:PSETID_Common:0x8502";
- $properties["commonstart"] = "PT_SYSTIME:PSETID_Common:0x8516";
- $properties["commonend"] = "PT_SYSTIME:PSETID_Common:0x8517";
- $properties["basedate"] = "PT_SYSTIME:PSETID_Appointment:0x8228";
- $properties["timezone_data"] = "PT_BINARY:PSETID_Appointment:0x8233";
- $this->proptags = getPropIdsFromStrings($store, $properties);
- $this->session = $session;
- $this->calendar = $calendar;
- $this->entryid = $entryid;
- $this->store = $store;
- }
- /**
- * 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(
- // OR
- // (item[start] >= start && item[start] <= end)
- 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
- )
- )
- )
- ),
- // OR
- // (item[end] >= start && item[end] <= 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
- )
- )
- )
- ),
- // OR
- // (item[start] < start && item[end] > 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
- )
- )
- )
- ),
- // OR
- Array(RES_OR,
- Array(
- // OR
- // (EXIST(ecurrence_enddate_property) && item[isRecurring] == true && item[end] >= start)
- 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
- )
- )
- )
- ),
- // OR
- // (!EXIST(ecurrence_enddate_property) && item[isRecurring] == true && item[start] <= end)
- 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
- )
- )
- )
- )
- )
- ) // EXISTS OR
- )
- ); // 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
- $fbsupport = false;
- try {
- $fbsupport = mapi_freebusysupport_open($this->session, $this->store);
- } catch (MAPIException $e) {
- if ($e->getCode() == MAPI_E_NOT_FOUND)
- $e->setHandled();
- }
- // Open updater for this user
- if ($fbsupport !== false) {
- $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);
- }
- }
- /**
- * Sorts by timestamp, if equal, then end before start
- */
- function cmp($a, $b)
- {
- if ($a["time"] == $b["time"]) {
- if($a["type"] < $b["type"])
- return 1;
- if($a["type"] > $b["type"])
- return -1;
- return 0;
- }
- return ($a["time"] > $b["time"] ? 1 : -1);
- }
- /**
- * Function mergeItems
- * @author Steve Hardy
- */
- function mergeItemsFB($items)
- {
- $merged = Array();
- $timestamps = Array();
- $csubj = Array();
- $cbusy = Array();
- $level = 0;
- $laststart = null;
- foreach($items as $item)
- {
- $ts["type"] = 0;
- $ts["time"] = $item[$this->proptags["startdate"]];
- $ts["subject"] = $item[PR_SUBJECT];
- $ts["status"] = $item[$this->proptags["busystatus"]];
- $timestamps[] = $ts;
- $ts["type"] = 1;
- $ts["time"] = $item[$this->proptags["duedate"]];
- $ts["subject"] = $item[PR_SUBJECT];
- $ts["status"] = $item[$this->proptags["busystatus"]];
- $timestamps[] = $ts;
- }
- usort($timestamps, Array($this, "cmp"));
- foreach($timestamps as $ts)
- {
- switch ($ts["type"])
- {
- case 0: // Start
- if ($level != 0 && $laststart != $ts["time"])
- {
- $newitem["start"] = $laststart;
- $newitem["end"] = $ts["time"];
- $newitem["subject"] = join(",", $csubj);
- $newitem["status"] = !empty($cbusy) ? max($cbusy) : 0;
- if ($newitem["status"] > 0)
- $merged[] = $newitem;
- }
- $level++;
- $csubj[] = $ts["subject"];
- $cbusy[] = $ts["status"];
- $laststart = $ts["time"];
- break;
- case 1: // End
- if ($laststart != $ts["time"])
- {
- $newitem["start"] = $laststart;
- $newitem["end"] = $ts["time"];
- $newitem["subject"] = join(",", $csubj);
- $newitem["status"] = !empty($cbusy) ? max($cbusy) : 0;
- if ($newitem["status"] > 0)
- $merged[] = $newitem;
- }
- $level--;
- array_splice($csubj, array_search($ts["subject"], $csubj, 1), 1);
- array_splice($cbusy, array_search($ts["status"], $cbusy, 1), 1);
- $laststart = $ts["time"];
- break;
- }
- }
- return $merged;
- }
- }
- ?>
|