/** * reset sync * * @param Zend_Console_Getopt $opts */ public function resetSync(Zend_Console_Getopt $opts) { $this->_addOutputLogWriter(6); $args = $this->_parseArgs($opts, array('user')); if ($args['user'] != Tinebase_Core::getUser()->accountLoginName && !$this->_checkAdminRight()) { return 1; } $possibleClasses = array('Calendar', 'Contacts', 'Tasks', 'Email'); $classesToReset = isset($args['collection']) && in_array($args['collection'], $possibleClasses) ? array($args['collection']) : $possibleClasses; $result = ActiveSync_Controller::getInstance()->resetSyncForUser($args['user'], $classesToReset); return $result ? 0 : 1; }
/** * process the XML file and add, change, delete or fetches data * */ public function handle() { $controller = ActiveSync_Controller::getInstance(); $xml = simplexml_import_dom($this->_inputDom); if (isset($xml->DeviceInformation->Set)) { $this->_deviceInformationSet = true; $this->_device->model = (string) $xml->DeviceInformation->Set->Model; $this->_device->imei = (string) $xml->DeviceInformation->Set->IMEI; $this->_device->friendlyname = (string) $xml->DeviceInformation->Set->FriendlyName; $this->_device->os = (string) $xml->DeviceInformation->Set->OS; $this->_device->oslanguage = (string) $xml->DeviceInformation->Set->OSLanguage; $this->_device->phonenumber = (string) $xml->DeviceInformation->Set->PhoneNumber; $this->_device = $controller->updateDevice($this->_device); } if (isset($xml->UserInformation->Get)) { $this->_userInformationRequested = true; } }
/** * the constructor * * @param mixed $_requestBody * @param ActiveSync_Model_Device $_device * @param string $_policyKey */ public function __construct($_requestBody, ActiveSync_Model_Device $_device = null, $_policyKey = null) { parent::__construct($_requestBody, $_device, $_policyKey); $this->_folderStateBackend = new ActiveSync_Backend_FolderState(); $this->_controller = ActiveSync_Controller::getInstance(); }
/** * process the XML file and add, change, delete or fetches data * * @todo can we get rid of LIBXML_NOWARNING * @todo we need to stored the initial data for folders and lifetime as the phone is sending them only when they change * @return resource */ public function handle() { $controller = ActiveSync_Controller::getInstance(); $intervalStart = time(); $status = self::STATUS_NO_CHANGES_FOUND; // the client does not send a wbxml document, if the Ping parameters did not change compared with the last request if ($this->_inputDom instanceof DOMDocument) { #$xml = simplexml_load_string($this->_inputDom->saveXML()); $xml = new SimpleXMLElement($this->_inputDom->saveXML(), LIBXML_NOWARNING); $xml->registerXPathNamespace('Ping', 'Ping'); if (isset($xml->HeartBeatInterval)) { $this->_device->pinglifetime = $xml->HeartBeatInterval; } if (isset($xml->Folders->Folder)) { foreach ($xml->Folders->Folder as $folderXml) { #Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " folderType: " . print_r($folderXml, true)); #$folderBackend = $this->_backend->factory((string)$folderXml->Class); try { // does the folder exist? # $folderBackend->getFolder($folderXml->Id); $folder = array('serverEntryId' => (string) $folderXml->Id, 'folderType' => (string) $folderXml->Class); $folders[] = $folder; } catch (Exception $e) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); } $status = self::STATUS_FOLDER_NOT_FOUND; break; } } $this->_device->pingfolder = serialize($folders); } $this->_device = $controller->updateDevice($this->_device); } $lifeTime = $this->_device->pinglifetime; Tinebase_Core::setExecutionLifeTime($lifeTime); $intervalEnd = $intervalStart + $lifeTime; $secondsLeft = $intervalEnd; $folders = unserialize($this->_device->pingfolder); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Folders to monitor({$lifeTime} / {$intervalStart} / {$intervalEnd} / {$status}): " . print_r($folders, true)); } if ($status === self::STATUS_NO_CHANGES_FOUND) { $folderWithChanges = array(); do { foreach ((array) $folders as $folder) { $dataController = ActiveSync_Controller::dataFactory($folder['folderType'], $this->_device, $this->_syncTimeStamp); #if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . print_r($folder, true)); try { $syncState = $controller->getSyncState($this->_device, $folder['folderType'], $folder['serverEntryId']); $count = $this->_getItemEstimate($dataController, $folder, $syncState->lastsync); } catch (ActiveSync_Exception_SyncStateNotFound $e) { // folder got never synchronized to client if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); } if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' syncstate not found. enforce sync for folder: ' . $folder['serverEntryId']); } $count = 1; } if ($count > 0) { $folderWithChanges[] = array('serverEntryId' => $folder['serverEntryId'], 'folderType' => $folder['folderType']); $status = self::STATUS_CHANGES_FOUND; } } if ($status === self::STATUS_CHANGES_FOUND) { break; } // another process synchronized data already if (isset($syncState) && $syncState->lastsync > $this->_syncTimeStamp) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " terminate ping process. Some other process updated data already."); break; } sleep(self::PING_TIMEOUT); $secondsLeft = $intervalEnd - time(); //if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " DeviceId: " . $this->_device->deviceid . " seconds left: " . $secondsLeft); } while ($secondsLeft > 0); } Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " DeviceId: " . $this->_device->deviceid . " Lifetime: {$lifeTime} SecondsLeft: {$secondsLeft} Status: {$status})"); $ping = $this->_outputDom->documentElement; $ping->appendChild($this->_outputDom->createElementNS('uri:Ping', 'Status', $status)); if ($status === self::STATUS_CHANGES_FOUND) { $folders = $ping->appendChild($this->_outputDom->createElementNS('uri:Ping', 'Folders')); foreach ($folderWithChanges as $changedFolder) { $folder = $folders->appendChild($this->_outputDom->createElementNS('uri:Ping', 'Folder', $changedFolder['serverEntryId'])); #$folder->appendChild($this->_outputDom->createElementNS('uri:Ping', 'Id', $changedFolder['serverEntryId'])); Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " DeviceId: " . $this->_device->deviceid . " changes in folder: " . $changedFolder['serverEntryId']); } } }
/** * force activesync calendar resync for iOS devices */ public function update_11() { if (Tinebase_Application::getInstance()->isInstalled('ActiveSync')) { $deviceBackend = new ActiveSync_Backend_Device(); $usersWithiPhones = $deviceBackend->search(new ActiveSync_Model_DeviceFilter(array('devicetype' => 'iphone')))->owner_id; $activeSyncController = ActiveSync_Controller::getInstance(); foreach ($usersWithiPhones as $userId) { try { $activeSyncController->resetSyncForUser($userId, 'Calendar'); } catch (Exception $e) { Tinebase_Exception::log($e, false); } } } $this->setApplicationVersion('Calendar', '8.12'); }
protected function _acknowledgePolicy() { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' acknowledge policy'); } $newPolicyKey = $this->generatePolicyKey(); $provision = $sync = $this->_outputDom->documentElement; $provision->appendChild($this->_outputDom->createElementNS('uri:Provision', 'Status', 1)); $policies = $provision->appendChild($this->_outputDom->createElementNS('uri:Provision', 'Policies')); $policy = $policies->appendChild($this->_outputDom->createElementNS('uri:Provision', 'Policy')); $policy->appendChild($this->_outputDom->createElementNS('uri:Provision', 'PolicyType', $this->_policyType)); $policy->appendChild($this->_outputDom->createElementNS('uri:Provision', 'Status', 1)); $policy->appendChild($this->_outputDom->createElementNS('uri:Provision', 'PolicyKey', $newPolicyKey)); $this->_device->policykey = $newPolicyKey; ActiveSync_Controller::getInstance()->updateDevice($this->_device); }
/** * testResetSync * * @see 0010584: CLI function for resetting sync on devices */ public function testResetSync() { $class = 'Calendar'; $this->testSyncOfEvents(); $result = ActiveSync_Controller::getInstance()->resetSyncForUser(Tinebase_Core::getUser()->accountLoginName, array($class)); $this->assertTrue($result); // check if synckey = 0 $folderState = Syncroton_Registry::getFolderBackend()->getFolderState($this->_device->id, $class); $this->assertTrue(count($folderState) > 0); foreach ($folderState as $folder) { try { Syncroton_Registry::getSyncStateBackend()->getSyncState($this->_device->id, $folder->id); $this->fail('should not find sync state for folder'); } catch (Exception $e) { $this->assertEquals('id not found', $e->getMessage()); } } }
/** * (non-PHPdoc) * @see ActiveSync_Command_Wbxml::getResponse() */ public function getResponse() { $controller = ActiveSync_Controller::getInstance(); $itemEstimate = $this->_outputDom->documentElement; foreach ($this->_collections as $collections) { foreach ($collections as $collectionData) { $response = $itemEstimate->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Response')); $dataController = ActiveSync_Controller::dataFactory($collectionData['class'], $this->_device, $this->_syncTimeStamp); try { // does the folder exist? $dataController->getFolder($collectionData['collectionId']); $folderExists = true; } catch (ActiveSync_Exception_FolderNotFound $asefnf) { $folderExists = false; } if ($folderExists !== true) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " folder does not exist"); $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Status', self::STATUS_INVALID_COLLECTION)); $collection = $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Collection')); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Class', $collectionData['class'])); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'CollectionId', $collectionData['collectionId'])); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Estimate', 0)); } elseif ($collectionData['syncKeyValid'] !== true) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " invalid synckey {$collectionData['syncKey']} provided"); /* * Android phones (and maybe others) don't take care about status 4(INVALID_SYNC_KEY) * To solve the problem we always return status 1(SUCCESS) even the sync key is invalid with Estimate set to 1. * This way the phone gets forced to sync. Handling invalid synckeys during sync command works without any problems. * $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Status', self::STATUS_INVALID_SYNC_KEY)); $collection = $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Collection')); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Class', $collectionData['class'])); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'CollectionId', $collectionData['collectionId'])); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Estimate', 0)); */ $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Status', self::STATUS_SUCCESS)); $collection = $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Collection')); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Class', $collectionData['class'])); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'CollectionId', $collectionData['collectionId'])); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Estimate', 1)); } else { $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Status', self::STATUS_SUCCESS)); $collection = $response->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Collection')); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Class', $collectionData['class'])); $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'CollectionId', $collectionData['collectionId'])); if ($collectionData['syncKey'] <= 1) { // this is the first sync. in most cases there are data on the server. $count = count($dataController->getServerEntries($collectionData['collectionId'], $collectionData['filterType'])); } else { $count = $this->_getItemEstimate($dataController, $collectionData); } $collection->appendChild($this->_outputDom->createElementNS('uri:ItemEstimate', 'Estimate', $count)); } // store current filter type $filter = new ActiveSync_Model_FolderStateFilter(array(array('field' => 'device_id', 'operator' => 'equals', 'value' => $this->_device->getId()), array('field' => 'class', 'operator' => 'equals', 'value' => $collectionData['class']), array('field' => 'folderid', 'operator' => 'equals', 'value' => $collectionData['collectionId']))); $folderState = $this->_folderStateBackend->search($filter)->getFirstRecord(); // folderState can be NULL in case of not existing folder if ($folderState instanceof ActiveSync_Model_FolderState) { $folderState->lastfiltertype = $collectionData['filterType']; $this->_folderStateBackend->update($folderState); } } } return $this->_outputDom; }