/** * 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; }
/** * Prints detailed informations about a device * * @param string $deviceId the id of the device * @param string $user the user * * @return * @access private */ private static function printDeviceData($deviceId, $user) { $device = ZPushAdmin::GetDeviceDetails($deviceId, $user); if (!$device instanceof ASDevice) { echo sprintf("Folder resync failed: %s\n", ZLog::GetLastMessage(LOGLEVEL_ERROR)); return false; } // Gather some statistics about synchronized folders $folders = $device->GetAllFolderIds(); $synchedFolders = 0; $synchedFolderTypes = array(); $syncedFoldersInProgress = 0; foreach ($folders as $folderid) { if ($device->GetFolderUUID($folderid)) { $synchedFolders++; $type = $device->GetFolderType($folderid); switch ($type) { case SYNC_FOLDER_TYPE_APPOINTMENT: case SYNC_FOLDER_TYPE_USER_APPOINTMENT: $gentype = "Calendars"; break; case SYNC_FOLDER_TYPE_CONTACT: case SYNC_FOLDER_TYPE_USER_CONTACT: $gentype = "Contacts"; break; case SYNC_FOLDER_TYPE_TASK: case SYNC_FOLDER_TYPE_USER_TASK: $gentype = "Tasks"; break; case SYNC_FOLDER_TYPE_NOTE: case SYNC_FOLDER_TYPE_USER_NOTE: $gentype = "Notes"; break; default: $gentype = "Emails"; break; } if (!isset($synchedFolderTypes[$gentype])) { $synchedFolderTypes[$gentype] = 0; } $synchedFolderTypes[$gentype]++; // set the folder name for all folders which are not fully synchronized yet $fstatus = $device->GetFolderSyncStatus($folderid); if ($fstatus !== false && is_array($fstatus)) { // TODO would be nice if we could see the real name of the folder, right now we use the folder type as name $fstatus['name'] = $gentype; $device->SetFolderSyncStatus($folderid, $fstatus); $syncedFoldersInProgress++; } } } $folderinfo = ""; foreach ($synchedFolderTypes as $gentype => $count) { $folderinfo .= $gentype; if ($count > 1) { $folderinfo .= "({$count})"; } $folderinfo .= " "; } if (!$folderinfo) { $folderinfo = "None available"; } echo "-----------------------------------------------------\n"; echo "DeviceId:\t\t{$deviceId}\n"; echo "Device type:\t\t" . ($device->GetDeviceType() !== ASDevice::UNDEFINED ? $device->GetDeviceType() : "unknown") . "\n"; echo "UserAgent:\t\t" . ($device->GetDeviceUserAgent() !== ASDevice::UNDEFINED ? $device->GetDeviceUserAgent() : "unknown") . "\n"; // TODO implement $device->GetDeviceUserAgentHistory() // device information transmitted during Settings command if ($device->GetDeviceModel()) { echo "Device Model:\t\t" . $device->GetDeviceModel() . "\n"; } if ($device->GetDeviceIMEI()) { echo "Device IMEI:\t\t" . $device->GetDeviceIMEI() . "\n"; } if ($device->GetDeviceFriendlyName()) { echo "Device friendly name:\t" . $device->GetDeviceFriendlyName() . "\n"; } if ($device->GetDeviceOS()) { echo "Device OS:\t\t" . $device->GetDeviceOS() . "\n"; } if ($device->GetDeviceOSLanguage()) { echo "Device OS Language:\t" . $device->GetDeviceOSLanguage() . "\n"; } if ($device->GetDevicePhoneNumber()) { echo "Device Phone nr:\t" . $device->GetDevicePhoneNumber() . "\n"; } if ($device->GetDeviceMobileOperator()) { echo "Device Operator:\t" . $device->GetDeviceMobileOperator() . "\n"; } if ($device->GetDeviceEnableOutboundSMS()) { echo "Device Outbound SMS:\t" . $device->GetDeviceEnableOutboundSMS() . "\n"; } echo "ActiveSync version:\t" . ($device->GetASVersion() ? $device->GetASVersion() : "unknown") . "\n"; echo "First sync:\t\t" . strftime("%Y-%m-%d %H:%M", $device->GetFirstSyncTime()) . "\n"; echo "Last sync:\t\t" . ($device->GetLastSyncTime() ? strftime("%Y-%m-%d %H:%M", $device->GetLastSyncTime()) : "never") . "\n"; echo "Total folders:\t\t" . count($folders) . "\n"; echo "Synchronized folders:\t" . $synchedFolders; if ($syncedFoldersInProgress > 0) { echo " (" . $syncedFoldersInProgress . " in progress)"; } echo "\n"; echo "Synchronized data:\t{$folderinfo}\n"; if ($syncedFoldersInProgress > 0) { echo "Synchronization progress:\n"; foreach ($folders as $folderid) { $d = $device->GetFolderSyncStatus($folderid); if ($d) { $status = ""; if ($d['total'] > 0) { $percent = round($d['done'] * 100 / $d['total']); $status = sprintf("Status: %s%d%% (%d/%d)", $percent < 10 ? " " : "", $percent, $d['done'], $d['total']); } printf("\tFolder: %s%s Sync: %s %s\n", $d['name'], str_repeat(" ", 12 - strlen($d['name'])), $d['status'], $status); } } } echo "Status:\t\t\t"; switch ($device->GetWipeStatus()) { case SYNC_PROVISION_RWSTATUS_OK: echo "OK\n"; break; case SYNC_PROVISION_RWSTATUS_PENDING: echo "Pending wipe\n"; break; case SYNC_PROVISION_RWSTATUS_REQUESTED: echo "Wipe requested on device\n"; break; case SYNC_PROVISION_RWSTATUS_WIPED: echo "Wiped\n"; break; default: echo "Not available\n"; break; } echo "WipeRequest on:\t\t" . ($device->GetWipeRequestedOn() ? strftime("%Y-%m-%d %H:%M", $device->GetWipeRequestedOn()) : "not set") . "\n"; echo "WipeRequest by:\t\t" . ($device->GetWipeRequestedBy() ? $device->GetWipeRequestedBy() : "not set") . "\n"; echo "Wiped on:\t\t" . ($device->GetWipeActionOn() ? strftime("%Y-%m-%d %H:%M", $device->GetWipeActionOn()) : "not set") . "\n"; echo "Attention needed:\t"; if ($device->GetDeviceError()) { echo $device->GetDeviceError() . "\n"; } else { if (!isset($device->ignoredmessages) || empty($device->ignoredmessages)) { echo "No errors known\n"; } else { printf("%d messages need attention because they could not be synchronized\n", count($device->ignoredmessages)); foreach ($device->ignoredmessages as $im) { $info = ""; if (isset($im->asobject->subject)) { $info .= sprintf("Subject: '%s'", $im->asobject->subject); } if (isset($im->asobject->fileas)) { $info .= sprintf("FileAs: '%s'", $im->asobject->fileas); } if (isset($im->asobject->from)) { $info .= sprintf(" - From: '%s'", $im->asobject->from); } if (isset($im->asobject->starttime)) { $info .= sprintf(" - On: '%s'", strftime("%Y-%m-%d %H:%M", $im->asobject->starttime)); } $reason = $im->reasonstring; if ($im->reasoncode == 2) { $reason = "Message was causing loop"; } printf("\tBroken object:\t'%s' ignored on '%s'\n", $im->asclass, strftime("%Y-%m-%d %H:%M", $im->timestamp)); printf("\tInformation:\t%s\n", $info); printf("\tReason: \t%s (%s)\n", $reason, $im->reasoncode); printf("\tItem/Parent id: %s/%s\n", $im->id, $im->folderid); echo "\n"; } } } }
/** * Called when a SyncObject is not being streamed to the mobile. * The user can be informed so he knows about this issue * * @param string $folderid id of the parent folder (may be false if unknown) * @param string $id message id * @param SyncObject $message the broken message * @param string $reason (self::MSG_BROKEN_UNKNOWN, self::MSG_BROKEN_CAUSINGLOOP, self::MSG_BROKEN_SEMANTICERR) * * @access public * @return boolean */ public function AnnounceIgnoredMessage($folderid, $id, SyncObject $message, $reason = self::MSG_BROKEN_UNKNOWN) { if ($folderid === false) { $folderid = $this->getLatestFolder(); } $class = get_class($message); $brokenMessage = new StateObject(); $brokenMessage->id = $id; $brokenMessage->folderid = $folderid; $brokenMessage->ASClass = $class; $brokenMessage->folderid = $folderid; $brokenMessage->reasonCode = $reason; $brokenMessage->reasonString = 'unknown cause'; $brokenMessage->timestamp = time(); $brokenMessage->asobject = $message; $brokenMessage->reasonString = ZLog::GetLastMessage(LOGLEVEL_WARN); $this->device->AddIgnoredMessage($brokenMessage); ZLog::Write(LOGLEVEL_ERROR, sprintf("Ignored broken message (%s). Reason: '%s' Folderid: '%s' message id '%s'", $class, $reason, $folderid, $id)); return true; }
public static function CommandClearLoopDetectionData() { $stat = false; $stat = ZPushAdmin::ClearLoopDetectionData(self::$user, self::$device); if (self::$user === false && self::$device === false) { echo sprintf("System wide loop detection data removed: %s", $stat ? 'OK' : ZLog::GetLastMessage(LOGLEVEL_ERROR)) . "\n"; } elseif (self::$user === false) { echo sprintf("Loop detection data of device '%s' removed: %s", self::$device, $stat ? 'OK' : ZLog::GetLastMessage(LOGLEVEL_ERROR)) . "\n"; } elseif (self::$device === false && self::$user !== false) { echo sprintf("Error: %s", $stat ? 'OK' : ZLog::GetLastMessage(LOGLEVEL_WARN)) . "\n"; } else { echo sprintf("Loop detection data of device '%s' of user '%s' removed: %s", self::$device, self::$user, $stat ? 'OK' : ZLog::GetLastMessage(LOGLEVEL_ERROR)) . "\n"; } }
/** * 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; }