Пример #1
0
 /**
  * Returns a list of all known devices with users and when they synchronized for the first time
  *
  * @access public
  * @return array
  */
 public function ListDevicesDetails()
 {
     $devices = ZPushAdmin::ListDevices(false);
     $output = array();
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceUsers::ListLastSync(): found %d devices", count($devices)));
     ZPush::GetTopCollector()->AnnounceInformation(sprintf("Retrieved details of %d devices and getting users", count($devices)), true);
     foreach ($devices as $deviceId) {
         $output[$deviceId] = array();
         $users = ZPushAdmin::ListUsers($deviceId);
         foreach ($users as $user) {
             $output[$deviceId][$user] = ZPushAdmin::GetDeviceDetails($deviceId, $user);
         }
     }
     return $output;
 }
Пример #2
0
 /**
  * Returns a list of folders of the Request::GetGETUser().
  * If the user has not enough permissions an empty result is returned.
  *
  * @access public
  * @return array
  */
 public function ListUserFolders()
 {
     $user = Request::GetGETUser();
     $output = array();
     $hasRights = ZPush::GetBackend()->Setup($user);
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceInfo::ListUserFolders(): permissions to open store '%s': %s", $user, Utils::PrintAsString($hasRights)));
     if ($hasRights) {
         $folders = ZPush::GetBackend()->GetHierarchy();
         ZPush::GetTopCollector()->AnnounceInformation(sprintf("Retrieved details of %d folders", count($folders)), true);
         foreach ($folders as $folder) {
             $folder->StripData();
             unset($folder->Store, $folder->flags, $folder->content, $folder->NoBackendFolder);
             $output[] = $folder;
         }
     }
     return $output;
 }
Пример #3
0
 /**
  * Constructor
  *
  * @access public
  */
 public function DeviceManager()
 {
     $this->statemachine = ZPush::GetStateMachine();
     $this->deviceHash = false;
     $this->devid = Request::GetDeviceID();
     $this->windowSize = array();
     $this->latestFolder = false;
     $this->hierarchySyncRequired = false;
     // only continue if deviceid is set
     if ($this->devid) {
         $this->device = new ASDevice($this->devid, Request::GetDeviceType(), Request::GetGETUser(), Request::GetUserAgent());
         $this->loadDeviceData();
         ZPush::GetTopCollector()->SetUserAgent($this->device->GetDeviceUserAgent());
     } else {
         throw new FatalNotImplementedException("Can not proceed without a device id.");
     }
     $this->loopdetection = new LoopDetection();
     $this->loopdetection->ProcessLoopDetectionInit();
     $this->loopdetection->ProcessLoopDetectionPreviousConnectionFailed();
     $this->stateManager = new StateManager();
     $this->stateManager->SetDevice($this->device);
 }
Пример #4
0
    if ($ex instanceof AuthenticationRequiredException) {
        ZPush::PrintZPushLegal($exclass, sprintf('<pre>%s</pre>', $ex->getMessage()));
        // log the failed login attemt e.g. for fail2ban
        if (defined('LOGAUTHFAIL') && LOGAUTHFAIL != false) {
            ZLog::Write(LOGLEVEL_WARN, sprintf("IP: %s failed to authenticate user '%s'", Request::GetRemoteAddr(), Request::GetAuthUser() ? Request::GetAuthUser() : Request::GetGETUser()));
        }
    } else {
        if ($ex instanceof WBXMLException) {
            ZLog::Write(LOGLEVEL_FATAL, "Request could not be processed correctly due to a WBXMLException. Please report this.");
        } else {
            if (!$ex instanceof ZPushException || $ex->showLegalNotice()) {
                $cmdinfo = Request::GetCommand() ? sprintf(" processing command <i>%s</i>", Request::GetCommand()) : "";
                $extrace = $ex->getTrace();
                $trace = !empty($extrace) ? "\n\nTrace:\n" . print_r($extrace, 1) : "";
                ZPush::PrintZPushLegal($exclass . $cmdinfo, sprintf('<pre>%s</pre>', $ex->getMessage() . $trace));
            }
        }
    }
    // Announce exception to process loop detection
    if (ZPush::GetDeviceManager(false)) {
        ZPush::GetDeviceManager()->AnnounceProcessException($ex);
    }
    // Announce exception if the TopCollector if available
    ZPush::GetTopCollector()->AnnounceInformation(get_class($ex), true);
}
// save device data if the DeviceManager is available
if (ZPush::GetDeviceManager(false)) {
    ZPush::GetDeviceManager()->Save();
}
// end gracefully
ZLog::Write(LOGLEVEL_DEBUG, '-------- End');
Пример #5
0
 /**
  * Checks if the currently known collections for changes for $lifetime seconds.
  * If the backend provides a ChangesSink the sink will be used.
  * If not every $interval seconds an exporter will be configured for each
  * folder to perform GetChangeCount().
  *
  * @param int       $lifetime       (opt) total lifetime to wait for changes / default 600s
  * @param int       $interval       (opt) time between blocking operations of sink or polling / default 30s
  * @param boolean   $onlyPingable   (opt) only check for folders which have the PingableFlag
  *
  * @access public
  * @return boolean              indicating if changes were found
  * @throws StatusException      with code SyncCollections::ERROR_NO_COLLECTIONS if no collections available
  *                              with code SyncCollections::ERROR_WRONG_HIERARCHY if there were errors getting changes
  */
 public function CheckForChanges($lifetime = 600, $interval = 30, $onlyPingable = false)
 {
     $classes = array();
     foreach ($this->collections as $folderid => $spa) {
         if ($onlyPingable && $spa->GetPingableFlag() !== true || !$folderid) {
             continue;
         }
         // the class name will be overwritten for KOE-GAB
         $class = $this->getPingClass($spa);
         if (!isset($classes[$class])) {
             $classes[$class] = 0;
         }
         $classes[$class] += 1;
     }
     if (empty($classes)) {
         $checkClasses = "policies only";
     } else {
         if (array_sum($classes) > 4) {
             $checkClasses = "";
             foreach ($classes as $class => $count) {
                 if ($count == 1) {
                     $checkClasses .= sprintf("%s ", $class);
                 } else {
                     $checkClasses .= sprintf("%s(%d) ", $class, $count);
                 }
             }
         } else {
             $checkClasses = implode(" ", array_keys($classes));
         }
     }
     $pingTracking = new PingTracking();
     $this->changes = array();
     ZPush::GetDeviceManager()->AnnounceProcessAsPush();
     ZPush::GetTopCollector()->AnnounceInformation(sprintf("lifetime %ds", $lifetime), true);
     ZLog::Write(LOGLEVEL_INFO, sprintf("SyncCollections->CheckForChanges(): Waiting for %s changes... (lifetime %d seconds)", empty($classes) ? 'policy' : 'store', $lifetime));
     // use changes sink where available
     $changesSink = ZPush::GetBackend()->HasChangesSink();
     // create changessink and check folder stats if there are folders to Ping
     if (!empty($classes)) {
         // initialize all possible folders
         foreach ($this->collections as $folderid => $spa) {
             if ($onlyPingable && $spa->GetPingableFlag() !== true || !$folderid) {
                 continue;
             }
             $backendFolderId = $spa->GetBackendFolderId();
             // get the user store if this is a additional folder
             $store = ZPush::GetAdditionalSyncFolderStore($backendFolderId);
             // initialize sink if no immediate changes were found so far
             if ($changesSink && empty($this->changes)) {
                 ZPush::GetBackend()->Setup($store);
                 if (!ZPush::GetBackend()->ChangesSinkInitialize($backendFolderId)) {
                     throw new StatusException(sprintf("Error initializing ChangesSink for folder id %s/%s", $folderid, $backendFolderId), self::ERROR_WRONG_HIERARCHY);
                 }
             }
             // check if the folder stat changed since the last sync, if so generate a change for it (only on first run)
             $currentFolderStat = ZPush::GetBackend()->GetFolderStat($store, $backendFolderId);
             if ($this->waitingTime == 0 && ZPush::GetBackend()->HasFolderStats() && $currentFolderStat !== false && $spa->IsExporterRunRequired($currentFolderStat, true)) {
                 $this->changes[$spa->GetFolderId()] = 1;
             }
         }
     }
     if (!empty($this->changes)) {
         ZLog::Write(LOGLEVEL_DEBUG, "SyncCollections->CheckForChanges(): Using ChangesSink but found changes verifying the folder stats");
         return true;
     }
     // wait for changes
     $started = time();
     $endat = time() + $lifetime;
     // always use policy key from the request if it was sent
     $policyKey = $this->GetReferencePolicyKey();
     if (Request::WasPolicyKeySent() && Request::GetPolicyKey() != 0) {
         ZLog::Write(LOGLEVEL_DEBUG, sprintf("refpolkey:'%s', sent polkey:'%s'", $policyKey, Request::GetPolicyKey()));
         $policyKey = Request::GetPolicyKey();
     }
     while (($now = time()) < $endat) {
         // how long are we waiting for changes
         $this->waitingTime = $now - $started;
         $nextInterval = $interval;
         // we should not block longer than the lifetime
         if ($endat - $now < $nextInterval) {
             $nextInterval = $endat - $now;
         }
         // Check if provisioning is necessary
         // if a PolicyKey was sent use it. If not, compare with the ReferencePolicyKey
         if (PROVISIONING === true && $policyKey !== false && ZPush::GetDeviceManager()->ProvisioningRequired($policyKey, true, false)) {
             // the hierarchysync forces provisioning
             throw new StatusException("SyncCollections->CheckForChanges(): Policies or PolicyKey changed. Provisioning required.", self::ERROR_WRONG_HIERARCHY);
         }
         // Check if a hierarchy sync is necessary
         if ($this->countHierarchyChange()) {
             throw new StatusException("SyncCollections->CheckForChanges(): HierarchySync required.", self::HIERARCHY_CHANGED);
         }
         // Check if there are newer requests
         // If so, this process should be terminated if more than 60 secs to go
         if ($pingTracking->DoForcePingTimeout()) {
             // do not update CPOs because another process has already read them!
             $this->saveData = false;
             // more than 60 secs to go?
             if ($now + 60 < $endat) {
                 ZPush::GetTopCollector()->AnnounceInformation(sprintf("Forced timeout after %ds", $now - $started), true);
                 throw new StatusException(sprintf("SyncCollections->CheckForChanges(): Timeout forced after %ss from %ss due to other process", $now - $started, $lifetime), self::OBSOLETE_CONNECTION);
             }
         }
         // Use changes sink if available
         if ($changesSink) {
             ZPush::GetTopCollector()->AnnounceInformation(sprintf("Sink %d/%ds on %s", $now - $started, $lifetime, $checkClasses));
             $notifications = ZPush::GetBackend()->ChangesSink($nextInterval);
             $validNotifications = false;
             foreach ($notifications as $backendFolderId) {
                 // Check hierarchy notifications
                 if ($backendFolderId === IBackend::HIERARCHYNOTIFICATION) {
                     // wait two seconds before validating this notification, because it could potentially be made by the mobile and we need some time to update the states.
                     sleep(2);
                     // check received hierarchy notifications by exporting
                     if ($this->countHierarchyChange(true)) {
                         throw new StatusException("SyncCollections->CheckForChanges(): HierarchySync required.", self::HIERARCHY_CHANGED);
                     }
                 } else {
                     // the backend will notify on the backend folderid
                     $folderid = ZPush::GetDeviceManager()->GetFolderIdForBackendId($backendFolderId);
                     // check if the notification on the folder is within our filter
                     if ($this->CountChange($folderid)) {
                         ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): Notification received on folder '%s'", $folderid));
                         $validNotifications = true;
                         $this->waitingTime = time() - $started;
                     } else {
                         ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): Notification received on folder '%s', but it is not relevant", $folderid));
                     }
                 }
             }
             if ($validNotifications) {
                 return true;
             }
         } else {
             ZPush::GetTopCollector()->AnnounceInformation(sprintf("Polling %d/%ds on %s", $now - $started, $lifetime, $checkClasses));
             if ($this->CountChanges($onlyPingable)) {
                 ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): Found changes polling"));
                 return true;
             } else {
                 sleep($nextInterval);
             }
         }
         // end polling
     }
     // end wait for changes
     ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): no changes found after %ds", time() - $started));
     return false;
 }
Пример #6
0
 /**
  * Checks if the currently known collections for changes for $lifetime seconds.
  * If the backend provides a ChangesSink the sink will be used.
  * If not every $interval seconds an exporter will be configured for each
  * folder to perform GetChangeCount().
  *
  * @param int       $lifetime       (opt) total lifetime to wait for changes / default 600s
  * @param int       $interval       (opt) time between blocking operations of sink or polling / default 30s
  * @param boolean   $onlyPingable   (opt) only check for folders which have the PingableFlag
  *
  * @access public
  * @return boolean              indicating if changes were found
  * @throws StatusException      with code SyncCollections::ERROR_NO_COLLECTIONS if no collections available
  *                              with code SyncCollections::ERROR_WRONG_HIERARCHY if there were errors getting changes
  */
 public function CheckForChanges($lifetime = 600, $interval = 30, $onlyPingable = false)
 {
     $classes = array();
     foreach ($this->collections as $folderid => $spa) {
         if ($onlyPingable && $spa->GetPingableFlag() !== true) {
             continue;
         }
         if (!isset($classes[$spa->GetContentClass()])) {
             $classes[$spa->GetContentClass()] = 0;
         }
         $classes[$spa->GetContentClass()] += 1;
     }
     if (empty($classes)) {
         $checkClasses = "policies only";
     } else {
         if (array_sum($classes) > 4) {
             $checkClasses = "";
             foreach ($classes as $class => $count) {
                 if ($count == 1) {
                     $checkClasses .= sprintf("%s ", $class);
                 } else {
                     $checkClasses .= sprintf("%s(%d) ", $class, $count);
                 }
             }
         } else {
             $checkClasses = implode(" ", array_keys($classes));
         }
     }
     $pingTracking = ZPush::GetPingTracking();
     $this->changes = array();
     $changesAvailable = false;
     ZPush::GetDeviceManager()->AnnounceProcessAsPush();
     ZPush::GetTopCollector()->AnnounceInformation(sprintf("lifetime %ds", $lifetime), true);
     ZLog::Write(LOGLEVEL_INFO, sprintf("SyncCollections->CheckForChanges(): Waiting for %s changes... (lifetime %d seconds)", empty($classes) ? 'policy' : 'store', $lifetime));
     // use changes sink where available
     $changesSink = false;
     $forceRealExport = 0;
     // do not create changessink if there are no folders
     if (!empty($classes) && ZPush::GetBackend()->HasChangesSink()) {
         $changesSink = true;
         // initialize all possible folders
         foreach ($this->collections as $folderid => $spa) {
             if ($onlyPingable && $spa->GetPingableFlag() !== true) {
                 continue;
             }
             // switch user store if this is a additional folder and initialize sink
             ZPush::GetBackend()->Setup(ZPush::GetAdditionalSyncFolderStore($folderid));
             if (!ZPush::GetBackend()->ChangesSinkInitialize($folderid)) {
                 throw new StatusException(sprintf("Error initializing ChangesSink for folder id '%s'", $folderid), self::ERROR_WRONG_HIERARCHY);
             }
         }
     }
     // wait for changes
     $started = time();
     $endat = time() + $lifetime;
     // always use policy key from the request if it was sent
     $policyKey = $this->GetReferencePolicyKey();
     if (Request::WasPolicyKeySent() && Request::GetPolicyKey() != 0) {
         ZLog::Write(LOGLEVEL_DEBUG, sprintf("refpolkey:'%s', sent polkey:'%s'", $policyKey, Request::GetPolicyKey()));
         $policyKey = Request::GetPolicyKey();
     }
     while (($now = time()) < $endat) {
         // how long are we waiting for changes
         $this->waitingTime = $now - $started;
         $nextInterval = $interval;
         // we should not block longer than the lifetime
         if ($endat - $now < $nextInterval) {
             $nextInterval = $endat - $now;
         }
         // Check if provisioning is necessary
         // if a PolicyKey was sent use it. If not, compare with the ReferencePolicyKey
         if (PROVISIONING === true && $policyKey !== false && ZPush::GetDeviceManager()->ProvisioningRequired($policyKey, true)) {
             // the hierarchysync forces provisioning
             throw new StatusException("SyncCollections->CheckForChanges(): PolicyKey changed. Provisioning required.", self::ERROR_WRONG_HIERARCHY);
         }
         // Check if a hierarchy sync is necessary
         if (ZPush::GetDeviceManager()->IsHierarchySyncRequired()) {
             throw new StatusException("SyncCollections->CheckForChanges(): HierarchySync required.", self::HIERARCHY_CHANGED);
         }
         // Check if there are newer requests
         // If so, this process should be terminated if more than 60 secs to go
         if ($pingTracking->DoForcePingTimeout()) {
             // do not update CPOs because another process has already read them!
             $this->saveData = false;
             // more than 60 secs to go?
             if ($now + 60 < $endat) {
                 ZPush::GetTopCollector()->AnnounceInformation(sprintf("Forced timeout after %ds", $now - $started), true);
                 throw new StatusException(sprintf("SyncCollections->CheckForChanges(): Timeout forced after %ss from %ss due to other process", $now - $started, $lifetime), self::OBSOLETE_CONNECTION);
             }
         }
         // Use changes sink if available
         if ($changesSink) {
             // in some occasions we do realize a full export to see if there are pending changes
             // every 5 minutes this is also done to see if there were "missed" notifications
             if (SINK_FORCERECHECK !== false && $forceRealExport + SINK_FORCERECHECK <= $now) {
                 if ($this->CountChanges($onlyPingable)) {
                     ZLog::Write(LOGLEVEL_DEBUG, "SyncCollections->CheckForChanges(): Using ChangesSink but found relevant changes on regular export");
                     return true;
                 }
                 $forceRealExport = $now;
             }
             ZPush::GetTopCollector()->AnnounceInformation(sprintf("Sink %d/%ds on %s", $now - $started, $lifetime, $checkClasses));
             $notifications = ZPush::GetBackend()->ChangesSink($nextInterval);
             $validNotifications = false;
             foreach ($notifications as $folderid) {
                 // check if the notification on the folder is within our filter
                 if ($this->CountChange($folderid)) {
                     ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): Notification received on folder '%s'", $folderid));
                     $validNotifications = true;
                     $this->waitingTime = time() - $started;
                 } else {
                     ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): Notification received on folder '%s', but it is not relevant", $folderid));
                 }
             }
             if ($validNotifications) {
                 return true;
             }
         } else {
             ZPush::GetTopCollector()->AnnounceInformation(sprintf("Polling %d/%ds on %s", $now - $started, $lifetime, $checkClasses));
             if ($this->CountChanges($onlyPingable)) {
                 ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): Found changes polling"));
                 return true;
             } else {
                 sleep($nextInterval);
             }
         }
         // end polling
     }
     // end wait for changes
     ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->CheckForChanges(): no changes found after %ds", time() - $started));
     return false;
 }
Пример #7
0
 /**
  * Constructor
  *
  * @access public
  */
 public function ZPushTop()
 {
     $this->starttime = time();
     $this->currenttime = time();
     $this->action = "";
     $this->filter = false;
     $this->status = false;
     $this->statusexpire = 0;
     $this->helpexpire = 0;
     $this->doingTail = false;
     $this->wide = false;
     $this->terminate = false;
     $this->showPush = true;
     $this->showOption = self::SHOW_DEFAULT;
     $this->showTermSec = self::SHOW_TERM_DEFAULT_TIME;
     $this->scrSize = array('width' => 80, 'height' => 24);
     $this->pingInterval = defined('PING_INTERVAL') && PING_INTERVAL > 0 ? PING_INTERVAL : 12;
     // get a TopCollector
     $this->topCollector = ZPush::GetTopCollector();
 }
Пример #8
0
 /**
  * Indicates if the next messages should be ignored (not be sent to the mobile!)
  *
  * @param string  $messageid        (opt) id of the message which is to be exported next
  * @param string  $folderid         (opt) parent id of the message
  * @param boolean $markAsIgnored    (opt) to peek without setting the next message to be
  *                                  ignored, set this value to false
  * @access public
  * @return boolean
  */
 public function IgnoreNextMessage($markAsIgnored = true, $messageid = false, $folderid = false)
 {
     // as the next message id is not available at all point this method is called, we use different indicators.
     // potentialbroken indicates that we know that the broken message should be exported next,
     // alltho we do not know for sure as it's export message orders can change
     // if the $messageid is available and matches then we are sure and only then really ignore it
     $potentialBroken = false;
     $realBroken = false;
     if (Request::GetCommandCode() == ZPush::COMMAND_SYNC && $this->ignore_messageid !== false) {
         $potentialBroken = true;
     }
     if ($messageid !== false && $this->ignore_messageid == $messageid) {
         $realBroken = true;
     }
     // this call is just to know what should be happening
     // no further actions necessary
     if ($markAsIgnored === false) {
         return $potentialBroken;
     }
     // we should really do something here
     // first we check if we are in the loop mode, if so,
     // we update the potential broken id message so we loop count the same message
     $changedData = false;
     // exclusive block
     if ($this->blockMutex()) {
         $loopdata = $this->hasData() ? $this->getData() : array();
         // check and initialize the array structure
         $this->checkArrayStructure($loopdata, $folderid);
         $current = $loopdata[self::$devid][self::$user][$folderid];
         // we found our broken message!
         if ($realBroken) {
             $this->ignore_messageid = false;
             $current['ignored'] = $messageid;
             $changedData = true;
             // check if this message was broken before - here we know that it still is and remove it from the tracking
             $brokenkey = self::BROKENMSGS . "-" . $folderid;
             if (isset($loopdata[self::$devid][self::$user][$brokenkey]) && isset($loopdata[self::$devid][self::$user][$brokenkey][$messageid])) {
                 ZLog::Write(LOGLEVEL_DEBUG, sprintf("LoopDetection->IgnoreNextMessage(): previously broken message '%s' is still broken and will not be tracked anymore", $messageid));
                 unset($loopdata[self::$devid][self::$user][$brokenkey][$messageid]);
             }
         } else {
             // update potential id if looping on an item
             if (isset($current['loopcount'])) {
                 $current['potential'] = $messageid;
                 // this message should be the broken one, but is not!!
                 // we should reset the loop count because this is certainly not the broken one
                 if ($potentialBroken) {
                     $current['loopcount'] = 1;
                     ZLog::Write(LOGLEVEL_DEBUG, "LoopDetection->IgnoreNextMessage(): this should be the broken one, but is not! Resetting loop count.");
                 }
                 ZLog::Write(LOGLEVEL_DEBUG, sprintf("LoopDetection->IgnoreNextMessage(): Loop mode, potential broken message id '%s'", $current['potential']));
                 $changedData = true;
             }
         }
         // update loop data
         if ($changedData == true) {
             $loopdata[self::$devid][self::$user][$folderid] = $current;
             $ok = $this->setData($loopdata);
         }
         $this->releaseMutex();
     }
     // end exclusive block
     if ($realBroken) {
         ZPush::GetTopCollector()->AnnounceInformation("Broken message ignored", true);
     }
     return $realBroken;
 }
Пример #9
0
 /**
  * Marks a a device of the Request::GetGETUser() for resynchronization
  *
  * @param string    $deviceId       the device id
  *
  * @access public
  * @return boolean
  * @throws SoapFault
  */
 public function ResyncDevice($deviceId)
 {
     $deviceId = preg_replace("/[^A-Za-z0-9]/", "", $deviceId);
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceDevice::ResyncDevice('%s'): mark device of user '%s' for resynchronization", $deviceId, Request::GetGETUser()));
     if (!ZPushAdmin::ResyncDevice(Request::GetGETUser(), $deviceId)) {
         ZPush::GetTopCollector()->AnnounceInformation(ZLog::GetLastMessage(LOGLEVEL_ERROR), true);
         throw new SoapFault("ERROR", ZLog::GetLastMessage(LOGLEVEL_ERROR));
     }
     ZPush::GetTopCollector()->AnnounceInformation(sprintf("Resync requested - device id '%s'", $deviceId), true);
     return true;
 }
 /**
  * Initialize the RequestProcessor
  *
  * @access public
  * @return
  */
 public static function Initialize()
 {
     self::$backend = ZPush::GetBackend();
     self::$deviceManager = ZPush::GetDeviceManager();
     self::$topCollector = ZPush::GetTopCollector();
     if (!ZPush::CommandNeedsPlainInput(Request::GetCommandCode())) {
         self::$decoder = new WBXMLDecoder(Request::GetInputStream());
     }
     self::$encoder = new WBXMLEncoder(Request::GetOutputStream(), Request::GetGETAcceptMultipart());
 }
Пример #11
0
 /**
  * Announces that the current process is a push connection to the process loop
  * detection and to the Top collector
  *
  * @access public
  * @return boolean
  */
 public function AnnounceProcessAsPush()
 {
     ZLog::Write(LOGLEVEL_DEBUG, "Announce process as PUSH connection");
     return $this->loopdetection->ProcessLoopDetectionSetAsPush() && ZPush::GetTopCollector()->SetAsPushConnection();
 }
Пример #12
0
 /**
  * Removes an additional folder from the given device and the Request::GetGETUser().
  *
  * @param string    $deviceId       device id of where the folder should be removed.
  * @param string    $add_folderid   the folder id of the additional folder.
  *
  * @access public
  * @return boolean
  */
 public function AdditionalFolderRemove($deviceId, $add_folderid)
 {
     $user = Request::GetGETUser();
     $deviceId = preg_replace("/[^A-Za-z0-9]/", "", $deviceId);
     $add_folderid = preg_replace("/[^A-Za-z0-9]/", "", $add_folderid);
     $status = ZPushAdmin::AdditionalFolderRemove($user, $deviceId, $add_folderid);
     if (!$status) {
         ZPush::GetTopCollector()->AnnounceInformation(ZLog::GetLastMessage(LOGLEVEL_ERROR), true);
         throw new SoapFault("ERROR", ZLog::GetLastMessage(LOGLEVEL_ERROR));
     }
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceDevice::AdditionalFolderRemove(): removed folder for device '%s' of user '%s': %s", $deviceId, $user, Utils::PrintAsString($status)));
     ZPush::GetTopCollector()->AnnounceInformation("Removed additional folder", true);
     return $status;
 }
Пример #13
0
 /**
  * Indicates if the next messages should be ignored (not be sent to the mobile!)
  *
  * @param  string  $messageid     (opt) id of the message which is to be exported next
  * @param  string  $folderid      (opt) parent id of the message
  * @param  boolean $markAsIgnored (opt) to peek without setting the next message to be
  *                                ignored, set this value to false
  * @access public
  * @return boolean
  */
 public function IgnoreNextMessage($markAsIgnored = true, $messageid = false, $folderid = false)
 {
     // as the next message id is not available at all point this method is called, we use different indicators.
     // potentialbroken indicates that we know that the broken message should be exported next,
     // alltho we do not know for sure as it's export message orders can change
     // if the $messageid is available and matches then we are sure and only then really ignore it
     $potentialBroken = false;
     $realBroken = false;
     if (Request::GetCommandCode() == ZPush::COMMAND_SYNC && $this->ignore_messageid !== false) {
         $potentialBroken = true;
     }
     if ($messageid !== false && $this->ignore_messageid == $messageid) {
         $realBroken = true;
     }
     // this call is just to know what should be happening
     // no further actions necessary
     if ($markAsIgnored === false) {
         return $potentialBroken;
     }
     // we should really do something here
     // first we check if we are in the loop mode, if so,
     // we update the potential broken id message so we loop count the same message
     // we found our broken message!
     if ($realBroken) {
         $this->ignore_messageid = false;
         self::$redis->hSet(self::$keyfolder . $folderid, 'ignored', $messageid);
         // check if this message was broken before - here we know that it still is and remove it from the tracking
         if ($this->RemoveBrokenMessage($folderid, $messageid)) {
             ZLog::Write(LOGLEVEL_DEBUG, "LoopDetection->IgnoreNextMessage(): previously broken message '{$messageid}' is still broken and will not be tracked anymore (folder = {$folderid})");
         }
         ZPush::GetTopCollector()->AnnounceInformation("Broken message ignored", true);
     } else {
         // update potential id if looping on an item
         if (self::$redis->hGet(self::$keyfolder . $folderid, 'loopcount') !== false) {
             // this message should be the broken one, but is not!!
             // we should reset the loop count because this is certainly not the broken one
             if ($potentialBroken) {
                 self::$redis->hMset(self::$keyfolder . $folderid, array('potential' => $messageid, 'loopcount' => 1));
                 ZLog::Write(LOGLEVEL_DEBUG, "LoopDetection->IgnoreNextMessage(): this should be the broken one, but is not! Resetting loop count.");
             } else {
                 self::$redis->hSet(self::$keyfolder . $folderid, 'potential', $messageid);
             }
             ZLog::Write(LOGLEVEL_DEBUG, sprintf("LoopDetection->IgnoreNextMessage(): Loop mode, potential broken message id '%s'", $messageid));
         }
     }
     return $realBroken;
 }