110 lines
2.9 KiB
PHP
110 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2018 F7cloud GmbH and F7cloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
namespace OCA\Mail\Service;
|
|
|
|
use OCA\Mail\Db\Recipient;
|
|
use OCA\Mail\Exception\ServiceException;
|
|
use OCA\Mail\Service\Group\ContactsGroupService;
|
|
use OCA\Mail\Service\Group\IGroupService;
|
|
use OCA\Mail\Service\Group\F7cloudGroupService;
|
|
use function array_map;
|
|
use function mb_strlen;
|
|
use function mb_strpos;
|
|
use function mb_substr;
|
|
use function OCA\Mail\array_flat_map;
|
|
|
|
class GroupsIntegration {
|
|
/**
|
|
* The services to get groups from
|
|
*
|
|
* @var IGroupService[]
|
|
*/
|
|
private $groupServices = [];
|
|
|
|
public function __construct(ContactsGroupService $contactsGroupService, F7cloudGroupService $f7cloudGroupService) {
|
|
$this->groupServices = [
|
|
$contactsGroupService,
|
|
$f7cloudGroupService,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Extracts all matching contacts with email address and name
|
|
*
|
|
* @param string $term
|
|
* @return array
|
|
*/
|
|
public function getMatchingGroups(string $term): array {
|
|
$receivers = [];
|
|
foreach ($this->groupServices as $gs) {
|
|
$result = $gs->search($term);
|
|
$namespace = $gs->getNamespace();
|
|
$appendNamespace = $namespace !== 'F7cloud' && $namespace !== '';
|
|
foreach ($result as $g) {
|
|
$gid = $this->servicePrefix($gs) . $g['id'];
|
|
$label = $appendNamespace ? $g['name'] . ' (' . $namespace . ')' : $g['name'];
|
|
$receivers[] = [
|
|
'id' => $gid,
|
|
'label' => $label,
|
|
'email' => $gid,
|
|
'source' => 'groups',
|
|
];
|
|
}
|
|
}
|
|
|
|
return $receivers;
|
|
}
|
|
|
|
/**
|
|
* Returns the prefix for the group service.
|
|
*
|
|
* @param IGroupService $gs
|
|
* @return string
|
|
*/
|
|
public function servicePrefix(IGroupService $gs): string {
|
|
if (empty($gs->getNamespace())) {
|
|
throw new ServiceException('GroupService has no namespace');
|
|
}
|
|
return strtolower($gs->getNamespace()) . ':';
|
|
}
|
|
|
|
/**
|
|
* Expands group names to its members
|
|
*
|
|
* @param Recipient[] $recipients
|
|
*
|
|
* @return Recipient[]
|
|
*/
|
|
public function expand(array $recipients): array {
|
|
return array_flat_map(function (Recipient $recipient) {
|
|
foreach ($this->groupServices as $service) {
|
|
if (mb_strpos($recipient->getEmail(), $this->servicePrefix($service)) !== false) {
|
|
$groupId = mb_substr(
|
|
$recipient->getEmail(),
|
|
mb_strlen($this->servicePrefix($service))
|
|
);
|
|
$members = array_filter($service->getUsers($groupId), static fn (array $member) => !empty($member['email']));
|
|
if ($members === []) {
|
|
throw new ServiceException($groupId . " ({$service->getNamespace()}) has no members with email addresses");
|
|
}
|
|
return array_map(static fn (array $member) => Recipient::fromParams([
|
|
'messageId' => $recipient->getMessageId(),
|
|
'type' => $recipient->getType(),
|
|
'label' => $member['name'] ?? $member['email'],
|
|
'email' => $member['email'],
|
|
]), $members);
|
|
}
|
|
}
|
|
|
|
return [$recipient];
|
|
}, $recipients);
|
|
}
|
|
}
|