From 073fca88e2efb1fa02e95e94d53326e85e63de77 Mon Sep 17 00:00:00 2001 From: Michael J Rubinsky Date: Wed, 31 Aug 2016 16:14:00 -0400 Subject: [PATCH] Refactor exporter out into separate classes for Sync and FolderSync. --- .../ActiveSync/Connector/Exporter/Base.php | 104 +++++ .../Connector/Exporter/FolderSync.php | 136 ++++++ .../{Exporter.php => Exporter/Sync.php} | 423 ++++++++---------- .../Horde/ActiveSync/Request/FolderSync.php | 4 +- .../lib/Horde/ActiveSync/Request/Sync.php | 95 +--- framework/ActiveSync/package.xml | 14 +- 6 files changed, 436 insertions(+), 340 deletions(-) create mode 100644 framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/Base.php create mode 100644 framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/FolderSync.php rename framework/ActiveSync/lib/Horde/ActiveSync/Connector/{Exporter.php => Exporter/Sync.php} (69%) diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/Base.php b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/Base.php new file mode 100644 index 00000000000..04f95d26ade --- /dev/null +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/Base.php @@ -0,0 +1,104 @@ + + * @package ActiveSync + */ +/** + * Horde_ActiveSync_Connector_Exporter_Base:: Base class contains common + * code for outputing common blocks of WBXML data in server responses. + * + * @license http://www.horde.org/licenses/gpl GPLv2 + * NOTE: According to sec. 8 of the GENERAL PUBLIC LICENSE (GPL), + * Version 2, the distribution of the Horde_ActiveSync module in or + * to the United States of America is excluded from the scope of this + * license. + * @copyright 2009-2016 Horde LLC (http://www.horde.org) + * @author Michael J Rubinsky + * @package ActiveSync + */ +abstract class Horde_ActiveSync_Connector_Exporter_Base +{ + /** + * The wbxml encoder + * + * @var Horde_ActiveSync_Wbxml_Encoder + */ + protected $_encoder; + + /** + * Local cache of changes to send. + * + * @var array + */ + protected $_changes = array(); + + /** + * Counter of changes sent. + * + * @var integer + */ + protected $_step = 0; + + /** + * The ActiveSync server object. + * + * @var Horde_ActiveSync + */ + protected $_as; + + /** + * Process id for logging. + * + * @var integer + */ + protected $_procid; + + /** + * Const'r + * + * @param Horde_ActiveSync $as The ActiveSync server. + * @param Horde_ActiveSync_Wbxml_Encoder $encoder The encoder + * + * @return Horde_ActiveSync_Connector_Exporter + */ + public function __construct( + Horde_ActiveSync $as, + Horde_ActiveSync_Wbxml_Encoder $encoder = null) + { + $this->_as = $as; + $this->_encoder = $encoder; + $this->_logger = $as->logger; + $this->_procid = getmypid(); + } + + /** + * Set the changes to send to the client. + * + * @param array $changes The changes array returned from the collection + * handler. + * @param array $collection The collection we are currently syncing. + */ + public function setChanges($changes, $collection = null) + { + $this->_changes = $changes; + $this->_seenObjects = array(); + $this->_step = 0; + } + + /** + * Sends the next change in the set to the client. + * + * @return boolean|Horde_Exception True if more changes can be sent false if + * all changes were sent, Horde_Exception if + * there was an error sending an item. + */ + abstract public function sendNextChange(); +} \ No newline at end of file diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/FolderSync.php b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/FolderSync.php new file mode 100644 index 00000000000..6221eef6c01 --- /dev/null +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/FolderSync.php @@ -0,0 +1,136 @@ + + * @package ActiveSync + */ +/** + * Horde_ActiveSync_Connector_Exporter_FolderSync:: Responsible for outputing + * blocks of WBXML responses in FOLDER_SYNC responses. + * + * @license http://www.horde.org/licenses/gpl GPLv2 + * NOTE: According to sec. 8 of the GENERAL PUBLIC LICENSE (GPL), + * Version 2, the distribution of the Horde_ActiveSync module in or + * to the United States of America is excluded from the scope of this + * license. + * @copyright 2009-2016 Horde LLC (http://www.horde.org) + * @author Michael J Rubinsky + * @package ActiveSync + */ +class Horde_ActiveSync_Connector_Exporter_Sync extends Horde_ActiveSync_Connector_Exporter_Base +{ + + /** + * Array of folder objects that have changed. + * Used when exporting folder structure changes since they are not streamed + * from this object. + * + * @var array + */ + public $changed = array(); + + /** + * Array of folder ids that have been deleted on the server. + * + * @var array + */ + public $deleted = array(); + + /** + * Tracks the total number of folder changes + * + * @var integer + */ + public $count = 0; + + /** + * Sends the next change in the set to the client. + * + * @return boolean|Horde_Exception True if more changes can be sent false if + * all changes were sent, Horde_Exception if + * there was an error sending an item. + */ + public function sendNextChange() + { + return $this->_sendNextFolderSyncChange(); + } + + /** + * Sends the next folder change to the client. + * + * @return @see self::sendNextChange() + */ + protected function _sendNextFolderSyncChange() + { + if ($this->_step < count($this->_changes)) { + $change = $this->_changes[$this->_step]; + switch($change['type']) { + case Horde_ActiveSync::CHANGE_TYPE_CHANGE: + // Folder add/change. + if ($folder = $this->_as->driver->getFolder($change['serverid'])) { + // @TODO BC HACK. Need to ensure we have a _serverid here. + // REMOVE IN H6. + if (empty($folder->_serverid)) { + $folder->_serverid = $folder->serverid; + } + $stat = $this->_as->driver->statFolder( + $change['id'], + $folder->parentid, + $folder->displayname, + $folder->_serverid, + $folder->type); + $this->folderChange($folder); + } else { + $this->_logger->err(sprintf( + '[%s] Error stating %s: ignoring.', + $this->_procid, $change['id'])); + $stat = array('id' => $change['id'], 'mod' => $change['id'], 0); + } + // Update the state. + $this->_as->state->updateState( + Horde_ActiveSync::CHANGE_TYPE_FOLDERSYNC, $stat); + break; + + case Horde_ActiveSync::CHANGE_TYPE_DELETE: + $this->folderDeletion($change['id']); + $this->_as->state->updateState( + Horde_ActiveSync::CHANGE_TYPE_DELETE, $change); + break; + } + $this->_step++; + return true; + } else { + return false; + } + } + + /** + * Add a folder change to the cache (used during FolderSync requests). + * + * @param Horde_ActiveSync_Message_Folder $folder + */ + public function folderChange(Horde_ActiveSync_Message_Folder $folder) + { + $this->changed[] = $folder; + $this->count++; + } + + /** + * Add a folder deletion to the cache (used during FolderSync Requests). + * + * @param string $id The folder id + */ + public function folderDeletion($id) + { + $this->deleted[] = $id; + $this->count++; + } + +} \ No newline at end of file diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter.php b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/Sync.php similarity index 69% rename from framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter.php rename to framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/Sync.php index 46d14a533a2..f303eac01b1 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Connector/Exporter/Sync.php @@ -1,17 +1,6 @@ * @package ActiveSync */ -class Horde_ActiveSync_Connector_Exporter +class Horde_ActiveSync_Connector_Exporter_Sync extends Horde_ActiveSync_Connector_Exporter_Base { - /** - * The wbxml encoder - * - * @var Horde_ActiveSync_Wbxml_Encoder - */ - protected $_encoder; /** * Local cache of object ids we have already dealt with. @@ -51,109 +36,210 @@ class Horde_ActiveSync_Connector_Exporter protected $_seenObjects = array(); /** - * Array of folder objects that have changed. - * Used when exporting folder structure changes since they are not streamed - * from this object. + * Currently syncing collection. * * @var array */ - public $changed = array(); + protected $_currentCollection; - /** - * Array of folder ids that have been deleted on the server. - * - * @var array - */ - public $deleted = array(); /** - * Tracks the total number of folder changes + * Set the changes to send to the client. * - * @var integer + * @param array $changes The changes array returned from the collection + * handler. + * @param array $collection The collection we are currently syncing. */ - public $count = 0; + public function setChanges($changes, $collection = null) + { + parent::setChanges($changes, $collection); + $this->_currentCollection = $collection; + } /** - * Local cache of changes to send. + * Sends the next change in the set to the client. * - * @var array + * @return boolean|Horde_Exception True if more changes can be sent false if + * all changes were sent, Horde_Exception if + * there was an error sending an item. */ - protected $_changes = array(); + public function sendNextChange() + { + return $this->_sendNextChange(); + } /** - * Counter of changes sent. + * Send a message change over the wbxml stream * - * @var integer + * @param string $id The uid of the message + * @param Horde_ActiveSync_Message_Base $message The message object */ - protected $_step = 0; + public function messageChange($id, Horde_ActiveSync_Message_Base $message) + { + // Just ignore any messages that are not from this collection and + // prevent sending the same object twice in one request. + if ($message->getClass() != $this->_currentCollection['class'] || + in_array($id, $this->_seenObjects)) { + $this->_logger->notice(sprintf( + '[%s] IGNORING message %s since it looks like it was already sent or does not belong to this collection. Class: %s, CurrentClass: %s', + $this->_procid, + $id, + $message->getClass(), + $this->_currentCollection['class'])); + return; + } - /** - * Currently syncing collection. - * - * @var array - */ - protected $_currentCollection; + // Ignore any empty objects. + if ($message->isEmpty()) { + $this->_logger->notice(sprintf( + '[%s] IGNORING message %s since it looks like it does not contain any data. Class: %s, CurrentClass: %s', + $this->_procid, + $id, + $message->getClass(), + $this->_currentCollection['class'])); + return; + } - /** - * The ActiveSync server object. - * - * @var Horde_ActiveSync - */ - protected $_as; + // Remember this message + $this->_seenObjects[] = $id; - /** - * Process id for logging. - * - * @var integer - */ - protected $_procid; + // Specify if this is an ADD or a MODIFY change? + if ($message->flags === Horde_ActiveSync::FLAG_NEWMESSAGE) { + $this->_encoder->startTag(Horde_ActiveSync::SYNC_ADD); + } else { + $this->_encoder->startTag(Horde_ActiveSync::SYNC_MODIFY); + } + + // Send the message + $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); + $this->_encoder->content($id); + $this->_encoder->endTag(); + $this->_encoder->startTag(Horde_ActiveSync::SYNC_DATA); + try { + $message->encodeStream($this->_encoder); + } catch (Horde_ActiveSync_Exception $e) { + $this->_logger->err($e); + } + $this->_encoder->endTag(); + $this->_encoder->endTag(); + } /** - * Const'r - * - * @param Horde_ActiveSync $as The ActiveSync server. - * @param Horde_ActiveSync_Wbxml_Encoder $encoder The encoder + * Stream a message deletion to the client. * - * @return Horde_ActiveSync_Connector_Exporter + * @param string $id The uid of the message we are deleting. + * @param boolean $soft If true, send a SOFTDELETE, otherwise a REMOVE. */ - public function __construct( - Horde_ActiveSync $as, - Horde_ActiveSync_Wbxml_Encoder $encoder = null) + public function messageDeletion($id, $soft = false) { - $this->_as = $as; - $this->_encoder = $encoder; - $this->_logger = $as->logger; - $this->_procid = getmypid(); + if ($soft) { + $this->_encoder->startTag(Horde_ActiveSync::SYNC_SOFTDELETE); + } else { + $this->_encoder->startTag(Horde_ActiveSync::SYNC_REMOVE); + } + $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); + $this->_encoder->content($id); + $this->_encoder->endTag(); + $this->_encoder->endTag(); } /** - * Set the changes to send to the client. + * Move a message to a different folder. * - * @param array $changes The changes array returned from the collection - * handler. - * @param array $collection The collection we are currently syncing. + * @param Horde_ActiveSync_Message_Base $message The message */ - public function setChanges($changes, $collection) + public function messageMove($message) { - $this->_changes = $changes; - $this->_seenObjects = array(); - $this->_step = 0; - $this->_currentCollection = $collection; } - /** - * Sends the next change in the set to the client. - * - * @return boolean|Horde_Exception True if more changes can be sent false if - * all changes were sent, Horde_Exception if - * there was an error sending an item. - */ - public function sendNextChange() + public function syncAddResponse($collection) { - if (empty($this->_currentCollection)) { - return $this->_sendNextFolderSyncChange(); - } else { - return $this->_sendNextChange(); + foreach ($collection['clientids'] as $clientid => $serverid) { + if ($serverid) { + $status = Horde_ActiveSync_Request_Sync::STATUS_SUCCESS; + } else { + $status = Horde_ActiveSync_Request_Sync::STATUS_INVALID; + } + // Start SYNC_ADD + $this->_encoder->startTag(Horde_ActiveSync::SYNC_ADD); + + // If we have clientids and a CLASS_EMAIL, this is + // a SMS response. + // @TODO: have collection classes be able to + // generate their own responses?? + if ($collection['class'] == Horde_ActiveSync::CLASS_EMAIL) { + $this->_encoder->startTag(Horde_ActiveSync::SYNC_FOLDERTYPE); + $this->_encoder->content(Horde_ActiveSync::CLASS_SMS); + $this->_encoder->endTag(); + } + + // CLIENTENTRYID + $this->_encoder->startTag(Horde_ActiveSync::SYNC_CLIENTENTRYID); + $this->_encoder->content($clientid); + $this->_encoder->endTag(); + + // SERVERENTRYID + if ($status == Horde_ActiveSync_Request_Sync::STATUS_SUCCESS) { + $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); + $this->_encoder->content($serverid); + $this->_encoder->endTag(); + } + + // EAS 16? + $this->_sendEas16MessageResponse($serverid, $collection); + + // STATUS + $this->_encoder->startTag(Horde_ActiveSync::SYNC_STATUS); + $this->_encoder->content($status); + $this->_encoder->endTag(); + + // END SYNC_ADD + $this->_encoder->endTag(); + } + } + + protected function _sendEas16MessageResponse($serverid, $collection) + { + if ($this->_as->device->version >= Horde_ActiveSync::VERSION_SIXTEEN && + $collection['class'] == Horde_ActiveSync::CLASS_CALENDAR && + !empty($collection['atchash'][$serverid])) { + + $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); + $this->_encoder->content($serverid); + $this->_encoder->endTag(); + + $msg = $this->_as->messageFactory('Appointment'); + $msg->uid = $serverid; + $msg->airsyncbaseattachments = $this->_as->messageFactory('AirSyncBaseAttachments'); + $msg->airsyncbaseattachments->attachment = array(); + foreach ($collection['atchash'][$serverid]['add'] as $clientid => $filereference) { + $atc = $this->_as->messageFactory('AirSyncBaseAttachment'); + $atc->clientid = $clientid; + $atc->attname = $filereference; + $msg->airsyncbaseattachments->attachment[] = $atc; + } + $this->_encoder->startTag(Horde_ActiveSync::SYNC_DATA); + $msg->encodeStream($this->_encoder); + $this->_encoder->endTag(); + } + } + + public function syncModifiedResponse($collection) + { + foreach ($collection['modifiedids'] as $serverid) { + // Start SYNC_MODIFY + $this->_encoder->startTag(Horde_ActiveSync::SYNC_MODIFY); + + // EAS 16? + $this->_sendEas16MessageResponse($serverid, $collection); + + // SYNC_STATUS + $this->_encoder->startTag(Horde_ActiveSync::SYNC_STATUS); + $this->_encoder->content(Horde_ActiveSync_Request_Sync::STATUS_SUCCESS); + $this->_encoder->endTag(); + + // End SYNC_MODIFY + $this->_encoder->endTag(); } } @@ -285,159 +371,4 @@ protected function _sendNextChange() return true; } - /** - * Sends the next folder change to the client. - * - * @return @see self::sendNextChange() - */ - protected function _sendNextFolderSyncChange() - { - if ($this->_step < count($this->_changes)) { - $change = $this->_changes[$this->_step]; - switch($change['type']) { - case Horde_ActiveSync::CHANGE_TYPE_CHANGE: - // Folder add/change. - if ($folder = $this->_as->driver->getFolder($change['serverid'])) { - // @TODO BC HACK. Need to ensure we have a _serverid here. - // REMOVE IN H6. - if (empty($folder->_serverid)) { - $folder->_serverid = $folder->serverid; - } - $stat = $this->_as->driver->statFolder( - $change['id'], - $folder->parentid, - $folder->displayname, - $folder->_serverid, - $folder->type); - $this->folderChange($folder); - } else { - $this->_logger->err(sprintf( - '[%s] Error stating %s: ignoring.', - $this->_procid, $change['id'])); - $stat = array('id' => $change['id'], 'mod' => $change['id'], 0); - } - // Update the state. - $this->_as->state->updateState( - Horde_ActiveSync::CHANGE_TYPE_FOLDERSYNC, $stat); - break; - - case Horde_ActiveSync::CHANGE_TYPE_DELETE: - $this->folderDeletion($change['id']); - $this->_as->state->updateState( - Horde_ActiveSync::CHANGE_TYPE_DELETE, $change); - break; - } - $this->_step++; - return true; - } else { - return false; - } - } - - /** - * Send a message change over the wbxml stream - * - * @param string $id The uid of the message - * @param Horde_ActiveSync_Message_Base $message The message object - */ - public function messageChange($id, Horde_ActiveSync_Message_Base $message) - { - // Just ignore any messages that are not from this collection and - // prevent sending the same object twice in one request. - if ($message->getClass() != $this->_currentCollection['class'] || - in_array($id, $this->_seenObjects)) { - $this->_logger->notice(sprintf( - '[%s] IGNORING message %s since it looks like it was already sent or does not belong to this collection. Class: %s, CurrentClass: %s', - $this->_procid, - $id, - $message->getClass(), - $this->_currentCollection['class'])); - return; - } - - // Ignore any empty objects. - if ($message->isEmpty()) { - $this->_logger->notice(sprintf( - '[%s] IGNORING message %s since it looks like it does not contain any data. Class: %s, CurrentClass: %s', - $this->_procid, - $id, - $message->getClass(), - $this->_currentCollection['class'])); - return; - } - - // Remember this message - $this->_seenObjects[] = $id; - - // Specify if this is an ADD or a MODIFY change? - if ($message->flags === Horde_ActiveSync::FLAG_NEWMESSAGE) { - $this->_encoder->startTag(Horde_ActiveSync::SYNC_ADD); - } else { - $this->_encoder->startTag(Horde_ActiveSync::SYNC_MODIFY); - } - - // Send the message - $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); - $this->_encoder->content($id); - $this->_encoder->endTag(); - $this->_encoder->startTag(Horde_ActiveSync::SYNC_DATA); - try { - $message->encodeStream($this->_encoder); - } catch (Horde_ActiveSync_Exception $e) { - $this->_logger->err($e); - } - $this->_encoder->endTag(); - $this->_encoder->endTag(); - } - - /** - * Stream a message deletion to the client. - * - * @param string $id The uid of the message we are deleting. - * @param boolean $soft If true, send a SOFTDELETE, otherwise a REMOVE. - */ - public function messageDeletion($id, $soft = false) - { - if ($soft) { - $this->_encoder->startTag(Horde_ActiveSync::SYNC_SOFTDELETE); - } else { - $this->_encoder->startTag(Horde_ActiveSync::SYNC_REMOVE); - } - $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); - $this->_encoder->content($id); - $this->_encoder->endTag(); - $this->_encoder->endTag(); - } - - /** - * Move a message to a different folder. - * - * @param Horde_ActiveSync_Message_Base $message The message - */ - function messageMove($message) - { - } - - /** - * Add a folder change to the cache (used during FolderSync requests). - * - * @param Horde_ActiveSync_Message_Folder $folder - */ - public function folderChange(Horde_ActiveSync_Message_Folder $folder) - { - $this->changed[] = $folder; - $this->count++; - } - - /** - * Add a folder deletion to the cache (used during FolderSync Requests). - * - * @param string $id The folder id - */ - public function folderDeletion($id) - { - $this->deleted[] = $id; - $this->count++; - } - -} \ No newline at end of file +} diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Request/FolderSync.php b/framework/ActiveSync/lib/Horde/ActiveSync/Request/FolderSync.php index 6ffe5f1bf24..005c398ce86 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Request/FolderSync.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Request/FolderSync.php @@ -182,8 +182,8 @@ protected function _handle() // Start sending server -> client changes $newsynckey = $this->_state->getNewSyncKey($synckey); - $exporter = new Horde_ActiveSync_Connector_Exporter($this->_activeSync); - $exporter->setChanges($collections->getHierarchyChanges(), false); + $exporter = new Horde_ActiveSync_Connector_Exporter_FolderSync($this->_activeSync); + $exporter->setChanges($collections->getHierarchyChanges()); // Perform the actual sync operation while($exporter->sendNextChange()); diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php b/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php index 8fd807353c2..9f9bffb8a94 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php @@ -338,9 +338,10 @@ protected function _handle() $this->_encoder->endTag(); $this->_encoder->startTag(Horde_ActiveSync::SYNC_FOLDERS); - $exporter = new Horde_ActiveSync_Connector_Exporter( + $exporter = new Horde_ActiveSync_Connector_Exporter_Sync( $this->_activeSync, - $this->_encoder); + $this->_encoder + ); $cnt_global = 0; $over_window = false; @@ -542,96 +543,14 @@ protected function _handle() // EAS 16. CHANGED responses for items that need one. This // is basically the results of any AirSyncBaseAttachments // actions on Appointment or Draft Email items. - if (!empty($collection['modifiedids'])) { - $this->_encoder->startTag(Horde_ActiveSync::SYNC_MODIFY); - - foreach ($collection['modifiedids'] as $serverid) { - // @TODO FIXME - don't do this here, make $collection - // a full object and have it be responsible for - // returning the necessary message objects for the - // response. @todo Instanceid? - if ($collection['class'] == Horde_ActiveSync::CLASS_CALENDAR && - $this->_activeSync->device->version >= Horde_ActiveSync::VERSION_SIXTEEN && - !empty($collection['atchash'][$serverid])) { - - $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); - $this->_encoder->content($serverid); - $this->_encoder->endTag(); - - $msg = $this->_activeSync->messageFactory('Appointment'); - $msg->uid = $serverid; - $msg->airsyncbaseattachments = $this->_activeSync->messageFactory('AirSyncBaseAttachments'); - $msg->airsyncbaseattachments->attachment = array(); - foreach ($collection['atchash'][$serverid]['add'] as $clientid => $filereference) { - $atc = $this->_activeSync->messageFactory('AirSyncBaseAttachment'); - $atc->clientid = $clientid; - $atc->attname = $filereference; - $msg->airsyncbaseattachments->attachment[] = $atc; - } - $this->_encoder->startTag(Horde_ActiveSync::SYNC_DATA); - $msg->encodeStream($this->_encoder); - $this->_encoder->endTag(); - - $this->_encoder->startTag(Horde_ActiveSync::SYNC_STATUS); - $this->_encoder->content(self::STATUS_SUCCESS); - $this->_encoder->endTag(); - } - } - $this->_encoder->endTag(); + if ($this->_device->version >= Horde_ActiveSync::VERSION_SIXTEEN && + !empty($collection['modifiedids'])) { + $exporter->syncModifiedResponse($collection); } // Server IDs for new items we received from client if (!empty($collection['clientids'])) { - foreach ($collection['clientids'] as $clientid => $serverid) { - if ($serverid) { - $status = self::STATUS_SUCCESS; - } else { - $status = self::STATUS_INVALID; - } - $this->_encoder->startTag(Horde_ActiveSync::SYNC_ADD); - // If we have clientids and a CLASS_EMAIL, this is - // a SMS response. - // @TODO: have collection classes be able to - // generate their own responses?? - if ($collection['class'] == Horde_ActiveSync::CLASS_EMAIL) { - $this->_encoder->startTag(Horde_ActiveSync::SYNC_FOLDERTYPE); - $this->_encoder->content(Horde_ActiveSync::CLASS_SMS); - $this->_encoder->endTag(); - } - $this->_encoder->startTag(Horde_ActiveSync::SYNC_CLIENTENTRYID); - $this->_encoder->content($clientid); - $this->_encoder->endTag(); - if ($status == self::STATUS_SUCCESS) { - $this->_encoder->startTag(Horde_ActiveSync::SYNC_SERVERENTRYID); - $this->_encoder->content($serverid); - $this->_encoder->endTag(); - } - - // @TODO. FIX ME. Don't do this here. - if ($collection['class'] == Horde_ActiveSync::CLASS_CALENDAR && - $this->_activeSync->device->version >= Horde_ActiveSync::VERSION_SIXTEEN) { - $msg = $this->_activeSync->messageFactory('Appointment'); - $msg->uid = $serverid; - if (!empty($collection['atchash'][$serverid])) { - $msg->airsyncbaseattachments = $this->_activeSync->messageFactory('AirSyncBaseAttachments'); - $msg->airsyncbaseattachments->attachment = array(); - foreach ($collection['atchash'][$serverid]['add'] as $clientid => $filereference) { - $atc = $this->_activeSync->messageFactory('AirSyncBaseAttachment'); - $atc->clientid = $clientid; - $atc->attname = $filereference; - $msg->airsyncbaseattachments->attachment[] = $atc; - } - } - $this->_encoder->startTag(Horde_ActiveSync::SYNC_DATA); - $msg->encodeStream($this->_encoder); - $this->_encoder->endTag(); - } - - $this->_encoder->startTag(Horde_ActiveSync::SYNC_STATUS); - $this->_encoder->content($status); - $this->_encoder->endTag(); - $this->_encoder->endTag(); - } + $exporter->syncAddResponse($collection); } // Errors from missing messages in REMOVE requests. diff --git a/framework/ActiveSync/package.xml b/framework/ActiveSync/package.xml index 428f76c0bab..656e8e281cc 100644 --- a/framework/ActiveSync/package.xml +++ b/framework/ActiveSync/package.xml @@ -10,7 +10,7 @@ mrubinsk@horde.org yes - 2016-08-27 + 2016-08-31 2.35.1 2.35.0 @@ -37,7 +37,11 @@ - + + + + + @@ -455,8 +459,10 @@ - + + + @@ -3220,7 +3226,7 @@ stable stable - 2016-08-27 + 2016-08-31 GPL-2.0 *