function HandleGetItemEstimate($backend, $protocolversion, $devid) { global $zpushdtd; global $input, $output; $collections = array(); $decoder = new WBXMLDecoder($input, $zpushdtd); $encoder = new WBXMLEncoder($output, $zpushdtd); if (!$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE)) { return false; } if (!$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERS)) { return false; } while ($decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDER)) { $collection = array(); if (!$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERTYPE)) { return false; } $class = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } if ($decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERID)) { $collectionid = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } } if (!$decoder->getElementStartTag(SYNC_FILTERTYPE)) { return false; } $filtertype = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } if (!$decoder->getElementStartTag(SYNC_SYNCKEY)) { return false; } $synckey = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } if (!$decoder->getElementEndTag()) { return false; } // compatibility mode - get folderid from the state directory if (!isset($collectionid)) { $collectionid = _getFolderID($devid, $class); } $collection = array(); $collection["synckey"] = $synckey; $collection["class"] = $class; $collection["filtertype"] = $filtertype; $collection["collectionid"] = $collectionid; array_push($collections, $collection); } $encoder->startWBXML(); $encoder->startTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE); foreach ($collections as $collection) { $encoder->startTag(SYNC_GETITEMESTIMATE_RESPONSE); $encoder->startTag(SYNC_GETITEMESTIMATE_STATUS); $encoder->content(1); $encoder->endTag(); $encoder->startTag(SYNC_GETITEMESTIMATE_FOLDER); $encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERTYPE); $encoder->content($collection["class"]); $encoder->endTag(); $encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERID); $encoder->content($collection["collectionid"]); $encoder->endTag(); $encoder->startTag(SYNC_GETITEMESTIMATE_ESTIMATE); $importer = new ImportContentsChangesMem(); $statemachine = new StateMachine(); $syncstate = $statemachine->getSyncState($collection["synckey"]); $exporter = $backend->GetExporter($collection["collectionid"]); $exporter->Config($importer, $collection["class"], $collection["filtertype"], $syncstate, 0, 0); $encoder->content($exporter->GetChangeCount()); $encoder->endTag(); $encoder->endTag(); $encoder->endTag(); } $encoder->endTag(); return true; }
function HandleGetItemEstimate($backend, $protocolversion, $devid) { global $zpushdtd; global $input, $output; global $user; $collections = array(); $decoder = new WBXMLDecoder($input, $zpushdtd); $encoder = new WBXMLEncoder($output, $zpushdtd); // Init state machine $statemachine = new StateMachine($devid, $user); $SyncCache = unserialize($statemachine->getSyncCache()); // Check the validity of the sync cache. If state is errornous set the syncstatus to 2 as retval for client $syncstatus = 1; if (!$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE)) { return false; } if (!$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERS)) { return false; } while ($decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDER)) { $collection = array(); unset($class); unset($filtertype); unset($synckey); $options = array(); $conversationmode = false; while (($type = $decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERTYPE) ? SYNC_GETITEMESTIMATE_FOLDERTYPE : ($decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERID) ? SYNC_GETITEMESTIMATE_FOLDERID : ($decoder->getElementStartTag(SYNC_FILTERTYPE) ? SYNC_FILTERTYPE : ($decoder->getElementStartTag(SYNC_SYNCKEY) ? SYNC_SYNCKEY : ($decoder->getElementStartTag(SYNC_CONVERSATIONMODE) ? SYNC_CONVERSATIONMODE : ($decoder->getElementStartTag(SYNC_OPTIONS) ? SYNC_OPTIONS : -1)))))) != -1) { switch ($type) { case SYNC_GETITEMESTIMATE_FOLDERTYPE: $class = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } break; case SYNC_GETITEMESTIMATE_FOLDERID: $collectionid = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } break; case SYNC_FILTERTYPE: $filtertype = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } break; case SYNC_SYNCKEY: $synckey = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } break; case SYNC_CONVERSATIONMODE: if (($conversationmode = $decoder->getElementContent()) !== false) { if (!$decoder->getElementEndTag()) { return false; } } else { $conversationmode = true; } break; case SYNC_OPTIONS: unset($options_tmp); while (($typeoptions = $decoder->getElementStartTag(SYNC_FOLDERTYPE) ? SYNC_FOLDERTYPE : ($decoder->getElementStartTag(SYNC_MAXITEMS) ? SYNC_MAXITEMS : ($decoder->getElementStartTag(SYNC_FILTERTYPE) ? SYNC_FILTERTYPE : -1))) != -1) { switch ($typeoptions) { case SYNC_FOLDERTYPE: $options_tmp['foldertype'] = $decoder->getElementContent(); if (strtolower($options_tmp['foldertype']) == strtolower($SyncCache['folders'][$collectionid]['class'])) { unset($options_tmp['foldertype']); } if (!$decoder->getElementEndTag()) { return false; } break; case SYNC_MAXITEMS: $options_tmp['maxitems'] = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } break; case SYNC_FILTERTYPE: $options_tmp['filtertype'] = $decoder->getElementContent(); if (!$decoder->getElementEndTag()) { return false; } break; } } if (isset($options_tmp['foldertype'])) { $options['foldertype'] = $options_tmp['foldertype']; $options[$options_tmp['foldertype']] = $options_tmp; } else { $options = array_merge($options, $options_tmp); } if (!$decoder->getElementEndTag()) { // END Options return false; } } } if (!$decoder->getElementEndTag()) { // END Folder return false; } // compatibility mode - get folderid from the state directory if (!isset($collectionid)) { $collectionid = _getFolderID($devid, $class); } if ($protocolversion >= 12.1 && !isset($class)) { $class = $SyncCache['folders'][$collectionid]['class']; } else { if ($protocolversion >= 12.1) { $SyncCache['folders'][$collectionid]['class'] = $class; } } if ($protocolversion >= 12.1 && !isset($options['filtertype']) && isset($SyncCache['collections'][$collectionid]['filtertype'])) { debugLog("filtertype not set! SyncCache Result " . $SyncCache['collections'][$collectionid]['filtertype']); $options['filtertype'] = $SyncCache['collections'][$collectionid]['filtertype']; } else { if ($protocolversion >= 12.1 && isset($options['filtertype'])) { $SyncCache['collections'][$collectionid]['filtertype'] = $options['filtertype']; } } if ($protocolversion >= 12.1 && isset($options['foldertype']) && !isset($options[$options['foldertype']]['filtertype']) && isset($SyncCache['collections'][$collectionid][$options['foldertype']]['filtertype'])) { debugLog("filtertype not set! SyncCache Result " . $SyncCache['collections'][$collectionid][$options['foldertype']]['filtertype']); $options[$options['foldertype']]['filtertype'] = $SyncCache['collections'][$collectionid][$options['foldertype']]['filtertype']; } else { if ($protocolversion >= 12.1 && isset($options['foldertype']) && isset($options[$options['foldertype']]['filtertype'])) { $SyncCache['collections'][$collectionid][$options['foldertype']]['filtertype'] = $options[$options['foldertype']]['filtertype']; } } if ($protocolversion >= 12.1 && !isset($synckey) && isset($SyncCache['collections'][$collectionid]['synckey'])) { $synckey = $SyncCache['collections'][$collectionid]['synckey']; } else { if ($protocolversion >= 12.1 && isset($synckey)) { $SyncCache['collections'][$collectionid]['synckey'] = $synckey; } } if ($protocolversion >= 12.1 && !isset($conversationmode) && isset($SyncCache['collections'][$collectionid]['conversationmode'])) { $conversationmode = $SyncCache['collections'][$collectionid]['conversationmode']; } else { if ($protocolversion >= 12.1 && isset($conversationmode)) { $SyncCache['collections'][$collectionid]['conversationmode'] = $conversationmode; } } $collection = array(); $collection["synckey"] = $synckey; $collection["class"] = $class; if (isset($filtertype)) { $collection["filtertype"] = $filtertype; } $collection["collectionid"] = $collectionid; $collection["options"] = $options; array_push($collections, $collection); } if (!$decoder->getElementEndTag()) { // END Folders return false; } if (!$decoder->getElementEndTag()) { // END GetItemEstimate return false; } $encoder->startWBXML(); $encoder->startTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE); foreach ($collections as $collection) { $encoder->startTag(SYNC_GETITEMESTIMATE_RESPONSE); $importer = new ImportContentsChangesMem(); $statemachine = new StateMachine($devid, $user); $syncstatus = 1; $changecount = 0; $optionchangecount = 0; if (isset($collection["options"]["filtertype"]) || isset($collection["filtertype"])) { $syncstate = $statemachine->getSyncState($collection["synckey"]); $statemachine->cleanOldSyncState($collection["synckey"]); if (is_numeric($syncstate) && $syncstate < 0 && strlen($syncstate) < 8) { debugLog("GetSyncState: Got an error in HandleGetItemEstimate"); $syncstate = false; if ($collection["synckey"] != '0' && $syncstate != -9) { $syncstatus = 2; } else { $syncstatus = 4; } } $exporter = $backend->GetExporter($collection["collectionid"]); $exporter->Config($importer, $collection["class"], isset($collection["options"]["filtertype"]) ? $collection["options"]["filtertype"] : (isset($collection['filtertype']) ? $collection["filtertype"] : 0), $syncstate, 0, 0, false, false); $changecount = $exporter->GetChangeCount(); if ($changecount === false) { $syncstatus = 2; } } // we currently add the optionfoldertype changecount to collection changecount since it is not better documented in specs! // todo: validate with future open protocol specification! if (isset($collection['options']['foldertype'])) { $optionsyncstatus = 1; $optionsyncstate = $statemachine->getSyncState($collection['options']['foldertype'] . $collection["synckey"]); $statemachine->cleanOldSyncState($collection['options']['foldertype'] . $collection["synckey"]); if (is_numeric($optionsyncstate) && $optionsyncstate < 0 && strlen($optionsyncstate) < 8) { debugLog("GetSyncState: Got an error in HandleGetItemEstimate"); $optionsyncstate = false; if ($collection["synckey"] != '0' && $syncstate != -9) { $optionsyncstatus = 2; } else { $optionsyncstatus = 4; } } $optionexporter = $backend->GetExporter($collection["collectionid"]); $optionexporter->Config($importer, $collection['options']['foldertype'], $collection['options'][$collection['options']['foldertype']]['filtertype'], $optionsyncstate, 0, 0, false, false); $optionchangecount = $optionexporter->GetChangeCount(); if ($optionchangecount === false) { $optionsyncstatus = 2; } else { $changecount = $changecount + $optionchangecount; } if ($syncstatus == 1 && $optionsyncstatus != 1) { $syncstatus = $optionsyncstatus; } } $statemachine->cleanOldSyncState("mi" . $collection["synckey"]); $encoder->startTag(SYNC_GETITEMESTIMATE_STATUS); $encoder->content($syncstatus); $encoder->endTag(); $encoder->startTag(SYNC_GETITEMESTIMATE_FOLDER); if ($protocolversion <= 12.0) { $encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERTYPE); debugLog("Collection Class is " . $collection["class"]); $encoder->content($collection["class"]); $encoder->endTag(); } $encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERID); $encoder->content($collection["collectionid"]); $encoder->endTag(); $encoder->startTag(SYNC_GETITEMESTIMATE_ESTIMATE); $encoder->content($changecount); $encoder->endTag(); $encoder->endTag(); $encoder->endTag(); } $encoder->endTag(); $TempSyncCache = unserialize($statemachine->getSyncCache()); if (isset($SyncCache['timestamp']) && $TempSyncCache['timestamp'] > $SyncCache['timestamp']) { debugLog("HandleSync: Changes in cache determined during Sync Wait/Heartbeat, exiting here. SyncCache not updated!"); return true; } else { $statemachine->setSyncCache(serialize($SyncCache)); } return true; }