Refactor/active sync#25
Merged
Merged
Conversation
Add tasklist to sync lists after creation.
Updated addTasklist method to include sync parameter and modified related methods to handle tasklist preferences more effectively.
Refactor addTasklist to include sync option and persist preferences.
Refactor ActiveSync task list cache removal logic to keep folder cache entries while dropping collection state.
Removed calls to persistPrefs() after tasklist operations.
4 tasks
Member
|
This PR is part of a companion pair: #25 invalidates hierarchy (sets hierarchy = '0') when task lists change on the web; horde/ActiveSync#32 makes PING They Noteworthy issues: Missing try/catch in deleteTasklist() for ActiveSync calls |
3 tasks
Contributor
Author
|
performance feedback embraced, issue solved by #28 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nag: ActiveSync task lists (separate folders, web ↔ mobile device)
Summary
Nag supports web-side create / update / delete of task lists when ActiveSync runs with separate task folders (
activesync_no_multiplex). List changes update preferences, invalidate folder hierarchy in the device cache, and rely on the ActiveSync mobile device to run FolderSync (FolderHierarchy:Add/Remove) before item-level SYNC onTasks:<share-id>.Companion changes in Horde ActiveSync (
Ping.php,Collections.php) are documented in a separate PR; this document covers Nag only.Background: two layers of sync
With
activesync_no_multiplexenabled, each synced task list is exposed as its own ActiveSync folder:Tasks:<share-id>Important constraints:
sync_listspreference — Nag only exposes lists selected here to ActiveSync (Nag_Api::sources(..., $sync_only = true)). The default list is always included via prefs logic.activesync.phpdo not share in-memory prefs; writes must hit storage immediately (persistPrefs()).Problem
With separate task folders enabled, web-side create, update, and delete of task lists must propagate to ActiveSync mobile devices. List CRUD must update
sync_lists, persist preferences for the next sync request, invalidate folder hierarchy on registered devices, and update the per-device sync cache without breaking foldersync state or PING.This PR implements that workflow for Nag list CRUD and for manual
sync_listspreference changes.Design constraints
Cache and preference handling follow these rules:
hierarchy = '0'onlynotifyActiveSyncOfTaskListChange()FolderHierarchy:Removesync_listson_changearray_values(getSyncLists())(share ids, not numeric array keys)persistPrefs()after web writesactivesync.phpuse separate sessions; prefs must be stored before the next sync requestSolution overview
sequenceDiagram participant Web as Nag web UI participant Nag as Nag.php participant Prefs as DB prefs participant Cache as Device sync cache participant Device as ActiveSync mobile device Web->>Nag: addTasklist / updateTasklist / deleteTasklist Nag->>Prefs: sync_lists, display_tasklists (persistPrefs) Nag->>Nag: expireListCache (shares) alt delete Nag->>Cache: remove collections only (keep folder mapping) end Nag->>Cache: hierarchy = 0, bump timestamp Device->>Cache: FolderSync Cache-->>Device: FolderHierarchy Add/Remove Device->>Cache: SYNC per Tasks:share-idBehaviour:
synchronize)sync_lists,persistPrefs, invalidate hierarchypersistPrefs, invalidate hierarchysync_listspref changepruneActiveSyncTaskCache(),touchActiveSyncDeviceCaches()File-by-file changes
lib/Nag.phpCentral implementation. New and changed behaviour:
Task list CRUD hooks
addTasklist($info, $display, $sync)$sync: when true, adds share id tosync_listsand callsnotifyActiveSyncOfTaskListChange(). Web create uses$sync = true.updateTasklist()notifyActiveSyncOfTaskListChange()after save (rename/color/description → folder Update on next FolderSync).deleteTasklist()display_tasklistsandsync_lists, deletes share/storage, thenremoveActiveSyncTaskListCollectionsFromDeviceCache()(collections only), thennotifyActiveSyncOfTaskListChange(). Does not remove folder mappings from device cache.Session and prefs
refreshWebSessionState()initialize(): reloads prefs from storage and expiresnag_shareslist cache so the web UI sees current data after external changes.persistPrefs()$GLOBALS['prefs']->store()— required so ActiveSync requests see web-writtensync_listsimmediately.addTasklistToDisplayListsPref()/removeTasklistFromDisplayListsPref()display_tasklistswithout duplicate entries; mirror updates in$GLOBALS['display_tasklists']when set.addTasklistToSyncLists()/removeTasklistFromSyncLists()sync_listsvia_getPrefList/_setPrefList.getSyncLists()Nag_Api::sources(..., true).ActiveSync notification and cache management
notifyActiveSyncOfTaskListChange()persistPrefs(), expire share cache,requestActiveSyncFolderHierarchySync()only — nopruneActiveSyncTaskCache()here. Optional user notification in Nag UI.requestActiveSyncFolderHierarchySync()hierarchy = '0',updateTimestamp(),save(). Skips devices with empty folder/collection cache. Requiresactivesync_no_multiplex. Does not delete foldersync rows in SQL.removeActiveSyncTaskListCollectionsFromDeviceCache($tasklistId)Tasks:<id>on all user devices; folders stay for FolderSync Remove. Used fromdeleteTasklist().removeActiveSyncTaskListFromDeviceCache($tasklistId)_purgeActiveSyncTaskListCollections($cache, $tasklistId)removeCollection($id, true)for matching task collections.pruneActiveSyncTaskCache($allowedShareIds = null)array_values(self::getSyncLists())(share ids →Tasks:<id>). Used from prefson_changeonly.touchActiveSyncDeviceCaches()sync_listschange._isActiveSyncEnabled()$GLOBALS['conf']['activesync']['enabled']._listActiveSyncDevicesForUser()listDevices()for auth id andgetAuth('original'); deduplicates bydevice_id+device_user.lib/Api.phpaddTasklist(..., $params)synchronizeparameter toNag::addTasklist(..., true, !empty($params['synchronize'])). ActiveSync / RPC callers that create a list withsynchronize => trueadd it tosync_listsand trigger hierarchy invalidation — same as web create.sources($writeable, $sync_only)$sync_onlyis true, intersects task lists withNag::getSyncLists(). This is how the ActiveSync connector builds the server folder list for FolderSync diffs.No change to delete/update API surface beyond delegating to
Nag::updateTasklist/ share layer; delete goes through shares/forms callingNag::deleteTasklist.lib/Form/CreateTaskList.phpexecute()calls:Ensures a task list created in the web UI is synced to the ActiveSync mobile device without a separate prefs step.
lib/Form/DeleteTaskList.phpUnchanged call path:
Nag::deleteTasklist($this->_tasklist). Documented here because it is the web delete entry point that triggers collection cleanup + hierarchy invalidation described above.config/prefs.phpsync_listson_change: ensures default list remains selected; if ActiveSync +activesync_no_multiplex, runsNag::pruneActiveSyncTaskCache()andNag::touchActiveSyncDeviceCaches()with user notification. This is the only supported path for shrinking the cached folder set when the user removes lists from sync in prefs UI.activesync_no_multiplexPrefs group
activesyncincludes both members for the Nag preferences screen.What is intentionally not in this PR
Ping.phpStateGone)Collections.phpHorde_Core_ActiveSync_Connector(existing)Enable
activesync_no_multiplexin Nag prefs and select lists undersync_listsbefore testing separate folders.Test plan
sync_listscontains share id; after the mobile device syncs, new task folder appears; tasks sync into it.addTasklist(..., synchronize => true)adds tosync_listsand invalidates hierarchy.KEYMISMATCHon web add; stable PING after delete when deployed together with the ActiveSync companion PR.Deployment
Ping.php,Collections.php) for hierarchy checks and orphan collection handling during PING.sync_listsfor deleted shares are filtered bygetSyncLists()at runtime; saving prefs rewrites the stored list.Related configuration
Horde-wide:
$conf['activesync']['enabled']must be true.