Commit 257a2a78 authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #317 in ZP/z-push from...

Merge pull request #317 in ZP/z-push from bugfix/ZP-1003-koe-sync-gab-is-not-always-able-to to develop

* commit 'ae0263bb':
  ZP-1003 Protected methods should start with a lowercase letter. Fixed names plural.
  ZP-1003 Always open store of the login user so we have a defaultstore available. Don't log when opening the store. Added missing property PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE to be fetched from the GAB.
parents 340e8da6 ae0263bb
......@@ -55,6 +55,7 @@ class Kopano extends SyncWorker {
const NAME = "Z-Push Kopano GAB Sync";
const VERSION = "1.1";
private $session;
private $defaultstore;
private $store;
private $mainUser;
private $targetStore;
......@@ -80,6 +81,7 @@ class Kopano extends SyncWorker {
}
$this->mainUser = USERNAME;
$this->targetStore = HIDDEN_FOLDERSTORE;
$this->defaultstore = $this->openMessageStore($this->mainUser);
$this->store = $this->openMessageStore(HIDDEN_FOLDERSTORE);
$this->folderCache = array();
$this->storeCache = array();
......@@ -109,14 +111,14 @@ class Kopano extends SyncWorker {
* @access protected
* @return string
*/
protected function CreateHiddenFolder($gabId = null, $gabName = 'default') {
protected function createHiddenFolder($gabId = null, $gabName = 'default') {
$store = $this->getStore($gabId, $gabName);
$parentfolder = $this->getRootFolder($store);
// mapi_folder_createfolder() fails if a folder with this name already exists -> MAPI_E_COLLISION
$newfolder = mapi_folder_createfolder($parentfolder, HIDDEN_FOLDERNAME, "");
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->CreateHiddenFolder(): Error, mapi_folder_createfolder() failed: 0x%08X", mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->createHiddenFolder(): Error, mapi_folder_createfolder() failed: 0x%08X", mapi_last_hresult()));
mapi_setprops($newfolder, array(PR_CONTAINER_CLASS => "IPF.Appointment", PR_ATTR_HIDDEN => true));
......@@ -127,7 +129,7 @@ class Kopano extends SyncWorker {
return $sourcekey;
}
else {
$this->Terminate(sprintf("Kopano->CreateHiddenFolder(): Error, folder created but PR_SOURCE_KEY not available: 0x%08X", mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->createHiddenFolder(): Error, folder created but PR_SOURCE_KEY not available: 0x%08X", mapi_last_hresult()));
}
}
......@@ -141,17 +143,17 @@ class Kopano extends SyncWorker {
* @access protected
* @return boolean
*/
protected function DeleteHiddenFolder($folderid, $gabId = null, $gabName = 'default') {
protected function deleteHiddenFolder($folderid, $gabId = null, $gabName = 'default') {
$store = $this->getStore($gabId, $gabName);
$parentfolder = $this->getRootFolder($store);
$folderentryid = mapi_msgstore_entryidfromsourcekey($store, hex2bin($folderid));
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->DeleteHiddenFolder(): Error, could not get PR_ENTRYID for hidden folder: 0x%08X", mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->deleteHiddenFolder(): Error, could not get PR_ENTRYID for hidden folder: 0x%08X", mapi_last_hresult()));
mapi_folder_deletefolder($parentfolder, $folderentryid);
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->DeleteHiddenFolder(): Error, mapi_folder_deletefolder() failed: 0x%08X", mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->deleteHiddenFolder(): Error, mapi_folder_deletefolder() failed: 0x%08X", mapi_last_hresult()));
return true;
}
......@@ -165,7 +167,7 @@ class Kopano extends SyncWorker {
* @access protected
* @return string|boolean on error
*/
protected function GetHiddenFolderId($gabId = null, $gabName = 'default') {
protected function getHiddenFolderId($gabId = null, $gabName = 'default') {
$store = $this->getStore($gabId, $gabName);
$parentfolder = $this->getRootFolder($store);
$table = mapi_folder_gethierarchytable($parentfolder);
......@@ -193,8 +195,8 @@ class Kopano extends SyncWorker {
* @access protected
* @return boolean
*/
protected function ClearFolderContents($folderid, $gabId = null, $gabName = 'default') {
$this->Log(sprintf("Kopano->ClearFolderContents: emptying folder in GAB '%s': %s", $gabName, $folderid));
protected function clearFolderContents($folderid, $gabId = null, $gabName = 'default') {
$this->Log(sprintf("Kopano->clearFolderContents: emptying folder in GAB '%s': %s", $gabName, $folderid));
$store = $this->getStore($gabId, $gabName);
$folder = $this->getFolder($store, $folderid);
......@@ -202,7 +204,7 @@ class Kopano extends SyncWorker {
$flags = 0;
mapi_folder_emptyfolder($folder, $flags);
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->ClearFolderContents: Error, mapi_folder_emptyfolder() failed on '%s': 0x%08X", $gabName, mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->clearFolderContents: Error, mapi_folder_emptyfolder() failed on '%s': 0x%08X", $gabName, mapi_last_hresult()));
return true;
}
......@@ -217,40 +219,40 @@ class Kopano extends SyncWorker {
* @access protected
* @return boolean
*/
protected function ClearAllNotCurrentChunkType($folderid, $gabId = null, $gabName = 'default') {
protected function clearAllNotCurrentChunkType($folderid, $gabId = null, $gabName = 'default') {
$store = $this->getStore($gabId, $gabName);
$folder = $this->getFolder($store, $folderid);
$table = mapi_folder_getcontentstable($folder);
if (!$table)
$this->Terminate(sprintf("Kopano->ClearAllNotCurrentChunkType: Error, unable to read contents table on '%s': 0x%08X", $gabName, mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->clearAllNotCurrentChunkType: Error, unable to read contents table on '%s': 0x%08X", $gabName, mapi_last_hresult()));
$restriction = array(RES_PROPERTY, array(RELOP => RELOP_NE, ULPROPTAG => $this->mapiprops['chunktype'], VALUE => $this->chunkType));
mapi_table_restrict($table, $restriction);
$querycnt = mapi_table_getrowcount($table);
if ($querycnt == 0) {
$this->Log("Kopano->ClearAllNotCurrentChunkType: no invalid items, done!");
$this->Log("Kopano->clearAllNotCurrentChunkType: no invalid items, done!");
}
else {
$this->Log(sprintf("Kopano->ClearAllNotCurrentChunkType: found %d invalid items, deleting", $querycnt));
$this->Log(sprintf("Kopano->clearAllNotCurrentChunkType: found %d invalid items, deleting", $querycnt));
$entries = mapi_table_queryallrows($table, array(PR_ENTRYID, $this->mapiprops['chunktype']));
$entry_ids = array_reduce($entries, function ($result, $item) {
$result[] = $item[PR_ENTRYID];
return $result;
}, array());
mapi_folder_deletemessages($folder, array_values($entry_ids));
$this->Log("Kopano->ClearAllNotCurrentChunkType: done");
$this->Log("Kopano->clearAllNotCurrentChunkType: done");
}
$this->Log("");
return true;
}
/**
* Returns a list of Global Address Books with their name and ids.
* Returns a list of Global Address Books with their names and ids.
*
* @access protected
* @return array
*/
protected function GetGABs() {
protected function getGABs() {
$names = array();
$companies = mapi_zarafa_getcompanylist($this->store);
if (is_array($companies)) {
......@@ -275,17 +277,17 @@ class Kopano extends SyncWorker {
* @access protected
* @return array of GABEntry
*/
protected function GetGAB($uniqueId = false, $gabId = null, $gabName = 'default') {
protected function getGAB($uniqueId = false, $gabId = null, $gabName = 'default') {
$data = array();
$addrbook = mapi_openaddressbook($this->session);
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->GetGAB: Error opening addressbook 0x%08X", mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->getGAB: Error opening addressbook 0x%08X", mapi_last_hresult()));
if ($gabId == null) {
$ab_entryid = mapi_ab_getdefaultdir($addrbook);
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->GetGAB: Error, could not get '%s' address directory: 0x%08X", $gabName, mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->getGAB: Error, could not get '%s' address directory: 0x%08X", $gabName, mapi_last_hresult()));
}
else {
$ab_entryid = hex2bin($gabId);
......@@ -293,11 +295,11 @@ class Kopano extends SyncWorker {
$ab_dir = mapi_ab_openentry($addrbook, $ab_entryid);
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->GetGAB: Error, could not open '%s' address directory: 0x%08X", $gabName, mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->getGAB: Error, could not open '%s' address directory: 0x%08X", $gabName, mapi_last_hresult()));
$table = mapi_folder_getcontentstable($ab_dir);
if (mapi_last_hresult())
$this->Terminate(sprintf("Kopano->GetGAB: error, could not open '%s' addressbook content table: 0x%08X", $gabName, mapi_last_hresult()));
$this->Terminate(sprintf("Kopano->getGAB: error, could not open '%s' addressbook content table: 0x%08X", $gabName, mapi_last_hresult()));
// get all the groups
$groups = mapi_zarafa_getgrouplist($this->store, $ab_entryid);
......@@ -309,10 +311,10 @@ class Kopano extends SyncWorker {
mapi_table_restrict($table, $restriction);
$querycnt = mapi_table_getrowcount($table);
if ($querycnt == 0) {
$this->Log(sprintf("Kopano->GetGAB(): Single GAB entry '%s' requested but could not be found.", $uniqueId));
$this->Log(sprintf("Kopano->getGAB(): Single GAB entry '%s' requested but could not be found.", $uniqueId));
}
elseif ($querycnt > 1) {
$this->Terminate(sprintf("Kopano->GetGAB(): Single GAB entry '%s' requested but %d entries found. Aborting.", $uniqueId, $querycnt));
$this->Terminate(sprintf("Kopano->getGAB(): Single GAB entry '%s' requested but %d entries found. Aborting.", $uniqueId, $querycnt));
}
}
......@@ -334,6 +336,7 @@ class Kopano extends SyncWorker {
PR_BUSINESS_ADDRESS_CITY,
PR_BUSINESS_ADDRESS_POSTAL_CODE,
PR_BUSINESS_ADDRESS_POST_OFFICE_BOX,
PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE,
PR_INITIALS,
PR_LANGUAGE,
PR_EMS_AB_THUMBNAIL_PHOTO,
......@@ -426,7 +429,7 @@ class Kopano extends SyncWorker {
* @access protected
* @return json string
*/
protected function GetChunkData($folderid, $chunkName, $gabId = null, $gabName = 'default') {
protected function getChunkData($folderid, $chunkName, $gabId = null, $gabName = 'default') {
// find the chunk message in the folder
$store = $this->getStore($gabId, $gabName);
$chunkdata = $this->findChunk($store, $folderid, $chunkName);
......@@ -458,8 +461,8 @@ class Kopano extends SyncWorker {
* @access protected
* @return boolean
*/
protected function SetChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId = null, $gabName = 'default') {
$log = sprintf("Kopano->SetChunkData: %s\tEntries: %d\t Size: %d B\tCRC: %s - ", $chunkName, $amountEntries, strlen($chunkData), $chunkCRC);
protected function setChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId = null, $gabName = 'default') {
$log = sprintf("Kopano->setChunkData: %s\tEntries: %d\t Size: %d B\tCRC: %s - ", $chunkName, $amountEntries, strlen($chunkData), $chunkCRC);
// find the chunk message in the folder
$store = $this->getStore($gabId, $gabName);
......@@ -583,8 +586,9 @@ class Kopano extends SyncWorker {
}
}
}
else
else {
$entryid = @mapi_msgstore_createentryid($this->defaultstore, $user);
}
if(!$entryid) {
$this->Terminate(sprintf("Kopano->openMessageStore(): No store found for user '%s': 0x%08X - Aborting.", $user, mapi_last_hresult()));
......@@ -595,7 +599,6 @@ class Kopano extends SyncWorker {
$this->Terminate(sprintf("Kopano->openMessageStore(): Could not open store for '%s': 0x%08X - Aborting.", $user, mapi_last_hresult()));
}
$this->Log(sprintf("Kopano->openMessageStore(): Found '%s' store of user '%s': '%s'", (($return_public)?'PUBLIC':'DEFAULT'), $user, $store));
return $store;
}
......
......@@ -75,7 +75,7 @@ abstract class SyncWorker {
* - gets all GAB entries
* - sorts them into chunks
* - serializes the chunk
* - sends it to SetChunkData() to be written
* - sends it to setChunkData() to be written
* - shows some stats
*
* @param string $targetGab the gab name id that should be synchronized, if not set 'default' or all are used.
......@@ -86,7 +86,7 @@ abstract class SyncWorker {
*/
public function Sync($targetGab = false, $doWrite = true) {
// gets a list of GABs
$gabs = $this->GetGABs();
$gabs = $this->getGABs();
if (empty($gabs)) {
if($targetGab) {
......@@ -122,10 +122,10 @@ abstract class SyncWorker {
// remove all messages that do not match the current $chunkType
if ($doWrite)
$this->ClearAllNotCurrentChunkType($folderid, $gabId, $gabName);
$this->clearAllNotCurrentChunkType($folderid, $gabId, $gabName);
// get all GAB entries
$gab = $this->GetGAB(false, $gabId, $gabName);
$gab = $this->getGAB(false, $gabId, $gabName);
// build the chunks
$chunks = array();
......@@ -170,7 +170,7 @@ abstract class SyncWorker {
if ($doWrite) {
$chunkName = $this->chunkType . "/". $chunkId;
$chunkCRC = md5($chunkData);
$this->SetChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId, $gabName);
$this->setChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId, $gabName);
}
}
......@@ -200,7 +200,7 @@ abstract class SyncWorker {
$this->Log(sprintf("Sync-one: %s = '%s'%s", UNIQUEID, $uniqueId, ($targetGab) ? " of '".$targetGab."'":''));
// gets a list of GABs
$gabs = $this->GetGABs();
$gabs = $this->getGABs();
if (empty($gabs)) {
if($targetGab) {
......@@ -221,7 +221,7 @@ abstract class SyncWorker {
}
// search for the entry in the GAB
$entries = $this->GetGAB($uniqueId, $gabId, $gabName);
$entries = $this->getGAB($uniqueId, $gabId, $gabName);
// if an entry is found, update the chunk
// if the entry is NOT found, we should remove it from the chunk (entry deleted)
......@@ -241,7 +241,7 @@ abstract class SyncWorker {
$folderid = $this->getFolderId($gabId, $gabName);
$chunkId = $this->calculateChunkId($key);
$chunkName = $this->chunkType . "/". $chunkId;
$chunkdata = $this->GetChunkData($folderid, $chunkName, $gabId, $gabName);
$chunkdata = $this->getChunkData($folderid, $chunkName, $gabId, $gabName);
$chunk = json_decode($chunkdata, true);
// update or remove the entry
......@@ -269,7 +269,7 @@ abstract class SyncWorker {
// update the chunk data
$chunkCRC = md5($chunkData);
$status = $this->SetChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId, $gabName);
$status = $this->setChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId, $gabName);
if ($status) {
$this->Log("Success!");
}
......@@ -286,7 +286,7 @@ abstract class SyncWorker {
*/
public function ClearAll($targetGab) {
// gets a list of GABs
$gabs = $this->GetGABs();
$gabs = $this->getGABs();
if (empty($gabs)) {
if($targetGab) {
......@@ -315,13 +315,13 @@ abstract class SyncWorker {
* @return boolean
*/
private function doClearAll($gabId = null, $gabName = 'default') {
$folderid = $this->GetHiddenFolderId($gabId, $gabName);
$folderid = $this->getHiddenFolderId($gabId, $gabName);
if (!$folderid) {
$this->Log(sprintf("Could not locate folder in '%s'. Aborting.", $gabName));
return false;
}
$status = $this->ClearFolderContents($folderid, $gabId, $gabName);
$status = $this->clearFolderContents($folderid, $gabId, $gabName);
if ($status) {
$this->Log(sprintf("Success for '%s'!", $gabName));
}
......@@ -339,7 +339,7 @@ abstract class SyncWorker {
*/
public function DeleteAll($targetGab) {
// gets a list of GABs
$gabs = $this->GetGABs();
$gabs = $this->getGABs();
if (empty($gabs)) {
if($targetGab) {
......@@ -368,14 +368,14 @@ abstract class SyncWorker {
* @return boolean
*/
private function doDeleteAll($gabId = null, $gabName = 'default') {
$folderid = $this->GetHiddenFolderId($gabId, $gabName);
$folderid = $this->getHiddenFolderId($gabId, $gabName);
if (!$folderid) {
$this->Log(sprintf("Could not locate folder in '%s'", $gabName));
return false;
}
$emptystatus = $this->ClearFolderContents($folderid, $gabId, $gabName);
$emptystatus = $this->clearFolderContents($folderid, $gabId, $gabName);
if ($emptystatus) {
$status = $this->DeleteHiddenFolder($folderid, $gabId, $gabName);
$status = $this->deleteHiddenFolder($folderid, $gabId, $gabName);
if ($status) {
$this->Log(sprintf("Success for '%s'!", $gabName));
return true;
......@@ -422,10 +422,10 @@ abstract class SyncWorker {
* @return string
*/
protected function getFolderId($gabId = null, $gabName = 'default', $doCreate = true) {
$id = $this->GetHiddenFolderId($gabId, $gabName);
$id = $this->getHiddenFolderId($gabId, $gabName);
if (!$id) {
if ($doCreate)
$id = $this->CreateHiddenFolder($gabId, $gabName);
$id = $this->createHiddenFolder($gabId, $gabName);
else
$id = "<does not yet exist>";
}
......@@ -478,7 +478,7 @@ abstract class SyncWorker {
* @access protected
* @return boolean
*/
protected abstract function CreateHiddenFolder($gabId = null, $gabName = 'default');
protected abstract function createHiddenFolder($gabId = null, $gabName = 'default');
/**
* Deletes the hidden folder.
......@@ -490,7 +490,7 @@ abstract class SyncWorker {
* @access protected
* @return boolean
*/
protected abstract function DeleteHiddenFolder($folderid, $gabId = null, $gabName = 'default');
protected abstract function deleteHiddenFolder($folderid, $gabId = null, $gabName = 'default');
/**
* Returns the internal identifier (folder-id) of the hidden folder.
......@@ -501,7 +501,7 @@ abstract class SyncWorker {
* @access protected
* @return string
*/
protected abstract function GetHiddenFolderId($gabId = null, $gabName = 'default');
protected abstract function getHiddenFolderId($gabId = null, $gabName = 'default');
/**
* Removes all messages that have not the same chunkType (chunk configuration changed!).
......@@ -513,7 +513,7 @@ abstract class SyncWorker {
* @access protected
* @return boolean
*/
protected abstract function ClearFolderContents($folderid, $gabId = null, $gabName = 'default');
protected abstract function clearFolderContents($folderid, $gabId = null, $gabName = 'default');
/**
* Removes all messages that do not match the current ChunkType.
......@@ -525,15 +525,15 @@ abstract class SyncWorker {
* @access protected
* @return boolean
*/
protected abstract function ClearAllNotCurrentChunkType($folderid, $gabId = null, $gabName = 'default');
protected abstract function clearAllNotCurrentChunkType($folderid, $gabId = null, $gabName = 'default');
/**
* Returns a list of Global Address Books with their name and ids.
* Returns a list of Global Address Books with their names and ids.
*
* @access protected
* @return array
*/
protected abstract function GetGABs();
protected abstract function getGABs();
/**
* Returns a list with all GAB entries or a single entry specified by $uniqueId.
......@@ -549,7 +549,7 @@ abstract class SyncWorker {
* @access protected
* @return array of GABEntry
*/
protected abstract function GetGAB($uniqueId = false, $gabId = null, $gabName = 'default');
protected abstract function getGAB($uniqueId = false, $gabId = null, $gabName = 'default');
/**
* Returns the chunk data of the chunkId of the hidden folder.
......@@ -564,7 +564,7 @@ abstract class SyncWorker {
* @access protected
* @return json string
*/
protected abstract function GetChunkData($folderid, $chunkName, $gabId = null, $gabName = 'default');
protected abstract function getChunkData($folderid, $chunkName, $gabId = null, $gabName = 'default');
/**
* Updates the chunk data in the hidden folder if it changed.
......@@ -583,5 +583,5 @@ abstract class SyncWorker {
* @access protected
* @return boolean
*/
protected abstract function SetChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId = null, $gabName = 'default');
protected abstract function setChunkData($folderid, $chunkName, $amountEntries, $chunkData, $chunkCRC, $gabId = null, $gabName = 'default');
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment