/** * Returns subfolders of given type for a folder or false if there are none. * * @access public * * @param MAPIFolder $folder * @param string $type * * @return MAPITable|boolean */ public static function GetSubfoldersForType($folder, $type) { $subfolders = mapi_folder_gethierarchytable($folder, CONVENIENT_DEPTH); mapi_table_restrict($subfolders, MAPIUtils::GetFolderTypeRestriction($type)); if (mapi_table_getrowcount($subfolders) > 0) { return mapi_table_queryallrows($subfolders, array(PR_ENTRYID)); } return false; }
/** * Sets the message body * * @param MAPIMessage $mapimessage * @param ContentParameters $contentparameters * @param SyncObject $message */ private function setMessageBody($mapimessage, $contentparameters, &$message) { //get the available body preference types $bpTypes = $contentparameters->GetBodyPreference(); if ($bpTypes !== false) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BodyPreference types: %s", implode(', ', $bpTypes))); //do not send mime data if the client requests it if ($contentparameters->GetMimeSupport() == SYNC_MIMESUPPORT_NEVER && ($key = array_search(SYNC_BODYPREFERENCE_MIME, $bpTypes) !== false)) { unset($bpTypes[$key]); ZLog::Write(LOGLEVEL_DEBUG, sprintf("Remove mime body preference type because the device required no mime support. BodyPreference types: %s", implode(', ', $bpTypes))); } //get the best fitting preference type $bpReturnType = Utils::GetBodyPreferenceBestMatch($bpTypes); ZLog::Write(LOGLEVEL_DEBUG, sprintf("GetBodyPreferenceBestMatch: %d", $bpReturnType)); $bpo = $contentparameters->BodyPreference($bpReturnType); ZLog::Write(LOGLEVEL_DEBUG, sprintf("bpo: truncation size:'%d', allornone:'%d', preview:'%d'", $bpo->GetTruncationSize(), $bpo->GetAllOrNone(), $bpo->GetPreview())); $this->setMessageBodyForType($mapimessage, $bpReturnType, $message); //only set the truncation size data if device set it in request if ($bpo->GetTruncationSize() != false && $bpReturnType != SYNC_BODYPREFERENCE_MIME && $message->asbody->estimatedDataSize > $bpo->GetTruncationSize() && $contentparameters->GetTruncation() != SYNC_TRUNCATION_ALL) { $message->asbody->data = Utils::Utf8_truncate($message->asbody->data, $bpo->GetTruncationSize()); $message->asbody->truncated = 1; } // set the preview or windows phones won't show the preview of an email if (Request::GetProtocolVersion() >= 14.0 && $bpo->GetPreview()) { $message->asbody->preview = Utils::Utf8_truncate(MAPIUtils::readPropStream($mapimessage, PR_BODY), $bpo->GetPreview()); } } else { // Override 'body' for truncation $truncsize = Utils::GetTruncSize($contentparameters->GetTruncation()); $this->setMessageBodyForType($mapimessage, SYNC_BODYPREFERENCE_PLAIN, $message); if ($message->bodysize > $truncsize) { $message->body = Utils::Utf8_truncate($message->body, $truncsize); $message->bodytruncated = 1; } if (!isset($message->body) || strlen($message->body) == 0) { $message->body = " "; } if ($contentparameters->GetMimeSupport() == SYNC_MIMESUPPORT_ALWAYS) { //set the html body for iphone in AS 2.5 version $this->imtoinet($mapimessage, $message); } } }
/** * Searches the GAB of Zarafa * Can be overwitten globally by configuring a SearchBackend * * @param string $searchquery * @param string $searchrange * * @access public * @return array * @throws StatusException */ public function GetGALSearchResults($searchquery, $searchrange) { // only return users from who the displayName or the username starts with $name //TODO: use PR_ANR for this restriction instead of PR_DISPLAY_NAME and PR_ACCOUNT $addrbook = mapi_openaddressbook($this->session); if ($addrbook) { $ab_entryid = mapi_ab_getdefaultdir($addrbook); } if ($ab_entryid) { $ab_dir = mapi_ab_openentry($addrbook, $ab_entryid); } if ($ab_dir) { $table = mapi_folder_getcontentstable($ab_dir); } if (!$table) { throw new StatusException(sprintf("ZarafaBackend->GetGALSearchResults(): could not open addressbook: 0x%X", mapi_last_hresult()), SYNC_SEARCHSTATUS_STORE_CONNECTIONFAILED); } $restriction = MAPIUtils::GetSearchRestriction(u2w($searchquery)); mapi_table_restrict($table, $restriction); mapi_table_sort($table, array(PR_DISPLAY_NAME => TABLE_SORT_ASCEND)); if (mapi_last_hresult()) { throw new StatusException(sprintf("ZarafaBackend->GetGALSearchResults(): could not apply restriction: 0x%X", mapi_last_hresult()), SYNC_SEARCHSTATUS_STORE_TOOCOMPLEX); } //range for the search results, default symbian range end is 50, wm 99, //so we'll use that of nokia $rangestart = 0; $rangeend = 50; if ($searchrange != '0') { $pos = strpos($searchrange, '-'); $rangestart = substr($searchrange, 0, $pos); $rangeend = substr($searchrange, $pos + 1); } $items = array(); $querycnt = mapi_table_getrowcount($table); //do not return more results as requested in range $querylimit = $rangeend + 1 < $querycnt ? $rangeend + 1 : $querycnt; $items['range'] = $querylimit > 0 ? $rangestart . '-' . ($querylimit - 1) : '0-0'; $items['searchtotal'] = $querycnt; if ($querycnt > 0) { $abentries = mapi_table_queryrows($table, array(PR_ACCOUNT, PR_DISPLAY_NAME, PR_SMTP_ADDRESS, PR_BUSINESS_TELEPHONE_NUMBER, PR_GIVEN_NAME, PR_SURNAME, PR_MOBILE_TELEPHONE_NUMBER, PR_HOME_TELEPHONE_NUMBER, PR_TITLE, PR_COMPANY_NAME, PR_OFFICE_LOCATION), $rangestart, $querylimit); } for ($i = 0; $i < $querylimit; $i++) { $items[$i][SYNC_GAL_DISPLAYNAME] = w2u($abentries[$i][PR_DISPLAY_NAME]); if (strlen(trim($items[$i][SYNC_GAL_DISPLAYNAME])) == 0) { $items[$i][SYNC_GAL_DISPLAYNAME] = w2u($abentries[$i][PR_ACCOUNT]); } $items[$i][SYNC_GAL_ALIAS] = w2u($abentries[$i][PR_ACCOUNT]); //it's not possible not get first and last name of an user //from the gab and user functions, so we just set lastname //to displayname and leave firstname unset //this was changed in Zarafa 6.40, so we try to get first and //last name and fall back to the old behaviour if these values are not set if (isset($abentries[$i][PR_GIVEN_NAME])) { $items[$i][SYNC_GAL_FIRSTNAME] = w2u($abentries[$i][PR_GIVEN_NAME]); } if (isset($abentries[$i][PR_SURNAME])) { $items[$i][SYNC_GAL_LASTNAME] = w2u($abentries[$i][PR_SURNAME]); } if (!isset($items[$i][SYNC_GAL_LASTNAME])) { $items[$i][SYNC_GAL_LASTNAME] = $items[$i][SYNC_GAL_DISPLAYNAME]; } $items[$i][SYNC_GAL_EMAILADDRESS] = w2u($abentries[$i][PR_SMTP_ADDRESS]); //check if an user has an office number or it might produce warnings in the log if (isset($abentries[$i][PR_BUSINESS_TELEPHONE_NUMBER])) { $items[$i][SYNC_GAL_PHONE] = w2u($abentries[$i][PR_BUSINESS_TELEPHONE_NUMBER]); } //check if an user has a mobile number or it might produce warnings in the log if (isset($abentries[$i][PR_MOBILE_TELEPHONE_NUMBER])) { $items[$i][SYNC_GAL_MOBILEPHONE] = w2u($abentries[$i][PR_MOBILE_TELEPHONE_NUMBER]); } //check if an user has a home number or it might produce warnings in the log if (isset($abentries[$i][PR_HOME_TELEPHONE_NUMBER])) { $items[$i][SYNC_GAL_HOMEPHONE] = w2u($abentries[$i][PR_HOME_TELEPHONE_NUMBER]); } if (isset($abentries[$i][PR_COMPANY_NAME])) { $items[$i][SYNC_GAL_COMPANY] = w2u($abentries[$i][PR_COMPANY_NAME]); } if (isset($abentries[$i][PR_TITLE])) { $items[$i][SYNC_GAL_TITLE] = w2u($abentries[$i][PR_TITLE]); } if (isset($abentries[$i][PR_OFFICE_LOCATION])) { $items[$i][SYNC_GAL_OFFICE] = w2u($abentries[$i][PR_OFFICE_LOCATION]); } } return $items; }
/** * 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; }
/** * 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; }
/** * Configures additional parameters used for content synchronization * * @param ContentParameters $contentparameters * * @access public * @return boolean * @throws StatusException */ public function ConfigContentParameters($contentparameters) { $filtertype = $contentparameters->GetFilterType(); switch ($contentparameters->GetContentClass()) { case "Email": $this->restriction = $filtertype || !Utils::CheckMapiExtVersion('7') ? MAPIUtils::GetEmailRestriction(Utils::GetCutOffDate($filtertype)) : false; break; case "Calendar": $this->restriction = $filtertype || !Utils::CheckMapiExtVersion('7') ? MAPIUtils::GetCalendarRestriction($this->store, Utils::GetCutOffDate($filtertype)) : false; break; default: case "Contacts": case "Tasks": $this->restriction = false; break; } $this->contentParameters = $contentparameters; }
/** * Gets the properties from a MAPI object and sets them in the Sync object according to mapping * * @param SyncObject &$message * @param mixed $mapimessage * @param array $mapping * * @access private * @return */ private function getPropsFromMAPI(&$message, $mapimessage, $mapping) { $messageprops = $this->getProps($mapimessage, $mapping); foreach ($mapping as $asprop => $mapiprop) { // Get long strings via openproperty if (isset($messageprops[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))])) { if ($messageprops[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))] == MAPI_E_NOT_ENOUGH_MEMORY_32BIT || $messageprops[mapi_prop_tag(PT_ERROR, mapi_prop_id($mapiprop))] == MAPI_E_NOT_ENOUGH_MEMORY_64BIT) { $messageprops[$mapiprop] = MAPIUtils::readPropStream($mapimessage, $mapiprop); } } if (isset($messageprops[$mapiprop])) { if (mapi_prop_type($mapiprop) == PT_BOOLEAN) { // Force to actual '0' or '1' if ($messageprops[$mapiprop]) { $message->{$asprop} = 1; } else { $message->{$asprop} = 0; } } else { // Special handling for PR_MESSAGE_FLAGS if ($mapiprop == PR_MESSAGE_FLAGS) { $message->{$asprop} = $messageprops[$mapiprop] & 1; } else { if ($mapiprop == PR_RTF_COMPRESSED) { //do not send rtf to the mobile continue; } else { if (is_array($messageprops[$mapiprop])) { $message->{$asprop} = array_map("w2u", $messageprops[$mapiprop]); } else { if (mapi_prop_type($mapiprop) != PT_BINARY && mapi_prop_type($mapiprop) != PT_MV_BINARY) { $message->{$asprop} = w2u($messageprops[$mapiprop]); } else { $message->{$asprop} = $messageprops[$mapiprop]; } } } } } } } }
/** * Sets the message body. * * @param MAPIMessage $mapimessage * @param ContentParameters $contentparameters * @param SyncObject $message */ private function setMessageBody($mapimessage, $contentparameters, &$message) { //get the available body preference types $bpTypes = $contentparameters->GetBodyPreference(); if ($bpTypes !== false) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BodyPreference types: %s", implode(', ', $bpTypes))); //do not send mime data if the client requests it if ($contentparameters->GetMimeSupport() == SYNC_MIMESUPPORT_NEVER && ($key = array_search(SYNC_BODYPREFERENCE_MIME, $bpTypes) !== false)) { unset($bpTypes[$key]); ZLog::Write(LOGLEVEL_DEBUG, sprintf("Remove mime body preference type because the device required no mime support. BodyPreference types: %s", implode(', ', $bpTypes))); } //get the best fitting preference type $bpReturnType = Utils::GetBodyPreferenceBestMatch($bpTypes); ZLog::Write(LOGLEVEL_DEBUG, sprintf("GetBodyPreferenceBestMatch: %d", $bpReturnType)); $bpo = $contentparameters->BodyPreference($bpReturnType); ZLog::Write(LOGLEVEL_DEBUG, sprintf("bpo: truncation size:'%d', allornone:'%d', preview:'%d'", $bpo->GetTruncationSize(), $bpo->GetAllOrNone(), $bpo->GetPreview())); $this->setMessageBodyForType($mapimessage, $bpReturnType, $message); //only set the truncation size data if device set it in request if ($bpo->GetTruncationSize() != false && $bpReturnType != SYNC_BODYPREFERENCE_MIME && $message->asbody->estimatedDataSize > $bpo->GetTruncationSize()) { // Truncated plaintext requests are used on iOS for the preview in the email list. All images and links should be removed - see https://jira.z-hub.io/browse/ZP-1025 if ($bpReturnType == SYNC_BODYPREFERENCE_PLAIN) { ZLog::Write(LOGLEVEL_DEBUG, "MAPIProvider->setMessageBody(): truncated plain-text body requested, stripping all links and images"); // Get more data because of the filtering it's most probably going down in size. It's going to be truncated to the correct size below. $plainbody = stream_get_contents($message->asbody->data, $bpo->GetTruncationSize() * 3); $message->asbody->data = StringStreamWrapper::Open(preg_replace('/<http(s){0,1}:\\/\\/.*?>/i', '', $plainbody)); } // truncate data stream ftruncate($message->asbody->data, $bpo->GetTruncationSize()); $message->asbody->truncated = 1; } // set the preview or windows phones won't show the preview of an email if (Request::GetProtocolVersion() >= 14.0 && $bpo->GetPreview()) { $message->asbody->preview = Utils::Utf8_truncate(MAPIUtils::readPropStream($mapimessage, PR_BODY), $bpo->GetPreview()); } } else { // Override 'body' for truncation $truncsize = Utils::GetTruncSize($contentparameters->GetTruncation()); $this->setMessageBodyForType($mapimessage, SYNC_BODYPREFERENCE_PLAIN, $message); if ($message->bodysize > $truncsize) { $message->body = Utils::Utf8_truncate($message->body, $truncsize); $message->bodytruncated = 1; } if (!isset($message->body) || strlen($message->body) == 0) { $message->body = " "; } if ($contentparameters->GetMimeSupport() == SYNC_MIMESUPPORT_ALWAYS) { //set the html body for iphone in AS 2.5 version $this->imtoinet($mapimessage, $message); } } }
/** * 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; }