mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-06 07:57:02 +03:00
Improved (Kolab) AddressBook handling
This commit is contained in:
parent
02e3ce779c
commit
41dac08dd1
4 changed files with 83 additions and 90 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue