Skip to content

Commit

Permalink
feat(notifications): added option to exclude subscribers
Browse files Browse the repository at this point in the history
Offers the option in a NotificationEventHandler to exlude owner,
container and/or entity subscribers while fetching subscribers.
  • Loading branch information
jeabakker committed Sep 9, 2021
1 parent c375028 commit 8af26bb
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 6 deletions.
16 changes: 16 additions & 0 deletions engine/classes/Elgg/Notifications/CreateCommentEventHandler.php
Expand Up @@ -49,4 +49,20 @@ protected function getNotificationBody(\ElggUser $recipient, string $method): st
$entity->getURL(),
], $recipient->getLanguage());
}

/**
* Is this event configurable by the user on the notification settings page
*
* @return bool
*/
public static function isConfigurableByUser(): bool {
return false;
}

/**
* {@inheritDoc}
*/
protected function excludeOwnerSubscribers(): bool {
return true;
}
}
59 changes: 58 additions & 1 deletion engine/classes/Elgg/Notifications/NotificationEventHandler.php
Expand Up @@ -88,7 +88,64 @@ final protected function prepareSubscriptions(): array {
* @return array
*/
public function getSubscriptions(): array {
return _elgg_services()->subscriptions->getNotificationEventSubscriptions($this->event, $this->getMethods());
return _elgg_services()->subscriptions->getNotificationEventSubscriptions($this->event, $this->getMethods(), $this->getNotificationSubsciptionExclusionGUIDs());
}

/**
* Get an array of GUIDs to not get the subscription records for
*
* @return int[]
*/
final protected function getNotificationSubsciptionExclusionGUIDs(): array {
$object = $this->event->getObject();
if (!$object instanceof \ElggEntity) {
return [];
}

$exclude = [];
if ($this->excludeOwnerSubscribers()) {
$exclude[] = $object->owner_guid;
}

if ($this->excludeContainerSubscribers()) {
$exclude[] = $object->container_guid;
}

if ($this->excludeEntitySubscribers()) {
$exclude[] = $object->guid;
}

return $exclude;
}

/**
* Don't get the subscribers of the NotificationEvent object owner when fetching the subscribers for this notification
*
* @return bool
* @see NotificationEventHandler::getSubscriptions();
*/
protected function excludeOwnerSubscribers(): bool {
return false;
}

/**
* Don't get the subscribers of the NotificationEvent object container when fetching the subscribers for this notification
*
* @return bool
* @see NotificationEventHandler::getSubscriptions();
*/
protected function excludeContainerSubscribers(): bool {
return false;
}

/**
* Don't get the subscribers of the NotificationEvent object when fetching the subscribers for this notification
*
* @return bool
* @see NotificationEventHandler::getSubscriptions();
*/
protected function excludeEntitySubscribers(): bool {
return false;
}

/**
Expand Down
15 changes: 10 additions & 5 deletions engine/classes/Elgg/Notifications/SubscriptionsService.php
Expand Up @@ -66,12 +66,13 @@ public function __construct(Database $db, RelationshipsTable $relationshipsTable
* <user guid> => array('email', 'sms', 'ajax'),
* );
*
* @param NotificationEvent $event Notification event
* @param array $methods Notification methods
* @param NotificationEvent $event Notification event
* @param array $methods Notification methods
* @param array $exclude_guids_for_records GUIDs to exclude from fetching subscription records
*
* @return array
*/
public function getNotificationEventSubscriptions(NotificationEvent $event, array $methods) {
public function getNotificationEventSubscriptions(NotificationEvent $event, array $methods, array $exclude_guids_for_records = []) {

if (empty($methods)) {
return [];
Expand All @@ -87,8 +88,6 @@ public function getNotificationEventSubscriptions(NotificationEvent $event, arra
return [];
}

$subscriptions = [];

$guids = [
$object->owner_guid,
$object->container_guid,
Expand All @@ -97,6 +96,12 @@ public function getNotificationEventSubscriptions(NotificationEvent $event, arra
$guids[] = $object->guid;
}

$guids = array_diff($guids, $exclude_guids_for_records);
if (empty($guids)) {
return [];
}

$subscriptions = [];
$records = $this->getSubscriptionRecords($guids, $methods, $object->type, $object->subtype, $event->getAction(), $event->getActorGUID());
foreach ($records as $record) {
if (empty($record->guid)) {
Expand Down
Expand Up @@ -439,6 +439,59 @@ public function testGetNotificationEventSubscriptionsWithMutedEntityBySubscripti
$this->assertEmpty($this->service->filterSubscriptions($subscriptions, $event));
}

public function testGetNotificationEventSubscriptionsWithExcludedOwnerGUID() {
$this->entities[] = $user = $this->createUser();

$event = $this->getSubscriptionNotificationEvent();

/* @var $object \ElggObject */
$object = $event->getObject();
$owner = $object->getOwnerEntity();
$this->assertTrue($owner->addSubscription($user->guid, 'apples'));

$subscriptions = $this->service->getNotificationEventSubscriptions($event, ['apples', 'bananas']);
$this->assertNotEmpty($subscriptions);

// exclude owner
$subscriptions = $this->service->getNotificationEventSubscriptions($event, ['apples', 'bananas'], [$owner->guid]);
$this->assertEmpty($subscriptions);
}

public function testGetNotificationEventSubscriptionsWithExcludedContainerGUID() {
$this->entities[] = $user = $this->createUser();

$event = $this->getSubscriptionNotificationEvent();

/* @var $object \ElggObject */
$object = $event->getObject();
$container = $object->getContainerEntity();
$this->assertTrue($container->addSubscription($user->guid, 'apples'));

$subscriptions = $this->service->getNotificationEventSubscriptions($event, ['apples', 'bananas']);
$this->assertNotEmpty($subscriptions);

// exclude container
$subscriptions = $this->service->getNotificationEventSubscriptions($event, ['apples', 'bananas'], [$container->guid]);
$this->assertEmpty($subscriptions);
}

public function testGetNotificationEventSubscriptionsWithExcludedEntityGUID() {
$this->entities[] = $user = $this->createUser();

$event = $this->getSubscriptionNotificationEvent();

/* @var $object \ElggObject */
$object = $event->getObject();
$this->assertTrue($object->addSubscription($user->guid, 'apples'));

$subscriptions = $this->service->getNotificationEventSubscriptions($event, ['apples', 'bananas']);
$this->assertNotEmpty($subscriptions);

// exclude entity
$subscriptions = $this->service->getNotificationEventSubscriptions($event, ['apples', 'bananas'], [$object->guid]);
$this->assertEmpty($subscriptions);
}

public function testGetNotificationEventSubscriptionsWhereEventActorIsNotPresentInResult() {
$event = $this->getSubscriptionNotificationEvent();

Expand Down

0 comments on commit 8af26bb

Please sign in to comment.