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(); }