From 41dac08dd1af304e681aa104ae0aeb6899991bd0 Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Fri, 13 May 2022 21:06:06 +0200 Subject: [PATCH] Improved (Kolab) AddressBook handling --- .../RainLoop/Providers/AddressBook.php | 18 +-- .../AddressBook/AddressBookInterface.php | 2 - .../AddressBook/KolabAddressBook.php | 148 ++++++++++-------- .../Providers/AddressBook/PdoAddressBook.php | 5 - 4 files changed, 83 insertions(+), 90 deletions(-) diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php index cccb7c5ad..ec41662d7 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php @@ -19,26 +19,12 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider public function Test() : string { \sleep(1); - return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface ? - $this->oDriver->Test() : 'Personal address book driver is not allowed'; + return $this->oDriver ? $this->oDriver->Test() : 'Personal address book driver is not allowed'; } public function IsActive() : bool { - return $this->oDriver instanceof \RainLoop\Providers\AddressBook\AddressBookInterface && - $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(); + return $this->oDriver && $this->oDriver->IsSupported(); } public function Sync(array $oConfig) : bool diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/AddressBookInterface.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/AddressBookInterface.php index 7cf207b1d..dbdd84ab5 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/AddressBookInterface.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/AddressBookInterface.php @@ -6,8 +6,6 @@ interface AddressBookInterface { public function IsSupported() : bool; - public function IsSharingAllowed() : bool; - public function Sync(array $oConfig) : bool; public function Export(string $sEmail, string $sType = 'vcf') : bool; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php index 27514e392..77387e422 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php @@ -12,62 +12,103 @@ class KolabAddressBook implements AddressBookInterface $oImapClient, $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 { if (!$this->oImapClient /*&&\RainLoop\Api::Config()->Get('labs', 'kolab_enabled', false)*/) { - $oActions = \RainLoop\Api::Actions(); - $oMailClient = $oActions->MailClient(); - if (!$oMailClient->IsLoggined()) { - $oActions->getAccountFromToken()->IncConnectAndLoginHelper($oActions->Plugins(), $oMailClient, $oActions->Config()); - } - $this->oImapClient = $oMailClient->ImapClient(); + $this->oImapClient = $this->MailClient()->ImapClient(); } return $this->oImapClient; } - public function FolderName() : string + protected function FolderName() : string { if (!\is_string($this->sFolderName)) { $oActions = \RainLoop\Api::Actions(); $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; } - public function SelectFolder() : bool + protected function SelectFolder() : bool { try { $sFolderName = $this->FolderName(); - if (!$sFolderName) { - return false; + if ($sFolderName) { + $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) { \trigger_error("KolabAddressBook {$sFolderName} error: {$e->getMessage()}"); } 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 { // Check $this->ImapClient()->IsSupported('METADATA') return true; } - public function IsSharingAllowed() : bool - { - return $this->IsSupported() && false; // TODO - } - public function Sync(array $oConfig) : bool { // TODO @@ -157,13 +198,18 @@ class KolabAddressBook implements AddressBookInterface public function DeleteContacts(string $sEmail, array $aContactIds) : bool { - // TODO + $this->MailClient()->MessageDelete( + $this->FolderName(), + new \MailSo\Imap\SequenceSet($aContactIds) + ); return false; } 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; } @@ -191,45 +237,9 @@ class KolabAddressBook implements AddressBookInterface try { - $oMessageList = \RainLoop\Api::Actions()->MailClient()->MessageList($oParams); + $oMessageList = $this->MailClient()->MessageList($oParams); foreach ($oMessageList as $oMessage) { - $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(); - $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 - */ - } + $aResult[] = $this->MessageAsContact($oMessage); } } catch (\Throwable $oException) @@ -243,8 +253,12 @@ class KolabAddressBook implements AddressBookInterface public function GetContactByID(string $sEmail, $mID, bool $bIsStrID = false) : ?Classes\Contact { - // TODO - return null; + if ($bIsStrID) { + $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 diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php index ba4426062..3aa835a08 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/PdoAddressBook.php @@ -72,11 +72,6 @@ class PdoAddressBook return \is_array($aDrivers) && \in_array($this->sDsnType, $aDrivers); } - public function IsSharingAllowed() : bool - { - return $this->IsSupported() && false; // TODO - } - private function flushDeletedContacts(int $iUserID) : bool { return !!$this->prepareAndExecute('DELETE FROM rainloop_ab_contacts WHERE id_user = :id_user AND deleted = 1', array(