\Horde_ActiveSync_State_Sql

SQL based state management. Responsible for maintaining device state information such as last sync time, provisioning status, client-sent changes, and for calculating deltas between server and client.

Needs a number of SQL tables present: syncStateTable (horde_activesync_state): sync_timestamp: - The timestamp of last sync sync_key: - The syncKey for the last sync sync_pending: - If the last sync resulted in a MOREAVAILABLE, this contains a list of UIDs that still need to be sent to the client. sync_data: - Any state data that we need to track for the specific syncKey. Data such as current folder list on the client (for a FOLDERSYNC) and IMAP email UIDs (for Email collections during a SYNC). sync_devid: - The device id. sync_folderid:- The folder id for this sync. sync_user: - The user for this synckey. sync_mod: - The last modification stamp.

syncMapTable (horde_activesync_map): message_uid - The server uid for the object sync_modtime - The time the change was received from the client and applied to the server data store. sync_key - The syncKey that was current at the time the change was received. sync_devid - The device id this change was done on. sync_user - The user that initiated the change.

syncDeviceTable (horde_activesync_device): device_id - The unique id for this device device_type - The device type the client identifies itself with device_agent - The user agent string sent by the device device_policykey - The current policykey for this device device_rwstatus - The current remote wipe status for this device

syncUsersTable (horde_activesync_device_users): device_user - A username attached to the device device_id - The device id device_policykey - The provisioned policykey for this device/user combination.

Summary

Methods
Properties
Constants
__construct()
setNewSyncKey()
getCurrentSyncKey()
generatePolicyKey()
getPolicyKey()
getDeviceRWStatus()
setBackend()
setLogger()
getChangeCount()
isConflict()
getKnownFolders()
getFolderUidToBackendIdMap()
getFolderUidForBackendId()
getChanges()
getNewSyncKeyWrapper()
checkCollision()
getNewSyncKey()
getSyncKeyCounter()
getSyncKeyUid()
RowCmp()
loadState()
getLatestSynckeyForCollection()
updateSyncStamp()
save()
updateState()
setPolicyKey()
resetAllPolicyKeys()
setDeviceRWStatus()
loadDeviceInfo()
deviceExists()
setDeviceInfo()
setDeviceProperties()
removeState()
listDevices()
getLastSyncTimestamp()
getSyncCache()
saveSyncCache()
deleteSyncCache()
isDuplicatePIMAddition()
disconnect()
connect()
updateServerIdInState()
isDuplicatePIMChange()
No public properties found
SYNCSTAMP_UPDATE_THRESHOLD
_getFolderChanges()
_getCutOffDate()
_getDiff()
_loadState()
_havePIMChanges()
_getMailMapChanges()
_loadStateFromResults()
_getPIMChangeTS()
_checkCollision()
_gc()
_resetDeviceState()
$_params
$_folder
$_syncKey
$_backend
$_procid
$_lastSyncStamp
$_thisSyncStamp
$_collection
$_logger
$_deviceInfo
$_changes
$_type
$_folderUidMap
$_db
$_syncStateTable
$_syncMapTable
$_syncMailMapTable
$_syncDeviceTable
$_syncUsersTable
$_syncCacheTable
N/A
No private methods found
No private properties found
N/A

Constants

SYNCSTAMP_UPDATE_THRESHOLD

SYNCSTAMP_UPDATE_THRESHOLD

When there are no changes found in a collection, but the difference in syncStamp values is more than this threshold, the syncStamp is updated in the collection state without modifying the synckey or anyother state.

Properties

$_params

$_params : array

Configuration parameters

Type

array

$_folder

$_folder : mixed

Caches the current state(s) in memory

Type

mixed — Horde_ActiveSync_Folder_Base if request is not a FOLDERSYNC otherwise an array containing all FOLDERSYNC state.

$_syncKey

$_syncKey : string

The syncKey for the current request.

Type

string

$_backend

$_backend : 

The backend driver

Type

$_procid

$_procid : integer

The process id (used for logging).

Type

integer

$_lastSyncStamp

$_lastSyncStamp : \timestamp

The timestamp for the last syncKey

Type

\timestamp

$_thisSyncStamp

$_thisSyncStamp : \timestamp

The current sync timestamp

Type

\timestamp

$_collection

$_collection : array

The collection array for the collection we are currently syncing.

Keys include:

  • class: The collection class Contacts, Calendar etc...
  • synckey: The current synckey
  • newsynckey: The new synckey sent back to the client
  • id: Server folder id
  • filtertype: Filter
  • conflict: Conflicts
  • truncation: Truncation

Type

array

$_logger

$_logger : \Horde_Log_Logger

Logger instance

Type

\Horde_Log_Logger

$_changes

$_changes : array

Local cache for changes to *send* to client.

(Will remain null until getChanges() is called)

Type

array

$_type

$_type : string

The type of request we are handling.

Type

string

$_folderUidMap

$_folderUidMap : array

A map of backend folderids to UIDs

Type

array

$_db

$_db : \Horde_Db_Adapter

DB handle

Type

\Horde_Db_Adapter

$_syncStateTable

$_syncStateTable : string

State table name. This table holds the device's current state.

Type

string

$_syncMapTable

$_syncMapTable : string

The Sync Map table. This table temporarily holds information about changes received FROM the client and is used to prevent mirroring back changes to the client that originated there.

Type

string

$_syncMailMapTable

$_syncMailMapTable : string

The Sync Mail Map table. Same principle as self::_syncMapTable, but for email collection data.

Type

string

$_syncDeviceTable

$_syncDeviceTable : string

Device information table. Holds information about each client.

Type

string

$_syncUsersTable

$_syncUsersTable : string

Users table. Holds information specific to a user.

Type

string

$_syncCacheTable

$_syncCacheTable : string

The Synccache table. Holds the sync cache and is used to cache info about SYNC and PING request that are only sent a single time. Also stores data supported looping SYNC requests.

Type

string

Methods

__construct()

__construct(array  $params = array()) : \Horde_ActiveSync_State_Sql

Const'r

Parameters

array $params

Must contain:

  • db: (Horde_Db_Adapter_Base) The Horde_Db instance.

Returns

\Horde_ActiveSync_State_Sql

setNewSyncKey()

setNewSyncKey(string  $newKey) 

Update the $oldKey syncState to $newKey.

Parameters

string $newKey

getCurrentSyncKey()

getCurrentSyncKey() : string

Get the current synckey

Returns

string —

The synkey we last retrieved state for

generatePolicyKey()

generatePolicyKey() : integer

Generate a random 10 digit policy key

Returns

integer

getPolicyKey()

getPolicyKey(string  $devId) : integer

Obtain the current policy key, if it exists.

Parameters

string $devId

The device id to obtain policy key for.

Returns

integer —

The current policy key for this device, or 0 if none exists.

getDeviceRWStatus()

getDeviceRWStatus(string  $devId, boolean  $refresh = false) : integer

Return a device wipe status

Parameters

string $devId
boolean $refresh

If true, reload the device's rwstatus flag. @since 2.31.0

Returns

integer

setBackend()

setBackend(\Horde_ActiveSync_Driver_Base  $backend) : void

Set the backend driver (should really only be called by a backend object when passing this object to client code)

Parameters

\Horde_ActiveSync_Driver_Base $backend

The backend driver

setLogger()

setLogger(\Horde_Log_Logger  $logger) 

Set the logger instance for this object.

Parameters

\Horde_Log_Logger $logger

getChangeCount()

getChangeCount() : integer

Get the number of server changes.

Returns

integer

isConflict()

isConflict(array  $stat, string  $type) : boolean

Determines if the server version of the message represented by $stat conflicts with the client version of the message. For this driver, this is true whenever $lastSyncTime is older then $stat['mod']. Method is only called from the Importer during an import of a non-new change from the client.

Parameters

array $stat

A message stat array

string $type

The type of change (change, delete, add)

Returns

boolean

getKnownFolders()

getKnownFolders() : array

Return an array of known folders. This is essentially the state for a FOLDERSYNC request. AS uses a seperate synckey for FOLDERSYNC requests also, so need to treat it as any other collection.

Returns

array —

An array of folder uids.

getFolderUidToBackendIdMap()

getFolderUidToBackendIdMap() : array

Return the mapping of folder uids to backend folderids.

Returns

array —

An array of backend folderids -> uids.

getFolderUidForBackendId()

getFolderUidForBackendId(string  $serverid) : string|boolean

Get a EAS Folder Uid for the given backend server id.

Parameters

string $serverid

The backend server id. E.g., 'INBOX'.

Returns

string|boolean —

The EAS UID for the requested serverid, or false if it is not found.

getChanges()

getChanges(array  $options = array()) : array

Get all items that have changed since the last sync time

Parameters

array $options

An options array:

  • ping: (boolean) Only detect if there is a change, do not build any messages. DEFAULT: false (Build full change array).

Throws

\Horde_ActiveSync_Exception_StaleState
\Horde_ActiveSync_Exception_FolderGone

Returns

array —

An array of hashes describing each change:

  • id: The id of the item being changed.
  • type: The type of change. a Horde_ActiveSync::CHANGETYPE* constant.
  • flags: Used to transport email message flags when type is Horde_ActiveSync::CHANGE_TYPE_FLAGS or set to Horde_ActiveSync::FLAG_NEWMESSAGE when type is Horde_ActiveSync::CHANGE_TYPE_CHANGE and the message represents a new message, as opposed to a change in an existing message.
  • ignore: Set to true when the change should be ignored, and not sent to the client by the exporter. Usually due to the change being the result of a client originated change.

getNewSyncKeyWrapper()

getNewSyncKeyWrapper(string  $syncKey) : string

Non-static wrapper for getNewSyncKey.

Parameters

string $syncKey

The old syncKey

Throws

\Horde_ActiveSync_Exception

Returns

string —

The new synckey

checkCollision()

checkCollision(string  $syncKey) : boolean

Check for the (rare) possibility of a synckey collision between collections.

Parameters

string $syncKey

The synckey to check.

Returns

boolean —

True if there was a collision.

getNewSyncKey()

getNewSyncKey(string  $syncKey) : string

Gets the new sync key for a specified sync key. You must save the new sync state under this sync key when done sync'ing by calling setNewSyncKey(), then save().

Parameters

string $syncKey

The old syncKey

Throws

\Horde_ActiveSync_Exception

Returns

string —

The new synckey

getSyncKeyCounter()

getSyncKeyCounter(string  $syncKey) : mixed

Return the counter for the specified syncKey.

Parameters

string $syncKey

The synckey to obtain the counter for.

Returns

mixed —

integer|boolean The increment counter or false if failed.

getSyncKeyUid()

getSyncKeyUid(string  $syncKey) : string

Return the UID portion of a synckey.

Parameters

string $syncKey

The synckey

Returns

string —

The UID.

RowCmp()

RowCmp(  $a,   $b) : \unknown_type

Helper function for the _diff method

Parameters

$a
$b

Returns

\unknown_type

loadState()

loadState(array  $collection, string  $syncKey, string  $type = null, string  $id = null) 

Load and initialize the sync state

Parameters

array $collection

The collection array for the collection, if a FOLDERSYNC, pass an empty array.

string $syncKey

The synckey of the state to load. If empty will force a reset of the state for the class specified in $id

string $type

The type of state a Horde_ActiveSync::REQUEST_TYPE constant.

string $id

The folder id this state represents. If empty assumed to be a foldersync state.

Throws

\Horde_ActiveSync_Exception,

Horde_ActiveSync_Exception_StateGone

getLatestSynckeyForCollection()

getLatestSynckeyForCollection(string  $collection_id) : string|integer

Return the most recently seen synckey for the given collection.

Parameters

string $collection_id

The activesync collection id.

Returns

string|integer —

The synckey or 0 if none found.

updateSyncStamp()

updateSyncStamp() 

Update the syncStamp in the collection state, outside of any other changes.

Used to prevent extremely large differences in syncStamps for clients and collections that don't often have changes and the backend server doesn't keep separate syncStamp values per collection.

Throws

\Horde_ActiveSync_Exception

save()

save() 

Save the current state to storage

Throws

\Horde_ActiveSync_Exception

updateState()

updateState(string  $type, array  $change, integer  $origin = \Horde_ActiveSync::CHANGE_ORIGIN_NA, string  $user = null, string  $clientid = '') 

Update the state to reflect changes

Notes: If we are importing client changes, need to update the syncMapTable so we don't mirror back the changes on next sync. If we are exporting server changes, we need to track which changes have been sent (by removing them from $this->_changes) so we know which items to send on the next sync if a MOREAVAILBLE response was needed. If this is being called from a FOLDERSYNC command, update state accordingly.

Parameters

string $type

The type of change (change, delete, flags or foldersync)

array $change

A stat/change hash describing the change. Contains:

  • id: (mixed) The message uid the change applies to.
  • serverid: (string) The backend server id for the folder.
  • folderuid: (string) The EAS folder UID for the folder.
  • parent: (string) The parent of the current folder, if any.
  • flags: (array) If this is a flag change, the state of the flags.
  • mod: (integer) The modtime of this change.
integer $origin

Flag to indicate the origin of the change: Horde_ActiveSync::CHANGE_ORIGIN_NA - Not applicapble/not important Horde_ActiveSync::CHANGE_ORIGIN_PIM - Change originated from client

string $user

The current sync user, only needed if change origin is CHANGE_ORIGIN_PIM

string $clientid

client clientid sent when adding a new message

setPolicyKey()

setPolicyKey(string  $devId, integer  $key) 

Save a new device policy key to storage.

Parameters

string $devId

The device id

integer $key

The new policy key

Throws

\Horde_ActiveSync_Exception

resetAllPolicyKeys()

resetAllPolicyKeys() 

Reset ALL device policy keys. Used when server policies have changed and you want to force ALL devices to pick up the changes. This will cause all devices that support provisioning to be reprovisioned.

Throws

\Horde_ActiveSync_Exception

setDeviceRWStatus()

setDeviceRWStatus(string  $devId, string  $status) 

Set a new remotewipe status for the device

Parameters

string $devId

The device id.

string $status

A HordeActiveSync::RWSTATUS* constant.

Throws

\Horde_ActiveSync_Exception

loadDeviceInfo()

loadDeviceInfo(string  $devId, string  $user = null, array  $params = array()) : \Horde_ActiveSync_Device

Load the device object.

Parameters

string $devId

The device id to obtain

string $user

The user to retrieve user-specific device info for

array $params

Additional parameters:

  • force: (boolean) If true, reload the device info even if it's already loaded. Used to refresh values such as device_rwstatus that may have changed during a long running PING/SYNC. DEFAULT: false. @since 2.31.0

Throws

\Horde_ActiveSync_Exception

Returns

\Horde_ActiveSync_Device

The device object

deviceExists()

deviceExists(string  $devId, string  $user = null) : integer

Check that a given device id is known to the server. This is regardless of Provisioning status. If $user is provided, checks that the device is attached to the provided username.

Parameters

string $devId

The device id to check.

string $user

The device should be owned by this user.

Returns

integer —

The numer of device entries found for the give devId, user combination. I.e., 0 == no device exists.

setDeviceInfo()

setDeviceInfo(\Horde_ActiveSync_Device  $data, array  $dirty = array()) 

Set new device info

Parameters

\Horde_ActiveSync_Device $data

The device information

array $dirty

Array of dirty properties. @since 2.9.0

Throws

\Horde_ActiveSync_Exception

setDeviceProperties()

setDeviceProperties(array  $data, string  $deviceId) 

Set the device's properties as sent by a SETTINGS request.

Parameters

array $data

The device settings

string $deviceId

The device id.

Throws

\Horde_ActiveSync_Exception

removeState()

removeState(array  $options) 

Explicitly remove a state from storage.

Parameters

array $options

An options array containing at least one of:

  • synckey: (string) Remove only the state associated with this synckey. DEFAULT: All synckeys are removed for the specified device.
  • devId: (string) Remove all information for this device. DEFAULT: None. If no device, a synckey is required.
  • user: (string) Restrict to removing data for this user only. DEFAULT: None - all users for the specified device are removed.
  • id: (string) When removing device state, restrict ro removing data only for this collection.

Throws

\Horde_ActiveSync_Exception

listDevices()

listDevices(string  $user = null, array  $filter = array()) : array

List all devices that we know about.

Parameters

string $user

The username to list devices for. If empty, will return all devices.

array $filter

An array of optional filters where the keys are field names and the values are values to match.

Throws

\Horde_ActiveSync_Exception

Returns

array —

An array of device hashes

getLastSyncTimestamp()

getLastSyncTimestamp(string  $id = null, string  $user = null) : integer

Get the last time the loaded device issued a SYNC request.

Parameters

string $id

The (optional) devivce id. If empty will use the currently loaded device.

string $user

The (optional) user id. If empty wil use the currently loaded device.

Throws

\Horde_ActiveSync_Exception

Returns

integer —

The timestamp of the last sync, regardless of collection

getSyncCache()

getSyncCache(string  $devid, string  $user, array  $fields = null) : array

Return the sync cache.

Parameters

string $devid

The device id.

string $user

The user id.

array $fields

An array of fields to return. Default is to return the full cache. @since 2.9.0

Throws

\Horde_ActiveSync_Exception

Returns

array —

The current sync cache for the user/device combination.

saveSyncCache()

saveSyncCache(array  $cache, string  $devid, string  $user, array  $dirty = array()) 

Save the provided sync_cache.

Parameters

array $cache

The cache to save.

string $devid

The device id.

string $user

The user id.

array $dirty

An array of dirty properties. @since 2.9.0

Throws

\Horde_ActiveSync_Exception

deleteSyncCache()

deleteSyncCache(string  $devid, string  $user = null) 

Delete a complete sync cache

Parameters

string $devid

The device id

string $user

The user name.

Throws

\Horde_ActiveSync_Exception

isDuplicatePIMAddition()

isDuplicatePIMAddition(string  $id) : string

Check and see that we didn't already see the incoming change from the client.

This would happen e.g., if the client failed to receive the server response after successfully importing new messages.

Parameters

string $id

The client id sent during message addition.

Throws

\Horde_ActiveSync_Exception

Returns

string —

The UID for the given clientid, null if none found.

disconnect()

disconnect() 

Close the underlying backend storage connection.

To be used during PING or looping SYNC operations.

connect()

connect() 

(Re)open backend storage connection.

updateServerIdInState()

updateServerIdInState(string  $uid, string  $serverid) 

Update the serverid for a given folder uid in the folder's state object.

Needed when a folder is renamed on a client, but the UID must remain the same.

Parameters

string $uid

The folder UID.

string $serverid

The new serverid for this uid.

isDuplicatePIMChange()

isDuplicatePIMChange(string  $uid, string  $synckey) : boolean

Check if the UID provided was altered during the SYNC_KEY provided.

Parameters

string $uid

The UID to check.

string $synckey

The synckey to check.

Returns

boolean —

True if the provided UID was updated during the SYNC for the synckey provided.

_getFolderChanges()

_getFolderChanges() 

Get folder changes. Populates $this->_changes with an array of change entries each containing 'type', 'id' and possibly 'flags'.

_getCutOffDate()

_getCutOffDate(integer  $restrict) : integer

Returns the timestamp of the earliest modification time to consider

Parameters

integer $restrict

The time period to restrict to

Returns

integer

_getDiff()

_getDiff(array  $old, array  $new) : \unknown_type

Helper function that performs the actual diff between client state and server state FOLDERSYNC arrays.

Parameters

array $old

The client state

array $new

The current server state

Returns

\unknown_type

_loadState()

_loadState() 

Load the state represented by $syncKey from storage.

Throws

\Horde_ActiveSync_Exception,

Horde_ActiveSync_Exception_StateGone

_havePIMChanges()

_havePIMChanges() : boolean

Check for the existence of ANY entries in the map table for this device and user.

An extra database query for each sync, but the payoff is that we avoid having to stat every message change we send to the client if there are no client generated changes for this sync period.

Throws

\Horde_ActiveSync_Exception

Returns

boolean

_getMailMapChanges()

_getMailMapChanges(array  $changes) : array

Return all available mailMap changes for the current folder.

Parameters

array $changes

The changes array

Returns

array —

An array of hashes, each in the form of {uid} => array( Horde_ActiveSync::CHANGE_TYPE_FLAGS => true|false, Horde_ActiveSync::CHANGE_TYPE_DELETE => true|false, Horde_ActiveSync::CHANGE_TYPE_DRAFT => true|false, )

_loadStateFromResults()

_loadStateFromResults(array  $results) 

Actually load the state data into the object from the query results.

Parameters

array $results

The results array from the state query.

_getPIMChangeTS()

_getPIMChangeTS(array  $changes) : array

Return an array of timestamps from the map table for the last client-initiated change for the provided uid. Used to avoid mirroring back changes to the client that it sent to the server.

Parameters

array $changes

The changes array, each entry a hash containing 'id' and 'type' keys.

Returns

array —

An array of UID -> timestamp of the last client-initiated change for the specified UIDs, or null if none found.

_checkCollision()

_checkCollision(string  $guid) : boolean

Check for the (rare) possibility of a synckey collision between collections.

Parameters

string $guid

The GUID portion of the synckey to check.

Returns

boolean —

true if there was a collision.

_gc()

_gc(string  $syncKey) 

Garbage collector - clean up from previous sync requests.

Parameters

string $syncKey

The sync key

Throws

\Horde_ActiveSync_Exception

_resetDeviceState()

_resetDeviceState(string  $id) : void

Reset the sync state for this device, for the specified collection.

Parameters

string $id

The collection to reset.

Throws

\Horde_ActiveSync_Exception