Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nextcloud address book #1227

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
edb1bf2
Attempt to add basic nextcloud addressbook
akhil1508 Aug 3, 2023
65521c5
Check if array
akhil1508 Aug 3, 2023
1ee07bb
Remove unused imports
akhil1508 Aug 3, 2023
5d04ca5
convert results from nc to sm contacts
akhil1508 Aug 3, 2023
2f7d121
Copy incfrec from kolab
akhil1508 Aug 3, 2023
147ba65
Keep only incfrec
akhil1508 Aug 3, 2023
dc6e93a
create addressbook if not already exists
Niveshkrishna Aug 15, 2023
b0a6d3b
fix addressbookid
Niveshkrishna Aug 15, 2023
6f61b06
add firstname to contacts
Niveshkrishna Aug 24, 2023
8a4eabe
Add IsExternal for external contact sources
akhil1508 Aug 31, 2023
b84487f
Fix IncFrec logic to actually create or update
akhil1508 Aug 31, 2023
ae7e008
Merge branch 'master' of https://github.com/Murena-SAS/snappymail int…
akhil1508 Sep 4, 2023
d77e863
Bump version to 3.0
akhil1508 Sep 4, 2023
46cfa9f
Unregister system addressbook
akhil1508 Sep 4, 2023
cc25129
Fix namespace and FN default
akhil1508 Sep 8, 2023
3c7ef4d
Fix issue when contact is found in some other addressbook
akhil1508 Jan 19, 2024
cdaa4b1
Do not save contact if it already exists
akhil1508 Jan 19, 2024
957654c
Merge branch 'upstream/master' into dev/sync-nextcloud-addressbook
Aug 23, 2024
500b997
feat: add addressBook user settings section for nextcloud plugin
Aug 29, 2024
a47cc45
feat: move nextcloud addressbook user settings under contatcs setting…
Aug 30, 2024
bda1c28
fix: addressbook translation for nextcloud plugin
Aug 30, 2024
0c9e471
Remove IsExternal
akhil1508 Sep 2, 2024
022bf43
Remove extra space
akhil1508 Sep 2, 2024
f4ad959
Resolve merge conflicts
akhil1508 Sep 2, 2024
19ddcfb
feat: add admin settings for nextcloudAddressbook related changes
Sep 2, 2024
2e3fbe0
Merge branch 'dev/sync-nextcloud-addressbook' into draft/dev_sync-nex…
Sep 3, 2024
552a91a
chore: refactor nexcloud plugin- related to NC-addressbook
Sep 3, 2024
e5044ff
Apply suggestions from code review
fahim44 Sep 3, 2024
dff305e
refactor: remove repeated variable initialization
Sep 3, 2024
943b256
chore: add Readme file for nextcloud plugin + fix typo
Sep 3, 2024
098cc82
Merge pull request #2 from Murena-SAS/draft/dev_sync-nextcloud-addres…
fahim44 Sep 3, 2024
cf870df
fix: remove Nextcloud contacts app direct dependency on nextcloud plugin
Sep 5, 2024
2b8f49f
Merge branch 'master' into dev/sync-nextcloud-addressbook
fahim44 Sep 24, 2024
8b6adb3
Update README.md
fahim44 Sep 24, 2024
721a849
Merge branch 'master' into dev/sync-nextcloud-addressbook
fahim44 Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions plugins/nextcloud/NextcloudAddressBook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
<?php

use RainLoop\Providers\AddressBook\Classes\Contact;

class NextcloudAddressBook implements \RainLoop\Providers\AddressBook\AddressBookInterface
{
use RainLoop\Providers\AddressBook\CardDAV;

private const SETTINGS_KEY = 'nextcloudAddressBookUri';

private string $defaultUri;
private string $defaultName;
private string $defaultDescription;
private bool $ignoreSystemAddressBook;
private $contactsManager;

function __construct(string $defaultUri = 'webmail', string $defaultName = 'WebMail', string $defaultDescription = 'Recipients from snappymail', bool $ignoreSystemAddressBook = true)
{
$this->defaultUri = $defaultUri;
$this->defaultName = $defaultName;
$this->defaultDescription = $defaultDescription;
$this->ignoreSystemAddressBook = $ignoreSystemAddressBook;

$this->GetSavedAddressBookKey();
}

private function getContactsManager()
{
if ($this->contactsManager == null) {
$this->contactsManager = \OC::$server->getContactsManager();
}

return $this->contactsManager;
}

private function GetSavedAddressBookKey() : string
{
if ($this->ignoreSystemAddressBook) {
foreach ($this->getContactsManager()->getUserAddressBooks() as $addressBook) {
if ($addressBook->isSystemAddressBook()) {
$this->getContactsManager()->unregisterAddressBook($addressBook);
}
}
}

$uid = \OC::$server->getUserSession()->getUser()->getUID();
$cardDavBackend = \OC::$server->get(\OCA\DAV\CardDAV\CardDavBackend::class);
$principalUri = 'principals/users/' . $uid;
$uri = $this->GetSavedUri();
$addressBookId = $cardDavBackend->getAddressBooksByUri($principalUri, $uri);

if ($addressBookId === null) {
return $cardDavBackend->createAddressBook($principalUri, $uri, array_filter([
'{DAV:}displayname' => $this->defaultName,
'{urn:ietf:params:xml:ns:carddav}addressbook-description' => $this->defaultDescription,
]));
}

return $addressBookId['id'];
}

public function IsSupported() : bool
{
// Maybe just return true, contacts app is just a frontend
akhil1508 marked this conversation as resolved.
Show resolved Hide resolved
// return \OC::$server->getAppManager()->isEnabledForUser('contacts');
return true;
}

public function SetEmail(string $sEmail) : bool
{
return true;
}

public function Sync() : bool
{
return false;
}

public function Export(string $sType = 'vcf') : bool
{
return false;
}

public function ContactSave(Contact $oContact) : bool
{
return false;
}

public function DeleteContacts(array $aContactIds) : bool
{
return false;
}

public function DeleteAllContacts(string $sEmail) : bool
{
return false;
}

public function GetContacts(int $iOffset = 0, int $iLimit = 20, string $sSearch = '', int &$iResultCount = 0) : array
{
return [];
}

public function GetContactByEmail(string $sEmail) : ?Contact
{
return null;
}

public function GetContactByID($mID, bool $bIsStrID = false) : ?Contact
{
return null;
}

public function GetSuggestions(string $sSearch, int $iLimit = 20) : array
{
return [];
}

private function GetEmailObjects(array $aEmails) : array
{
$aEmailsObjects = \array_map(function ($mItem) {
$oResult = null;
try {
$oResult = \MailSo\Mime\Email::Parse(\trim($mItem));
} catch (\Throwable $oException) {
unset($oException);
}
return $oResult;
}, $aEmails);

$aEmailsObjects = \array_filter($aEmailsObjects, function ($oItem) {
return !!$oItem;
});
return $aEmailsObjects;
}

/**
* Add/increment email address usage
* Handy for "most used" sorting suggestions in PdoAddressBook
*/
public function IncFrec(array $aEmails, bool $bCreateAuto = true) : bool
{
if ($bCreateAuto) {
$aEmailsObjects = $this->GetEmailObjects($aEmails);

if (!count($aEmailsObjects)) {
return false;
}

foreach ($aEmailsObjects as $oEmail) {
$this->createOrUpdateContact($oEmail);
}

return true;
}

return false;
}

private function createOrUpdateContact($oEmail)
{
if ('' === \trim($oEmail->GetEmail())) {
return;
}
$sEmail = \trim($oEmail->GetEmail(true));
$existingResults = $this->getContactsManager()->search($sEmail, ['EMAIL'], ['strict_search' => true]);

if (!empty($existingResults)) {
return;
}

$properties = [
'EMAIL' => $sEmail,
'FN' => $sEmail
];

if ('' !== \trim($oEmail->GetDisplayName())) {
$properties['FN'] = $oEmail->GetDisplayName();
}
$this->getContactsManager()->createOrUpdate($properties, $this->GetSavedAddressBookKey());
}

public function Test() : string
{
return '';
}

private function Account() : \RainLoop\Model\Account
{
return \RainLoop\Api::Actions()->getAccountFromToken();
}

private function SettingsProvider() : \RainLoop\Providers\Settings
{
return \RainLoop\Api::Actions()->SettingsProvider(true);
}

private function Settings() : \RainLoop\Settings
{
return $this->SettingsProvider()->Load($this->Account());
}

private function GetSavedUri() : string
{
return $this->Settings()->GetConf(self::SETTINGS_KEY, $this->defaultUri);
}
}
14 changes: 14 additions & 0 deletions plugins/nextcloud/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SnappyMail plugin for nextcloud

## Nextcloud Addressbook to save recipients' contacts

This plugin can let user to choose which nextcloud addressbook to use save recipients (requires enableing snappyMail contacts) . This is opt-in feature (enabled by admin). After admin enable this, user will find a dropdown in his/her SnappyMail's `Contacts` section, containing all his/her addressbook. It works better with [Nextcloud Contacts App](https://github.com/nextcloud/contacts/)

### Admin settings

- `enableNcAddressbook` : Enable: save recipient contacts into nextcloud addressbook feature. User will see a new section into her/his `Contacts` setting, so s/he can choose Nextcloud addressbook to save recipients' contacts. Default value: `false`
- `disableSnappymailContactsUI` : Hide SnappyMail internal addressbook accesspoint. This is recomended if nextcloud addressbook to save recipients contacts is being used. So, users won't be confused to having multiple addressbook options. Default value: `false`
- `defaultNCAddressbookUri` : Default nextcloud addressbook URI to save recipients' contacts. Ignored if `enableNcAddressbook` is set to false. User can change this value for her/his account. Default value: `webmail`
- `defaultNCAddressbookName` : Default nextcloud addressbook Name to save recipients' contacts. Ignored if `enableNcAddressbook` is set to false. User can change this value for her/his account. Default value: `WebMail`
- `defaultNCAddressbookDescription` : Default nextcloud addressbook description to save recipients' contacts. Ignored if `enableNcAddressbook` is set to false. User can change this value for her/his account. Default value: `Recipients from snappymail`

Loading