Пример #1
0
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;
}
Пример #2
0
 /**
  * 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;
             }
         }
     }
 }
Пример #3
0
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;
}
Пример #4
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;
}