Improved (Kolab) AddressBook handling

This commit is contained in:
the-djmaze 2022-05-13 21:06:06 +02:00
parent 02e3ce779c
commit 41dac08dd1
4 changed files with 83 additions and 90 deletions

View file

@ -19,26 +19,12 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
public function Test() : string public function Test() : string
{ {
\sleep(1); \sleep(1);
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface ? return $this->oDriver ? $this->oDriver->Test() : 'Personal address book driver is not allowed';
$this->oDriver->Test() : 'Personal address book driver is not allowed';
} }
public function IsActive() : bool public function IsActive() : bool
{ {
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface && return $this->oDriver && $this->oDriver->IsSupported();
$this->oDriver->IsSupported();
}
public function IsSupported() : bool
{
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface &&
$this->oDriver->IsSupported();
}
public function IsSharingAllowed() : bool
{
return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface &&
$this->oDriver->IsSharingAllowed();
} }
public function Sync(array $oConfig) : bool public function Sync(array $oConfig) : bool

View file

@ -6,8 +6,6 @@ interface AddressBookInterface
{ {
public function IsSupported() : bool; public function IsSupported() : bool;
public function IsSharingAllowed() : bool;
public function Sync(array $oConfig) : bool; public function Sync(array $oConfig) : bool;
public function Export(string $sEmail, string $sType = 'vcf') : bool; public function Export(string $sEmail, string $sType = 'vcf') : bool;

View file

@ -12,62 +12,103 @@ class KolabAddressBook implements AddressBookInterface
$oImapClient, $oImapClient,
$sFolderName; $sFolderName;
protected function MailClient() : \MailSo\Mail\MailClient
{
$oActions = \RainLoop\Api::Actions();
$oMailClient = $oActions->MailClient();
if (!$oMailClient->IsLoggined()) {
$oActions->getAccountFromToken()->IncConnectAndLoginHelper($oActions->Plugins(), $oMailClient, $oActions->Config());
}
return $oMailClient;
}
protected function ImapClient() : \MailSo\Imap\ImapClient protected function ImapClient() : \MailSo\Imap\ImapClient
{ {
if (!$this->oImapClient /*&&\RainLoop\Api::Config()->Get('labs', 'kolab_enabled', false)*/) { if (!$this->oImapClient /*&&\RainLoop\Api::Config()->Get('labs', 'kolab_enabled', false)*/) {
$oActions = \RainLoop\Api::Actions(); $this->oImapClient = $this->MailClient()->ImapClient();
$oMailClient = $oActions->MailClient();
if (!$oMailClient->IsLoggined()) {
$oActions->getAccountFromToken()->IncConnectAndLoginHelper($oActions->Plugins(), $oMailClient, $oActions->Config());
}
$this->oImapClient = $oMailClient->ImapClient();
} }
return $this->oImapClient; return $this->oImapClient;
} }
public function FolderName() : string protected function FolderName() : string
{ {
if (!\is_string($this->sFolderName)) { if (!\is_string($this->sFolderName)) {
$oActions = \RainLoop\Api::Actions(); $oActions = \RainLoop\Api::Actions();
$oAccount = $oActions->getAccountFromToken(); $oAccount = $oActions->getAccountFromToken();
$this->sFolderName = (string) $oActions->SettingsProvider(true)->Load($oAccount)->GetConf('KolabContactFolder', ''); $sFolderName = (string) $oActions->SettingsProvider(true)->Load($oAccount)->GetConf('KolabContactFolder', '');
$metadata = $this->ImapClient()->FolderGetMetadata($sFolderName, [\MailSo\Imap\Enumerations\MetadataKeys::KOLAB_CTYPE]);
if (!$metadata || 'contact' !== \array_shift($metadata)) {
$sFolderName = '';
// throw new \Exception("Invalid kolab contact folder: {$sFolderName}");
}
$this->sFolderName = $sFolderName;
} }
return $this->sFolderName; return $this->sFolderName;
} }
public function SelectFolder() : bool protected function SelectFolder() : bool
{ {
try { try {
$sFolderName = $this->FolderName(); $sFolderName = $this->FolderName();
if (!$sFolderName) { if ($sFolderName) {
return false; $this->ImapClient()->FolderSelect($sFolderName);
return true;
} }
$metadata = $this->ImapClient()->FolderGetMetadata($sFolderName, [\MailSo\Imap\Enumerations\MetadataKeys::KOLAB_CTYPE]);
if (!$metadata || 'contact' !== \array_shift($metadata)) {
throw new \Exception("Invalid kolab contact folder: {$sFolderName}");
}
$this->ImapClient()->FolderSelect($sFolderName);
$this->sFolderName = $sFolderName;
return true;
} catch (\Throwable $e) { } catch (\Throwable $e) {
\trigger_error("KolabAddressBook {$sFolderName} error: {$e->getMessage()}"); \trigger_error("KolabAddressBook {$sFolderName} error: {$e->getMessage()}");
} }
return false; return false;
} }
protected function MessageAsContact(\MailSo\Mail\Message $oMessage) : ?Classes\Contact
{
$oContact = new Classes\Contact;
$oContact->IdContact = $oMessage->Uid();
$oContact->IdContactStr = $oMessage->Subject();
// $oContact->Display = isset($aItem['display']) ? (string) $aItem['display'] : '';
$oContact->Changed = $oMessage->HeaderTimeStampInUTC();
$oFrom = $oMessage->From();
if ($oFrom) {
$oMail = $oFrom[0];
$oProperty = new Classes\Property(PropertyType::EMAIl, $oMail->GetEmail());
$oContact->Properties[] = $oProperty;
$oProperty = new Classes\Property(PropertyType::FULLNAME, $oMail->GetDisplayName());
// $oProperty = new Classes\Property(PropertyType::FULLNAME, $oMail->ToString());
$oContact->Properties[] = $oProperty;
// $oProperty = new Classes\Property(PropertyType::NICK_NAME, $oMail->GetDisplayName());
// $oContact->Properties[] = $oProperty;
$oContact->UpdateDependentValues();
/*
// TODO extract xCard attachment
$oMessage->ContentType() = multipart/mixed
$oMessage->Attachments() : ?AttachmentCollection
[0] => MailSo\Mail\Attachment(
[oBodyStructure:MailSo\Mail\Attachment:private] => MailSo\Imap\BodyStructure(
[sContentType:MailSo\Imap\BodyStructure:private] => application/vcard+xml
[sCharset:MailSo\Imap\BodyStructure:private] =>
[aBodyParams:MailSo\Imap\BodyStructure:private] => Array(
[name] => kolab.xml
)
[sMailEncodingName:MailSo\Imap\BodyStructure:private] => quoted-printable
[sDisposition:MailSo\Imap\BodyStructure:private] => attachment
[sFileName:MailSo\Imap\BodyStructure:private] => kolab.xml
[iSize:MailSo\Imap\BodyStructure:private] => 1043
[sPartID:MailSo\Imap\BodyStructure:private] => 2
*/
}
return $oContact;
}
public function IsSupported() : bool public function IsSupported() : bool
{ {
// Check $this->ImapClient()->IsSupported('METADATA') // Check $this->ImapClient()->IsSupported('METADATA')
return true; return true;
} }
public function IsSharingAllowed() : bool
{
return $this->IsSupported() && false; // TODO
}
public function Sync(array $oConfig) : bool public function Sync(array $oConfig) : bool
{ {
// TODO // TODO
@ -157,13 +198,18 @@ class KolabAddressBook implements AddressBookInterface
public function DeleteContacts(string $sEmail, array $aContactIds) : bool public function DeleteContacts(string $sEmail, array $aContactIds) : bool
{ {
// TODO $this->MailClient()->MessageDelete(
$this->FolderName(),
new \MailSo\Imap\SequenceSet($aContactIds)
);
return false; return false;
} }
public function DeleteAllContacts(string $sEmail) : bool public function DeleteAllContacts(string $sEmail) : bool
{ {
// TODO // Called by \RainLoop\Api::ClearUserData()
// Not needed as the contacts are inside IMAP mailbox
// $this->MailClient()->FolderClear($this->FolderName());
return false; return false;
} }
@ -191,45 +237,9 @@ class KolabAddressBook implements AddressBookInterface
try try
{ {
$oMessageList = \RainLoop\Api::Actions()->MailClient()->MessageList($oParams); $oMessageList = $this->MailClient()->MessageList($oParams);
foreach ($oMessageList as $oMessage) { foreach ($oMessageList as $oMessage) {
$oContact = new Classes\Contact; $aResult[] = $this->MessageAsContact($oMessage);
$oContact->IdContact = $oMessage->Uid();
$oContact->IdContactStr = $oMessage->Subject();
// $oContact->Display = isset($aItem['display']) ? (string) $aItem['display'] : '';
$oContact->Changed = $oMessage->HeaderTimeStampInUTC();
$oFrom = $oMessage->From();
if ($oFrom) {
$oMail = $oFrom[0];
$oProperty = new Classes\Property(PropertyType::EMAIl, $oMail->GetEmail());
$oContact->Properties[] = $oProperty;
$oProperty = new Classes\Property(PropertyType::FULLNAME, $oMail->GetDisplayName());
// $oProperty = new Classes\Property(PropertyType::FULLNAME, $oMail->ToString());
$oContact->Properties[] = $oProperty;
// $oProperty = new Classes\Property(PropertyType::NICK_NAME, $oMail->GetDisplayName());
// $oContact->Properties[] = $oProperty;
$oContact->UpdateDependentValues();
$aResult[] = $oContact;
/*
// TODO extract xCard attachment
$oMessage->ContentType() = multipart/mixed
$oMessage->Attachments() : ?AttachmentCollection
[0] => MailSo\Mail\Attachment(
[oBodyStructure:MailSo\Mail\Attachment:private] => MailSo\Imap\BodyStructure(
[sContentType:MailSo\Imap\BodyStructure:private] => application/vcard+xml
[sCharset:MailSo\Imap\BodyStructure:private] =>
[aBodyParams:MailSo\Imap\BodyStructure:private] => Array(
[name] => kolab.xml
)
[sMailEncodingName:MailSo\Imap\BodyStructure:private] => quoted-printable
[sDisposition:MailSo\Imap\BodyStructure:private] => attachment
[sFileName:MailSo\Imap\BodyStructure:private] => kolab.xml
[iSize:MailSo\Imap\BodyStructure:private] => 1043
[sPartID:MailSo\Imap\BodyStructure:private] => 2
*/
}
} }
} }
catch (\Throwable $oException) catch (\Throwable $oException)
@ -243,8 +253,12 @@ class KolabAddressBook implements AddressBookInterface
public function GetContactByID(string $sEmail, $mID, bool $bIsStrID = false) : ?Classes\Contact public function GetContactByID(string $sEmail, $mID, bool $bIsStrID = false) : ?Classes\Contact
{ {
// TODO if ($bIsStrID) {
return null; $oMessage = null;
} else {
$oMessage = $this->MailClient()->Message($this->FolderName(), $mID);
}
return $oMessage ? $this->MessageAsContact($oMessage) : null;
} }
public function GetSuggestions(string $sEmail, string $sSearch, int $iLimit = 20) : array public function GetSuggestions(string $sEmail, string $sSearch, int $iLimit = 20) : array

View file

@ -72,11 +72,6 @@ class PdoAddressBook
return \is_array($aDrivers) && \in_array($this->sDsnType, $aDrivers); return \is_array($aDrivers) && \in_array($this->sDsnType, $aDrivers);
} }
public function IsSharingAllowed() : bool
{
return $this->IsSupported() && false; // TODO
}
private function flushDeletedContacts(int $iUserID) : bool private function flushDeletedContacts(int $iUserID) : bool
{ {
return !!$this->prepareAndExecute('DELETE FROM rainloop_ab_contacts WHERE id_user = :id_user AND deleted = 1', array( return !!$this->prepareAndExecute('DELETE FROM rainloop_ab_contacts WHERE id_user = :id_user AND deleted = 1', array(