diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Collections.php b/framework/ActiveSync/lib/Horde/ActiveSync/Collections.php index 98658bb00c1..c7e936058b5 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Collections.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Collections.php @@ -1134,18 +1134,41 @@ public function updatePingableFlag() * we are not PINGing. * * @param boolean $ping True if this is a PING request, false otherwise. + * @param array $ensure An array of UIDs that should be sent in the + * current response if possible, and not put off + * because of a MOREAVAILABLE situation. * * @return array The changes array. */ - public function getCollectionChanges($ping = false) + public function getCollectionChanges($ping = false, array $ensure = array()) { if (empty($this->_changes)) { $this->_changes = $this->_as->state->getChanges(array('ping' => $ping)); } + if (!empty($ensure)) { + $this->_changes = $this->_reorderChanges($ensure); + } + return $this->_changes; } + protected function _reorderChanges(array $ensure) + { + $changes = array(); + foreach ($this->_changes as $change) { + if (array_search($change['id'], $ensure) !== false) { + $this->_logger->info(sprintf( + 'Placing %s at beginning of changes array.', $change['id'])); + array_unshift($changes, $change); + } else { + $changes[] = $change; + } + } + + return $changes; + } + /** * Return the count of the current collection's chagnes. * diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php b/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php index 57dccf5d786..7d9ddc632ce 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Request/Sync.php @@ -510,6 +510,7 @@ protected function _handle() } // Output any SYNC_MODIFY failures + $ensure_sent = array(); if (!empty($collection['importfailures'])) { foreach ($collection['importfailures'] as $id => $reason) { $this->_encoder->startTag(Horde_ActiveSync::SYNC_MODIFY); @@ -520,7 +521,14 @@ protected function _handle() $this->_encoder->content($reason); $this->_encoder->endTag(); $this->_encoder->endTag(); + // If we have a conflict, ensure we send the new server + // data in the response, if possible. Some android + // clients require this, or never accept the response. + if ($reason == self::STATUS_CONFLICT) { + $ensure_sent[] = $id; + } } + } if (!empty($collection['fetchids'])) { @@ -576,7 +584,7 @@ protected function _handle() } if (!empty($changecount)) { - $exporter->setChanges($this->_collections->getCollectionChanges(), $collection); + $exporter->setChanges($this->_collections->getCollectionChanges(false, $ensure_sent), $collection); $this->_encoder->startTag(Horde_ActiveSync::SYNC_COMMANDS); $cnt_collection = 0; while ($cnt_collection < $collection['windowsize'] &&