Commit e6736c56 authored by Manfred Kutas's avatar Manfred Kutas

ZP-1128 Do not sync "Suggested Contacts" folder.

Released under the Affero GNU General Public License (AGPL) version 3.
parent 1ee79a10
......@@ -1226,3 +1226,21 @@ define('PR_TODO_ITEM_FLAGS' ,mapi_prop_tag(PT_LONG,
define('PR_LOCAL_COMMIT_TIME_MAX' ,mapi_prop_tag(PT_SYSTIME, 0x670A));
define('PR_DELETED_MSG_COUNT' ,mapi_prop_tag(PT_LONG, 0x6640));
// PR_IPM_OL2007_ENTRYIDS / PR_ADDITIONAL_REN_ENTRYIDS_EX PersistIDs
define('RSF_PID_RSS_SUBSCRIPTION' ,0x8001); // Indicates that the structure contains data for the RSS Feeds folder
define('RSF_PID_SEND_AND_TRACK' ,0x8002); // Indicates that the structure contains data for the Tracked Mail Processing folder
define('RSF_PID_TODO_SEARCH' ,0x8004); // Indicates that the structure contains data for the To-Do folder
define('RSF_PID_CONV_ACTIONS' ,0x8006); // Indicates that the structure contains data for the Conversation Action Settings folder
define('RSF_PID_COMBINED_ACTIONS' ,0x8007); // This value is reserved.
define('RSF_PID_SUGGESTED_CONTACTS' ,0x8008); // Indicates that the structure contains data for the Suggested Contacts folder.
define('RSF_PID_CONTACT_SEARCH' ,0x8009); // Indicates that the structure contains data for the Contacts Search folder.
define('RSF_PID_BUDDYLIST_PDLS' ,0x800A); // Indicates that the structure contains data for the IM Contacts List folder.
define('RSF_PID_BUDDYLIST_CONTACTS' ,0x800B); // Indicates that the structure contains data for the Quick Contacts folder.
define('PERSIST_SENTINEL' ,0x0000); // Indicates that the PersistData structure is the last one contained in the PidTagAdditionalRenEntryIdsEx property
// ElementIDs for persist data of PR_IPM_OL2007_ENTRYIDS / PR_ADDITIONAL_REN_ENTRYIDS_EX
define('RSF_ELID_HEADER' ,0x0002); // 4 bytes Indicates that the ElementData field contains a 4-byte header value equal to 0x00000000.
define('RSF_ELID_ENTRYID' ,0x0001); // variable Indicates that the ElementData field contains the entry ID of the special folder
// that is of the type indicated by the value of the PersistID field of the PersistData structure.
define('ELEMENT_SENTINEL' ,0x0000); // 0 bytes Indicates that the PersistElement structure is the last one contained in the DataElements field of the PersistData structure.
\ No newline at end of file
......@@ -30,6 +30,7 @@ class MAPIProvider {
private $addressbook;
private $storeProps;
private $inboxProps;
private $rootProps;
/**
* Constructor of the MAPI Provider
......@@ -905,12 +906,24 @@ class MAPIProvider {
}
// ignore suggested contacts folder
if (isset($folderprops[PR_CONTAINER_CLASS]) && $folderprops[PR_CONTAINER_CLASS] == "IPF.Contact" && isset($folderprops[PR_EXTENDED_FOLDER_FLAGS])) {
// the PR_EXTENDED_FOLDER_FLAGS is a binary value which consists of subproperties. 070403000000 indicates a suggested contacts folder
$extendedFlags = bin2hex($folderprops[PR_EXTENDED_FOLDER_FLAGS]);
if (substr_count($extendedFlags, "070403000000") > 0) {
// The persist data of an entry in PR_IPM_OL2007_ENTRYIDS consists of:
// PersistId - e.g. RSF_PID_SUGGESTED_CONTACTS (2 bytes)
// DataElementsSize - size of DataElements field (2 bytes)
// DataElements - array of PersistElement structures (variable size)
// PersistElement Structure consists of
// ElementID - e.g. RSF_ELID_ENTRYID (2 bytes)
// ElementDataSize - size of ElementData (2 bytes)
// ElementData - The data for the special folder identified by the PersistID (variable size)
$rootProps = $this->getRootProps();
if (isset($rootProps[PR_IPM_OL2007_ENTRYIDS])) {
$scPos = strpos($rootProps[PR_IPM_OL2007_ENTRYIDS], RSF_PID_SUGGESTED_CONTACTS);
// check RSF_ELID_ENTRYID with strpos, in order to avoid unpack or chr hassle
if ($scPos !== false && strpos(substr($rootProps[PR_IPM_OL2007_ENTRYIDS], $scPos + 4, 2), RSF_ELID_ENTRYID) !== false) {
// size of ElementDataSize is an unsigned short in little endian order
$elDataSize = unpack("v", substr($rootProps[PR_IPM_OL2007_ENTRYIDS], $scPos + 6, 2));
if (isset($elDataSize[1]) && substr($rootProps[PR_IPM_OL2007_ENTRYIDS], $scPos + 8, $elDataSize [1]) == $folderprops[PR_ENTRYID]) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIProvider->GetFolder(): folder '%s' should not be synchronized", $folderprops[PR_DISPLAY_NAME]));
return false;
}
}
}
......@@ -1001,7 +1014,7 @@ class MAPIProvider {
if(!mapi_last_hresult())
$inboxProps = mapi_getprops($inbox, array(PR_ENTRYID));
$root = mapi_msgstore_openentry($this->store, null);
$root = mapi_msgstore_openentry($this->store, null); // TODO use getRootProps()
$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();
......@@ -2841,6 +2854,20 @@ class MAPIProvider {
return $this->inboxProps;
}
/**
* Gets the required store root properties.
*
* @access private
* @return array
*/
private function getRootProps() {
if (!isset($this->rootProps)) {
$root = mapi_msgstore_openentry($this->store, null);
$this->rootProps = mapi_getprops($root, array(PR_IPM_OL2007_ENTRYIDS));
}
return $this->rootProps;
}
/**
* Returns categories for a message.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment