diff --git a/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php b/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php
index 12da61a33..68ef3c2ff 100644
--- a/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php
+++ b/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php
@@ -29,6 +29,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use UserRights;
+use utils;
/**
* Class UserProvider
@@ -44,6 +45,8 @@ class UserProvider
private $sPortalId;
/** @var \User $oUser */
private $oUser;
+ /** @var bool $bUserCanLogOff Whether the current user can log off or not */
+ private $bUserCanLogOff;
/** @var array $aAllowedPortals */
private $aAllowedPortals;
@@ -89,6 +92,9 @@ class UserProvider
throw new Exception('Could not load connected user.');
}
+ // User allowed to log off or not
+ $this->bUserCanLogOff = utils::CanLogOff();
+
// Allowed portals
$aAllowedPortals = UserRights::GetAllowedPortals();
@@ -119,6 +125,15 @@ class UserProvider
return $this->oUser;
}
+ /**
+ * @return bool {@see static::$bUserCanLogOff}
+ * @since 3.1.2 3.2.0
+ */
+ public function getCurrentUserCanLogOff(): bool
+ {
+ return $this->bUserCanLogOff;
+ }
+
/**
* Get allowed portals.
*
diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/CurrentUserAccessor.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/CurrentUserAccessor.php
index d9778da35..b1b94b9af 100644
--- a/datamodels/2.x/itop-portal-base/portal/src/Twig/CurrentUserAccessor.php
+++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/CurrentUserAccessor.php
@@ -61,4 +61,13 @@ class CurrentUserAccessor
{
return $this->userProvider->getCurrentUser()->Get($key);
}
+
+ /**
+ * @return bool
+ * @since 3.1.2 3.2.0
+ */
+ public function CanLogOff(): bool
+ {
+ return $this->userProvider->getCurrentUserCanLogOff();
+ }
}
\ No newline at end of file
diff --git a/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig b/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig
index 002258658..0646a2a1b 100644
--- a/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig
+++ b/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig
@@ -3,11 +3,13 @@
{% if app['combodo.current_user'] is defined and app['combodo.current_user'] is not null %}
{% set bUserConnected = true %}
+ {% set bUserCanLogOff = app['combodo.current_user'].CanLogOff() %}
{% set sUserFullname = app['combodo.current_user'].Get('first_name') ~ ' ' ~ app['combodo.current_user'].Get('last_name') %}
{% set sUserEmail = app['combodo.current_user'].Get('email') %}
{% set sUserPhotoUrl = app['combodo.current_contact.photo_url'] %}
{% else %}
{% set bUserConnected = false %}
+ {% set bUserCanLogOff = false %}
{% set sUserFullname = '' %}
{% set sUserEmail = '' %}
{% set sUserPhotoUrl = app['combodo.portal.base.absolute_url'] ~ 'img/user-profile-default-256px.png' %}
@@ -127,15 +129,13 @@
{# - Hilighter for code snippets created with CKEditor #}
- {# - Custom settings #}
-
{# Date-time picker for Bootstrap #}
{# Typeahead files for autocomplete #}
-
+
{# Selectize for sets #}
@@ -232,11 +232,13 @@
{{ aPortal.label|dict_s }}
{% endif %}
{% endfor %}
- {# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
- {% if allowed_portals|length > 1 %}
-
- {% endif %}
- {{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}
+ {% if bUserCanLogOff %}
+ {# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
+ {% if allowed_portals|length > 1 %}
+
+ {% endif %}
+ {{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}
+ {% endif %}
{% endif %}
@@ -271,11 +273,13 @@
{{ aPortal.label|dict_s }}
{% endif %}
{% endfor %}
- {# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
- {% if allowed_portals|length > 1 %}
-
- {% endif %}
- {{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}
+ {% if bUserCanLogOff %}
+ {# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
+ {% if allowed_portals|length > 1 %}
+
+ {% endif %}
+ {{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}
+ {% endif %}
@@ -539,12 +543,7 @@
});
// Initialize confirmation message handler when a form with touched fields is closed
- oBodyElem.leave_handler({
- 'message': '{{ 'Portal:Form:Close:Warning'|dict_s }}',
- 'extra_events': {
- 'body': ['hide.bs.modal']
- }
- });
+ oBodyElem.portal_leave_handler({'message': '{{ 'Portal:Form:Close:Warning'|dict_s }}'});
{% endblock %}
});
diff --git a/sources/Controller/Notifications/NotificationsCenterController.php b/sources/Controller/Notifications/NotificationsCenterController.php
index f058dbf53..4636bad32 100644
--- a/sources/Controller/Notifications/NotificationsCenterController.php
+++ b/sources/Controller/Notifications/NotificationsCenterController.php
@@ -59,9 +59,6 @@ class NotificationsCenterController extends Controller
$oNotificationsPanel = new Panel(Dict::S('UI:NotificationsCenter:Panel:Title'), array(), 'grey', 'ibo-notifications-center');
$oNotificationsPanel->AddCSSClass('ibo-datatable-panel');
$oSubtitleBlock = new UIContentBlock(null, ['ibo-notifications-center--sub-title']);
- $sDisplayAdvancedPageUrl = Router::GetInstance()->GenerateUrl(self::ROUTE_NAMESPACE.'.display_advanced_page', [], true);
- $oSubtitleBlock->AddSubBlock(new Html(Dict::Format('UI:NotificationsCenter:Panel:SubTitle', $sDisplayAdvancedPageUrl)));
- $oNotificationsPanel->SetSubTitleBlock($oSubtitleBlock);
$oNotificationsCenterTableColumns = [
'trigger' => array('label' => MetaModel::GetName('Trigger')),
'trigger_class' => array('label' => MetaModel::GetAttributeDef('Trigger', 'finalclass')->GetLabel()),
@@ -267,205 +264,6 @@ JS
return $oPage;
}
-
- public function OperationDisplayAdvancedPage(){
- $oPage = new iTopWebPage(Dict::S('UI:NotificationsCenter:Page:Title'));
- // Create a panel that will contain the table
- $oNotificationsPanel = new Panel(Dict::S('UI:NotificationsCenter:Panel:Title'), array(), 'grey', 'ibo-notifications-center');
- $oSubtitleBlock = new UIContentBlock(null, ['ibo-notifications-center--sub-title']);
- $sDisplayAdvancedPageUrl = Router::GetInstance()->GenerateUrl(self::ROUTE_NAMESPACE.'.display_page', [], true);
- $oSubtitleBlock->AddSubBlock(new Html(Dict::Format('UI:NotificationsCenter:Panel:Advanced:SubTitle', $sDisplayAdvancedPageUrl)));
- $oNotificationsPanel->SetSubTitleBlock($oSubtitleBlock);
- $oPage->AddUiBlock($oNotificationsPanel);
-
- // Get all subscribed/unsubscribed actions notifications for the current user
- $oLnkNotificationsSet = NotificationsRepository::GetInstance()->SearchSubscriptionsByContact(\UserRights::GetContactId());
- $oActionsNotificationsByTrigger = [];
- $aSubscribedActionsNotificationsByTrigger = [];
- while ($oLnkActionsNotifications = $oLnkNotificationsSet->Fetch()) {
- $oSubscribedActionNotification = MetaModel::GetObject(ActionNotification::class, $oLnkActionsNotifications->Get('action_id'));
- $oTrigger = MetaModel::GetObject('Trigger', $oLnkActionsNotifications->Get('trigger_id'));
- $iTriggerId = $oTrigger->GetKey();
- // Create a new array for the trigger if it doesn't exist
- if (!isset($oActionsNotificationsByTrigger[$iTriggerId])) {
- $oActionsNotificationsByTrigger[$iTriggerId] = [];
- $aSubscribedActionsNotificationsByTrigger[$iTriggerId] = [];
- }
- // Add the action notification to the list of actions notifications for the trigger
- $oActionsNotificationsByTrigger[$iTriggerId][] = $oSubscribedActionNotification;
- // Add the subscribed status to the list of subscribed actions notifications for the trigger
- $aSubscribedActionsNotificationsByTrigger[$iTriggerId][$oSubscribedActionNotification->GetKey()] = $oLnkActionsNotifications->Get('subscribed') || $oTrigger->Get('subscription_policy') === SubscriptionPolicy::ForceAllChannels->value;
- }
-
- $oPage->AddTabContainer('NotificationsCenter', '', $oNotificationsPanel);
- $oPage->SetCurrentTabContainer('NotificationsCenter');
- // Create a new tab for each trigger
- foreach ($oActionsNotificationsByTrigger as $iTriggerId => $aActionsNotifications) {
- $oTrigger = MetaModel::GetObject('Trigger', $iTriggerId, false);
- if ($oTrigger === null) {
- continue;
- }
- foreach ($aActionsNotifications as $oActionNotification) {
- $oPage->SetCurrentTab(MetaModel::GetName(get_class($oActionNotification)));
- $oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(
- Dict::Format('UI:NotificationsCenter:Advanced:Input:Label', $oTrigger->Get('description'), $oActionNotification->Get('name')),
- $oTrigger->GetKey().'|'.$oActionNotification->GetKey(),
- "",
- $oTrigger->GetKey().'|'.$oActionNotification->GetKey(),
- "checkbox"
- );
- $oCheckBox->GetInput()->SetIsChecked($aSubscribedActionsNotificationsByTrigger[$iTriggerId][$oActionNotification->GetKey()] === true);
- $oCheckBox->SetBeforeInput(false);
- $oCheckBox->GetInput()->AddCSSClass('ibo-input--label-right');
- $oCheckBox->GetInput()->AddCSSClass('ibo-input-checkbox');
- $oContainer = new UIContentBlock(null, ['ibo-notifications-center-advanced--input--container']);
- $oContainer->AddSubBlock($oCheckBox);
- $oPage->AddUiBlock($oContainer);
- }
- }
- $sSubscribeUrl = Router::GetInstance()->GenerateUrl(self::ROUTE_NAMESPACE.'.subscribe', [], true);
- $sUnsubscribeUrl = Router::GetInstance()->GenerateUrl(self::ROUTE_NAMESPACE.'.unsubscribe', [], true);
- $sCSRFToken = utils::GetNewTransactionId();
- $oPage->add_ready_script(
-<<CheckPostedCSRF()) {
- throw new \Exception('Invalid token');
- }
-
- $sChannel = utils::ReadParam('channel', '', true, 'raw_data');
- $aChannel = explode('|', $sChannel);
- $oPage = new \JsonPage();
- $aReturnData = [];
- try {
- if (count($aChannel) !== 2) {
- throw new \Exception('Invalid channel');
- }
- $iTriggerKey = $aChannel[0];
- $iActionNotificationKey = $aChannel[1];
- $oTrigger = MetaModel::GetObject('Trigger', $iTriggerKey, false);
- if ($oTrigger === null) {
- throw new \Exception('Invalid trigger');
- }
- $oActionNotification = MetaModel::GetObject('ActionNotification', $iActionNotificationKey, false);
- if ($oActionNotification === null) {
- throw new \Exception('Invalid action notification');
- }
- $oSubscribedActionsNotificationsSet = NotificationsRepository::GetInstance()->SearchSubscribedSubscriptionsByTriggerContactAndAction($iTriggerKey, $iActionNotificationKey);
- if ($oSubscribedActionsNotificationsSet->Count() === 0) {
- throw new \Exception('You are not subscribed to this channel');
- }
- while ($oSubscribedActionsNotifications = $oSubscribedActionsNotificationsSet->Fetch()) {
- $oSubscribedActionsNotifications->Set('subscribed', false);
- $oSubscribedActionsNotifications->DBUpdate();
- }
- $aReturnData = [
- 'status' => 'success',
- 'message' => Dict::S('UI:NotificationsCenter:Unsubscribe:Success'),
- ];
- }
- catch (Exception $e) {
- $aReturnData = [
- 'status' => 'error',
- 'message' => $e->getMessage(),
- ];
- }
- $oPage->SetData($aReturnData);
- $oPage->SetOutputDataOnly(true);
-
- return $oPage;
- }
-
- function OperationSubscribe()
- {
-
- // Get the CSRF token from the request and check if it's valid
- if (!$this->CheckPostedCSRF()) {
- throw new \Exception('Invalid token');
- }
-
- $sChannel = utils::ReadParam('channel', '', true, 'raw_data');
- $aChannel = explode('|', $sChannel);
-
- $oPage = new \JsonPage();
- $aReturnData = [];
- try {
- if (count($aChannel) !== 2) {
- throw new \Exception('Invalid channel');
- }
- $iTriggerKey = $aChannel[0];
- $iActionNotificationKey = $aChannel[1];
- $oTrigger = MetaModel::GetObject('Trigger', $iTriggerKey, false);
- if ($oTrigger === null) {
- throw new \Exception('Invalid trigger');
- }
- $oActionNotification = MetaModel::GetObject('ActionNotification', $iActionNotificationKey, false);
- if ($oActionNotification === null) {
- throw new \Exception('Invalid action notification');
- }
- $oSubscribedActionsNotificationsSet = NotificationsRepository::GetInstance()->SearchUnsubscribedSubscriptionsByTriggerContactAndAction($iTriggerKey, $iActionNotificationKey);
- if ($oSubscribedActionsNotificationsSet->Count() === 0) {
- throw new \Exception('You are not allow to subscribe to this channel');
- }
- while ($oSubscribedActionsNotifications = $oSubscribedActionsNotificationsSet->Fetch()) {
- $oSubscribedActionsNotifications->Set('subscribed', true);
- $oSubscribedActionsNotifications->DBUpdate();
- }
- $aReturnData = [
- 'status' => 'success',
- 'message' => Dict::S('UI:NotificationsCenter:Subscribe:Success'),
- ];
- }
- catch (Exception $e) {
- $aReturnData = [
- 'status' => 'error',
- 'message' => $e->getMessage(),
- ];
- }
- $oPage->SetData($aReturnData);
- $oPage->SetOutputDataOnly(true);
-
- return $oPage;
- }
/**
* @return \JsonPage
diff --git a/synchro/synchrodatasource.class.inc.php b/synchro/synchrodatasource.class.inc.php
index f418b4eb9..791a5ebfc 100644
--- a/synchro/synchrodatasource.class.inc.php
+++ b/synchro/synchrodatasource.class.inc.php
@@ -1961,6 +1961,12 @@ class SynchroLog extends DBObject
{
$this->TraceToText();
$sMemPeak = max($this->Get('memory_usage_peak'), ExecutionKPI::memory_get_peak_usage());
+
+ // memory peak overflow protection
+ if($sMemPeak > 2147483647){
+ $sMemPeak = 2147483647;
+ }
+
$this->Set('memory_usage_peak', $sMemPeak);
parent::OnUpdate();
}