/**
  * reset sync for user
  *
  * @param mixed $user
  * @param array|string $classesToReset
  * @return boolean
  */
 public function resetSyncForUser($user, $classesToReset)
 {
     if (is_string($classesToReset)) {
         $classesToReset = array($classesToReset);
     }
     if (!$user instanceof Tinebase_Model_User) {
         try {
             $user = Tinebase_User::getInstance()->getFullUserById($user);
         } catch (Tinebase_Exception_NotFound $tenf) {
             $user = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountLoginName', $user);
         }
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Resetting sync for user ' . $user->accountDisplayName . ' collections: ' . print_r($classesToReset, true));
     }
     self::initSyncrotonRegistry();
     $devices = $this->_getDevicesForUser($user->getId());
     foreach ($devices as $device) {
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Resetting device' . $device->friendlyname . ' / id: ' . $device->getId());
         }
         foreach ($classesToReset as $class) {
             $folderToReset = $this->_getFoldersForDeviceAndClass($device, $class);
             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Resetting ' . count($folderToReset) . ' folder(s) for class ' . $class);
             }
             foreach ($folderToReset as $folderState) {
                 Syncroton_Registry::getSyncStateBackend()->resetState($device->getId(), $folderState->id);
             }
         }
     }
     return true;
 }
Пример #2
0
    /**
     * test reponse with synckey 1
     */
    public function testGetFoldersSyncKey1()
    {
        $this->testGetFoldersSyncKey0();
        // rewind back last sync timestamp
        $syncState = Syncroton_Registry::getSyncStateBackend()->getSyncState($this->_device, 'FolderSync');
        $syncState->lastsync = new DateTime('2013-02-09 10:40:36', new DateTimeZone('utc'));
        $syncState = Syncroton_Registry::getSyncStateBackend()->update($syncState);
        $createdFolder = Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_CONTACTS, $this->_device, new DateTime(null, new DateTimeZone('utc')))->createFolder(new Syncroton_Model_Folder(array('serverId' => 'addressbookFolderId2', 'parentId' => null, 'displayName' => 'User created Contacts Folder', 'type' => Syncroton_Command_FolderSync::FOLDERTYPE_CONTACT_USER_CREATED)));
        // update created folder to validate that created folders are not returned as changes folders
        Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_CONTACTS, $this->_device, new DateTime(null, new DateTimeZone('utc')))->updateFolder($createdFolder);
        Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_CONTACTS, $this->_device, new DateTime(null, new DateTimeZone('utc')))->updateFolder(new Syncroton_Model_Folder(array('serverId' => 'anotherAddressbookFolderId', 'parentId' => null, 'displayName' => 'User updated Contacts Folder', 'type' => Syncroton_Command_FolderSync::FOLDERTYPE_CONTACT_USER_CREATED)));
        $doc = new DOMDocument();
        $doc->loadXML('<?xml version="1.0" encoding="utf-8"?' . '>
			<!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
			<FolderSync xmlns="uri:FolderHierarchy"><SyncKey>1</SyncKey></FolderSync>');
        $folderSync = new Syncroton_Command_FolderSync($doc, $this->_device, $this->_device->policykey);
        $folderSync->handle();
        $responseDoc = $folderSync->getResponse();
        //$responseDoc->formatOutput = true; echo '<pre>'.htmlspecialchars($responseDoc->saveXML()).'</pre>'; die;
        $xpath = new DomXPath($responseDoc);
        $xpath->registerNamespace('FolderHierarchy', 'uri:FolderHierarchy');
        $nodes = $xpath->query('//FolderHierarchy:FolderSync/FolderHierarchy:Status');
        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
        $this->assertEquals(Syncroton_Command_FolderSync::STATUS_SUCCESS, $nodes->item(0)->nodeValue, $responseDoc->saveXML());
        $nodes = $xpath->query('//FolderHierarchy:FolderSync/FolderHierarchy:SyncKey');
        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
        $this->assertEquals(2, $nodes->item(0)->nodeValue, $responseDoc->saveXML());
        $nodes = $xpath->query('//FolderHierarchy:FolderSync/FolderHierarchy:Changes/FolderHierarchy:Add');
        $this->assertGreaterThanOrEqual(1, $nodes->length, $responseDoc->saveXML());
        $nodes = $xpath->query('//FolderHierarchy:FolderSync/FolderHierarchy:Changes/FolderHierarchy:Add/FolderHierarchy:DisplayName');
        $this->assertGreaterThanOrEqual('User created Contacts Folder', $nodes->item(0)->nodeValue, $responseDoc->saveXML());
        $nodes = $xpath->query('//FolderHierarchy:FolderSync/FolderHierarchy:Changes/FolderHierarchy:Update');
        $this->assertGreaterThanOrEqual(1, $nodes->length, $responseDoc->saveXML());
        $nodes = $xpath->query('//FolderHierarchy:FolderSync/FolderHierarchy:Changes/FolderHierarchy:Update/FolderHierarchy:DisplayName');
        $this->assertGreaterThanOrEqual('User updated Contacts Folder', $nodes->item(0)->nodeValue, $responseDoc->saveXML());
    }
Пример #3
0
    /**
     *
     */
    public function testPingContacts()
    {
        // first do a foldersync
        $doc = new DOMDocument();
        $doc->loadXML('<?xml version="1.0" encoding="utf-8"?>
			<!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
			<FolderSync xmlns="uri:FolderHierarchy"><SyncKey>0</SyncKey></FolderSync>');
        $folderSync = new Syncroton_Command_FolderSync($doc, $this->_device, $this->_device->policykey);
        $folderSync->handle();
        $folderSync->getResponse();
        // request initial synckey
        $doc = new DOMDocument();
        $doc->loadXML('<?xml version="1.0" encoding="utf-8"?>
			<!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
			<Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase"><Collections><Collection><Class>Contacts</Class><SyncKey>0</SyncKey><CollectionId>addressbookFolderId</CollectionId><DeletesAsMoves/><GetChanges/><WindowSize>100</WindowSize><Options><AirSyncBase:BodyPreference><AirSyncBase:Type>1</AirSyncBase:Type><AirSyncBase:TruncationSize>5120</AirSyncBase:TruncationSize></AirSyncBase:BodyPreference><Conflict>1</Conflict></Options></Collection></Collections></Sync>');
        $sync = new Syncroton_Command_Sync($doc, $this->_device, $this->_device->policykey);
        $sync->handle();
        $syncDoc = $sync->getResponse();
        #$syncDoc->formatOutput = true; echo $syncDoc->saveXML();
        // now do the first sync
        $doc = new DOMDocument();
        $doc->loadXML('<?xml version="1.0" encoding="utf-8"?>
			<!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
			<Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase"><Collections><Collection><Class>Contacts</Class><SyncKey>1</SyncKey><CollectionId>addressbookFolderId</CollectionId><DeletesAsMoves/><GetChanges/><WindowSize>100</WindowSize><Options><AirSyncBase:BodyPreference><AirSyncBase:Type>1</AirSyncBase:Type><AirSyncBase:TruncationSize>5120</AirSyncBase:TruncationSize></AirSyncBase:BodyPreference><Conflict>1</Conflict></Options></Collection></Collections></Sync>');
        $sync = new Syncroton_Command_Sync($doc, $this->_device, $this->_device->policykey);
        $sync->handle();
        $syncDoc = $sync->getResponse();
        #$syncDoc->formatOutput = true; echo $syncDoc->saveXML();
        $folder = Syncroton_Registry::getFolderBackend()->getFolder($this->_device, 'addressbookFolderId');
        $oneSecondAgo = new DateTime(null, new DateTimeZone('utc'));
        $oneSecondAgo->modify('-1 second');
        $tenSecondsAgo = new DateTime(null, new DateTimeZone('utc'));
        $tenSecondsAgo->modify('-10 second');
        // update modify timeStamp of contact
        $dataController = Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_CONTACTS, $this->_device, $oneSecondAgo);
        $contact = $dataController->getEntry(new Syncroton_Model_SyncCollection(array('folder' => 'addressbookFolderId')), 'contact1');
        $dataController->updateEntry('addressbookFolderId', 'contact1', $contact);
        // turn back last sync time
        $syncState = Syncroton_Registry::getSyncStateBackend()->getSyncState($this->_device, $folder);
        $syncState->lastsync = $tenSecondsAgo;
        $syncState = Syncroton_Registry::getSyncStateBackend()->update($syncState);
        // and now we can start the ping request
        $doc = new DOMDocument();
        $doc->loadXML('<?xml version="1.0" encoding="utf-8"?>
			<!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
			<Ping xmlns="uri:Ping"><HeartBeatInterval>10</HeartBeatInterval><Folders><Folder><Id>addressbookFolderId</Id><Class>Contacts</Class></Folder></Folders></Ping>');
        $search = new Syncroton_Command_Ping($doc, $this->_device, null);
        $search->handle();
        $responseDoc = $search->getResponse();
        #$responseDoc->formatOutput = true; echo $responseDoc->saveXML();
        $xpath = new DomXPath($responseDoc);
        $xpath->registerNamespace('Ping', 'uri:Ping');
        $nodes = $xpath->query('//Ping:Ping/Ping:Status');
        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
        $this->assertEquals(Syncroton_Command_Ping::STATUS_CHANGES_FOUND, $nodes->item(0)->nodeValue, $responseDoc->saveXML());
        $nodes = $xpath->query('//Ping:Ping/Ping:Folders/Ping:Folder');
        $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
        $this->assertEquals('addressbookFolderId', $nodes->item(0)->nodeValue, $responseDoc->saveXML());
    }
Пример #4
0
    /**
     * @return string the id of the newly created contact
     */
    public function testConcurringSyncRequest()
    {
        $this->testSyncOfContacts();
        $dataController = Syncroton_Data_Factory::factory(Syncroton_Data_Factory::CLASS_CONTACTS, $this->_device, new DateTime(null, new DateTimeZone('UTC')));
        $entries = $dataController->getServerEntries('addressbookFolderId', null);
        // lets add one contact
        $doc = new DOMDocument();
        $doc->loadXML('<?xml version="1.0" encoding="utf-8"?>
			<!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/">
			<Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase"><Collections>
				<Collection>
					<Class>Contacts</Class><SyncKey>4</SyncKey><CollectionId>addressbookFolderId</CollectionId><DeletesAsMoves/><GetChanges/><WindowSize>100</WindowSize>
					<Options><AirSyncBase:BodyPreference><AirSyncBase:Type>1</AirSyncBase:Type><AirSyncBase:TruncationSize>5120</AirSyncBase:TruncationSize></AirSyncBase:BodyPreference><Conflict>1</Conflict></Options>
					<Commands><Add><ClientId>42</ClientId><ApplicationData></ApplicationData></Add></Commands>
				</Collection>
			</Collections></Sync>');
        $sync = new Syncroton_Command_Sync($doc, $this->_device, $this->_device->policykey);
        $sync->handle();
        $count = count($dataController->getServerEntries('addressbookFolderId', null));
        $folder = Syncroton_Registry::getFolderBackend()->getFolder($this->_device, 'addressbookFolderId');
        $syncState = Syncroton_Registry::getSyncStateBackend()->getSyncState($this->_device, $folder);
        $syncState->counter++;
        $syncState = Syncroton_Registry::getSyncStateBackend()->create($syncState);
        try {
            $syncDoc = $sync->getResponse();
            $catchedException = false;
            //} catch (Zend_Db_Statement_Exception $zdse) {
        } catch (Exception $zdse) {
            $catchedException = true;
        }
        $this->assertTrue($catchedException);
        $this->assertGreaterThan(count($dataController->getServerEntries('addressbookFolderId', null)), $count);
    }
 /**
  * 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());
         }
     }
 }
Пример #6
0
 /**
  * the constructor
  *
  * @param  mixed				   $requestBody
  * @param  Syncroton_Model_Device  $device
  * @param  array				   $requestParameters
  */
 public function __construct($requestBody, Syncroton_Model_IDevice $device, $requestParameters)
 {
     $this->_requestBody = $requestBody;
     $this->_device = $device;
     $this->_requestParameters = $requestParameters;
     $this->_policyKey = $requestParameters['policyKey'];
     $this->_deviceBackend = Syncroton_Registry::getDeviceBackend();
     $this->_folderBackend = Syncroton_Registry::getFolderBackend();
     $this->_syncStateBackend = Syncroton_Registry::getSyncStateBackend();
     $this->_contentStateBackend = Syncroton_Registry::getContentStateBackend();
     $this->_policyBackend = Syncroton_Registry::getPolicyBackend();
     if (Syncroton_Registry::isRegistered('loggerBackend')) {
         $this->_logger = Syncroton_Registry::get('loggerBackend');
     }
     $this->_syncTimeStamp = new DateTime(null, new DateTimeZone('UTC'));
     // set default content type
     $this->_headers['Content-Type'] = 'application/vnd.ms-sync.wbxml';
     if ($this->_logger instanceof Syncroton_Log) {
         $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " sync timestamp: " . $this->_syncTimeStamp->format('Y-m-d H:i:s'));
     }
     if (isset($this->_defaultNameSpace) && isset($this->_documentElement)) {
         // Creates an instance of the DOMImplementation class
         $imp = new DOMImplementation();
         // Creates a DOMDocumentType instance
         $dtd = $imp->createDocumentType('AirSync', "-//AIRSYNC//DTD AirSync//EN", "http://www.microsoft.com/");
         // Creates a DOMDocument instance
         $this->_outputDom = $imp->createDocument($this->_defaultNameSpace, $this->_documentElement, $dtd);
         $this->_outputDom->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:Syncroton', 'uri:Syncroton');
         $this->_outputDom->formatOutput = false;
         $this->_outputDom->encoding = 'utf-8';
     }
     if ($this->_skipValidatePolicyKey != true) {
         if (!empty($this->_device->policyId)) {
             $policy = $this->_policyBackend->get($this->_device->policyId);
             if ((int) $policy->policyKey != (int) $this->_policyKey) {
                 $this->_outputDom->documentElement->appendChild($this->_outputDom->createElementNS($this->_defaultNameSpace, 'Status', 142));
                 $sepn = new Syncroton_Exception_ProvisioningNeeded();
                 $sepn->domDocument = $this->_outputDom;
                 throw $sepn;
             }
             // should we wipe the mobile phone?
             if ($this->_device->remotewipe >= Syncroton_Command_Provision::REMOTEWIPE_REQUESTED) {
                 $this->_outputDom->documentElement->appendChild($this->_outputDom->createElementNS($this->_defaultNameSpace, 'Status', 140));
                 $sepn = new Syncroton_Exception_ProvisioningNeeded();
                 $sepn->domDocument = $this->_outputDom;
                 throw $sepn;
             }
         }
     }
 }