function foldersize($store, $entryid) { $size = 0; $folder = mapi_msgstore_openentry($store, $entryid); if (!$folder) { print "Unable to open folder."; return false; } $table = mapi_folder_getcontentstable($folder); if (!$table) { print "Unable to open table."; return false; } while (1) { $rows = mapi_table_queryrows($table, array(PR_MESSAGE_SIZE), 0, 100); if (count($rows) == 0) { break; } foreach ($rows as $row) { if (isset($row[PR_MESSAGE_SIZE])) { $size += $row[PR_MESSAGE_SIZE]; } } } return $size; }
function getFullRecurrenceBlob() { $message = mapi_msgstore_openentry($this->store, $this->messageprops[PR_ENTRYID]); $recurrBlob = ''; $stream = mapi_openproperty($message, $this->proptags["recurring_data"], IID_IStream, 0, 0); $stat = mapi_stream_stat($stream); for ($i = 0; $i < $stat['cb']; $i += 1024) { $recurrBlob .= mapi_stream_read($stream, 1024); } if (!empty($recurrBlob)) { $this->messageprops[$this->proptags["recurring_data"]] = $recurrBlob; } }
function renamefolder($store, $entryid, $name) { if (!$entryid) { print "Unable to find {$name} folder\n"; return; } $folder = mapi_msgstore_openentry($store, $entryid); if (!$folder) { print "Unable to open folder " . bin2hex($entryid) . "\n"; return; } mapi_setprops($folder, array(PR_DISPLAY_NAME => $name)); if (mapi_last_hresult() != 0) { print "Unable to rename " . bin2hex($entryid) . " to '{$name}'\n"; } else { print "Renamed " . bin2hex($entryid) . " to '{$name}'\n"; } }
function SetSecurity($store, $entryid, $acls) { if ($entryid == "") { $object = $store; } else { $object = mapi_msgstore_openentry($store, $entryid); } if (!$object) { print "Unable to open folder\n"; return; } $ret = mapi_zarafa_setpermissionrules($object, $acls); if ($ret == false) { print "Unable to set permissions\n"; } else { print "Permissions successfully set\n"; } }
/** * Publishing the FreeBusy information of the default calendar. The * folderentryid argument is used to check if the default calendar * should be updated or not. * * @param $store MAPIobject Store object of the store that needs publishing * @param $folderentryid binary entryid of the folder that needs to be updated. */ function publishFreeBusy($store, $l_rSession, $folderentryid = false) { // Publish updated free/busy information // First get default calendar from the root folder $rootFolder = mapi_msgstore_openentry($store, null); $rootFolderProps = mapi_getprops($rootFolder, array(PR_IPM_APPOINTMENT_ENTRYID)); // If no folderentryid supplied or if the supplied entryid matches the default calendar. if (!$folderentryid || $rootFolderProps[PR_IPM_APPOINTMENT_ENTRYID] == $folderentryid) { // Get the calendar and owner entryID $calendar = mapi_msgstore_openentry($store, $rootFolderProps[PR_IPM_APPOINTMENT_ENTRYID]); $storeProps = mapi_msgstore_getprops($store, array(PR_MAILBOX_OWNER_ENTRYID)); if (isset($storeProps[PR_MAILBOX_OWNER_ENTRYID])) { // Lets share! $pub = new FreeBusyPublish($l_rSession, $store, $calendar, $storeProps[PR_MAILBOX_OWNER_ENTRYID]); $pub->publishFB(time() - 7 * 24 * 60 * 60, 6 * 30 * 24 * 60 * 60); // publish from one week ago, 6 months ahead } } }
/** * Imports a change on a folder * * @param object $folder SyncFolder * * @access public * @return string id of the folder * @throws StatusException */ public function ImportFolderChange($folder) { $id = isset($folder->serverid) ? $folder->serverid : false; $parent = $folder->parentid; $displayname = u2wi($folder->displayname); $type = $folder->type; if (Utils::IsSystemFolder($type)) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, system folder can not be created/modified", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname), SYNC_FSSTATUS_SYSTEMFOLDER); } // create a new folder if $id is not set if (!$id) { // the root folder is "0" - get IPM_SUBTREE if ($parent == "0") { $parentprops = mapi_getprops($this->store, array(PR_IPM_SUBTREE_ENTRYID)); if (isset($parentprops[PR_IPM_SUBTREE_ENTRYID])) { $parentfentryid = $parentprops[PR_IPM_SUBTREE_ENTRYID]; } } else { $parentfentryid = mapi_msgstore_entryidfromsourcekey($this->store, hex2bin($parent)); } if (!$parentfentryid) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open parent folder (no entry id)", Utils::PrintAsString(false), $folder->parentid, $displayname), SYNC_FSSTATUS_PARENTNOTFOUND); } $parentfolder = mapi_msgstore_openentry($this->store, $parentfentryid); if (!$parentfolder) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open parent folder (open entry)", Utils::PrintAsString(false), $folder->parentid, $displayname), SYNC_FSSTATUS_PARENTNOTFOUND); } // mapi_folder_createfolder() fails if a folder with this name already exists -> MAPI_E_COLLISION $newfolder = mapi_folder_createfolder($parentfolder, $displayname, ""); if (mapi_last_hresult()) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, mapi_folder_createfolder() failed: 0x%X", Utils::PrintAsString(false), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_FOLDEREXISTS); } mapi_setprops($newfolder, array(PR_CONTAINER_CLASS => MAPIUtils::GetContainerClassFromFolderType($type))); $props = mapi_getprops($newfolder, array(PR_SOURCE_KEY)); if (isset($props[PR_SOURCE_KEY])) { $sourcekey = bin2hex($props[PR_SOURCE_KEY]); ZLog::Write(LOGLEVEL_DEBUG, sprintf("Created folder '%s' with id: '%s'", $displayname, $sourcekey)); return $sourcekey; } else { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, folder created but PR_SOURCE_KEY not available: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } return false; } // open folder for update $entryid = mapi_msgstore_entryidfromsourcekey($this->store, hex2bin($id)); if (!$entryid) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open folder (no entry id): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_PARENTNOTFOUND); } // check if this is a MAPI default folder if ($this->mapiprovider->IsMAPIDefaultFolder($entryid)) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, MAPI default folder can not be created/modified", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname), SYNC_FSSTATUS_SYSTEMFOLDER); } $mfolder = mapi_msgstore_openentry($this->store, $entryid); if (!$mfolder) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open folder (open entry): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_PARENTNOTFOUND); } $props = mapi_getprops($mfolder, array(PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY, PR_DISPLAY_NAME, PR_CONTAINER_CLASS)); if (!isset($props[PR_SOURCE_KEY]) || !isset($props[PR_PARENT_SOURCE_KEY]) || !isset($props[PR_DISPLAY_NAME]) || !isset($props[PR_CONTAINER_CLASS])) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, folder data not available: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } // get the real parent source key from mapi if ($parent == "0") { $parentprops = mapi_getprops($this->store, array(PR_IPM_SUBTREE_ENTRYID)); $parentfentryid = $parentprops[PR_IPM_SUBTREE_ENTRYID]; $mapifolder = mapi_msgstore_openentry($this->store, $parentfentryid); $rootfolderprops = mapi_getprops($mapifolder, array(PR_SOURCE_KEY)); $parent = bin2hex($rootfolderprops[PR_SOURCE_KEY]); ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->ImportFolderChange(): resolved AS parent '0' to sourcekey '%s'", $parent)); } // a changed parent id means that the folder should be moved if (bin2hex($props[PR_PARENT_SOURCE_KEY]) !== $parent) { $sourceparentfentryid = mapi_msgstore_entryidfromsourcekey($this->store, $props[PR_PARENT_SOURCE_KEY]); if (!$sourceparentfentryid) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open parent source folder (no entry id): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_PARENTNOTFOUND); } $sourceparentfolder = mapi_msgstore_openentry($this->store, $sourceparentfentryid); if (!$sourceparentfolder) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open parent source folder (open entry): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_PARENTNOTFOUND); } $destparentfentryid = mapi_msgstore_entryidfromsourcekey($this->store, hex2bin($parent)); if (!$sourceparentfentryid) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open destination folder (no entry id): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } $destfolder = mapi_msgstore_openentry($this->store, $destparentfentryid); if (!$destfolder) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open destination folder (open entry): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } // mapi_folder_copyfolder() fails if a folder with this name already exists -> MAPI_E_COLLISION if (!mapi_folder_copyfolder($sourceparentfolder, $entryid, $destfolder, $displayname, FOLDER_MOVE)) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to move folder: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_FOLDEREXISTS); } $folderProps = mapi_getprops($mfolder, array(PR_SOURCE_KEY)); return $folderProps[PR_SOURCE_KEY]; } // update the display name $props = array(PR_DISPLAY_NAME => $displayname); mapi_setprops($mfolder, $props); mapi_savechanges($mfolder); if (mapi_last_hresult()) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, mapi_savechanges() failed: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } ZLog::Write(LOGLEVEL_DEBUG, "Imported changes for folder: {$id}"); return $id; }
/** * Imports a single message * * @param array $props * @param long $flags * @param object $retmapimessage * * @access public * @return long */ public function ImportMessageChange($props, $flags, &$retmapimessage) { $sourcekey = $props[PR_SOURCE_KEY]; $parentsourcekey = $props[PR_PARENT_SOURCE_KEY]; $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $parentsourcekey, $sourcekey); if (!$entryid) { return SYNC_E_IGNORE; } $mapimessage = mapi_msgstore_openentry($this->store, $entryid); try { $message = $this->mapiprovider->GetMessage($mapimessage, $this->contentparameters); } catch (SyncObjectBrokenException $mbe) { $brokenSO = $mbe->GetSyncObject(); if (!$brokenSO) { ZLog::Write(LOGLEVEL_ERROR, sprintf("PHPWrapper->ImportMessageChange(): Catched SyncObjectBrokenException but broken SyncObject available")); } else { if (!isset($brokenSO->id)) { $brokenSO->id = "Unknown ID"; ZLog::Write(LOGLEVEL_ERROR, sprintf("PHPWrapper->ImportMessageChange(): Catched SyncObjectBrokenException but no ID of object set")); } ZPush::GetDeviceManager()->AnnounceIgnoredMessage(false, $brokenSO->id, $brokenSO); } // tell MAPI to ignore the message return SYNC_E_IGNORE; } // substitute the MAPI SYNC_NEW_MESSAGE flag by a z-push proprietary flag if ($flags == SYNC_NEW_MESSAGE) { $message->flags = SYNC_NEWMESSAGE; } else { $message->flags = $flags; } $this->importer->ImportMessageChange(bin2hex($sourcekey), $message); // Tell MAPI it doesn't need to do anything itself, as we've done all the work already. return SYNC_E_IGNORE; }
/** * Constructor * * @param mapisession $session * @param mapistore $store * @param string (opt) * * @access public * @throws StatusException */ public function ExportChangesICS($session, $store, $folderid = false) { // Open a hierarchy or a contents exporter depending on whether a folderid was specified $this->session = $session; $this->folderid = $folderid; $this->store = $store; $this->restriction = false; try { if ($folderid) { $entryid = mapi_msgstore_entryidfromsourcekey($store, $folderid); } else { $storeprops = mapi_getprops($this->store, array(PR_IPM_SUBTREE_ENTRYID)); $entryid = $storeprops[PR_IPM_SUBTREE_ENTRYID]; } $folder = false; if ($entryid) { $folder = mapi_msgstore_openentry($this->store, $entryid); } // Get the actual ICS exporter if ($folderid) { if ($folder) { $this->exporter = mapi_openproperty($folder, PR_CONTENTS_SYNCHRONIZER, IID_IExchangeExportChanges, 0, 0); } else { $this->exporter = false; } } else { $this->exporter = mapi_openproperty($folder, PR_HIERARCHY_SYNCHRONIZER, IID_IExchangeExportChanges, 0, 0); } } catch (MAPIException $me) { $this->exporter = false; // We return the general error SYNC_FSSTATUS_CODEUNKNOWN (12) which is also SYNC_STATUS_FOLDERHIERARCHYCHANGED (12) // if this happened while doing content sync, the mobile will try to resync the folderhierarchy throw new StatusException(sprintf("ExportChangesICS('%s','%s','%s'): Error, unable to open folder: 0x%X", $session, $store, Utils::PrintAsString($folderid), mapi_last_hresult()), SYNC_FSSTATUS_CODEUNKNOWN); } }
function UpdateFB($addressbook, $session, $rootstore, $entryid) { $abentry = mapi_ab_openentry($addressbook, $entryid); if (!$abentry) { print "Unable to open entry in addressbook\n"; return false; } $abprops = mapi_getprops($abentry, array(PR_ACCOUNT)); $storeid = mapi_msgstore_createentryid($rootstore, $abprops[PR_ACCOUNT]); if (!$storeid) { print "Unable to get store entryid\n"; return false; } $store = mapi_openmsgstore($session, $storeid); if (!$store) { print "Unable to open store\n"; return false; } $root = mapi_msgstore_openentry($store); if (!$root) { print "Unable to open root folder\n"; return false; } $rootprops = mapi_getprops($root, array(PR_IPM_APPOINTMENT_ENTRYID)); $calendar = mapi_msgstore_openentry($store, $rootprops[PR_IPM_APPOINTMENT_ENTRYID]); $fbupdate = new FreeBusyPublish($session, $store, $calendar, $entryid); $fbupdate->publishFB(0, 0); // publish from one week ago, 6 months ahead return true; }
require MAPI_PATH . "mapicode.php"; require MAPI_PATH . "mapidefs.php"; require MAPI_PATH . "mapitags.php"; require MAPI_PATH . "mapiguid.php"; $supported_classes = array("IPF.Note" => "SYNC_FOLDER_TYPE_USER_MAIL", "IPF.Task" => "SYNC_FOLDER_TYPE_USER_TASK", "IPF.Appointment" => "SYNC_FOLDER_TYPE_USER_APPOINTMENT", "IPF.Contact" => "SYNC_FOLDER_TYPE_USER_CONTACT", "IPF.StickyNote" => "SYNC_FOLDER_TYPE_USER_NOTE"); $session = @mapi_logon_zarafa(ZARAFA_USER, ZARAFA_PASS, ZARAFA_SERVER); if (!$session) { die("Login to Zarafa failed\n"); } $storetable = @mapi_getmsgstorestable($session); $storeslist = @mapi_table_queryallrows($storetable, array(PR_ENTRYID, PR_MDB_PROVIDER)); for ($i = 0; $i < count($storeslist); $i++) { if ($storeslist[$i][PR_MDB_PROVIDER] == ZARAFA_STORE_PUBLIC_GUID) { $publicstore = @mapi_openmsgstore($session, $storeslist[$i][PR_ENTRYID]); break; } } if (!isset($publicstore)) { die("Public folder not available"); } $pub_folder = @mapi_msgstore_openentry($publicstore); $h_table = @mapi_folder_gethierarchytable($pub_folder, CONVENIENT_DEPTH); $subfolders = @mapi_table_queryallrows($h_table, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_CONTAINER_CLASS, PR_SOURCE_KEY)); echo "Available folders in public folder:\n" . str_repeat("-", 50) . "\n"; foreach ($subfolders as $folder) { if (isset($folder[PR_CONTAINER_CLASS]) && array_key_exists($folder[PR_CONTAINER_CLASS], $supported_classes)) { echo "Name:\t\t" . $folder[PR_DISPLAY_NAME] . "\n"; echo "Sync-class:\t" . $supported_classes[$folder[PR_CONTAINER_CLASS]] . "\n"; echo "PUID:\t\t" . bin2hex($folder[PR_SOURCE_KEY]) . "\n\n"; } }
/** * Imports a single folder change * * @param mixed $props sourcekey of the changed folder * * @access public * @return */ function ImportFolderChange($props) { $sourcekey = $props[PR_SOURCE_KEY]; $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $sourcekey); $mapifolder = mapi_msgstore_openentry($this->store, $entryid); $folder = $this->mapiprovider->GetFolder($mapifolder); // do not import folder if there is something "wrong" with it if ($folder === false) { return 0; } $this->importer->ImportFolderChange($folder); return 0; }
/** * Function returns correspondent calendar item attached with the meeting request/response/cancellation. * This will only check for actual MAPIMessages in calendar folder, so if a meeting request is * for exception then this function will return recurring series for that meeting request * after that you need to use getExceptionItem function to get exception item that will be * fetched from the attachment table of recurring series MAPIMessage. * @param Boolean $open boolean to indicate the function should return entryid or MAPIMessage. Defaults to true. * @return entryid or MAPIMessage resource of calendar item. */ function getCorrespondentCalendarItem($open = true) { $props = mapi_getprops($this->message, array(PR_MESSAGE_CLASS, $this->proptags['goid'], $this->proptags['goid2'], PR_RCVD_REPRESENTING_NAME)); if (!$this->isMeetingRequest($props[PR_MESSAGE_CLASS]) && !$this->isMeetingRequestResponse($props[PR_MESSAGE_CLASS]) && !$this->isMeetingCancellation($props[PR_MESSAGE_CLASS])) { // can work only with meeting requests/responses/cancellations return false; } $globalId = $props[$this->proptags['goid']]; $cleanGlobalId = $props[$this->proptags['goid2']]; // If Delegate is processing Meeting Request/Response for Delegator then retrieve Delegator's store and calendar. if (isset($props[PR_RCVD_REPRESENTING_NAME])) { $delegatorStore = $this->getDelegatorStore($props[PR_RCVD_REPRESENTING_NAME], array(PR_IPM_APPOINTMENT_ENTRYID)); $store = $delegatorStore['store']; $calFolder = $delegatorStore[PR_IPM_APPOINTMENT_ENTRYID]; } else { $store = $this->store; $calFolder = $this->openDefaultCalendar(); } $basedate = $this->getBasedateFromGlobalID($globalId); /** * First search for any appointments which correspond to the $globalId, * this can be the entire series (if the Meeting Request refers to the * entire series), or an particular Occurence (if the meeting Request * contains a basedate). * * If we cannot find a corresponding item, and the $globalId contains * a $basedate, it might imply that a new exception will have to be * created for a series which is present in the calendar, we can look * that one up by searching for the $cleanGlobalId. */ $entryids = $this->findCalendarItems($globalId, $calFolder); if ($basedate && empty($entryids)) { $entryids = $this->findCalendarItems($cleanGlobalId, $calFolder, true); } // there should be only one item returned if (!empty($entryids) && count($entryids) === 1) { // return only entryid if ($open === false) { return $entryids[0]; } // open calendar item and return it return mapi_msgstore_openentry($store, $entryids[0]); } // no items found in calendar return false; }
function delete_duplicate_messages($store, $entryid) { global $total_deleted; $folder = mapi_msgstore_openentry($store, $entryid); if (!$folder) { print "Unable to open folder."; return false; } $table = mapi_folder_getcontentstable($folder); if (!$table) { print "Unable to open table."; return false; } $org_hash = null; $dup_messages = array(); $dup_count = 0; $result = mapi_table_sort($table, array(PR_SUBJECT => TABLE_SORT_ASCEND)); if ($result == false) { die("Could not sort table\n"); } while (1) { // query messages from folders content table $rows = mapi_table_queryrows($table, array(PR_MESSAGE_SIZE, PR_CLIENT_SUBMIT_TIME, PR_BODY, PR_HTML, PR_ENTRYID, PR_SUBJECT), 0, 50); if (count($rows) == 0) { break; } // we got the messages foreach ($rows as $row) { // hash message body (plaintext + html + subject) $md5_subject = md5($row[PR_SUBJECT]); $md5_body = md5($row[PR_BODY]); $md5_html = md5($row[PR_HTML]); // concat hashes, just in case there are messages with // no HTML or plaintext content. $cur_hash = $md5_body . $md5_html . $md5_subject; // when we have accumulated enough messages, perform a burst delete if ($dup_count == 50) { echo " [i] Deleting {$dup_count} duplicates..."; delete_messages($folder, $dup_messages); // reset the delete-queue $dup_messages = array(); $dup_count = 0; $total_deleted += 100; echo "done.\n"; echo "Deleted {$total_deleted} messages so far.\n\n"; } // duplicate messages are adjacent, so we push the first message with // a distinct hash and mark all following messages with this hash // for deletion. if ($org_hash != $cur_hash) { $org_hash = $cur_hash; } else { $dup_messages[] = $row[PR_ENTRYID]; $dup_count++; echo " [i] For {$org_hash} adding DUP {$md5_eid} to delete list\n"; } } } // final cleanup $dup_count = count($dup_messages); if ($dup_count) { $total_deleted += $dup_count; echo " [i] Finally deleting {$dup_count} duplicates. \n"; delete_messages($folder, $dup_messages); $dup_messages = array(); echo "Deleted {$total_deleted} messages so far.\n\n"; } }
function _getFoldersRecursive($mapifolder, $parent, &$list) { $hierarchytable = mapi_folder_gethierarchytable($mapifolder); $folderprops = mapi_getprops($mapifolder, array(PR_ENTRYID)); if (!$hierarchytable) { return false; } $rows = mapi_table_queryallrows($hierarchytable, array(PR_DISPLAY_NAME, PR_SUBFOLDERS, PR_ENTRYID)); foreach ($rows as $row) { $folder = array(); $folder["mod"] = $row[PR_DISPLAY_NAME]; $folder["id"] = bin2hex($row[PR_ENTRYID]); $folder["parent"] = $parent; array_push($list, $folder); if (isset($row[PR_SUBFOLDERS]) && $row[PR_SUBFOLDERS]) { $this->_getFoldersRecursive(mapi_msgstore_openentry($this->_defaultstore, $row[PR_ENTRYID]), $folderprops[PR_ENTRYID], $list); } } return true; }
/** * Imports a change on a folder * * @param object $folder SyncFolder * * @access public * @return string id of the folder * @throws StatusException */ public function ImportFolderChange($folder) { $id = isset($folder->serverid) ? $folder->serverid : false; $parent = $folder->parentid; $displayname = u2wi($folder->displayname); $type = $folder->type; if (Utils::IsSystemFolder($type)) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, system folder can not be created/modified", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname), SYNC_FSSTATUS_SYSTEMFOLDER); } // create a new folder if $id is not set if (!$id) { // the root folder is "0" - get IPM_SUBTREE if ($parent == "0") { $parentprops = mapi_getprops($this->store, array(PR_IPM_SUBTREE_ENTRYID)); if (isset($parentprops[PR_IPM_SUBTREE_ENTRYID])) { $parentfentryid = $parentprops[PR_IPM_SUBTREE_ENTRYID]; } } else { $parentfentryid = mapi_msgstore_entryidfromsourcekey($this->store, hex2bin($parent)); } if (!$parentfentryid) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open parent folder (no entry id)", Utils::PrintAsString(false), $folder->parentid, $displayname), SYNC_FSSTATUS_PARENTNOTFOUND); } $parentfolder = mapi_msgstore_openentry($this->store, $parentfentryid); if (!$parentfolder) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open parent folder (open entry)", Utils::PrintAsString(false), $folder->parentid, $displayname), SYNC_FSSTATUS_PARENTNOTFOUND); } // mapi_folder_createfolder() fails if a folder with this name already exists -> MAPI_E_COLLISION $newfolder = mapi_folder_createfolder($parentfolder, $displayname, ""); if (mapi_last_hresult()) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, mapi_folder_createfolder() failed: 0x%X", Utils::PrintAsString(false), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_FOLDEREXISTS); } mapi_setprops($newfolder, array(PR_CONTAINER_CLASS => MAPIUtils::GetContainerClassFromFolderType($type))); $props = mapi_getprops($newfolder, array(PR_SOURCE_KEY)); if (isset($props[PR_SOURCE_KEY])) { $sourcekey = bin2hex($props[PR_SOURCE_KEY]); ZLog::Write(LOGLEVEL_DEBUG, sprintf("Created folder '%s' with id: '%s'", $displayname, $sourcekey)); return $sourcekey; } else { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, folder created but PR_SOURCE_KEY not available: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } return false; } // update folder $entryid = mapi_msgstore_entryidfromsourcekey($this->store, hex2bin($id)); if (!$entryid) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open folder (no entry id): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_PARENTNOTFOUND); } $folder = mapi_msgstore_openentry($this->store, $entryid); if (!$folder) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, unable to open folder (open entry): 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_PARENTNOTFOUND); } $props = mapi_getprops($folder, array(PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY, PR_DISPLAY_NAME, PR_CONTAINER_CLASS)); if (!isset($props[PR_SOURCE_KEY]) || !isset($props[PR_PARENT_SOURCE_KEY]) || !isset($props[PR_DISPLAY_NAME]) || !isset($props[PR_CONTAINER_CLASS])) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, folder data not available: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } if ($parent == "0") { $parentprops = mapi_getprops($this->store, array(PR_IPM_SUBTREE_ENTRYID)); $parentfentryid = $parentprops[PR_IPM_SUBTREE_ENTRYID]; $mapifolder = mapi_msgstore_openentry($this->store, $parentfentryid); $rootfolderprops = mapi_getprops($mapifolder, array(PR_SOURCE_KEY)); $parent = bin2hex($rootfolderprops[PR_SOURCE_KEY]); ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->ImportFolderChange(): resolved AS parent '0' to sourcekey '%s'", $parent)); } // In theory the parent id could change, which means that the folder was moved. // It is unknown if any device supports this, so we do currently not implement it (no known device is able to do this) if (bin2hex($props[PR_PARENT_SOURCE_KEY]) !== $parent) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Folder was moved to another location, which is currently not supported. Please report this to the Z-Push dev team together with the WBXML log and your device details (model, firmware etc).", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_UNKNOWNERROR); } $props = array(PR_DISPLAY_NAME => $displayname); mapi_setprops($folder, $props); mapi_savechanges($folder); if (mapi_last_hresult()) { throw new StatusException(sprintf("ImportChangesICS->ImportFolderChange('%s','%s','%s'): Error, mapi_savechanges() failed: 0x%X", Utils::PrintAsString($folder->serverid), $folder->parentid, $displayname, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR); } ZLog::Write(LOGLEVEL_DEBUG, "Imported changes for folder: {$id}"); return $id; }
$l_bbnEntryID = false; // Either boolean or binary // Loop through returned rows for ($i = 0; $i < count($l_aTableRows); $i++) { // Check to see if this entry is the default store if (isset($l_aTableRows[$i][PR_DEFAULT_STORE]) && $l_aTableRows[$i][PR_DEFAULT_STORE] == true) { $storeEntryId = $l_aTableRows[$i][PR_ENTRYID]; break; } } // check if default root store's entry id found if ($storeEntryId) { $store = mapi_openmsgstore($l_rSession, $storeEntryId); $root = mapi_msgstore_openentry($store, null); $spamStoreProps = mapi_getprops($root, array(PR_ADDITIONAL_REN_ENTRYIDS)); $spamFolder = mapi_msgstore_openentry($store, $spamStoreProps[PR_ADDITIONAL_REN_ENTRYIDS][4]); $table = mapi_folder_getcontentstable($spamFolder); $spamRows = mapi_table_queryallrows($table, array(PR_ENTRYID, PR_CREATION_TIME)); echo (mapi_last_hresult() == 0 ? "Fetching messages from Junk Folder..." : "Some error in fetching...") . "\n"; if (count($spamRows) > 0) { $spamEntryIds = array(); echo "\nTotal messages in Junk folder found are : " . count($spamRows) . "\n"; for ($i = 0; $i < count($spamRows); $i++) { if (greaterDate(date("Y-m-d G:i:s", $spamRows[$i][PR_CREATION_TIME]), $daysBeforeDeleted)) { array_push($spamEntryIds, $spamRows[$i][PR_ENTRYID]); } } if (count($spamEntryIds) > 0) { echo "\nDeleting all " . count($spamEntryIds) . " message(s)...\n"; mapi_folder_deletemessages($spamFolder, $spamEntryIds); echo "" . (mapi_last_hresult() == 0 ? "\nHooray! there is no spam." : "Some error in deleting... There are still some spam messages.") . "\n";
/** * Returns contacts matching given email address from a folder. * * @param MAPIStore $store * @param binary $folderEntryid * @param string $email * * @return array|boolean */ private function getContactsFromFolder($store, $folderEntryid, $email) { $folder = mapi_msgstore_openentry($store, $folderEntryid); $folderContent = mapi_folder_getcontentstable($folder); mapi_table_restrict($folderContent, MAPIUtils::GetEmailAddressRestriction($store, $email)); // TODO max limit if (mapi_table_getrowcount($folderContent) > 0) { return mapi_table_queryallrows($folderContent, array(PR_DISPLAY_NAME, PR_USER_X509_CERTIFICATE)); } return false; }
} $storesTable = mapi_getmsgstorestable($session); $stores = mapi_table_queryallrows($storesTable, array(PR_ENTRYID, PR_MDB_PROVIDER)); for ($i = 0; $i < count($stores); $i++) { if ($stores[$i][PR_MDB_PROVIDER] == ZARAFA_SERVICE_GUID) { $storeEntryid = $stores[$i][PR_ENTRYID]; break; } } if (!isset($storeEntryid)) { trigger_error("Default store not found", E_USER_ERROR); } $store = mapi_openmsgstore($session, $storeEntryid); $root = mapi_msgstore_openentry($store, null); $rootProps = mapi_getprops($root, array(PR_IPM_CONTACT_ENTRYID)); $folder = mapi_msgstore_openentry($store, $rootProps[PR_IPM_CONTACT_ENTRYID]); isUnicodeStore($store); // open the csv file and start reading $fh = fopen($csv_file, "r"); if (!$fh) { trigger_error("Can't open CSV file \"" . $csv_file . "\"", E_USER_ERROR); } // empty folder if needed if (EMPTY_FOLDER) { mapi_folder_emptyfolder($folder, DEL_ASSOCIATED); } $properties = array(); loadProperties($properties); $properties = getPropIdsFromStrings($store, $properties); //composed properties which require more work $special_properties = array("email_address_1", "email_address_2", "email_address_3");
private function getMessage($id, $announceErrors = true) { if (!$id) { return false; } $message = false; list($fsk, $sk) = Utils::SplitMessageId($id); $sourcekey = hex2bin($sk); $parentsourcekey = hex2bin(ZPush::GetDeviceManager()->GetBackendIdForFolderId($fsk)); // Backwards compatibility for old style folder ids if (empty($parentsourcekey)) { $parentsourcekey = $this->folderid; } $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $parentsourcekey, $sourcekey); if (!$entryid) { ZLog::Write(LOGLEVEL_INFO, sprintf("ReplyBackImExporter->getMessage(): Couldn't retrieve message from MAPIProvider, sourcekey: '%s', parentsourcekey: '%s'", bin2hex($sourcekey), bin2hex($parentsourcekey), bin2hex($entryid))); return false; } $mapimessage = mapi_msgstore_openentry($this->store, $entryid); try { ZLog::Write(LOGLEVEL_DEBUG, sprintf("ReplyBackImExporter->getMessage(): Getting message from MAPIProvider, sourcekey: '%s', parentsourcekey: '%s', entryid: '%s'", bin2hex($sourcekey), bin2hex($parentsourcekey), bin2hex($entryid))); $message = $this->mapiprovider->GetMessage($mapimessage, $this->contentparameters); } catch (SyncObjectBrokenException $mbe) { if ($announceErrors) { $brokenSO = $mbe->GetSyncObject(); if (!$brokenSO) { ZLog::Write(LOGLEVEL_ERROR, sprintf("ReplyBackImExporter->getMessage(): Catched SyncObjectBrokenException but broken SyncObject available")); } else { if (!isset($brokenSO->id)) { $brokenSO->id = "Unknown ID"; ZLog::Write(LOGLEVEL_ERROR, sprintf("ReplyBackImExporter->getMessage(): Catched SyncObjectBrokenException but no ID of object set")); } ZPush::GetDeviceManager()->AnnounceIgnoredMessage(false, $brokenSO->id, $brokenSO); } return false; } } return $message; }
/** * Retrieve vCard for a contact. If need be will "build" the vCard data * @see RFC6350 http://tools.ietf.org/html/rfc6350 * @param $contactId contact EntryID * @return VCard 4 UTF-8 encoded content */ public function getContactVCard($addressBookId, $contactId) { $this->logger->trace("getContactVCard(" . bin2hex($contactId) . ")"); $contact = mapi_msgstore_openentry($this->getStore($addressBookId), $contactId); $contactProperties = $this->getProperties($addressBookId, $contactId); $p = $this->extendedProperties; $this->logger->trace("PR_CARDDAV_RAW_DATA: " . PR_CARDDAV_RAW_DATA); $this->logger->trace("PR_CARDDAV_RAW_DATA_GENERATION_TIME: " . PR_CARDDAV_RAW_DATA_GENERATION_TIME); $this->logger->trace("PR_CARDDAV_RAW_DATA_VERSION: " . PR_CARDDAV_RAW_DATA_VERSION); $this->logger->debug("CACHE VERSION: " . CACHE_VERSION); // dump properties $dump = print_r($contactProperties, true); $this->logger->trace("Contact properties:\n{$dump}"); if (SAVE_RAW_VCARD && isset($contactProperties[PR_CARDDAV_RAW_DATA])) { // Check if raw vCard is up-to-date $vcardGenerationTime = $contactProperties[PR_CARDDAV_RAW_DATA_GENERATION_TIME]; $lastModifiedDate = $contactProperties[$p['last_modification_time']]; // Get cache version $vcardCacheVersion = isset($contactProperties[PR_CARDDAV_RAW_DATA_VERSION]) ? $contactProperties[PR_CARDDAV_RAW_DATA_VERSION] : 'NONE'; $this->logger->trace("Saved vcard cache version: " . $vcardCacheVersion); if ($vcardGenerationTime >= $lastModifiedDate && $vcardCacheVersion == CACHE_VERSION) { $this->logger->debug("Using saved vcard"); return $contactProperties[PR_CARDDAV_RAW_DATA]; } else { $this->logger->trace("Contact modified or new version of Sabre-Zarafa"); } } else { if (SAVE_RAW_VCARD) { $this->logger->trace("No saved raw vcard"); } else { $this->logger->trace("Generation of vcards forced by config"); } } $producer = new VCardProducer($this, VCARD_VERSION); $vCard = new Sabre_VObject_Component('VCARD'); // Produce VCard object $this->logger->trace("Producing vcard from contact properties"); $producer->propertiesToVObject($contact, $vCard); // Serialize $vCardData = $vCard->serialize(); $this->logger->debug("Produced VCard\n" . $vCardData); // Charset conversion? $targetCharset = VCARD_CHARSET == '' ? $producer->getDefaultCharset() : VCARD_CHARSET; if ($targetCharset != 'utf-8') { $this->logger->debug("Converting from UTF-8 to {$targetCharset}"); $vCardData = iconv("UTF-8", $targetCharset, $vCardData); } if (SAVE_RAW_VCARD) { $this->logger->debug("Saving vcard to contact properties"); // Check if raw vCard is up-to-date mapi_setprops($contact, array(PR_CARDDAV_RAW_DATA => $vCardData, PR_CARDDAV_RAW_DATA_VERSION => CACHE_VERSION, PR_CARDDAV_RAW_DATA_GENERATION_TIME => time())); if (mapi_last_hresult() > 0) { $this->logger->warn("Error setting contact properties: " . get_mapi_error_name()); } mapi_savechanges($contact); if (mapi_last_hresult() > 0) { $this->logger->warn("Error saving vcard to contact: " . get_mapi_error_name()); } else { $this->logger->trace("VCard successfully added to contact properties"); } } return $vCardData; }
/** * Creates a search folder if it not exists or opens an existing one * and returns it. * * @param mapiFolderObject $searchFolderRoot * * @return mapiFolderObject */ private function createSearchFolder($searchFolderRoot) { $folderName = "Z-Push Search Folder " . @getmypid(); $searchFolders = mapi_folder_gethierarchytable($searchFolderRoot); $restriction = array(RES_CONTENT, array(FUZZYLEVEL => FL_PREFIX, ULPROPTAG => PR_DISPLAY_NAME, VALUE => array(PR_DISPLAY_NAME => $folderName))); //restrict the hierarchy to the z-push search folder only mapi_table_restrict($searchFolders, $restriction); if (mapi_table_getrowcount($searchFolders)) { $searchFolder = mapi_table_queryrows($searchFolders, array(PR_ENTRYID), 0, 1); return mapi_msgstore_openentry($this->store, $searchFolder[0][PR_ENTRYID]); } return mapi_folder_createfolder($searchFolderRoot, $folderName, null, 0, FOLDER_SEARCH); }
/** * Returns categories for a message. * * @param binary $parentsourcekey * @param binary $sourcekey * * @access public * @return array or false on failure */ public function GetMessageCategories($parentsourcekey, $sourcekey) { $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $parentsourcekey, $sourcekey); if (!$entryid) { ZLog::Write(LOGLEVEL_INFO, sprintf("MAPIProvider->GetMessageCategories(): Couldn't retrieve message, sourcekey: '%s', parentsourcekey: '%s'", bin2hex($sourcekey), bin2hex($parentsourcekey))); return false; } $mapimessage = mapi_msgstore_openentry($this->store, $entryid); $emailMapping = MAPIMapping::GetEmailMapping(); $emailMapping = array("categories" => $emailMapping["categories"]); $messageCategories = $this->getProps($mapimessage, $emailMapping); if (isset($messageCategories[$emailMapping["categories"]]) && is_array($messageCategories[$emailMapping["categories"]])) { return $messageCategories[$emailMapping["categories"]]; } return false; }
/** * Function which clones current occurrence and sets appropriate properties. * The original recurring item is moved to next occurrence. *@param boolean $markComplete true if existing occurrence has to be mark complete else false. */ function regenerateTask($markComplete) { // Get all properties $taskItemProps = mapi_getprops($this->message); if (isset($this->action["subject"])) { $taskItemProps[$this->proptags["subject"]] = $this->action["subject"]; } if (isset($this->action["importance"])) { $taskItemProps[$this->proptags["importance"]] = $this->action["importance"]; } if (isset($this->action["startdate"])) { $taskItemProps[$this->proptags["startdate"]] = $this->action["startdate"]; $taskItemProps[$this->proptags["commonstart"]] = $this->action["startdate"]; } if (isset($this->action["duedate"])) { $taskItemProps[$this->proptags["duedate"]] = $this->action["duedate"]; $taskItemProps[$this->proptags["commonend"]] = $this->action["duedate"]; } $folder = mapi_msgstore_openentry($this->store, $taskItemProps[PR_PARENT_ENTRYID]); $newMessage = mapi_folder_createmessage($folder); $taskItemProps[$this->proptags["status"]] = $markComplete ? olTaskComplete : olTaskNotStarted; $taskItemProps[$this->proptags["complete"]] = $markComplete; $taskItemProps[$this->proptags["percent_complete"]] = $markComplete ? 1 : 0; // This occurrence has been marked as 'Complete' so disable reminder if ($markComplete) { $taskItemProps[$this->proptags["reset_reminder"]] = false; $taskItemProps[$this->proptags["reminder"]] = false; $taskItemProps[$this->proptags["datecompleted"]] = $this->action["datecompleted"]; unset($this->action[$this->proptags['datecompleted']]); } // Recurrence ends for this item $taskItemProps[$this->proptags["dead_occurrence"]] = true; $taskItemProps[$this->proptags["task_f_creator"]] = true; //OL props $taskItemProps[$this->proptags["side_effects"]] = 1296; $taskItemProps[$this->proptags["icon_index"]] = 1280; // Copy recipients $recipienttable = mapi_message_getrecipienttable($this->message); $recipients = mapi_table_queryallrows($recipienttable, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_RECIPIENT_ENTRYID, PR_RECIPIENT_TYPE, PR_SEND_INTERNET_ENCODING, PR_SEND_RICH_INFO, PR_RECIPIENT_DISPLAY_NAME, PR_ADDRTYPE, PR_DISPLAY_TYPE, PR_RECIPIENT_TRACKSTATUS, PR_RECIPIENT_TRACKSTATUS_TIME, PR_RECIPIENT_FLAGS, PR_ROWID)); $copy_to_recipientTable = mapi_message_getrecipienttable($newMessage); $copy_to_recipientRows = mapi_table_queryallrows($copy_to_recipientTable, array(PR_ROWID)); foreach ($copy_to_recipientRows as $recipient) { mapi_message_modifyrecipients($newMessage, MODRECIP_REMOVE, array($recipient)); } mapi_message_modifyrecipients($newMessage, MODRECIP_ADD, $recipients); // Copy attachments $attachmentTable = mapi_message_getattachmenttable($this->message); if ($attachmentTable) { $attachments = mapi_table_queryallrows($attachmentTable, array(PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME, PR_ATTACHMENT_HIDDEN, PR_DISPLAY_NAME, PR_ATTACH_METHOD)); foreach ($attachments as $attach_props) { $attach_old = mapi_message_openattach($this->message, (int) $attach_props[PR_ATTACH_NUM]); $attach_newResourceMsg = mapi_message_createattach($newMessage); mapi_copyto($attach_old, array(), array(), $attach_newResourceMsg, 0); mapi_savechanges($attach_newResourceMsg); } } mapi_setprops($newMessage, $taskItemProps); mapi_savechanges($newMessage); // Update body of original message $msgbody = mapi_message_openproperty($this->message, PR_BODY); $msgbody = trim($this->windows1252_to_utf8($msgbody), ""); $separator = "------------\r\n"; if (!empty($msgbody) && strrpos($msgbody, $separator) === false) { $msgbody = $separator . $msgbody; $stream = mapi_openpropertytostream($this->message, PR_BODY, MAPI_CREATE | MAPI_MODIFY); mapi_stream_setsize($stream, strlen($msgbody)); mapi_stream_write($stream, $msgbody); mapi_stream_commit($stream); } // We need these properties to notify client return mapi_getprops($newMessage, array(PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID)); }
echo (mapi_last_hresult() == 0 ? "Fetching Deleted Folder..." : "Some error in fetching...") . "\n"; $l_bbnEntryID = false; // Either boolean or binary // Loop through returned rows for ($i = 0; $i < count($l_aTableRows); $i++) { // Check to see if this entry is the default store if (isset($l_aTableRows[$i][PR_DEFAULT_STORE]) && $l_aTableRows[$i][PR_DEFAULT_STORE] == true) { $storeEntryId = $l_aTableRows[$i][PR_ENTRYID]; break; } } // check if default root store's entry id found if ($storeEntryId) { $store = mapi_openmsgstore($l_rSession, $storeEntryId); $delStoreProps = mapi_getprops($store, array(PR_IPM_WASTEBASKET_ENTRYID)); $deletedFolder = mapi_msgstore_openentry($store, $delStoreProps[PR_IPM_WASTEBASKET_ENTRYID]); $table = mapi_folder_getcontentstable($deletedFolder); $delRows = mapi_table_queryallrows($table, array(PR_ENTRYID, PR_CREATION_TIME)); echo (mapi_last_hresult() == 0 ? "Fetching messages from Deleted Folder..." : "Some error in fetching...") . "\n"; if (count($delRows) > 0) { $delEntryIds = array(); echo 'Total messages in deleted folder found are : ' . count($delRows) . "\n"; for ($i = 0; $i < count($delRows); $i++) { if (greaterDate(date("Y-m-d G:i:s", $delRows[$i][PR_CREATION_TIME]), $daysBeforeDeleted)) { array_push($delEntryIds, $delRows[$i][PR_ENTRYID]); } } if (count($delEntryIds) > 0) { echo "\nDeleting all " . count($delEntryIds) . " messages...\n"; mapi_folder_deletemessages($deletedFolder, $delEntryIds); echo "" . (mapi_last_hresult() == 0 ? "Successfully deleted all messages" : "Some error in deleting... please try again later") . "\n";
/** * Get all public contact folders */ function getPublicContactFolders($session, $publicstore) { $pub_folder = mapi_msgstore_openentry($publicstore); $h_table = mapi_folder_gethierarchytable($pub_folder, CONVENIENT_DEPTH); $contact_properties = getContactProperties($publicstore); $subfolders = mapi_table_queryallrows($h_table, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_DISPLAY_TYPE, PR_CONTAINER_CLASS, PR_SUBFOLDERS)); $pub_list2 = array(); $contacts = array(); foreach ($subfolders as $folder) { // check if folder contains PR_CONTAINER_CLASS and if its a contact if (isset($folder[907214878]) && $folder[907214878] == "IPF.Contact" && $folder[805371934] != "Kontakte") { $entryid = $folder[268370178]; $pub_folder2 = mapi_msgstore_openentry($publicstore, $entryid); $pub_table2 = mapi_folder_getcontentstable($pub_folder2); $pub_list2 = mapi_table_queryallrows($pub_table2, $contact_properties); for ($j = 0; $j < sizeof($pub_list2); $j++) { $pub_list2[$j][268370178] = md5($pub_list2[$j][268370178]); } for ($k = 0; $k < sizeof($pub_list2); $k++) { foreach ($pub_list2[$k] as $key => $value) { $attribute = mapKey($key); if ($attribute != "") { $contacts[$k][$attribute] = $value; } } } //$contactFolders[$folder[805371934]] = $pub_list2; $contactFolders[] = array("foldername" => $folder[805371934], "contacts" => $contacts); } } //print_r($contactFolders); return $contactFolders; }
function listfolders_getlist($adminStore, $session, $user) { global $supported_classes; if (strtoupper($user) == 'SYSTEM') { // Find the public store store $storestables = @mapi_getmsgstorestable($session); $result = @mapi_last_hresult(); if ($result == NOERROR) { $rows = @mapi_table_queryallrows($storestables, array(PR_ENTRYID, PR_MDB_PROVIDER)); foreach ($rows as $row) { if (isset($row[PR_MDB_PROVIDER]) && $row[PR_MDB_PROVIDER] == ZARAFA_STORE_PUBLIC_GUID) { if (!isset($row[PR_ENTRYID])) { echo "Public folder are not available.\nIf this is a multi-tenancy system, use -u and -p and login with an admin user of the company.\nThe script will exit.\n"; exit(1); } $entryid = $row[PR_ENTRYID]; break; } } } } else { $entryid = @mapi_msgstore_createentryid($adminStore, $user); } $userStore = @mapi_openmsgstore($session, $entryid); $hresult = mapi_last_hresult(); // Cache the store for later use if ($hresult != NOERROR) { echo "Could not open store for '{$user}'. The script will exit.\n"; exit(1); } $folder = @mapi_msgstore_openentry($userStore); $h_table = @mapi_folder_gethierarchytable($folder, CONVENIENT_DEPTH); $subfolders = @mapi_table_queryallrows($h_table, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_CONTAINER_CLASS, PR_SOURCE_KEY)); echo "Available folders in store '{$user}':\n" . str_repeat("-", 50) . "\n"; foreach ($subfolders as $folder) { if (isset($folder[PR_CONTAINER_CLASS]) && array_key_exists($folder[PR_CONTAINER_CLASS], $supported_classes)) { echo "Folder name:\t" . $folder[PR_DISPLAY_NAME] . "\n"; echo "Folder ID:\t" . bin2hex($folder[PR_SOURCE_KEY]) . "\n"; echo "Type:\t\t" . $supported_classes[$folder[PR_CONTAINER_CLASS]] . "\n"; echo "\n"; } } }
function getDelegatorStore($messageprops) { // Find the organiser of appointment in addressbook $delegatorName = array(array(PR_DISPLAY_NAME => $messageprops[PR_RCVD_REPRESENTING_NAME])); $ab = mapi_openaddressbook($this->session); $user = mapi_ab_resolvename($ab, $delegatorName, EMS_AB_ADDRESS_LOOKUP); // Get StoreEntryID by username $delegatorEntryid = mapi_msgstore_createentryid($this->store, $user[0][PR_EMAIL_ADDRESS]); // Open store of the delegator $delegatorStore = mapi_openmsgstore($this->session, $delegatorEntryid); // Open root folder $delegatorRoot = mapi_msgstore_openentry($delegatorStore, null); // Get calendar entryID $delegatorRootProps = mapi_getprops($delegatorRoot, array(PR_IPM_APPOINTMENT_ENTRYID)); // Open the calendar Folder $calFolder = mapi_msgstore_openentry($delegatorStore, $delegatorRootProps[PR_IPM_APPOINTMENT_ENTRYID]); return array('store' => $delegatorStore, 'calFolder' => $calFolder); }
/** Deletes incoming task request from Inbox * * @returns array returns PR_ENTRYID, PR_STORE_ENTRYID and PR_PARENT_ENTRYID of the deleted task request */ function deleteReceivedTR() { $store = $this->getTaskFolderStore(); $inbox = mapi_msgstore_getreceivefolder($store); $storeProps = mapi_getprops($store, array(PR_IPM_WASTEBASKET_ENTRYID)); $props = mapi_getprops($this->message, array($this->props['taskglobalobjid'])); $globalobjid = $props[$this->props['taskglobalobjid']]; // Find the task by looking for the taskglobalobjid $restriction = array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->props['taskglobalobjid'], VALUE => $globalobjid)); $contents = mapi_folder_getcontentstable($inbox); $rows = mapi_table_queryallrows($contents, array(PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID), $restriction); $taskrequest = false; if (!empty($rows)) { // If there are multiple, just use the first $entryid = $rows[0][PR_ENTRYID]; $wastebasket = mapi_msgstore_openentry($store, $storeProps[PR_IPM_WASTEBASKET_ENTRYID]); mapi_folder_copymessages($inbox, array($entryid), $wastebasket, MESSAGE_MOVE); return array(PR_ENTRYID => $entryid, PR_PARENT_ENTRYID => $rows[0][PR_PARENT_ENTRYID], PR_STORE_ENTRYID => $rows[0][PR_STORE_ENTRYID]); } return false; }
/** * Indicates if the entry id is a default MAPI folder * * @param string $entryid * * @access public * @return boolean */ public function IsMAPIDefaultFolder($entryid) { $msgstore_props = mapi_getprops($this->store, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_IPM_SUBTREE_ENTRYID, PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID, PR_IPM_WASTEBASKET_ENTRYID, PR_MDB_PROVIDER, PR_IPM_PUBLIC_FOLDERS_ENTRYID, PR_IPM_FAVORITES_ENTRYID, PR_MAILBOX_OWNER_ENTRYID)); $inboxProps = array(); $inbox = mapi_msgstore_getreceivefolder($this->store); if (!mapi_last_hresult()) { $inboxProps = mapi_getprops($inbox, array(PR_ENTRYID)); } $root = mapi_msgstore_openentry($this->store, null); $rootProps = mapi_getprops($root, array(PR_IPM_APPOINTMENT_ENTRYID, PR_IPM_CONTACT_ENTRYID, PR_IPM_DRAFTS_ENTRYID, PR_IPM_JOURNAL_ENTRYID, PR_IPM_NOTE_ENTRYID, PR_IPM_TASK_ENTRYID, PR_ADDITIONAL_REN_ENTRYIDS)); $additional_ren_entryids = array(); if (isset($rootProps[PR_ADDITIONAL_REN_ENTRYIDS])) { $additional_ren_entryids = $rootProps[PR_ADDITIONAL_REN_ENTRYIDS]; } $defaultfolders = array("inbox" => array("inbox" => PR_ENTRYID), "outbox" => array("store" => PR_IPM_OUTBOX_ENTRYID), "sent" => array("store" => PR_IPM_SENTMAIL_ENTRYID), "wastebasket" => array("store" => PR_IPM_WASTEBASKET_ENTRYID), "favorites" => array("store" => PR_IPM_FAVORITES_ENTRYID), "publicfolders" => array("store" => PR_IPM_PUBLIC_FOLDERS_ENTRYID), "calendar" => array("root" => PR_IPM_APPOINTMENT_ENTRYID), "contact" => array("root" => PR_IPM_CONTACT_ENTRYID), "drafts" => array("root" => PR_IPM_DRAFTS_ENTRYID), "journal" => array("root" => PR_IPM_JOURNAL_ENTRYID), "note" => array("root" => PR_IPM_NOTE_ENTRYID), "task" => array("root" => PR_IPM_TASK_ENTRYID), "junk" => array("additional" => 4), "syncissues" => array("additional" => 1), "conflicts" => array("additional" => 0), "localfailures" => array("additional" => 2), "serverfailures" => array("additional" => 3)); foreach ($defaultfolders as $key => $prop) { $tag = reset($prop); $from = key($prop); switch ($from) { case "inbox": if (isset($inboxProps[$tag]) && $entryid == $inboxProps[$tag]) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIProvider->IsMAPIFolder(): Inbox found, key '%s'", $key)); return true; } break; case "store": if (isset($msgstore_props[$tag]) && $entryid == $msgstore_props[$tag]) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIProvider->IsMAPIFolder(): Store folder found, key '%s'", $key)); return true; } break; case "root": if (isset($rootProps[$tag]) && $entryid == $rootProps[$tag]) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIProvider->IsMAPIFolder(): Root folder found, key '%s'", $key)); return true; } break; case "additional": if (isset($additional_ren_entryids[$tag]) && $entryid == $additional_ren_entryids[$tag]) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIProvider->IsMAPIFolder(): Additional folder found, key '%s'", $key)); return true; } } } return false; }
/** * GET method handler * * @param array parameter passing array * @return bool true on success */ function GET(&$options) { if ($options["path"] == "/") { $store = $this->zarafa["store"]; $contacts = $this->zarafa["contacts"]; $files["files"] = array(); $global_etag = ""; $html_content = "<html><head><title>Zarafa Contacts for " . $this->zarafa['user'] . "</title></head><body><br/>"; foreach ($contacts as $contact) { $message = mapi_msgstore_openentry($store, $contact[PR_ENTRYID]); $props = mapi_getprops($message); $name = $props[PR_DISPLAY_NAME]; $html_content .= "<a href=\"" . sha1($name) . $this->extension . "\">" . $name . "</a><br/>\n"; } $html_content .= "</body></html>"; $options['mimetype'] = "text/html"; $options['data'] = $html_content; return true; } $contactprops = $this->get_contact($options["path"]); if ($contactprops === false) { return false; } $options['mimetype'] = $this->mime; $vcard = $this->build_vcard($contactprops); $vcard = $vcard->fetch(); $etag = $this->get_etag($contactprops); $options['data'] = $vcard; header("ETAG: \"" . $etag . "\""); return true; }