mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°7157 - Allow users to unsubscribe from notification channels (#611)
* N°7157 - Allow users to unsubscribe from notification channels * Fix type hinting * Add missing dict entries * Allows to subscribe/unsubscribe from notifications individually * Refactor NotificationsService to singleton pattern * Refactor NotificationsRepository to singleton pattern and rename methods to a more functional naming * Add PHPDoc and type hints * Dump autoloaders * Replace modals with toasts * Add dict entry --------- Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
This commit is contained in:
120
sources/Service/Notification/NotificationsRepository.php
Normal file
120
sources/Service/Notification/NotificationsRepository.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Service\Notification;
|
||||
|
||||
use DBObjectSearch;
|
||||
use DBObjectSet;
|
||||
|
||||
/**
|
||||
* Class NotificationsRepository
|
||||
*
|
||||
* @author Stephen Abello <stephen.abello@combodo.com>
|
||||
* @package Combodo\iTop\Service\Notification
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class NotificationsRepository
|
||||
{
|
||||
/** @var NotificationsRepository|null Singleton */
|
||||
protected static ?NotificationsRepository $oSingleton = null;
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @return static The singleton instance of the notifications repository
|
||||
*/
|
||||
public static function GetInstance(): static
|
||||
{
|
||||
if (is_null(self::$oSingleton)) {
|
||||
self::$oSingleton = new static();
|
||||
}
|
||||
|
||||
return self::$oSingleton;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Non-static methods */
|
||||
/**********************/
|
||||
|
||||
/**
|
||||
* Singleton pattern, can't use the constructor. Use {@see \Combodo\iTop\Service\Notification\NotificationsRepository::GetInstance()} instead.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Don't do anything, we don't want to be initialized
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for subscriptions by contact ID.
|
||||
*
|
||||
* @param int $iContactId The ID of the contact.
|
||||
*
|
||||
* @return DBObjectSet The result set of subscriptions associated with the contact.
|
||||
*/
|
||||
public function SearchSubscriptionByContact(int $iContactId): DBObjectSet
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT lnkActionNotificationToContact AS lnk WHERE lnk.contact_id = :contact_id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('contact_id' => $iContactId));
|
||||
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a subscription by trigger, contact, and action.
|
||||
*
|
||||
* @param int $iTriggerId The ID of the trigger.
|
||||
* @param int $iContactId The ID of the contact.
|
||||
* @param int $iActionID The ID of the action.
|
||||
*
|
||||
* @return DBObjectSet The set of subscriptions matching the given trigger, contact, and action.
|
||||
*/
|
||||
public function SearchSubscriptionByTriggerContactAndAction(int $iTriggerId, int $iContactId, int $iActionID): DBObjectSet
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT lnkActionNotificationToContact AS lnk WHERE lnk.contact_id = :contact_id AND lnk.trigger_id = :trigger_id AND lnk.action_id = :action_id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('trigger_id' => $iTriggerId, 'contact_id' => $iContactId, 'action_id' => $iActionID));
|
||||
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for subscriptions based on trigger, contact, and subscription type.
|
||||
*
|
||||
* @param int $iTriggerId The ID of the trigger.
|
||||
* @param int $iContactId The ID of the contact.
|
||||
* @param string $sSubscription The subscription type.
|
||||
*
|
||||
* @return DBObjectSet A set of subscription objects matching the given parameters.
|
||||
*/
|
||||
public function SearchSubscriptionByTriggerContactAndSubscription(int $iTriggerId, int $iContactId, string $sSubscription): DBObjectSet
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT lnkActionNotificationToContact AS lnk WHERE lnk.contact_id = :contact_id AND lnk.trigger_id = :trigger_id AND lnk.subscribed = :subscription");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('trigger_id' => $iTriggerId, 'contact_id' => $iContactId, 'subscription' => $sSubscription));
|
||||
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search for subscriptions based on trigger, contact, subscription type, and final class.
|
||||
*
|
||||
* @param int $iTriggerId The ID of the trigger.
|
||||
* @param int $iContactId The ID of the contact.
|
||||
* @param int $sSubscription The subscription type.
|
||||
* @param string $sFinalclass The final class of the action notification.
|
||||
*
|
||||
* @return DBObjectSet A set of subscription objects matching the given parameters.
|
||||
*/
|
||||
public function SearchSubscriptionByTriggerContactSubscriptionAndFinalclass(int $iTriggerId, int $iContactId, int $sSubscription, string $sFinalclass): DBObjectSet
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT lnkActionNotificationToContact AS lnk JOIN ActionNotification AS an ON lnk.action_id = an.id WHERE lnk.contact_id = :contact_id AND lnk.trigger_id = :trigger_id AND lnk.subscribed = :subscription AND an.finalclass = :finalclass");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('trigger_id' => $iTriggerId, 'contact_id' => $iContactId, 'subscription' => $sSubscription, 'finalclass' => $sFinalclass));
|
||||
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
public function GetSearchOQLContactUnsubscribedByTriggerAndAction(): DBObjectSearch
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Contact AS c JOIN lnkActionNotificationToContact AS lnk ON lnk.contact_id = c.id WHERE lnk.trigger_id = :trigger_id AND lnk.action_id = :action_id AND lnk.subscribed = '0'");
|
||||
return $oSearch;
|
||||
}
|
||||
}
|
||||
116
sources/Service/Notification/NotificationsService.php
Normal file
116
sources/Service/Notification/NotificationsService.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
namespace Combodo\iTop\Service\Notification;
|
||||
|
||||
|
||||
use ActionNotification;
|
||||
use Contact;
|
||||
use lnkActionNotificationToContact;
|
||||
use Trigger;
|
||||
|
||||
/**
|
||||
* Class NotificationsService
|
||||
*
|
||||
* @author Stephen Abello <stephen.abello@combodo.com>
|
||||
* @package Combodo\iTop\Service\Notification
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class NotificationsService {
|
||||
protected static ?NotificationsService $oSingleton = null;
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @return static The singleton instance of the notifications service
|
||||
*/
|
||||
public static function GetInstance(): static
|
||||
{
|
||||
if (null === static::$oSingleton) {
|
||||
static::$oSingleton = new static();
|
||||
}
|
||||
|
||||
return static::$oSingleton;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Non-static methods */
|
||||
/**********************/
|
||||
|
||||
/**
|
||||
* Singleton pattern, can't use the constructor. Use {@see \Combodo\iTop\Service\Notification\NotificationsService::GetInstance()} instead.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct() {
|
||||
// Don't do anything, we don't want to be initialized
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that $oRecipient was a recipient for the $oTrigger / $oActionNotification tuple at least one time
|
||||
*
|
||||
* @param \Trigger $oTrigger
|
||||
* @param \ActionNotification $oActionNotification
|
||||
* @param \Contact $oRecipient
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function RegisterSubscription(Trigger $oTrigger, ActionNotification $oActionNotification, Contact $oRecipient): void
|
||||
{
|
||||
// Check if the user is already subscribed to the action notification
|
||||
$oSubscribedActionsNotificationsSet = NotificationsRepository::GetInstance()->SearchSubscriptionByTriggerContactAndAction($oTrigger->GetKey(), $oRecipient->GetKey(), $oActionNotification->GetKey());
|
||||
if ($oSubscribedActionsNotificationsSet->Count() === 0) {
|
||||
// Create a new subscription
|
||||
$oSubscribedActionsNotifications = new lnkActionNotificationToContact();
|
||||
$oSubscribedActionsNotifications->Set('action_id', $oActionNotification->GetKey());
|
||||
$oSubscribedActionsNotifications->Set('contact_id', $oRecipient->GetKey());
|
||||
$oSubscribedActionsNotifications->Set('trigger_id', $oTrigger->GetKey());
|
||||
$oSubscribedActionsNotifications->Set('subscribed', true);
|
||||
$oSubscribedActionsNotifications->DBInsertNoReload();
|
||||
}
|
||||
else {
|
||||
while ($oSubscribedActionsNotifications = $oSubscribedActionsNotificationsSet->Fetch()) {
|
||||
// Update the subscription
|
||||
$oSubscribedActionsNotifications->Set('subscribed', true);
|
||||
$oSubscribedActionsNotifications->DBUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Trigger $oTrigger
|
||||
* @param \ActionNotification $oActionNotification
|
||||
* @param \Contact $oRecipient
|
||||
*
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*/
|
||||
public function IsSubscribed(Trigger $oTrigger, ActionNotification $oActionNotification, Contact $oRecipient): bool
|
||||
{
|
||||
// Check if the trigger subscription policy is 'force_all_channels'
|
||||
if ($oTrigger->Get('subscription_policy') === 'force_all_channels') {
|
||||
return true;
|
||||
}
|
||||
// Check if the user is already subscribed to the action notification
|
||||
$oSubscribedActionsNotificationsSet = NotificationsRepository::GetInstance()->SearchSubscriptionByTriggerContactAndAction($oTrigger->GetKey(), $oRecipient->GetKey(), $oActionNotification->GetKey());
|
||||
if ($oSubscribedActionsNotificationsSet->Count() === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the subscribed status
|
||||
$oSubscribedActionsNotifications = $oSubscribedActionsNotificationsSet->Fetch();
|
||||
return $oSubscribedActionsNotifications->Get('subscribed');
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user