diff --git a/framework/ActiveSync/lib/Horde/ActiveSync.php b/framework/ActiveSync/lib/Horde/ActiveSync.php index 0143af3b79e..b54befdef1d 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync.php @@ -766,10 +766,9 @@ public function handleRequest($cmd, $devId) $this->_device->rwstatus = self::RWSTATUS_NA; $this->_device->user = $this->_driver->getUser(); $this->_device->id = $devId; - $this->_device->version = $version; $this->_device->needsVersionUpdate($this->getSupportedVersions()); - // @TODO: Remove is_callable check (and extra else clause) for H6. + // @TODO: Remove is_callable check for H6. // Combine this with the modifyDevice callback? Allow $device // to be modified here? if (is_callable(array($this->_driver, 'createDeviceCallback'))) { @@ -790,17 +789,22 @@ public function handleRequest($cmd, $devId) if (is_callable(array($this->_driver, 'modifyDeviceCallback'))) { $this->_device = $this->_driver->modifyDeviceCallback($this->_device); } - $this->_device->save(); } - } else { - $this->_device->save(); } } else { $this->_device = $this->_state->loadDeviceInfo($devId, $this->_driver->getUser()); - $this->_device->version = $version; + + // If the device state was removed from storage, we may lose the + // device properties, so try to repopulate what we can. userAgent + // is ALWAYS available, so if it's missing, the state is gone. + if (empty($this->_device->userAgent)) { + $this->_device->userAgent = $this->_request->getHeader('User-Agent'); + $this->_device->deviceType = !empty($get['DeviceType']) ? $get['DeviceType'] : ''; + $this->_device->user = $this->_driver->getUser(); + } // Check this here so we only need to save the device object once. - if ($this->_device->properties['version'] < $this->_maxVersion && + if ($this->_device->properties[Horde_ActiveSync_Device::VERSION] < $this->_maxVersion && $this->_device->needsVersionUpdate($this->getSupportedVersions())) { $needMsRp = true; @@ -810,22 +814,22 @@ public function handleRequest($cmd, $devId) if (is_callable(array($this->_driver, 'modifyDeviceCallback'))) { $this->_device = $this->_driver->modifyDeviceCallback($this->_device); } + } - $this->_device->save(); - - if (is_callable(array($this->_driver, 'deviceCallback'))) { - $callback_ret = $this->_driver->deviceCallback($this->_device); - if ($callback_ret !== true) { - $msg = sprintf( - 'The device %s was disallowed for user %s per policy settings.', - $this->_device->id, - $this->_device->user); - self::$_logger->err($msg); - if ($version > self::VERSION_TWELVEONE) { - $this->_globalError = $callback_ret; - } else { - throw new Horde_ActiveSync_Exception($msg); - } + $this->_device->save(); + $this->_device->version = $version; + if (is_callable(array($this->_driver, 'deviceCallback'))) { + $callback_ret = $this->_driver->deviceCallback($this->_device); + if ($callback_ret !== true) { + $msg = sprintf( + 'The device %s was disallowed for user %s per policy settings.', + $this->_device->id, + $this->_device->user); + self::$_logger->err($msg); + if ($version > self::VERSION_TWELVEONE) { + $this->_globalError = $callback_ret; + } else { + throw new Horde_ActiveSync_Exception($msg); } } } diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Device.php b/framework/ActiveSync/lib/Horde/ActiveSync/Device.php index 98f599d8c26..cd69aa5b65e 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Device.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Device.php @@ -35,6 +35,11 @@ * along with any custom properties set. * @property string announcedVersion The most last EAS supported versions * announced to the device. + * @property string multiplex Bitmask describing collections that this + * device does not support user created + * folders for, therefore all sources must + * be multiplexed together. Masks are + * the MULTIPLEX_* constants. * */ class Horde_ActiveSync_Device @@ -47,6 +52,7 @@ class Horde_ActiveSync_Device const PHONE_NUMBER = 'Settings:PhoneNumber'; const VERSION = 'version'; const MULTIPLEX = 'multiplex'; + const ANNOUNCED_VERSION = 'announcedVersion'; // Bitwise constants for flagging device must use multiplexed collections. // @since 2.9.0 @@ -93,11 +99,18 @@ public function __construct(Horde_ActiveSync_State_Base $state, array $data = ar */ public function &__get($property) { - if (isset($this->_properties[$property])) { - return $this->_properties[$property]; - } else { - $return = null; - return $return; + switch ($property) { + //case self::VERSION: + case self::MULTIPLEX: + case self::ANNOUNCED_VERSION: + return $this->_properties['properties'][$property]; + default: + if (isset($this->_properties[$property])) { + return $this->_properties[$property]; + } else { + $return = null; + return $return; + } } } @@ -106,9 +119,23 @@ public function &__get($property) */ public function __set($property, $value) { - if (!isset($this->_properties[$property]) || $value != $this->_properties[$property]) { - $this->_dirty[$property] = true; - $this->_properties[$property] = $value; + switch ($property) { + //case self::VERSION: + case self::MULTIPLEX: + case self::ANNOUNCED_VERSION: + $properties = $this->properties; + if (empty($properties)) { + $properties = array(); + } + $properties[$property] = $value; + $this->setDeviceProperties($properties); + break; + + default: + if (!isset($this->_properties[$property]) || $value != $this->_properties[$property]) { + $this->_dirty[$property] = true; + $this->_properties[$property] = $value; + } } } @@ -129,14 +156,16 @@ public function __isset($property) */ public function needsVersionUpdate($supported) { - if (empty($this->properties['announcedVersion'])) { - $this->_properties['properties']['announcedVersion'] = $supported; - $this->_dirty['properties'] = true; + if (empty($this->properties[self::ANNOUNCED_VERSION])) { + $properties = $this->properties; + $properties[self::ANNOUNCED_VERSION] = $supported; + $this->setDeviceProperties($properties); return false; } - if ($this->properties['announcedVersion'] != $supported) { - $this->_properties['properties']['announcedVersion'] = $supported; - $this->_dirty['properties'] = true; + if ($this->properties[self::ANNOUNCED_VERSION] != $supported) { + $properties = $this->properties; + $properties[self::ANNOUNCED_VERSION] = $supported; + $this->setDeviceProperties($properties); return true; } @@ -231,6 +260,9 @@ public function getFormattedDeviceProperties() if (!empty($this->properties[self::VERSION])) { $data[_("EAS Version")] = $this->properties[self::VERSION]; } + if (!empty($this->properties[self::MULTIPLEX])) { + $data[_("Forced Multiplexed Bitmask")] = $this->properties[self::MULTIPLEX]; + } return $data; } diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Request/Settings.php b/framework/ActiveSync/lib/Horde/ActiveSync/Request/Settings.php index a4003942fd7..ed3875f3e76 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Request/Settings.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Request/Settings.php @@ -193,6 +193,7 @@ protected function _handle() $this->_decoder->getElementEndTag(); // end self::SETTINGS_OOF break; case self::SETTINGS_DEVICEINFORMATION : + $device_properties = $this->_device->properties; while (($field = ($this->_decoder->getElementStartTag(self::SETTINGS_MODEL) ? self::SETTINGS_MODEL : ($this->_decoder->getElementStartTag(self::SETTINGS_IMEI) ? self::SETTINGS_IMEI : ($this->_decoder->getElementStartTag(self::SETTINGS_FRIENDLYNAME) ? self::SETTINGS_FRIENDLYNAME : @@ -203,16 +204,16 @@ protected function _handle() ($this->_decoder->getElementStartTag(self::SETTINGS_MOBILEOPERATOR) ? self::SETTINGS_MOBILEOPERATOR : ($this->_decoder->getElementStartTag(self::SETTINGS_ENABLEOUTBOUNDSMS) ? self::SETTINGS_ENABLEOUTBOUNDSMS : -1)))))))))) != -1) { - if (($deviceinfo[$field] = $this->_decoder->getElementContent()) !== false) { + if (($device_properties[$field] = $this->_decoder->getElementContent()) !== false) { $this->_decoder->getElementEndTag(); // end $field } } try { - $deviceinfo['version'] = $this->_device->version; - $this->_device->setDeviceProperties($deviceinfo); + $device_properties['version'] = $this->_device->version; + $this->_device->setDeviceProperties($device_properties); } catch (Horde_ActiveSync_Exception $e) { $this->_logger->err($e->getMessage()); - unset($deviceinfo); + unset($device_properties); } $this->_decoder->getElementEndTag(); // end self::SETTINGS_DEVICEINFORMATION break; @@ -261,7 +262,7 @@ protected function _handle() $this->_encoder->endTag(); // end self::SETTINGS_STATUS $this->_encoder->endTag(); // end self::SETTINGS_OOF } - if (isset($deviceinfo)) { + if (isset($device_properties)) { $this->_encoder->startTag(self::SETTINGS_DEVICEINFORMATION); $this->_encoder->startTag(self::SETTINGS_STATUS); if (!isset($result['set']['deviceinformation'])) { diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/State/Mongo.php b/framework/ActiveSync/lib/Horde/ActiveSync/State/Mongo.php index c901beb5865..a184d917521 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/State/Mongo.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/State/Mongo.php @@ -626,8 +626,7 @@ public function setDeviceProperties(array $data, $deviceId) $query = array('_id' => $deviceId); $update = array( '$set' => array( - 'device_properties' => $data, - 'device_agent' => !empty($data[Horde_ActiveSync_Request_Settings::SETTINGS_USERAGENT]) ? $data[Horde_ActiveSync_Request_Settings::SETTINGS_USERAGENT] : '' + 'device_properties' => $data ) ); try { diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/State/Sql.php b/framework/ActiveSync/lib/Horde/ActiveSync/State/Sql.php index c62f8086715..ba3671ea279 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/State/Sql.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/State/Sql.php @@ -646,10 +646,9 @@ public function setDeviceInfo(Horde_ActiveSync_Device $data, array $dirty = arra public function setDeviceProperties(array $data, $deviceId) { $query = 'UPDATE ' . $this->_syncDeviceTable . ' SET device_properties = ?,' - . ' device_agent = ? WHERE device_id = ?'; + . ' WHERE device_id = ?'; $properties = array( serialize($data), - !empty($data[Horde_ActiveSync_Request_Settings::SETTINGS_USERAGENT]) ? $data[Horde_ActiveSync_Request_Settings::SETTINGS_USERAGENT] : '', $deviceId); try { $this->_db->update($query, $properties);