function HandleFolderCreate($backend, $protocolversion) { global $zpushdtd; global $input, $output; $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(); $syncstate = $statemachine->getSyncState($synckey); $newsynckey = $statemachine->getNewSyncKey($synckey); // additional information about already seen folders $seenfolders = unserialize($statemachine->getSyncState("s" . $synckey)); if (!$seenfolders) { $seenfolders = array(); } // Configure importer with last state $importer = $backend->GetHierarchyImporter(); $importer->Config($syncstate); if (!$delete) { // Send change $serverid = $importer->ImportFolderChange($serverid, $parentid, $displayname, $type); } else { // delete folder $deletedstat = $importer->ImportFolderDeletion($serverid, 0); } $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)); return true; }
/** * Decodes the WBXML from a WBXMLdecoder until we reach the same depth level of WBXML. * This means that if there are multiple objects at this level, then only the first is * decoded SubOjects are auto-instantiated and decoded using the same functionality * * @param WBXMLDecoder $decoder * * @access public */ public function Decode(&$decoder) { while (1) { $entity = $decoder->getElement(); if ($entity[EN_TYPE] == EN_TYPE_STARTTAG) { if (!($entity[EN_FLAGS] & EN_FLAGS_CONTENT)) { $map = $this->mapping[$entity[EN_TAG]]; if (isset($map[self::STREAMER_ARRAY])) { $this->{$map}[self::STREAMER_VAR] = array(); } else { if (!isset($map[self::STREAMER_TYPE])) { $this->{$map}[self::STREAMER_VAR] = ""; } else { if ($map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE || $map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE_DASHES) { $this->{$map}[self::STREAMER_VAR] = ""; } else { if (isset($map[self::STREAMER_PROP]) && $map[self::STREAMER_PROP] == self::STREAMER_TYPE_SEND_EMPTY) { $this->{$map}[self::STREAMER_VAR] = ""; } } } } continue; } // Found a start tag if (!isset($this->mapping[$entity[EN_TAG]])) { // This tag shouldn't be here, abort ZLog::Write(LOGLEVEL_WBXMLSTACK, sprintf("Tag '%s' unexpected in type XML type '%s'", $entity[EN_TAG], get_class($this))); return false; } else { $map = $this->mapping[$entity[EN_TAG]]; // Handle an array if (isset($map[self::STREAMER_ARRAY])) { while (1) { //do not get start tag for an array without a container if (!(isset($map[self::STREAMER_PROP]) && $map[self::STREAMER_PROP] == self::STREAMER_TYPE_NO_CONTAINER)) { if (!$decoder->getElementStartTag($map[self::STREAMER_ARRAY])) { break; } } if (isset($map[self::STREAMER_TYPE])) { $decoded = new $map[self::STREAMER_TYPE](); $decoded->Decode($decoder); } else { $decoded = $decoder->getElementContent(); } if (!isset($this->{$map}[self::STREAMER_VAR])) { $this->{$map}[self::STREAMER_VAR] = array($decoded); } else { array_push($this->{$map}[self::STREAMER_VAR], $decoded); } if (!$decoder->getElementEndTag()) { //end tag of a container element return false; } if (isset($map[self::STREAMER_PROP]) && $map[self::STREAMER_PROP] == self::STREAMER_TYPE_NO_CONTAINER) { $e = $decoder->peek(); //go back to the initial while if another block of no container elements is found if ($e[EN_TYPE] == EN_TYPE_STARTTAG) { continue 2; } //break on end tag because no container elements block end is reached if ($e[EN_TYPE] == EN_TYPE_ENDTAG) { break; } if (empty($e)) { break; } } } //do not get end tag for an array without a container if (!(isset($map[self::STREAMER_PROP]) && $map[self::STREAMER_PROP] == self::STREAMER_TYPE_NO_CONTAINER)) { if (!$decoder->getElementEndTag()) { //end tag of container return false; } } } else { // Handle single value if (isset($map[self::STREAMER_TYPE])) { // Complex type, decode recursively if ($map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE || $map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE_DASHES) { $decoded = $this->parseDate($decoder->getElementContent()); if (!$decoder->getElementEndTag()) { return false; } } else { if ($map[self::STREAMER_TYPE] == self::STREAMER_TYPE_HEX) { $decoded = hex2bin($decoder->getElementContent()); if (!$decoder->getElementEndTag()) { return false; } } else { if ($map[self::STREAMER_TYPE] == self::STREAMER_TYPE_COMMA_SEPARATED || $map[self::STREAMER_TYPE] == self::STREAMER_TYPE_SEMICOLON_SEPARATED) { $glue = $map[self::STREAMER_TYPE] == self::STREAMER_TYPE_COMMA_SEPARATED ? ", " : "; "; $decoded = explode($glue, $decoder->getElementContent()); if (!$decoder->getElementEndTag()) { return false; } } else { $subdecoder = new $map[self::STREAMER_TYPE](); if ($subdecoder->Decode($decoder) === false) { return false; } $decoded = $subdecoder; if (!$decoder->getElementEndTag()) { ZLog::Write(LOGLEVEL_WBXMLSTACK, sprintf("No end tag for '%s'", $entity[EN_TAG])); return false; } } } } } else { // Simple type, just get content $decoded = $decoder->getElementContent(); if ($decoded === false) { // the tag is declared to have content, but no content is available. // set an empty content $decoded = ""; } if (!$decoder->getElementEndTag()) { ZLog::Write(LOGLEVEL_WBXMLSTACK, sprintf("Unable to get end tag for '%s'", $entity[EN_TAG])); return false; } } // $decoded now contains data object (or string) $this->{$map}[self::STREAMER_VAR] = $decoded; } } } else { if ($entity[EN_TYPE] == EN_TYPE_ENDTAG) { $decoder->ungetElement($entity); break; } else { ZLog::Write(LOGLEVEL_WBXMLSTACK, "Unexpected content in type"); break; } } } }
function HandleFolderCreate($backend, $protocolversion) { global $zpushdtd; global $input, $output; $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; } } // 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(); $syncstate = $statemachine->getSyncState($synckey); $newsynckey = $statemachine->getNewSyncKey($synckey); // Configure importer with last state $importer = $backend->GetHierarchyImporter(); $importer->Config($syncstate); // Send change $serverid = $importer->ImportFolderChange($serverid, $parentid, $displayname, $type); $encoder->startWBXML(); $encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERCREATE); $encoder->startTag(SYNC_FOLDERHIERARCHY_ERROR); $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(); // Save the sync state for the next time $statemachine->setSyncState($newsynckey, $importer->GetState()); return true; }
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; }