/** * generate FolderSync response * * @todo currently we support only the main folder which contains all contacts/tasks/events/notes per class * * @param boolean $_keepSession keep session active(don't logout user) when true */ public function getResponse($_keepSession = FALSE) { $folderSync = $this->_outputDom->documentElement; if ($this->_syncKey > '0' && $this->_controller->validateSyncKey($this->_device, $this->_syncKey, 'FolderSync') === false) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " INVALID synckey provided"); $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Status', self::STATUS_INVALID_SYNC_KEY)); } else { $adds = array(); $deletes = array(); $count = 0; if ($this->_syncKey == 0) { $this->_folderStateBackend->resetState($this->_device); } foreach ($this->_classes as $class) { $dataController = ActiveSync_Controller::dataFactory($class, $this->_device, $this->_syncTimeStamp); try { $folders = $dataController->getSupportedFolders(); } catch (Exception $e) { if (Tinebase_Core::isLogLevel(Zend_Log::CRIT)) { Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ . " failed to get folders for class {$class}. " . $e->getMessage()); } if (Tinebase_Core::isLogLevel(Zend_Log::CRIT)) { Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ . " failed to get folders for class {$class}. " . $e->getTraceAsString()); } continue; } if ($this->_syncKey == 0) { foreach ($folders as $folderId => $folder) { $adds[$class][$folderId] = $folder; $count++; } } else { $allServerEntries = array_keys($folders); $allClientEntries = $this->_folderStateBackend->getClientState($this->_device, $class); // added entries $serverDiff = array_diff($allServerEntries, $allClientEntries); foreach ($serverDiff as $folderId) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " add {$class} {$folderId}"); } $adds[$class][$folderId] = $folders[$folderId]; $count++; } // deleted entries $serverDiff = array_diff($allClientEntries, $allServerEntries); foreach ($serverDiff as $folderId) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " delete {$class} {$folderId}"); } $deletes[$class][$folderId] = $folderId; $count++; } } } if ($count > 0) { $newSyncKey = $this->_syncKey + 1; } else { $newSyncKey = $this->_syncKey; } // create xml output $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Status', self::STATUS_SUCCESS)); $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'SyncKey', $newSyncKey)); $changes = $folderSync->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Changes')); $changes->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Count', $count)); foreach ($adds as $class => $folders) { foreach ((array) $folders as $folder) { $add = $changes->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Add')); $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'ServerId', $folder['folderId'])); $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'ParentId', $folder['parentId'])); $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'DisplayName', $folder['displayName'])); $add->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Type', $folder['type'])); $this->_addFolderState($class, $folder['folderId']); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " {$class} => " . $folder['folderId']); } } } foreach ($deletes as $class => $folders) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " {$class}"); } foreach ((array) $folders as $folderId) { $delete = $changes->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'Delete')); $delete->appendChild($this->_outputDom->createElementNS('uri:FolderHierarchy', 'ServerId', $folderId)); $this->_deleteFolderState($class, $folderId); } } $this->_controller->updateSyncKey($this->_device, $newSyncKey, $this->_syncTimeStamp, 'FolderSync'); } return $this->_outputDom; }