예제 #1
0
function HandleFolderCreate($backend, $devid, $protocolversion)
{
    global $zpushdtd;
    global $input, $output;
    global $user;
    $decoder = new WBXMLDecoder($input, $zpushdtd);
    $encoder = new WBXMLEncoder($output, $zpushdtd);
    $el = $decoder->getElement();
    if ($el[EN_TYPE] != EN_TYPE_STARTTAG) {
        return false;
    }
    $create = $update = $delete = false;
    if ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERCREATE) {
        $create = true;
    } else {
        if ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERUPDATE) {
            $update = true;
        } else {
            if ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERDELETE) {
                $delete = true;
            }
        }
    }
    if (!$create && !$update && !$delete) {
        return false;
    }
    // SyncKey
    if (!$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SYNCKEY)) {
        return false;
    }
    $synckey = $decoder->getElementContent();
    if (!$decoder->getElementEndTag()) {
        return false;
    }
    // ServerID
    $serverid = false;
    if ($decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID)) {
        $serverid = $decoder->getElementContent();
        if (!$decoder->getElementEndTag()) {
            return false;
        }
    }
    // when creating or updating more information is necessary
    if (!$delete) {
        // Parent
        $parentid = false;
        if ($decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_PARENTID)) {
            $parentid = $decoder->getElementContent();
            if (!$decoder->getElementEndTag()) {
                return false;
            }
        }
        // Displayname
        if (!$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_DISPLAYNAME)) {
            return false;
        }
        $displayname = $decoder->getElementContent();
        if (!$decoder->getElementEndTag()) {
            return false;
        }
        // Type
        $type = false;
        if ($decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_TYPE)) {
            $type = $decoder->getElementContent();
            if (!$decoder->getElementEndTag()) {
                return false;
            }
        }
    }
    if (!$decoder->getElementEndTag()) {
        return false;
    }
    // Get state of hierarchy
    $statemachine = new StateMachine($devid, $user);
    $syncstate = $statemachine->getSyncState($synckey);
    if (is_numeric($syncstate) && $syncstate < 0 && strlen($syncstate) < 8) {
        debugLog("GetSyncState: Got an error in HandleGetFolderCreate - syncstate");
        $syncstate = false;
    }
    $newsynckey = $statemachine->getNewSyncKey($synckey);
    // additional information about already seen folders
    $seenfolders = $statemachine->getSyncState("s" . $synckey);
    if ($synckey != "0" && is_numeric($seenfolders) && $seenfolders < 0) {
        debugLog("GetSyncState: Got an error in HandleGetFolderCreate - seenfolders");
        $seenfolders = false;
    }
    $seenfolders = unserialize($seenfolders);
    if (!$seenfolders) {
        $seenfolders = array();
    }
    if ($synckey != "0") {
        $statemachine->cleanOldSyncState("s" . $synckey);
        $statemachine->cleanOldSyncState($synckey);
    }
    // get the foldercache from synccache
    $foldercache = unserialize($statemachine->getSyncCache());
    if (!$delete && !$create) {
        debugLog("Here1 folder create serverid: " . $serverid . " type: " . $type . " displayname: " . $displayname . " parentid: " . $parentid);
        if (!isset($serverid) || $serverid === false) {
            return false;
        }
        if ($type === false && isset($foldercache['folders'][$serverid]['type'])) {
            $type = $foldercache['folders'][$serverid]['type'];
        }
        if ($displayname === false && isset($foldercache['folders'][$serverid]['displayname'])) {
            $displayname = $foldercache['folders'][$serverid]['displayname'];
        }
        if ($parentid === false && isset($foldercache['folders'][$serverid]['parentid'])) {
            $parentid = $foldercache['folders'][$serverid]['parentid'];
        }
        if ($type === false || $displayname === false || $parentid === false) {
            return false;
        }
        debugLog("Here2 folder create serverid: " . $serverid . " type: " . $type . " displayname: " . $displayname . " parentid: " . $parentid);
    }
    // Configure importer with last state
    $importer = $backend->GetHierarchyImporter();
    $importer->Config($syncstate);
    if (!$delete) {
        // Send change
        $serverid = $importer->ImportFolderChange($serverid, $parentid, $displayname, $type);
        // add the folderinfo to synccache
        $statemachine->updateSyncCacheFolder($foldercache, $serverid, $parentid, $displayname, $type);
    } else {
        // delete folder
        $deletedstat = $importer->ImportFolderDeletion($serverid, 0);
        // remove the folder from synccache
        $statemachine->deleteSyncCacheFolder($foldercache, $serverid);
    }
    $encoder->startWBXML();
    if ($create) {
        // add folder id to the seen folders
        $seenfolders[] = $serverid;
        $encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERCREATE);
        $encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
        $encoder->content(1);
        $encoder->endTag();
        $encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
        $encoder->content($newsynckey);
        $encoder->endTag();
        $encoder->startTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID);
        $encoder->content($serverid);
        $encoder->endTag();
        $encoder->endTag();
        $encoder->endTag();
    } elseif ($update) {
        $encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERUPDATE);
        $encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
        $encoder->content(1);
        $encoder->endTag();
        $encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
        $encoder->content($newsynckey);
        $encoder->endTag();
        $encoder->endTag();
    } elseif ($delete) {
        $encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERDELETE);
        $encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
        $encoder->content($deletedstat);
        $encoder->endTag();
        $encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
        $encoder->content($newsynckey);
        $encoder->endTag();
        $encoder->endTag();
        // remove folder from the folderflags array
        if (($sid = array_search($serverid, $seenfolders)) !== false) {
            unset($seenfolders[$sid]);
            $seenfolders = array_values($seenfolders);
            debugLog("deleted from seenfolders: " . $serverid);
        }
    }
    $encoder->endTag();
    // Save the sync state for the next time
    $statemachine->setSyncState($newsynckey, $importer->GetState());
    $statemachine->setSyncState("s" . $newsynckey, serialize($seenfolders));
    $statemachine->setSyncCache(serialize($foldercache), true);
    return true;
}