Commit 85242faa authored by skummer's avatar skummer

ZP-258 #comment pass contentparameters to importer so on every incoming...

ZP-258 #comment pass contentparameters to importer so on every incoming operation a check can be performed to see if the message is in the sync window #time 4h

git-svn-id: https://z-push.org/svn/z-push/trunk@1500 b7dd7b3b-3a3c-0410-9da9-bee62a6cc5b5
parent 24daddd0
......@@ -69,6 +69,8 @@ class ImportChangesICS implements IImportChanges {
private $conflictsLoaded;
private $conflictsContentParameters;
private $conflictsState;
private $cutoffdate;
private $contentClass;
/**
* Constructor
......@@ -85,6 +87,8 @@ class ImportChangesICS implements IImportChanges {
$this->store = $store;
$this->folderid = $folderid;
$this->conflictsLoaded = false;
$this->cutoffdate = false;
$this->contentClass = false;
if ($folderid) {
$entryid = mapi_msgstore_entryidfromsourcekey($store, $folderid);
......@@ -154,6 +158,33 @@ class ImportChangesICS implements IImportChanges {
return $stat;
}
/**
* Configures additional parameters for content selection
*
* @param ContentParameters $contentparameters
*
* @access public
* @return boolean
* @throws StatusException
*/
public function ConfigContentParameters($contentparameters) {
$filtertype = $contentparameters->GetFilterType();
switch($contentparameters->GetContentClass()) {
case "Email":
$this->cutoffdate = ($filtertype) ? Utils::GetCutOffDate($filtertype) : false;
break;
case "Calendar":
$this->cutoffdate = ($filtertype) ? Utils::GetCutOffDate($filtertype) : false;
break;
default:
case "Contacts":
case "Tasks":
$this->cutoffdate = false;
break;
}
$this->contentClass = $contentparameters->GetContentClass();
}
/**
* Reads state from the Importer
*
......@@ -187,6 +218,33 @@ class ImportChangesICS implements IImportChanges {
return $state;
}
/**
* Checks if a message is in the synchronization interval (window)
* if a filter (e.g. Sync items two weeks back) or limits this synchronization.
* These checks only apply to Emails and Appointments only, Contacts, Tasks and Notes do not have time restrictions.
*
* @param string $messageid the message id to be checked
*
* @access private
* @return boolean
*/
private function isMessageInSyncInterval($messageid) {
$entryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid, hex2bin($messageid));
if(!$entryid) {
ZLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isMessageInSyncInterval('%s'): Error, unable to resolve message id", $id));
return false;
}
$mapimessage = mapi_msgstore_openentry($this->store, $entryid);
if ($this->contentClass == "Email")
return MAPIUtils::IsInEmailSyncInterval($this->store, $mapimessage, $this->cutoffdate);
elseif ($this->contentClass == "Calendar")
return MAPIUtils::IsInCalendarSyncInterval($this->store, $mapimessage, $this->cutoffdate);
return true;
}
/**----------------------------------------------------------------------------------------------------------
* Methods for ContentsExporter
*/
......@@ -281,6 +339,10 @@ class ImportChangesICS implements IImportChanges {
if($id) {
$props[PR_SOURCE_KEY] = $sourcekey;
// on editing an existing message, check if it is in the synchronization interval
if (!$this->isMessageInSyncInterval($id))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageChange('%s','%s'): Message is outside the sync interval. Data not saved.", $id, get_class($message)), SYNC_STATUS_SYNCCANNOTBECOMPLETED);
// check for conflicts
$this->lazyLoadConflicts();
if($this->memChanges->IsChanged($id)) {
......@@ -324,6 +386,10 @@ class ImportChangesICS implements IImportChanges {
* @throws StatusException
*/
public function ImportMessageDeletion($id) {
// check if the message is in the current syncinterval
if (!$this->isMessageInSyncInterval($id))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageDeletion('%s'): Message is outside the sync interval and so far not deleted.", $id), SYNC_STATUS_OBJECTNOTFOUND);
// check for conflicts
$this->lazyLoadConflicts();
if($this->memChanges->IsChanged($id)) {
......@@ -353,6 +419,10 @@ class ImportChangesICS implements IImportChanges {
* @throws StatusException
*/
public function ImportMessageReadFlag($id, $flags) {
// check if the message is in the current syncinterval
if (!$this->isMessageInSyncInterval($id))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageReadFlag('%s','%d'): Message is outside the sync interval. Flags not updated.", $id, $flags), SYNC_STATUS_OBJECTNOTFOUND);
// check for conflicts
/*
* Checking for conflicts is correct at this point, but is a very expensive operation.
......@@ -394,6 +464,10 @@ class ImportChangesICS implements IImportChanges {
if (strtolower($newfolder) == strtolower(bin2hex($this->folderid)) )
throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, source and destination are equal", $id, $newfolder), SYNC_MOVEITEMSSTATUS_SAMESOURCEANDDEST);
// check if the source message is in the current syncinterval
if (!$this->isMessageInSyncInterval($id))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Source message is outside the sync interval. Move not performed.", $id, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
// Get the entryid of the message we're moving
$entryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid, hex2bin($id));
if(!$entryid)
......
......@@ -59,6 +59,7 @@ class MAPIUtils {
* @return array
*/
public static function GetEmailRestriction($timestamp) {
// ATTENTION: ON CHANGING THIS RESTRICTION, MAPIUtils::IsInEmailRestriction() also needs to be changed
$restriction = array ( RES_PROPERTY,
array ( RELOP => RELOP_GE,
ULPROPTAG => PR_MESSAGE_DELIVERY_TIME,
......@@ -74,6 +75,7 @@ class MAPIUtils {
* Create a MAPI restriction to use in the calendar which will
* return all future calendar items, plus those since $timestamp
*
* @param MAPIStore $store the MAPI store
* @param long $timestamp Timestamp since when to include messages
*
* @access public
......@@ -88,6 +90,7 @@ class MAPIUtils {
$props = MAPIMapping::GetAppointmentProperties();
$props = getPropIdsFromStrings($store, $props);
// ATTENTION: ON CHANGING THIS RESTRICTION, MAPIUtils::IsInCalendarRestriction() also needs to be changed
$restriction = Array(RES_OR,
Array(
// OR
......@@ -112,7 +115,7 @@ class MAPIUtils {
Array(RES_OR,
Array(
// OR
// (EXIST(recurrence_enddate_property) && item[isRecurring] == true && item[end] >= start)
// (EXIST(recurrence_enddate_property) && item[isRecurring] == true && recurrence_enddate_property >= start)
Array(RES_AND,
Array(
Array(RES_EXIST,
......@@ -210,14 +213,90 @@ class MAPIUtils {
);
}
/**
* Checks if mapimessage is inside the synchronization interval
* also defined by MAPIUtils::GetEmailRestriction()
*
* @param MAPIStore $store mapi store
* @param MAPIMessage $mapimessage the mapi message to be checked
* @param long $timestamp the lower time limit
*
* @access public
* @return boolean
*/
public static function IsInEmailSyncInterval($store, $mapimessage, $timestamp) {
$p = mapi_getprops($mapimessage, array(PR_MESSAGE_DELIVERY_TIME));
if (isset($p[PR_MESSAGE_DELIVERY_TIME]) && $p[PR_MESSAGE_DELIVERY_TIME] >= $timestamp) {
ZLog::Write(LOGLEVEL_DEBUG, "MAPIUtils->IsInEmailSyncInterval: Message is in the synchronization interval");
return true;
}
ZLog::Write(LOGLEVEL_WARN, "MAPIUtils->IsInEmailSyncInterval: Message is OUTSIDE the synchronization interval");
return false;
}
/**
* Handles recurring item for meeting request coming from tnef
* Checks if mapimessage is inside the synchronization interval
* also defined by MAPIUtils::GetCalendarRestriction()
*
* @param MAPIStore $store mapi store
* @param MAPIMessage $mapimessage the mapi message to be checked
* @param long $timestamp the lower time limit
*
* @access public
* @return boolean
*/
public static function IsInCalendarSyncInterval($store, $mapimessage, $timestamp) {
// This is our viewing window
$start = $timestamp;
$end = 0x7fffffff; // infinite end
$props = MAPIMapping::GetAppointmentProperties();
$props = getPropIdsFromStrings($store, $props);
$p = mapi_getprops($mapimessage, array($props["starttime"], $props["endtime"], $props["recurrenceend"], $props["isrecurring"], $props["recurrenceend"]));
if (
(
isset($p[$props["endtime"]]) && isset($p[$props["starttime"]]) &&
//item.end > window.start && item.start < window.end
$p[$props["endtime"]] > $start && $p[$props["starttime"]] < $end
)
||
(
isset($p[$props["isrecurring"]]) &&
//(EXIST(recurrence_enddate_property) && item[isRecurring] == true && recurrence_enddate_property >= start)
isset($p[$props["recurrenceend"]]) && $p[$props["isrecurring"]] == true && $p[$props["recurrenceend"]] >= $start
)
||
(
isset($p[$props["isrecurring"]]) && isset($p[$props["starttime"]]) &&
//(!EXIST(recurrence_enddate_property) && item[isRecurring] == true && item[start] <= end)
!isset($p[$props["recurrenceend"]]) && $p[$props["isrecurring"]] == true && $p[$props["starttime"]] <= $end
)
) {
ZLog::Write(LOGLEVEL_DEBUG, "MAPIUtils->IsInCalendarSyncInterval: Message is in the synchronization interval");
return true;
}
ZLog::Write(LOGLEVEL_WARN, "MAPIUtils->IsInCalendarSyncInterval: Message is OUTSIDE the synchronization interval");
return false;
}
/**
* Handles recurring item for meeting request coming from tnef
*
* @param array $mapiprops
* @param array $props
*
* @access public
* @return
*/
public static function handleRecurringItem(&$mapiprops, &$props) {
$mapiprops[$props["isrecurringtag"]] = true;
......@@ -237,10 +316,10 @@ class MAPIUtils {
/**
* Reads data of large properties from a stream
*
* @access public
*
* @param MAPIMessage $message
* @param long $prop
*
* @access public
* @return string
*/
public static function readPropStream($message, $prop) {
......@@ -270,8 +349,10 @@ class MAPIUtils {
/**
* Checks if a store supports properties containing unicode characters
*
* @access public
* @param MAPIStore $store
*
* @access public
* @return
*/
public static function IsUnicodeStore($store) {
$supportmask = mapi_getprops($store, array(PR_STORE_SUPPORT_MASK));
......
......@@ -1007,6 +1007,13 @@ class Sync extends RequestProcessor {
}
else
$this->importer->Config($sc->GetParameter($spa, "state"), $spa->GetConflict());
// the CPO is also needed by the importer to check if imported changes
// are inside the sync window - see ZP-258
// TODO ConfigContentParameters needs to be defined in IImportChanges and all implementing importers/backends
// this is currently only supported by the Zarafa Backend
if (method_exists($this->importer, "ConfigContentParameters"))
$this->importer->ConfigContentParameters($spa->GetCPO());
}
catch (StatusException $stex) {
$status = $stex->getCode();
......
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