Пример #1
0
 /**
  * Invalidates all pingable flags for all folders.
  *
  * @access public
  * @return boolean
  */
 public static function InvalidatePingableFlags()
 {
     ZLog::Write(LOGLEVEL_DEBUG, "SyncCollections::InvalidatePingableFlags(): Invalidating now");
     try {
         $sc = new SyncCollections();
         $sc->LoadAllCollections();
         foreach ($sc as $folderid => $spa) {
             if ($spa->GetPingableFlag() == true) {
                 $spa->DelPingableFlag();
                 $sc->SaveCollection($spa);
             }
         }
         return true;
     } catch (ZPushException $e) {
     }
     return false;
 }
 /**
  * Returns the timestamp of the last synchronization of a device.
  *
  * @param $device       an ASDevice
  *
  * @access public
  * @return int                  timestamp
  */
 public static function GetLastSyncTimeOfDevice(&$device)
 {
     // we need a StateManager for this operation
     $stateManager = new StateManager();
     $stateManager->SetDevice($device);
     $sc = new SyncCollections();
     $sc->SetStateManager($stateManager);
     // load all collections of device without loading states or checking permissions
     $sc->LoadAllCollections(true, false, false);
     return $sc->GetLastSyncTime();
 }
Пример #3
0
 /**
  * Handles the Ping command
  *
  * @param int       $commandCode
  *
  * @access public
  * @return boolean
  */
 public function Handle($commandCode)
 {
     $interval = defined('PING_INTERVAL') && PING_INTERVAL > 0 ? PING_INTERVAL : 30;
     $pingstatus = false;
     $fakechanges = array();
     $foundchanges = false;
     // Contains all requested folders (containers)
     $sc = new SyncCollections();
     // Load all collections - do load states and check permissions
     try {
         $sc->LoadAllCollections(true, true, true);
     } catch (StateNotFoundException $snfex) {
         $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
         self::$topCollector->AnnounceInformation("StateNotFoundException: require HierarchySync", true);
     } catch (StateInvalidException $snfex) {
         // we do not have a ping status for this, but SyncCollections should have generated fake changes for the folders which are broken
         $fakechanges = $sc->GetChangedFolderIds();
         $foundchanges = true;
         self::$topCollector->AnnounceInformation("StateInvalidException: force sync", true);
     } catch (StatusException $stex) {
         $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
         self::$topCollector->AnnounceInformation("StatusException: require HierarchySync", true);
     }
     ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): reference PolicyKey for PING: %s", $sc->GetReferencePolicyKey()));
     // receive PING initialization data
     if (self::$decoder->getElementStartTag(SYNC_PING_PING)) {
         self::$topCollector->AnnounceInformation("Processing PING data");
         ZLog::Write(LOGLEVEL_DEBUG, "HandlePing(): initialization data received");
         if (self::$decoder->getElementStartTag(SYNC_PING_LIFETIME)) {
             $sc->SetLifetime(self::$decoder->getElementContent());
             self::$decoder->getElementEndTag();
         }
         if (($el = self::$decoder->getElementStartTag(SYNC_PING_FOLDERS)) && $el[EN_FLAGS] & EN_FLAGS_CONTENT) {
             // remove PingableFlag from all collections
             foreach ($sc as $folderid => $spa) {
                 $spa->DelPingableFlag();
             }
             while (self::$decoder->getElementStartTag(SYNC_PING_FOLDER)) {
                 while (1) {
                     if (self::$decoder->getElementStartTag(SYNC_PING_SERVERENTRYID)) {
                         $folderid = self::$decoder->getElementContent();
                         self::$decoder->getElementEndTag();
                     }
                     if (self::$decoder->getElementStartTag(SYNC_PING_FOLDERTYPE)) {
                         $class = self::$decoder->getElementContent();
                         self::$decoder->getElementEndTag();
                     }
                     $e = self::$decoder->peek();
                     if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
                         self::$decoder->getElementEndTag();
                         break;
                     }
                 }
                 $spa = $sc->GetCollection($folderid);
                 if (!$spa) {
                     // The requested collection is not synchronized.
                     // check if the HierarchyCache is available, if not, trigger a HierarchySync
                     try {
                         self::$deviceManager->GetFolderClassFromCacheByID($folderid);
                     } catch (NoHierarchyCacheAvailableException $nhca) {
                         ZLog::Write(LOGLEVEL_INFO, sprintf("HandlePing(): unknown collection '%s', triggering HierarchySync", $folderid));
                         $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
                     }
                     // Trigger a Sync request because then the device will be forced to resync this folder.
                     $fakechanges[$folderid] = 1;
                     $foundchanges = true;
                 } else {
                     if ($class == $spa->GetContentClass()) {
                         $spa->SetPingableFlag(true);
                         ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): using saved sync state for '%s' id '%s'", $spa->GetContentClass(), $folderid));
                     }
                 }
             }
             if (!self::$decoder->getElementEndTag()) {
                 return false;
             }
         }
         if (!self::$decoder->getElementEndTag()) {
             return false;
         }
         // save changed data
         foreach ($sc as $folderid => $spa) {
             $sc->SaveCollection($spa);
         }
     } else {
         // if no ping initialization data was sent, we check if we have pingable folders
         // if not, we indicate that there is nothing to do.
         if (!$sc->PingableFolders()) {
             $pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
             ZLog::Write(LOGLEVEL_DEBUG, "HandlePing(): no pingable folders found and no initialization data sent. Returning SYNC_PINGSTATUS_FAILINGPARAMS.");
         }
     }
     // Check for changes on the default LifeTime, set interval and ONLY on pingable collections
     try {
         if (!$pingstatus && empty($fakechanges)) {
             $foundchanges = $sc->CheckForChanges($sc->GetLifetime(), $interval, true);
         }
     } catch (StatusException $ste) {
         switch ($ste->getCode()) {
             case SyncCollections::ERROR_NO_COLLECTIONS:
                 $pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
                 break;
             case SyncCollections::ERROR_WRONG_HIERARCHY:
                 $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
                 self::$deviceManager->AnnounceProcessStatus(false, $pingstatus);
                 break;
             case SyncCollections::OBSOLETE_CONNECTION:
                 $foundchanges = false;
                 break;
         }
     }
     self::$encoder->StartWBXML();
     self::$encoder->startTag(SYNC_PING_PING);
     self::$encoder->startTag(SYNC_PING_STATUS);
     if (isset($pingstatus) && $pingstatus) {
         self::$encoder->content($pingstatus);
     } else {
         self::$encoder->content($foundchanges ? SYNC_PINGSTATUS_CHANGES : SYNC_PINGSTATUS_HBEXPIRED);
     }
     self::$encoder->endTag();
     if (!$pingstatus) {
         self::$encoder->startTag(SYNC_PING_FOLDERS);
         if (empty($fakechanges)) {
             $changes = $sc->GetChangedFolderIds();
         } else {
             $changes = $fakechanges;
         }
         foreach ($changes as $folderid => $changecount) {
             if ($changecount > 0) {
                 self::$encoder->startTag(SYNC_PING_FOLDER);
                 self::$encoder->content($folderid);
                 self::$encoder->endTag();
                 if (empty($fakechanges)) {
                     self::$topCollector->AnnounceInformation(sprintf("Found change in %s", $sc->GetCollection($folderid)->GetContentClass()), true);
                 }
             }
         }
         self::$encoder->endTag();
     }
     self::$encoder->endTag();
     return true;
 }
Пример #4
0
 /**
  * Returns details of a device like synctimes,
  * policy and wipe status, synched folders etc
  *
  * @param string    $devid      device id
  * @param string    $user       user to be looked up
  *
  * @return ASDevice object
  * @access public
  */
 public static function GetDeviceDetails($devid, $user)
 {
     try {
         $device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
         $device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
         $device->StripData();
         try {
             // we need a StateManager for this operation
             $stateManager = new StateManager();
             $stateManager->SetDevice($device);
             $sc = new SyncCollections();
             $sc->SetStateManager($stateManager);
             // load all collections of device without loading states or checking permissions
             $sc->LoadAllCollections(true, false, false);
             if ($sc->GetLastSyncTime()) {
                 $device->SetLastSyncTime($sc->GetLastSyncTime());
             }
             // get information about the folder synchronization status from SyncCollections
             $folders = $device->GetAllFolderIds();
             foreach ($folders as $folderid) {
                 $fstatus = $device->GetFolderSyncStatus($folderid);
                 if ($fstatus !== false && isset($fstatus[ASDevice::FOLDERSYNCSTATUS])) {
                     $spa = $sc->GetCollection($folderid);
                     $total = $spa->GetFolderSyncTotal();
                     $todo = $spa->GetFolderSyncRemaining();
                     $fstatus['status'] = $fstatus[ASDevice::FOLDERSYNCSTATUS] == 1 ? 'Initialized' : 'Synchronizing';
                     $fstatus['total'] = $total;
                     $fstatus['done'] = $total - $todo;
                     $fstatus['todo'] = $todo;
                     $device->SetFolderSyncStatus($folderid, $fstatus);
                 }
             }
         } catch (StateInvalidException $sive) {
             ZLog::Write(LOGLEVEL_WARN, sprintf("ZPushAdmin::GetDeviceDetails(): device '%s' of user '%s' has invalid states. Please sync to solve this issue.", $devid, $user));
             $device->SetDeviceError("Invalid states. Please force synchronization!");
         }
         return $device;
     } catch (StateNotFoundException $e) {
         ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::GetDeviceDetails(): device '%s' of user '%s' can not be found", $devid, $user));
         return false;
     }
 }