Example #1
0
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;
}
Example #2
0
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;
}