Commit 70e8b943 authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #441 in ZP/z-push from...

Merge pull request #441 in ZP/z-push from bugfix/ZP-1128-do-not-sync-suggested-contacts-folder to develop

* commit 'fbf359bd':
  ZP-1128 Do not sync undesired folders.
  ZP-1128 Do not sync "Suggested Contacts" folder.
parents 1ee79a10 fbf359bd
......@@ -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,8 @@ class MAPIProvider {
private $addressbook;
private $storeProps;
private $inboxProps;
private $rootProps;
private $specialFoldersData;
/**
* Constructor of the MAPI Provider
......@@ -898,22 +900,13 @@ class MAPIProvider {
return false;
}
// ignore certain undesired folders, like "RSS Feeds"
if (isset($folderprops[PR_CONTAINER_CLASS]) && $folderprops[PR_CONTAINER_CLASS] == "IPF.Note.OutlookHomepage") {
// ignore certain undesired folders, like "RSS Feeds" and "Suggested contacts"
if ((isset($folderprops[PR_CONTAINER_CLASS]) && $folderprops[PR_CONTAINER_CLASS] == "IPF.Note.OutlookHomepage")
|| in_array($folderprops[PR_ENTRYID], $this->getSpecialFoldersData())) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIProvider->GetFolder(): folder '%s' should not be synchronized", $folderprops[PR_DISPLAY_NAME]));
return false;
}
// 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) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIProvider->GetFolder(): folder '%s' should not be synchronized", $folderprops[PR_DISPLAY_NAME]));
return false;
}
}
$folder->BackendId = bin2hex($folderprops[PR_SOURCE_KEY]);
$folder->serverid = ZPush::GetDeviceManager()->GetFolderIdForBackendId($folder->BackendId, true, DeviceManager::FLD_ORIGIN_USER, $folderprops[PR_DISPLAY_NAME]);
if($folderprops[PR_PARENT_ENTRYID] == $storeprops[PR_IPM_SUBTREE_ENTRYID]) {
......@@ -1001,7 +994,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 +2834,61 @@ 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 an array with entryids of some special folders.
*
* @access private
* @return array
*/
private function getSpecialFoldersData() {
// 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)
if (empty($this->specialFoldersData)) {
$this->specialFoldersData = array();
$rootProps = $this->getRootProps();
if (isset($rootProps[PR_IPM_OL2007_ENTRYIDS])) {
$persistData = $rootProps[PR_IPM_OL2007_ENTRYIDS];
while (strlen($persistData) > 0) {
// PERSIST_SENTINEL marks the end of the persist data
if (strlen($persistData) == 4 && $persistData == PERSIST_SENTINEL) {
break;
}
$unpackedData = unpack("vdataSize/velementID/velDataSize", substr($persistData, 2, 6));
if (isset($unpackedData['dataSize']) && isset($unpackedData['elementID']) && $unpackedData['elementID'] == RSF_ELID_ENTRYID && isset($unpackedData['elDataSize'])) {
$this->specialFoldersData[] = substr($persistData, 8, $unpackedData['elDataSize']);
// Add PersistId and DataElementsSize lenghts to the data size as they're not part of it
$persistData = substr($persistData, $unpackedData['dataSize'] + 4);
}
else {
ZLog::Write(LOGLEVEL_INFO, "MAPIProvider->getSpecialFoldersData(): persistent data is not valid");
break;
}
}
}
}
return $this->specialFoldersData;
}
/**
* 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