/**
* Prepares the syncCache for a partial sync request and checks that
* it is allowed.
*
* @return boolean True if parital sync is possible, false otherwise.
*/
public function initPartialSync()
{
// PARTIAL is allowed without a <collection> tag if the waitinterval,
// heartbeat, or windowsize changed. So, short circuit the logic for
// checking for changed collections in this case.
if (empty($this->_collections)) {
$this->_logger->info('No collections in collection handler, loading full collection set from cache.');
$this->loadCollectionsFromCache();
// Need this for all PARTIAL sync requests.
$this->_tempSyncCache = clone $this->_cache;
foreach ($this->_collections as $value) {
// Remove keys from confirmed synckeys array and count them
if (isset($value['synckey'])) {
if (isset($this->_cache->confirmed_synckeys[$value['synckey']])) {
$this->_logger->info(sprintf('Removed %s from confirmed_synckeys', $value['synckey']));
$this->_cache->removeConfirmedKey($value['synckey']);
}
$this->_synckeyCount++;
}
}
if (!$this->_checkConfirmedKeys()) {
$this->_logger->err('Some synckeys were not confirmed. Requesting full SYNC');
$this->save();
return false;
}
return true;
}
$this->_tempSyncCache = clone $this->_cache;
$c = $this->_tempSyncCache->getCollections();
foreach ($this->_collections as $key => $value) {
// Collections from cache might not all have synckeys.
if (!empty($c[$key])) {
$v1 = $value;
foreach ($v1 as $k => $o) {
if (is_null($o)) {
unset($v1[$k]);
}
}
unset($v1['id'], $v1['serverid'], $v1['clientids'], $v1['fetchids'], $v1['getchanges'], $v1['changeids'], $v1['pingable'], $v1['class'], $v1['synckey'], $v1['lastsynckey']);
$v2 = $c[$key];
foreach ($v2 as $k => $o) {
if (is_null($o)) {
unset($v2[$k]);
}
}
unset($v2['id'], $v2['serverid'], $v2['pingable'], $v2['class'], $v2['synckey'], $v2['lastsynckey']);
ksort($v1);
if (isset($v1['bodyprefs'])) {
ksort($v1['bodyprefs']);
foreach (array_keys($v1['bodyprefs']) as $k) {
if (is_array($v1['bodyprefs'][$k])) {
ksort($v1['bodyprefs'][$k]);
}
}
}
ksort($v2);
if (isset($v2['bodyprefs'])) {
ksort($v2['bodyprefs']);
foreach (array_keys($v2['bodyprefs']) as $k) {
if (is_array($v2['bodyprefs'][$k])) {
ksort($v2['bodyprefs'][$k]);
}
}
}
if (md5(serialize($v1)) == md5(serialize($v2))) {
$this->_unchangedCount++;
}
// Unset in tempSyncCache, since we have it from device.
// Afterwards, anything left in tempSyncCache needs to be added
// to _collections (this is done in
// self::_haveNoChangesInPartialSync()).
$this->_tempSyncCache->removeCollection($key);
// Remove keys from confirmed synckeys array and count them.
if (isset($value['synckey'])) {
if (isset($this->_cache->confirmed_synckeys[$value['synckey']])) {
$this->_logger->info(sprintf('Removed %s from confirmed_synckeys', $value['synckey']));
$this->_cache->removeConfirmedKey($value['synckey']);
}
$this->_synckeyCount++;
}
}
}
if (!$this->_checkConfirmedKeys()) {
$this->_logger->err('Some synckeys were not confirmed. Requesting full SYNC');
$this->save();
return false;
}
if ($this->_haveNoChangesInPartialSync()) {
$this->_logger->warn(sprintf('[%s] Partial Request with completely unchanged collections. Request a full SYNC', $this->_procid));
return false;
}
return true;
}