mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-20 15:52:24 +02:00
N°8796 - Add PHP code style validation in iTop and extensions - format whole code base
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Page:DefaultTitle' => 'Uživatelský portál %1$s',
|
||||
'Page:PleaseWait' => 'Počkejte prosím',
|
||||
'Page:Home' => 'Domů',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Otevřít</a> / <a href="%4$s" class="file_download_link">Stáhnout</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'cs', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Zavřít tento vstup',
|
||||
'Portal:Form:Close:Warning' => 'Opravdu chcete opustit tento formulář? Data vložená do formuláře budou ztracena ',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Chyba: objekt nelze vytvořit. Před opětovným odesláním tohoto formuláře zkontrolujte související objekty a přílohy.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Chyba: objekt nelze vytvořit. Před opětovným odesláním tohoto formuláře zkontrolujte související objekty a přílohy.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Uživatelský profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Můj profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Odhlásit',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Nepodařilo se změnit heslo, kontaktujte prosím administrátora',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Osobní informace',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Foto',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Nástěnka',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Brick:Portal:Browse:Name' => 'Procházet položky',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Seznam',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Strom',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Rozbalit vše',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Sbalit vše',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Žádná položka',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Brick:Portal:Manage:Name' => 'Spravovat položky',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Žádná položka',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Akce',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Průměr',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Brick:Portal:Object:Name' => 'Objekt',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Nový %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Aktualizace %2$s (%1$s)',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Vybrat %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%1$s: %2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Zkopíruj odkaz na objekt',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Zkopírováno'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Zkopírováno',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Brick:Portal:Create:Name' => 'Rychlé vytvoření',
|
||||
'Brick:Portal:Create:ChooseType' => 'Vyberte typ',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Brick:Portal:Filter:Name' => 'Předfiltrování dlaždice',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'např. připojení k wifi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Vyhledat',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Page:DefaultTitle' => '%1$s User portal~~',
|
||||
'Page:PleaseWait' => 'Please wait...~~',
|
||||
'Page:Home' => 'Home~~',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>~~',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>~~',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'da', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry~~',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form? Data entered may be lost~~',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Brick:Portal:UserProfile:Name' => 'User profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'My profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Logoff~~',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Can\'t change password, please contact your %1$s administrator~~',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Personal information~~',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Brick:Portal:Browse:Name' => 'Browse throught items~~',
|
||||
'Brick:Portal:Browse:Mode:List' => 'List~~',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Tree~~',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expand all~~',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Collapse all~~',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'No item~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Brick:Portal:Manage:Name' => 'Manage items~~',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'No item.~~',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions~~',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Average~~',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min~~',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Brick:Portal:Object:Name' => 'Object~~',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'New %1$s~~',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Updating %2$s (%1$s)~~',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)~~',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copy object link~~',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Brick:Portal:Create:Name' => 'Quick creation~~',
|
||||
'Brick:Portal:Create:ChooseType' => 'Please, choose a type~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefilter a brick~~',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'eg. connect wifi~~',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Search~~',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Page:DefaultTitle' => '%1$s - Benutzer Portal',
|
||||
'Page:PleaseWait' => 'Bitte warten...',
|
||||
'Page:Home' => 'Start',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Öffnen</a> / <a href="%4$s" class="file_download_link">Download</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'de', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Dieses Objekt schließen',
|
||||
'Portal:Form:Close:Warning' => 'Soll diese Eingabemaske verlassen werden? Eingegebene Daten werden nicht gespeichert.',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: Objekt kann nicht erzeugt werden. Prüfen Sie verknüpfte Objekte und Anhänge bevor Sie dieses Formular erneut abschicken.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: Objekt kann nicht geupdated werden. Prüfen Sie verknüpfte Objekte und Anhänge bevor Sie dieses Formular erneut abschicken.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Benutzer Profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Mein Profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Abmelden',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Passwort kann nicht geändert werden - bitte kontaktieren Sie Ihren %1$s Administrator',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Persönliche Informationen',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Foto',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Brick:Portal:Browse:Name' => 'Liste durchgehen',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Liste',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Baum',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Alle expandieren',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Alle kollabieren',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Kein Eintrag',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Brick:Portal:Manage:Name' => 'Einträge managen',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Kein Eintrag.',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Aktionen',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Durchschnitt',
|
||||
'Brick:Portal:Manage:fct:min' => 'Minimum',
|
||||
'Brick:Portal:Manage:fct:max' => 'Maximum',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Brick:Portal:Object:Name' => 'Object',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Neue %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Wird aktualisiert %2$s (%1$s)',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Objektverknüpfung kopieren',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Kopiert'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Kopiert',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Brick:Portal:Create:Name' => 'Schnelles Erstellen',
|
||||
'Brick:Portal:Create:ChooseType' => 'Bitte wählen Sie einen Typ',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Brick:Portal:Filter:Name' => 'Brick vorfiltern',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'z.B. connect wifi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Suchen',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -18,7 +19,7 @@
|
||||
*/
|
||||
|
||||
// Portal
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Page:DefaultTitle' => '%1$s User portal',
|
||||
'Page:PleaseWait' => 'Please wait...',
|
||||
'Page:Home' => 'Home',
|
||||
@@ -62,19 +63,19 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'en-us', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form? Data entered may be lost',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Brick:Portal:UserProfile:Name' => 'User profile',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'My profile',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Logoff',
|
||||
@@ -85,15 +86,15 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Can\'t change password, please contact your %1$s administrator',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Personal information',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Brick:Portal:Browse:Name' => 'Browse throught items',
|
||||
'Brick:Portal:Browse:Mode:List' => 'List',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Tree',
|
||||
@@ -106,10 +107,10 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expand all',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Collapse all',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'No item',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Brick:Portal:Manage:Name' => 'Manage items',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'No item.',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions',
|
||||
@@ -124,10 +125,10 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Average',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Brick:Portal:Object:Name' => 'Object',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'New %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Updating %2$s (%1$s)',
|
||||
@@ -139,18 +140,18 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copy object link',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Brick:Portal:Create:Name' => 'Quick creation',
|
||||
'Brick:Portal:Create:ChooseType' => 'Please, choose a type',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefilter a brick',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'eg. connect wifi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Search',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
// Portal
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Page:DefaultTitle' => '%1$s User portal',
|
||||
'Page:PleaseWait' => 'Please wait...',
|
||||
'Page:Home' => 'Home',
|
||||
@@ -49,19 +50,19 @@ Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'en-gb',
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form? Data entered may be lost',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Brick:Portal:UserProfile:Name' => 'User profile',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'My profile',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Log off',
|
||||
@@ -72,15 +73,15 @@ Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Can\'t change password, please contact your %1$s administrator',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Personal information',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Brick:Portal:Browse:Name' => 'Browse through items',
|
||||
'Brick:Portal:Browse:Mode:List' => 'List',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Tree',
|
||||
@@ -93,10 +94,10 @@ Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expand all',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Collapse all',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'No item',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Brick:Portal:Manage:Name' => 'Manage items',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'No item.',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions',
|
||||
@@ -111,10 +112,10 @@ Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Average',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Brick:Portal:Object:Name' => 'Object',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'New %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Updating %2$s (%1$s)',
|
||||
@@ -126,18 +127,18 @@ Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copy object link',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Brick:Portal:Create:Name' => 'Quick creation',
|
||||
'Brick:Portal:Create:ChooseType' => 'Please, choose a type',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('EN GB', 'British English', 'British English', array(
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefilter a brick',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'eg. connect wifi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Search',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Spanish Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
* @author Miguel Turrubiates <miguel_tf@yahoo.com>
|
||||
* @notas Utilizar codificación UTF-8 para mostrar acentos y otros caracteres especiales
|
||||
* @notas Utilizar codificación UTF-8 para mostrar acentos y otros caracteres especiales
|
||||
*/
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Page:DefaultTitle' => '%1$s - Portal de Usuario',
|
||||
'Page:PleaseWait' => 'Por favor espere...',
|
||||
'Page:Home' => 'Inicio',
|
||||
@@ -51,19 +52,19 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Abierto</a> / <a href="%4$s" class="file_download_link">Descarga</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'es', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Cerrar este registro',
|
||||
'Portal:Form:Close:Warning' => '¿Desea abandorar este formulario? Datos modificados se perderan',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: no se puede crear el objeto. Verifique los objetos asociados y archivos adjuntos antes de enviar nuevamente este formulario.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: no se puede actualizar el objeto. Verifique los objetos asociados y archivos adjuntos antes de enviar nuevamente este formulario.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Perfil del usuario',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Mi perfil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Cerrar Sesión',
|
||||
@@ -74,15 +75,15 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'No se puede cambiar la contraseña, póngase en contacto con el administrador de %1$s',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Información Personal',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Foto',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Tablero de Control',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Brick:Portal:Browse:Name' => 'Buscar en todos los elementos',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Lista',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Árbol',
|
||||
@@ -95,10 +96,10 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expandir todo',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Desplegar todo',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Sin elementos',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Brick:Portal:Manage:Name' => 'Administrar elementos',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Sin elementos',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Acciones',
|
||||
@@ -113,10 +114,10 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Promedio',
|
||||
'Brick:Portal:Manage:fct:min' => 'Mínimo',
|
||||
'Brick:Portal:Manage:fct:max' => 'Máximo',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Brick:Portal:Object:Name' => 'Objecto',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Nuevo %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Actualizando %2$s (%1$s)',
|
||||
@@ -128,18 +129,18 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Selección %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copiar liga al objeto',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copiado'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copiado',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Brick:Portal:Create:Name' => 'Creación rápida',
|
||||
'Brick:Portal:Create:ChooseType' => 'Por favor, seleccione un tipo',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefiltrar bloque',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'Ej.:. Conectar a WiFi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Buscar',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Page:DefaultTitle' => 'Portail utilisateur %1$s',
|
||||
'Page:PleaseWait' => 'Veuillez patienter...',
|
||||
'Page:Home' => 'Accueil',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Ouvrir</a> / <a href="%4$s" class="file_download_link">Télécharger</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'fr', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Fermer cette entrée',
|
||||
'Portal:Form:Close:Warning' => 'Voulez-vous quitter ce formulaire ? Les données saisies seront perdues',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Erreur: L\'objet n\'a pas été créé. Vérifiez les objets liés et les attachements avant de soumettre à nouveau le formulaire.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Erreur: L\'objet n\'a pas été modifié. Vérifiez les objets liés et les attachements avant de soumettre à nouveau le formulaire.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Erreur durant la validation du champ \'%1$s\' : %2$s',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Erreur durant la validation du champ \'%1$s\' : %2$s',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Profil utilisateur',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Mon profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Déconnexion',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Impossible de modifier votre mot de passe, veuillez contacter votre administrateur %1$s',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Informations personnelles',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Tableau de bord',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Brick:Portal:Browse:Name' => 'Navigation dans les éléments',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Liste',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Hiérarchie',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Tout déplier',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Tout replier',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Aucun élément',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Brick:Portal:Manage:Name' => 'Gestion d\'éléments',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Aucun élément',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Moyenne',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Brick:Portal:Object:Name' => 'Objet',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Création de %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Modification de %2$s (%1$s)',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Sélection de %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copier l\'url de l\'objet',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copié'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copié',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Brick:Portal:Create:Name' => 'Création rapide',
|
||||
'Brick:Portal:Create:ChooseType' => 'Veuillez choisir le type',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Brick:Portal:Filter:Name' => 'Préfiltre une brique',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'ex : connecter wifi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Rechercher',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Page:DefaultTitle' => '%1$s Felhasználói portál',
|
||||
'Page:PleaseWait' => 'Kérem várjon...',
|
||||
'Page:Home' => 'Kezdőlap',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Megnyitás</a> / <a href="%4$s" class="file_download_link">Letöltés</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'hu', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Bejegyzés bezárása',
|
||||
'Portal:Form:Close:Warning' => 'Szeretné elhagyni ezt az űrlapot? A megadott adatok elveszhetnek',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Hiba: az objektum nem hozható létre. Ellenőrizze a kapcsolódó objektumokat és mellékleteket, mielőtt újra elküldi ezt az űrlapot.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Hiba: az objektum nem frissíthető. Ellenőrizze a kapcsolódó objektumokat és mellékleteket, mielőtt újra elküldi ezt az űrlapot.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Felhasználói profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Saját profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Kijelentkezés',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Nem tudja megváltoztatni a jelszót, lépjen kapcsolatba a %1$s rendszergazdával',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Személyi adatok',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Fénykép',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Műszerfal',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Brick:Portal:Browse:Name' => 'Böngésszen az elemek között',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Lista',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Fa',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Összes kinyitása',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Összecsukás',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Nincs elem',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Brick:Portal:Manage:Name' => 'Elemek kezelése',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Nincs elem',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Műveletek',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Átlag',
|
||||
'Brick:Portal:Manage:fct:min' => 'Minimum',
|
||||
'Brick:Portal:Manage:fct:max' => 'Maximum',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Brick:Portal:Object:Name' => 'Objektum',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Új %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => '%2$s frissítése (%1$s)',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => '%1$s kiválasztása (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Objektum hivatkozás másolása',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Másolva'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Másolva',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Brick:Portal:Create:Name' => 'Gyors létrehozás',
|
||||
'Brick:Portal:Create:ChooseType' => 'Válasszon típust',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Brick:Portal:Filter:Name' => 'Tégla előszűrése',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'pl. wifi kapcsolat',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Keresés',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Page:DefaultTitle' => '%1$s Portale Utente',
|
||||
'Page:PleaseWait' => 'Attendere…',
|
||||
'Page:Home' => 'Home',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>~~',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'it', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry~~',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form? Data entered may be lost~~',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Brick:Portal:UserProfile:Name' => 'User profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'My profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Logoff~~',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Can\'t change password, please contact your %1$s administrator~~',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Personal information~~',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Brick:Portal:Browse:Name' => 'Browse throught items~~',
|
||||
'Brick:Portal:Browse:Mode:List' => 'List~~',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Tree~~',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expand all~~',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Collapse all~~',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'No item~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Brick:Portal:Manage:Name' => 'Manage items~~',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'No item.~~',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions~~',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Average~~',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min~~',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Brick:Portal:Object:Name' => 'Object~~',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'New %1$s~~',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Updating %2$s (%1$s)~~',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)~~',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copy object link~~',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Brick:Portal:Create:Name' => 'Quick creation~~',
|
||||
'Brick:Portal:Create:ChooseType' => 'Please, choose a type~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefilter a brick~~',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'eg. connect wifi~~',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Search~~',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Page:DefaultTitle' => '%1$s User portal~~',
|
||||
'Page:PleaseWait' => 'Please wait...~~',
|
||||
'Page:Home' => 'Home~~',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>~~',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>~~',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'ja', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry~~',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form? Data entered may be lost~~',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Brick:Portal:UserProfile:Name' => 'User profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'My profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Logoff~~',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Can\'t change password, please contact your %1$s administrator~~',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Personal information~~',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Brick:Portal:Browse:Name' => 'Browse throught items~~',
|
||||
'Brick:Portal:Browse:Mode:List' => 'List~~',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Tree~~',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expand all~~',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Collapse all~~',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'No item~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Brick:Portal:Manage:Name' => 'Manage items~~',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'No item.~~',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions~~',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Average~~',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min~~',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Brick:Portal:Object:Name' => 'Object~~',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'New %1$s~~',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Updating %2$s (%1$s)~~',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)~~',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copy object link~~',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Brick:Portal:Create:Name' => 'Quick creation~~',
|
||||
'Brick:Portal:Create:ChooseType' => 'Please, choose a type~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefilter a brick~~',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'eg. connect wifi~~',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Search~~',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @author Jeffrey Bostoen <info@jeffreybostoen.be> (2018 - 2022)
|
||||
*
|
||||
*/
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Page:DefaultTitle' => '%1$s Gebruikersportaal',
|
||||
'Page:PleaseWait' => 'Even geduld...',
|
||||
'Page:Home' => 'Welkom',
|
||||
@@ -54,19 +55,19 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'nl', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Sluit dit item.',
|
||||
'Portal:Form:Close:Warning' => 'Ben je zeker dat je dit venster wil sluiten? Ingevoerde gegevens kunnen verloren gaan.',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Fout: object kan niet worden aangemaakt. Kijk verwante objecten en bijlagen na vooraleer dit formulier opnieuw te versturen.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Fout: object kan niet worden aangepast. Kijk verwante objecten en bijlagen na vooraleer dit formulier opnieuw te versturen.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Gebruikersprofiel',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Mijn profiel',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Uitloggen',
|
||||
@@ -77,15 +78,15 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Jouw wachtwoord kan niet gewijzigd worden. Neem contact op met de beheerder',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Persoonlijke informatie',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Foto',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Brick:Portal:Browse:Name' => 'Bladeren',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Lijst',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Boomstructuur',
|
||||
@@ -98,10 +99,10 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Toon alles',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Verberg alles',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Geen gegevens',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Brick:Portal:Manage:Name' => 'Beheer items',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Geen gegevens',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Acties',
|
||||
@@ -116,10 +117,10 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Gemiddelde',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Brick:Portal:Object:Name' => 'Object',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Nieuw %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Verwerken %2$s (%1$s)',
|
||||
@@ -131,18 +132,18 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Selecteer %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Kopieer link naar object',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Gekopieerd'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Gekopieerd',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Brick:Portal:Create:Name' => 'Snel aanmaken',
|
||||
'Brick:Portal:Create:ChooseType' => 'Geef een type op.',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Brick:Portal:Filter:Name' => 'Voorfilteren van een bouwsteen',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'bv. wifi-verbinding',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Zoek',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Page:DefaultTitle' => '%1$s portal użytkownika',
|
||||
'Page:PleaseWait' => 'Proszę czekać...',
|
||||
'Page:Home' => 'Start',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Pobierz</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'en-us', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Zamknij ten wpis',
|
||||
'Portal:Form:Close:Warning' => 'Chcesz opuścić ten formularz? Wprowadzone dane mogą zostać utracone',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Błąd: nie można utworzyć obiektu. Sprawdź powiązane obiekty i załączniki przed ponownym przesłaniem tego formularza.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Błąd: nie można zaktualizować obiektu. Sprawdź powiązane obiekty i załączniki przed ponownym przesłaniem tego formularza.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Profil użytkownika',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Mój profil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Wyloguj',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Nie można zmienić hasła. Skontaktuj się z administratorem %1$s',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Informacje osobiste',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Zdjęcie',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Pulpit',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Brick:Portal:Browse:Name' => 'Przeglądaj elementy',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Lista',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Drzewo',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Rozwiń wszystkie',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Zwiń wszystkie',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Brak elementu',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Brick:Portal:Manage:Name' => 'Zarządzaj elementami',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Brak elementu.',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Akcje',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Średnia',
|
||||
'Brick:Portal:Manage:fct:min' => 'Minimum',
|
||||
'Brick:Portal:Manage:fct:max' => 'Maksimum',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Brick:Portal:Object:Name' => 'Obiekty',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Nowy %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Aktualizacja %2$s (%1$s)',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Wybierz %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Skopiuj obiekt',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Skopiowano'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Skopiowano',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Brick:Portal:Create:Name' => 'Szybkie tworzenie',
|
||||
'Brick:Portal:Create:ChooseType' => 'Proszę wybrać typ',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Brick:Portal:Filter:Name' => 'Wstępny filtr',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'na przykład. podłącz wifi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Szukaj',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Page:DefaultTitle' => 'Portal do Usuário do '.ITOP_APPLICATION_SHORT,
|
||||
'Page:PleaseWait' => 'Aguarde...',
|
||||
'Page:Home' => 'Página inicial',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Abrir</a> / <a href="%4$s" class="file_download_link">Download</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'pt-br', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Fechar esta solicitação',
|
||||
'Portal:Form:Close:Warning' => 'Você deseja abandonar esta página? Os dados digitados podem ser perdidos',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Erro: objeto não pode ser criado. Verifique os objetos e anexos associados antes de enviar novamente este formulário',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Erro: objeto não pode ser atualizado. Verifique os objetos e anexos associados antes de enviar novamente este formulário',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Perfil de Usuário',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Meu Perfil',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Sair',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Não foi possível alterar sua senha, entre em contato com a T.I.',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Informações pessoais',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Imagem',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Painel do '.ITOP_APPLICATION_SHORT,
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Brick:Portal:Browse:Name' => 'Navegar por itens',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Lista',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Cascata',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expandir todos',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Recolher todos',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Sem dados',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Brick:Portal:Manage:Name' => 'Gerenciar itens',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Sem dados',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Ações',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Média',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min.',
|
||||
'Brick:Portal:Manage:fct:max' => 'Máx.',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Brick:Portal:Object:Name' => 'Objeto',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Novo %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Alterar %2$s (%1$s)',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Selecinar %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copiar',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copiado'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copiado',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Brick:Portal:Create:Name' => 'Criação rápida',
|
||||
'Brick:Portal:Create:ChooseType' => 'Por favor, escolha um tipo:',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Brick:Portal:Filter:Name' => 'Filtro ativado',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'ex. conectar ao WiFi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Pesquisa',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
*
|
||||
*/
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Page:DefaultTitle' => 'Пользовательский портал %1$s',
|
||||
'Page:PleaseWait' => 'Пожалуйста, подождите...',
|
||||
'Page:Home' => 'Домашняя страница',
|
||||
@@ -54,19 +55,19 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Открыть</a> / <a href="%4$s" class="file_download_link">Скачать</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'ru', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry~~',
|
||||
'Portal:Form:Close:Warning' => 'Вы действительно хотите закрыть эту форму? Введённые данные могут быть утеряны.',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Brick:Portal:UserProfile:Name' => 'Профиль пользователя',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'Мой профиль',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Выйти',
|
||||
@@ -77,15 +78,15 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Не удалось изменить пароль, пожалуйста, свяжитесь с вашим администратором %1$s.',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Персональная информация',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Фотография',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Дашборд',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Brick:Portal:Browse:Name' => 'Просмотр элементов',
|
||||
'Brick:Portal:Browse:Mode:List' => 'Список',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Дерево',
|
||||
@@ -98,10 +99,10 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Развернуть все',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Свернуть все',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'Нет элементов',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Brick:Portal:Manage:Name' => 'Управление элементами',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'Нет элементов',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Действия',
|
||||
@@ -116,10 +117,10 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Среднее',
|
||||
'Brick:Portal:Manage:fct:min' => 'Минимум',
|
||||
'Brick:Portal:Manage:fct:max' => 'Максимум',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Brick:Portal:Object:Name' => 'Object',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'Создать %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Обновление %2$s (%1$s)',
|
||||
@@ -131,18 +132,18 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Выбрать %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Скопировать ссылку на объект',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Ссылка скопирована'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Ссылка скопирована',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Brick:Portal:Create:Name' => 'Быстрое создание',
|
||||
'Brick:Portal:Create:ChooseType' => 'Пожалуйста, выберите тип',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Brick:Portal:Filter:Name' => 'Фильтр',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'например, подключить wi-fi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Искать',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Page:DefaultTitle' => '%1$s User portal~~',
|
||||
'Page:PleaseWait' => 'Please wait...~~',
|
||||
'Page:Home' => 'Home~~',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>~~',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>~~',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'en-us~~', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry~~',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form? Data entered may be lost~~',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Brick:Portal:UserProfile:Name' => 'User profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'My profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Logoff~~',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Can\'t change password, please contact your %1$s administrator~~',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Personal information~~',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Brick:Portal:Browse:Name' => 'Browse throught items~~',
|
||||
'Brick:Portal:Browse:Mode:List' => 'List~~',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Tree~~',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expand all~~',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Collapse all~~',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'No item~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Brick:Portal:Manage:Name' => 'Manage items~~',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'No item.~~',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions~~',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Average~~',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min~~',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Brick:Portal:Object:Name' => 'Object~~',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'New %1$s~~',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Updating %2$s (%1$s)~~',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)~~',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copy object link~~',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Brick:Portal:Create:Name' => 'Quick creation~~',
|
||||
'Brick:Portal:Create:ChooseType' => 'Please, choose a type~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefilter a brick~~',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'eg. connect wifi~~',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Search~~',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Page:DefaultTitle' => '%1$s User portal~~',
|
||||
'Page:PleaseWait' => 'Please wait...~~',
|
||||
'Page:Home' => 'Home~~',
|
||||
@@ -53,19 +54,19 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>~~',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>~~',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'tr', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry~~',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form? Data entered may be lost~~',
|
||||
'Portal:Error:ObjectCannotBeCreated' => 'Error: object cannot be created. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => 'Error: object cannot be updated. Check associated objects and attachments before submitting this form again.~~',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Brick:Portal:UserProfile:Name' => 'User profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => 'My profile~~',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => 'Logoff~~',
|
||||
@@ -76,15 +77,15 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => 'Can\'t change password, please contact your %1$s administrator~~',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => 'Personal information~~',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => 'Photo~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => 'Dashboard~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Brick:Portal:Browse:Name' => 'Browse throught items~~',
|
||||
'Brick:Portal:Browse:Mode:List' => 'List~~',
|
||||
'Brick:Portal:Browse:Mode:Tree' => 'Tree~~',
|
||||
@@ -97,10 +98,10 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => 'Expand all~~',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => 'Collapse all~~',
|
||||
'Brick:Portal:Browse:Filter:NoData' => 'No item~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Brick:Portal:Manage:Name' => 'Manage items~~',
|
||||
'Brick:Portal:Manage:Table:NoData' => 'No item.~~',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => 'Actions~~',
|
||||
@@ -115,10 +116,10 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Brick:Portal:Manage:fct:avg' => 'Average~~',
|
||||
'Brick:Portal:Manage:fct:min' => 'Min~~',
|
||||
'Brick:Portal:Manage:fct:max' => 'Max~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Brick:Portal:Object:Name' => 'Object~~',
|
||||
'Brick:Portal:Object:Form:Create:Title' => 'New %1$s~~',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => 'Updating %2$s (%1$s)~~',
|
||||
@@ -130,18 +131,18 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => 'Select %1$s (%2$s)~~',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => 'Copy object link~~',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => 'Copied~~',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Brick:Portal:Create:Name' => 'Quick creation~~',
|
||||
'Brick:Portal:Create:ChooseType' => 'Please, choose a type~~',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Brick:Portal:Filter:Name' => 'Prefilter a brick~~',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => 'eg. connect wifi~~',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => 'Search~~',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license https://opensource.org/licenses/AGPL-3.0
|
||||
@@ -18,7 +19,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
// Portal
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Page:DefaultTitle' => '%1$s 用户门户',
|
||||
'Page:PleaseWait' => '请稍候...',
|
||||
'Page:Home' => '主页',
|
||||
@@ -62,19 +63,19 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">打开</a> / <a href="%4$s" class="file_download_link">下载</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'zh-cn', //work with moment.js locales
|
||||
));
|
||||
]);
|
||||
|
||||
// Object form
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => '关闭此条目',
|
||||
'Portal:Form:Close:Warning' => '确定要离开表单吗? 已输入数据会丢失',
|
||||
'Portal:Error:ObjectCannotBeCreated' => '错误: 无法创建对象. 请在再次提交表单前检查相关对象和附件.',
|
||||
'Portal:Error:ObjectCannotBeUpdated' => '错误: 无法更新对象. 请在再次提交表单前检查相关对象和附件.',
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
));
|
||||
'Portal:Error:CheckToWriteFailed' => 'Error during validation of field \'%1$s\': %2$s~~',
|
||||
]);
|
||||
|
||||
// UserProfile brick
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Brick:Portal:UserProfile:Name' => '用户资料',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil' => '我的资料',
|
||||
'Brick:Portal:UserProfile:Navigation:Dropdown:Logout' => '注销',
|
||||
@@ -85,15 +86,15 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason' => '无法修改密码, 请联系管理员',
|
||||
'Brick:Portal:UserProfile:PersonalInformations:Title' => '人员信息',
|
||||
'Brick:Portal:UserProfile:Photo:Title' => '头像',
|
||||
));
|
||||
]);
|
||||
|
||||
// AggregatePageBrick
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Brick:Portal:AggregatePage:DefaultTitle' => '仪表盘',
|
||||
));
|
||||
]);
|
||||
|
||||
// BrowseBrick brick
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Brick:Portal:Browse:Name' => '浏览项目',
|
||||
'Brick:Portal:Browse:Mode:List' => '列表',
|
||||
'Brick:Portal:Browse:Mode:Tree' => '树形',
|
||||
@@ -106,10 +107,10 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Brick:Portal:Browse:Tree:ExpandAll' => '全部展开',
|
||||
'Brick:Portal:Browse:Tree:CollapseAll' => '全部收起',
|
||||
'Brick:Portal:Browse:Filter:NoData' => '没有项目',
|
||||
));
|
||||
]);
|
||||
|
||||
// ManageBrick brick
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Brick:Portal:Manage:Name' => '管理项目',
|
||||
'Brick:Portal:Manage:Table:NoData' => '没有项目.',
|
||||
'Brick:Portal:Manage:Table:ItemActions' => '操作',
|
||||
@@ -124,10 +125,10 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Brick:Portal:Manage:fct:avg' => '平均',
|
||||
'Brick:Portal:Manage:fct:min' => '最小',
|
||||
'Brick:Portal:Manage:fct:max' => '最大',
|
||||
));
|
||||
]);
|
||||
|
||||
// ObjectBrick brick
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Brick:Portal:Object:Name' => '对象',
|
||||
'Brick:Portal:Object:Form:Create:Title' => '新建 %1$s',
|
||||
'Brick:Portal:Object:Form:Edit:Title' => '正在更新 %2$s (%1$s)',
|
||||
@@ -139,18 +140,18 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Brick:Portal:Object:Search:Hierarchy:Title' => '选择 %1$s (%2$s)',
|
||||
'Brick:Portal:Object:Copy:TextToCopy' => '%2$s',
|
||||
'Brick:Portal:Object:Copy:Tooltip' => '复制对象链接',
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => '已复制'
|
||||
));
|
||||
'Brick:Portal:Object:Copy:CopiedTooltip' => '已复制',
|
||||
]);
|
||||
|
||||
// CreateBrick brick
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Brick:Portal:Create:Name' => '快速创建',
|
||||
'Brick:Portal:Create:ChooseType' => '请选择类型',
|
||||
));
|
||||
]);
|
||||
|
||||
// Filter brick
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Brick:Portal:Filter:Name' => '预筛选组件',
|
||||
'Brick:Portal:Filter:SearchInput:Placeholder' => '例如. 连接wifi',
|
||||
'Brick:Portal:Filter:SearchInput:Submit' => '搜索',
|
||||
));
|
||||
]);
|
||||
|
||||
@@ -24,12 +24,9 @@
|
||||
*/
|
||||
|
||||
// Load current environment
|
||||
if (file_exists(__DIR__.'/../../approot.inc.php'))
|
||||
{
|
||||
if (file_exists(__DIR__.'/../../approot.inc.php')) {
|
||||
require_once __DIR__.'/../../approot.inc.php'; // When in env-xxxx folder
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
require_once __DIR__.'/../../../approot.inc.php'; // When in datamodels/x.x folder
|
||||
}
|
||||
require_once APPROOT.'application/startup.inc.php';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -20,37 +21,38 @@
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-portal-base/3.2.1', array(
|
||||
'itop-portal-base/3.2.1',
|
||||
[
|
||||
// Identification
|
||||
'label' => 'Portal Development Library',
|
||||
'category' => 'Portal',
|
||||
// Setup
|
||||
'dependencies' => array(
|
||||
),
|
||||
'dependencies' => [
|
||||
],
|
||||
'mandatory' => true,
|
||||
'visible' => false,
|
||||
// Components
|
||||
'datamodel' => array(
|
||||
'datamodel' => [
|
||||
// Note: The autoloader is there instead of portal/config/bootstrap.php in order to be available for other modules with a dependency on this one.
|
||||
// eg. If a module has a class extending \Combodo\iTop\Portal\Controller\AbstractController, it needs to find it even if the portal kernel is not loaded.
|
||||
'portal/vendor/autoload.php',
|
||||
),
|
||||
'webservice' => array(
|
||||
],
|
||||
'webservice' => [
|
||||
//'webservices.itop-portal-base.php',
|
||||
),
|
||||
'dictionary' => array(
|
||||
),
|
||||
'data.struct' => array(
|
||||
],
|
||||
'dictionary' => [
|
||||
],
|
||||
'data.struct' => [
|
||||
//'data.struct.itop-portal-base.xml',
|
||||
),
|
||||
'data.sample' => array(
|
||||
],
|
||||
'data.sample' => [
|
||||
//'data.sample.itop-portal-base.xml',
|
||||
),
|
||||
],
|
||||
// Documentation
|
||||
'doc.manual_setup' => '',
|
||||
'doc.more_information' => '',
|
||||
// Default settings
|
||||
'settings' => array(
|
||||
),
|
||||
)
|
||||
'settings' => [
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
@@ -28,14 +28,10 @@ use Symfony\Component\Dotenv\Dotenv;
|
||||
require_once APPROOT.'/lib/autoload.php';
|
||||
|
||||
// Load current environment if necessary (typically from CLI as the app is not started yet)
|
||||
if (!defined('MODULESROOT'))
|
||||
{
|
||||
if (file_exists(__DIR__.'/../../../../approot.inc.php'))
|
||||
{
|
||||
if (!defined('MODULESROOT')) {
|
||||
if (file_exists(__DIR__.'/../../../../approot.inc.php')) {
|
||||
require_once __DIR__.'/../../../../approot.inc.php'; // When in env-xxxx folder
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
require_once __DIR__.'/../../../../../approot.inc.php'; // When in datamodels/x.x folder
|
||||
}
|
||||
require_once APPROOT.'/application/startup.inc.php';
|
||||
@@ -62,7 +58,7 @@ if (!class_exists(Dotenv::class)) {
|
||||
}
|
||||
|
||||
if (null === $sEnv = (isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null))) {
|
||||
$oDotenv->populate(array('APP_ENV' => $sEnv = 'prod'));
|
||||
$oDotenv->populate(['APP_ENV' => $sEnv = 'prod']);
|
||||
}
|
||||
|
||||
if ('test' !== $sEnv && file_exists($sPathDist = "$sPath.local")) {
|
||||
@@ -83,31 +79,27 @@ if (!class_exists(Dotenv::class)) {
|
||||
$_SERVER += $_ENV;
|
||||
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = (isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null)) ?: 'prod';
|
||||
$_SERVER['APP_DEBUG'] = isset($_SERVER['APP_DEBUG']) ? $_SERVER['APP_DEBUG'] : (isset($_ENV['APP_DEBUG']) ? $_ENV['APP_DEBUG'] : ('prod' !== $_SERVER['APP_ENV']));
|
||||
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int)$_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'],
|
||||
FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
|
||||
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int)$_SERVER['APP_DEBUG'] || filter_var(
|
||||
$_SERVER['APP_DEBUG'],
|
||||
FILTER_VALIDATE_BOOLEAN
|
||||
) ? '1' : '0';
|
||||
|
||||
if ($_SERVER['APP_DEBUG'])
|
||||
{
|
||||
if ($_SERVER['APP_DEBUG']) {
|
||||
umask(0000);
|
||||
|
||||
if (class_exists(Debug::class))
|
||||
{
|
||||
if (class_exists(Debug::class)) {
|
||||
Debug::enable();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_ENV['PORTAL_ID']))
|
||||
{
|
||||
if (isset($_ENV['PORTAL_ID'])) {
|
||||
// Nothing to do
|
||||
}
|
||||
// Note: Default value is set to "false" to differentiate an empty value from a non given parameter
|
||||
elseif ($sPortalId = utils::ReadParam('portal_id', false, true))
|
||||
{
|
||||
elseif ($sPortalId = utils::ReadParam('portal_id', false, true)) {
|
||||
|
||||
$_ENV['PORTAL_ID'] = $sPortalId;
|
||||
}
|
||||
elseif (defined('PORTAL_ID'))
|
||||
{
|
||||
} elseif (defined('PORTAL_ID')) {
|
||||
$_ENV['PORTAL_ID'] = PORTAL_ID;
|
||||
@trigger_error(
|
||||
sprintf(
|
||||
@@ -118,16 +110,14 @@ elseif (defined('PORTAL_ID'))
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($_ENV['PORTAL_ID']))
|
||||
{
|
||||
if (empty($_ENV['PORTAL_ID'])) {
|
||||
echo "Missing argument 'portal_id'";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Make sure that the PORTAL_ID constant is also defined
|
||||
// Note: This is widely used in extensions, snippets and all
|
||||
if (!defined('PORTAL_ID'))
|
||||
{
|
||||
if (!defined('PORTAL_ID')) {
|
||||
define('PORTAL_ID', $_ENV['PORTAL_ID']);
|
||||
}
|
||||
|
||||
@@ -138,4 +128,4 @@ $_ENV['COMBODO_CONF_APP_ICON_URL'] = MetaModel::GetConfig()->Get('app_icon_url')
|
||||
$_ENV['COMBODO_MODULES_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot();
|
||||
$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot().'itop-portal-base/portal/public/';
|
||||
$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'] = MODULESROOT.'/itop-portal-base/portal/public/';
|
||||
$_ENV['COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot().$_ENV['PORTAL_ID'].'/';
|
||||
$_ENV['COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot().$_ENV['PORTAL_ID'].'/';
|
||||
|
||||
@@ -7,4 +7,4 @@ return static function (ContainerConfigurator $container) {
|
||||
// kernel.secret
|
||||
$container->parameters()->set('kernel.secret', MetaModel::GetConfig()->Get('application.secret'));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
|
||||
@@ -58,26 +58,25 @@ $oKPI->ComputeAndReport('Load portal lists definition');
|
||||
// A dedicated listener 'CssFromSassCompiler' exists to compile files again when by-passing HTTP cache.
|
||||
// This is to keep developers comfort when tuning the SCSS files.
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aImportPaths = array($_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/');
|
||||
$aImportPaths = [$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/'];
|
||||
$aPortalConf = $container->getParameter('combodo.portal.instance.conf');
|
||||
foreach ($aPortalConf['properties']['themes'] as $sKey => $value)
|
||||
{
|
||||
if (!is_array($value))
|
||||
{
|
||||
$aPortalConf['properties']['themes'][$sKey] = utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$value,
|
||||
$aImportPaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aValues = array();
|
||||
foreach ($value as $sSubValue)
|
||||
{
|
||||
$aValues[] = utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$sSubValue,
|
||||
$aImportPaths);
|
||||
foreach ($aPortalConf['properties']['themes'] as $sKey => $value) {
|
||||
if (!is_array($value)) {
|
||||
$aPortalConf['properties']['themes'][$sKey] = utils::GetCSSFromSASS(
|
||||
'env-'.utils::GetCurrentEnvironment().'/'.$value,
|
||||
$aImportPaths
|
||||
);
|
||||
} else {
|
||||
$aValues = [];
|
||||
foreach ($value as $sSubValue) {
|
||||
$aValues[] = utils::GetCSSFromSASS(
|
||||
'env-'.utils::GetCurrentEnvironment().'/'.$sSubValue,
|
||||
$aImportPaths
|
||||
);
|
||||
}
|
||||
$aPortalConf['properties']['themes'][$sKey] = $aValues;
|
||||
}
|
||||
}
|
||||
$oKPI->ComputeAndReport('Generating CSS files');
|
||||
|
||||
$container->setParameter('combodo.portal.instance.conf', $aPortalConf);
|
||||
$container->setParameter('combodo.portal.instance.conf', $aPortalConf);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -24,8 +25,7 @@ use Symfony\Component\Routing\Route;
|
||||
$oRouteCollection = new RouteCollection();
|
||||
|
||||
$aRoutes = ItopExtensionsExtraRoutes::GetRoutes();
|
||||
foreach ($aRoutes as $aRoute)
|
||||
{
|
||||
foreach ($aRoutes as $aRoute) {
|
||||
$aRoute['values'] = (isset($aRoute['values'])) ? $aRoute['values'] : [];
|
||||
$aRoute['asserts'] = (isset($aRoute['asserts'])) ? $aRoute['asserts'] : [];
|
||||
|
||||
@@ -42,4 +42,4 @@ foreach ($aRoutes as $aRoute)
|
||||
);
|
||||
}
|
||||
|
||||
return $oRouteCollection;
|
||||
return $oRouteCollection;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -45,4 +46,4 @@ return static function (ContainerConfigurator $oContainer) {
|
||||
->autoconfigure();
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -26,7 +27,6 @@ require_once MODULESROOT.'itop-portal-base/portal/config/bootstrap.php';
|
||||
$oContext = new ContextTag(ContextTag::TAG_PORTAL);
|
||||
$oContext2 = new ContextTag('Portal:'.$_ENV['PORTAL_ID']);
|
||||
|
||||
|
||||
$oKPI = new ExecutionKPI();
|
||||
|
||||
// Note: Manually refactored ternary condition to be PHP 5.x compatible
|
||||
@@ -52,10 +52,8 @@ $oResponse = $oKernel->handle($oRequest);
|
||||
$oResponse->send();
|
||||
$oKPI->ComputeAndReport('Page execution and rendering');
|
||||
|
||||
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oKernel->terminate($oRequest, $oResponse);
|
||||
$oKPI->ComputeAndReport('Symfony kernel termination');
|
||||
|
||||
|
||||
ExecutionKPI::ReportStats();
|
||||
ExecutionKPI::ReportStats();
|
||||
|
||||
@@ -43,34 +43,34 @@ use ModuleDesign;
|
||||
abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
{
|
||||
/** @var string ENUM_DATA_LOADING_LAZY */
|
||||
const ENUM_DATA_LOADING_LAZY = 'lazy';
|
||||
public const ENUM_DATA_LOADING_LAZY = 'lazy';
|
||||
/** @var string ENUM_DATA_LOADING_FULL */
|
||||
const ENUM_DATA_LOADING_FULL = 'full';
|
||||
public const ENUM_DATA_LOADING_FULL = 'full';
|
||||
/** @var string ENUM_DATA_LOADING_AUTO */
|
||||
const ENUM_DATA_LOADING_AUTO = 'auto';
|
||||
public const ENUM_DATA_LOADING_AUTO = 'auto';
|
||||
|
||||
/** @var bool DEFAULT_MANDATORY */
|
||||
const DEFAULT_MANDATORY = true;
|
||||
public const DEFAULT_MANDATORY = true;
|
||||
/** @var bool DEFAULT_ACTIVE */
|
||||
const DEFAULT_ACTIVE = true;
|
||||
public const DEFAULT_ACTIVE = true;
|
||||
/** @var bool DEFAULT_VISIBLE */
|
||||
const DEFAULT_VISIBLE = true;
|
||||
public const DEFAULT_VISIBLE = true;
|
||||
/** @var float DEFAULT_RANK */
|
||||
const DEFAULT_RANK = 1.0;
|
||||
public const DEFAULT_RANK = 1.0;
|
||||
/** @var string|null DEFAULT_PAGE_TEMPLATE_PATH @deprecated since 3.2.1 */
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = null;
|
||||
public const DEFAULT_PAGE_TEMPLATE_PATH = null;
|
||||
/** @var string DEFAULT_TITLE */
|
||||
const DEFAULT_TITLE = '';
|
||||
public const DEFAULT_TITLE = '';
|
||||
/** @var string|null DEFAULT_DESCRIPTION */
|
||||
const DEFAULT_DESCRIPTION = null;
|
||||
public const DEFAULT_DESCRIPTION = null;
|
||||
/** @var string DEFAULT_DATA_LOADING */
|
||||
const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_AUTO;
|
||||
public const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_AUTO;
|
||||
/** @var string DEFAULT_ALLOWED_PROFILES_OQL */
|
||||
const DEFAULT_ALLOWED_PROFILES_OQL = '';
|
||||
public const DEFAULT_ALLOWED_PROFILES_OQL = '';
|
||||
/** @var string DEFAULT_DENIED_PROFILES_OQL */
|
||||
const DEFAULT_DENIED_PROFILES_OQL = '';
|
||||
public const DEFAULT_DENIED_PROFILES_OQL = '';
|
||||
/** @var string TEMPLATES_BASE_PATH */
|
||||
const TEMPLATES_BASE_PATH = 'itop-portal-base/portal/templates/bricks/';
|
||||
public const TEMPLATES_BASE_PATH = 'itop-portal-base/portal/templates/bricks/';
|
||||
|
||||
/** @var string $sId */
|
||||
protected $sId;
|
||||
@@ -105,8 +105,9 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
/** @inheritdoc */
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'layout.html.twig'),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH.'layout.html.twig'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -135,9 +136,9 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static function GetEnumDataLoadingValues()
|
||||
public static function GetEnumDataLoadingValues()
|
||||
{
|
||||
return array(self::ENUM_DATA_LOADING_LAZY, self::ENUM_DATA_LOADING_FULL, self::ENUM_DATA_LOADING_AUTO);
|
||||
return [self::ENUM_DATA_LOADING_LAZY, self::ENUM_DATA_LOADING_FULL, self::ENUM_DATA_LOADING_AUTO];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,8 +156,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
$this->sTitle = static::DEFAULT_TITLE;
|
||||
$this->sDescription = static::DEFAULT_DESCRIPTION;
|
||||
$this->sDataLoading = static::DEFAULT_DATA_LOADING;
|
||||
$this->aAllowedProfiles = array();
|
||||
$this->aDeniedProfiles = array();
|
||||
$this->aAllowedProfiles = [];
|
||||
$this->aDeniedProfiles = [];
|
||||
$this->sAllowedProfilesOql = static::DEFAULT_ALLOWED_PROFILES_OQL;
|
||||
$this->sDeniedProfilesOql = static::DEFAULT_DENIED_PROFILES_OQL;
|
||||
}
|
||||
@@ -297,8 +298,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the brick id
|
||||
*
|
||||
* @param string $sId
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetId($sId)
|
||||
{
|
||||
@@ -310,8 +311,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets if the brick is mandatory
|
||||
*
|
||||
* @param boolean $bMandatory
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetMandatory($bMandatory)
|
||||
{
|
||||
@@ -336,8 +337,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets if the brick is active
|
||||
*
|
||||
* @param boolean $bActive
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetActive($bActive)
|
||||
{
|
||||
@@ -349,8 +350,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the rank of the brick
|
||||
*
|
||||
* @param float $fRank
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetRank($fRank)
|
||||
{
|
||||
@@ -362,15 +363,15 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the page template path of the brick
|
||||
*
|
||||
* @param string $sPageTemplatePath
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @deprecated since 3.2.1 use SetTemplatePath('page') instead
|
||||
*/
|
||||
public function SetPageTemplatePath($sPageTemplatePath)
|
||||
{
|
||||
$this->sPageTemplatePath = $sPageTemplatePath;
|
||||
$this->SetTemplatePath( 'page', $sPageTemplatePath);
|
||||
$this->SetTemplatePath('page', $sPageTemplatePath);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -378,8 +379,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the title of the brick
|
||||
*
|
||||
* @param string $sTitle
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetTitle($sTitle)
|
||||
{
|
||||
@@ -391,8 +392,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the description of the brick
|
||||
*
|
||||
* @param string $sDescription
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetDescription($sDescription)
|
||||
{
|
||||
@@ -404,8 +405,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the data loading mode of the brick
|
||||
*
|
||||
* @param string $sDataLoading
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetDataLoading($sDataLoading)
|
||||
{
|
||||
@@ -444,8 +445,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the allowed profiles oql query for the brick
|
||||
*
|
||||
* @param string $sAllowedProfilesOql
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetAllowedProfilesOql($sAllowedProfilesOql)
|
||||
{
|
||||
@@ -457,8 +458,8 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
* Sets the denied profiles oql query for the brick
|
||||
*
|
||||
* @param string $sDeniedProfilesOql
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
|
||||
*/
|
||||
public function SetDeniedProfilesOql($sDeniedProfilesOql)
|
||||
{
|
||||
@@ -489,8 +490,7 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
*/
|
||||
public function RemoveAllowedProfile($sProfile)
|
||||
{
|
||||
if (isset($this->aAllowedProfiles[$sProfile]))
|
||||
{
|
||||
if (isset($this->aAllowedProfiles[$sProfile])) {
|
||||
unset($this->aAllowedProfiles[$sProfile]);
|
||||
}
|
||||
|
||||
@@ -530,8 +530,7 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
*/
|
||||
public function RemoveDeniedProfile($sProfile)
|
||||
{
|
||||
if (isset($this->aDeniedProfiles[$sProfile]))
|
||||
{
|
||||
if (isset($this->aDeniedProfiles[$sProfile])) {
|
||||
unset($this->aDeniedProfiles[$sProfile]);
|
||||
}
|
||||
|
||||
@@ -560,7 +559,7 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
*/
|
||||
public function IsGrantedForProfile($sProfile)
|
||||
{
|
||||
return $this->IsGrantedForProfiles(array($sProfile));
|
||||
return $this->IsGrantedForProfiles([$sProfile]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -577,27 +576,21 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
{
|
||||
$bGranted = true;
|
||||
|
||||
if ($this->HasAllowedProfiles())
|
||||
{
|
||||
if ($this->HasAllowedProfiles()) {
|
||||
// We set $bGranted to false as the user must explicitly have an allowed profile to be granted
|
||||
$bGranted = false;
|
||||
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
if (in_array($sProfile, $this->aAllowedProfiles))
|
||||
{
|
||||
foreach ($aProfiles as $sProfile) {
|
||||
if (in_array($sProfile, $this->aAllowedProfiles)) {
|
||||
$bGranted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->HasDeniedProfiles())
|
||||
{
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
if (in_array($sProfile, $this->aDeniedProfiles))
|
||||
{
|
||||
if ($this->HasDeniedProfiles()) {
|
||||
foreach ($aProfiles as $sProfile) {
|
||||
if (in_array($sProfile, $this->aDeniedProfiles)) {
|
||||
$bGranted = false;
|
||||
break;
|
||||
}
|
||||
@@ -629,18 +622,15 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
public function LoadFromXml(DesignElement $oMDElement)
|
||||
{
|
||||
// Checking mandatory elements
|
||||
if (!$oMDElement->hasAttribute('id'))
|
||||
{
|
||||
if (!$oMDElement->hasAttribute('id')) {
|
||||
throw new DOMFormatException('Brick node must have both id and xsi:type attributes defined', 0, null, $oMDElement);
|
||||
}
|
||||
$this->SetId($oMDElement->getAttribute('id'));
|
||||
|
||||
// Checking others elements
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickSubNode */
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode)
|
||||
{
|
||||
switch ($oBrickSubNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) {
|
||||
switch ($oBrickSubNode->nodeName) {
|
||||
case 'mandatory':
|
||||
$this->SetMandatory(($oBrickSubNode->GetText() === 'no') ? false : true);
|
||||
break;
|
||||
@@ -649,15 +639,13 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
break;
|
||||
case 'rank':
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('default');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$this->SetRank((float)$oOptionalNode->GetText(static::DEFAULT_RANK));
|
||||
}
|
||||
break;
|
||||
case 'templates':
|
||||
$oTemplateNodeList = $oBrickSubNode->GetNodes('template[@id='.ModuleDesign::XPathQuote('page').']');
|
||||
if ($oTemplateNodeList->length > 0)
|
||||
{
|
||||
if ($oTemplateNodeList->length > 0) {
|
||||
/** @var \Combodo\iTop\DesignElement $oTemplateNode */
|
||||
$oTemplateNode = $oTemplateNodeList->item(0);
|
||||
$this->SetTemplatePath('page', $oTemplateNode->GetText(static::DEFAULT_PAGE_TEMPLATE_PATH));
|
||||
@@ -665,8 +653,7 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
break;
|
||||
case 'title':
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('default');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$this->SetTitle($oOptionalNode->GetText(static::DEFAULT_TITLE));
|
||||
}
|
||||
break;
|
||||
@@ -678,16 +665,17 @@ abstract class AbstractBrick implements TemplatesProviderInterface
|
||||
break;
|
||||
case 'security':
|
||||
/** @var \Combodo\iTop\DesignElement $oSecurityNode */
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oSecurityNode)
|
||||
{
|
||||
if ($oSecurityNode->nodeType === XML_TEXT_NODE && $oSecurityNode->GetText() === '')
|
||||
{
|
||||
throw new DOMFormatException('Brick security node "'.$oSecurityNode->nodeName.'" must contain an OQL query, it cannot be empty',
|
||||
null, null, $oMDElement);
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oSecurityNode) {
|
||||
if ($oSecurityNode->nodeType === XML_TEXT_NODE && $oSecurityNode->GetText() === '') {
|
||||
throw new DOMFormatException(
|
||||
'Brick security node "'.$oSecurityNode->nodeName.'" must contain an OQL query, it cannot be empty',
|
||||
null,
|
||||
null,
|
||||
$oMDElement
|
||||
);
|
||||
}
|
||||
|
||||
switch ($oSecurityNode->nodeName)
|
||||
{
|
||||
switch ($oSecurityNode->nodeName) {
|
||||
case 'denied_profiles':
|
||||
$this->SetDeniedProfilesOql($oSecurityNode->GetText());
|
||||
break;
|
||||
|
||||
@@ -38,11 +38,11 @@ use DOMFormatException;
|
||||
class AggregatePageBrick extends PortalBrick
|
||||
{
|
||||
// Overloaded constants
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-tachometer-alt';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-tachometer-alt fa-2x';
|
||||
public const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-tachometer-alt';
|
||||
public const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-tachometer-alt fa-2x';
|
||||
|
||||
/** @var string @deprecated since 3.2.1 */
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/aggregate-page/layout.html.twig';
|
||||
public const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/aggregate-page/layout.html.twig';
|
||||
|
||||
// Overloaded variables
|
||||
public static $sRouteName = 'p_aggregatepage_brick';
|
||||
@@ -50,21 +50,22 @@ class AggregatePageBrick extends PortalBrick
|
||||
/**
|
||||
* @var string[] list of bricks to use, ordered by rank (key=id, value=rank)
|
||||
*/
|
||||
private $aAggregatePageBricks = array();
|
||||
private $aAggregatePageBricks = [];
|
||||
|
||||
/** @inheritdoc */
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'aggregate-page/layout.html.twig')
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH.'aggregate-page/layout.html.twig')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* AggregatePageBrick constructor.
|
||||
*/
|
||||
function __construct()
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
@@ -83,25 +84,24 @@ class AggregatePageBrick extends PortalBrick
|
||||
parent::LoadFromXml($oMDElement);
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickSubNode */
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode)
|
||||
{
|
||||
switch ($oBrickSubNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) {
|
||||
switch ($oBrickSubNode->nodeName) {
|
||||
case 'aggregate_page_bricks':
|
||||
/** @var \Combodo\iTop\DesignElement $oAggregatePageBrickNode */
|
||||
foreach ($oBrickSubNode->GetNodes('./aggregate_page_brick') as $oAggregatePageBrickNode)
|
||||
{
|
||||
if (!$oAggregatePageBrickNode->hasAttribute('id'))
|
||||
{
|
||||
throw new DOMFormatException('AggregatePageBrick : must have an id attribute', 0,
|
||||
null, $oAggregatePageBrickNode);
|
||||
foreach ($oBrickSubNode->GetNodes('./aggregate_page_brick') as $oAggregatePageBrickNode) {
|
||||
if (!$oAggregatePageBrickNode->hasAttribute('id')) {
|
||||
throw new DOMFormatException(
|
||||
'AggregatePageBrick : must have an id attribute',
|
||||
0,
|
||||
null,
|
||||
$oAggregatePageBrickNode
|
||||
);
|
||||
}
|
||||
$sBrickName = $oAggregatePageBrickNode->getAttribute('id');
|
||||
|
||||
$iBrickRank = static::DEFAULT_RANK;
|
||||
$oOptionalNode = $oAggregatePageBrickNode->GetOptionalElement('rank');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$iBrickRank = $oOptionalNode->GetText();
|
||||
}
|
||||
|
||||
@@ -123,5 +123,4 @@ class AggregatePageBrick extends PortalBrick
|
||||
return $this->aAggregatePageBricks;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -67,8 +68,8 @@ class BrickCollection
|
||||
$this->aAllowedBricks = null;
|
||||
$this->iDisplayedInHome = 0;
|
||||
$this->iDisplayedInNavigationMenu = 0;
|
||||
$this->aHomeOrdering = array();
|
||||
$this->aNavigationMenuOrdering = array();
|
||||
$this->aHomeOrdering = [];
|
||||
$this->aNavigationMenuOrdering = [];
|
||||
|
||||
$this->Load();
|
||||
}
|
||||
@@ -84,8 +85,7 @@ class BrickCollection
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
// Made for cleaner/easier access from twig (eg. app['brick_collection'].bricks)
|
||||
switch ($method)
|
||||
{
|
||||
switch ($method) {
|
||||
case 'bricks':
|
||||
return $this->GetBricks();
|
||||
break;
|
||||
@@ -128,10 +128,8 @@ class BrickCollection
|
||||
*/
|
||||
public function GetBrickById($sId)
|
||||
{
|
||||
foreach ($this->GetBricks() as $oBrick)
|
||||
{
|
||||
if ($oBrick->GetId() === $sId)
|
||||
{
|
||||
foreach ($this->GetBricks() as $oBrick) {
|
||||
if ($oBrick->GetId() === $sId) {
|
||||
return $oBrick;
|
||||
}
|
||||
}
|
||||
@@ -146,19 +144,15 @@ class BrickCollection
|
||||
{
|
||||
$aRawBrickList = $this->GetRawBrickList();
|
||||
|
||||
foreach ($aRawBrickList as $oBrick)
|
||||
{
|
||||
foreach ($aRawBrickList as $oBrick) {
|
||||
ApplicationHelper::LoadBrickSecurity($oBrick);
|
||||
|
||||
if ($oBrick->GetActive() && $oBrick->IsGrantedForProfiles(UserRights::ListProfiles()))
|
||||
{
|
||||
if ($oBrick->GetActive() && $oBrick->IsGrantedForProfiles(UserRights::ListProfiles())) {
|
||||
$this->aAllowedBricks[] = $oBrick;
|
||||
if ($oBrick->GetVisibleHome())
|
||||
{
|
||||
if ($oBrick->GetVisibleHome()) {
|
||||
$this->iDisplayedInHome++;
|
||||
}
|
||||
if ($oBrick->GetVisibleNavigationMenu())
|
||||
{
|
||||
if ($oBrick->GetVisibleNavigationMenu()) {
|
||||
$this->iDisplayedInNavigationMenu++;
|
||||
}
|
||||
}
|
||||
@@ -191,35 +185,30 @@ class BrickCollection
|
||||
*/
|
||||
private function GetRawBrickList()
|
||||
{
|
||||
$aBricks = array();
|
||||
$aBricks = [];
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickNode */
|
||||
foreach ($this->oModuleDesign->GetNodes('/module_design/bricks/brick') as $oBrickNode)
|
||||
{
|
||||
foreach ($this->oModuleDesign->GetNodes('/module_design/bricks/brick') as $oBrickNode) {
|
||||
$sBrickClass = $oBrickNode->getAttribute('xsi:type');
|
||||
try
|
||||
{
|
||||
if (class_exists($sBrickClass))
|
||||
{
|
||||
try {
|
||||
if (class_exists($sBrickClass)) {
|
||||
/** @var \Combodo\iTop\Portal\Brick\PortalBrick $oBrick */
|
||||
$oBrick = new $sBrickClass();
|
||||
|
||||
|
||||
// Load the brick specific properties from its XML definition
|
||||
$oBrick->LoadFromXml($oBrickNode);
|
||||
|
||||
$aBricks[] = $oBrick;
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'Unknown brick class "'.$sBrickClass.'" from xsi:type attribute',
|
||||
null,
|
||||
null,
|
||||
$oBrickNode
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('Unknown brick class "'.$sBrickClass.'" from xsi:type attribute', null,
|
||||
null, $oBrickNode);
|
||||
}
|
||||
}
|
||||
catch (DOMFormatException $e)
|
||||
{
|
||||
} catch (DOMFormatException $e) {
|
||||
throw new Exception('Could not create brick ('.$sBrickClass.') from XML because of a DOM problem : '.$e->getMessage());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Could not create brick ('.$sBrickClass.') from XML : '.$oBrickNode->Dump().' '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -227,4 +216,4 @@ class BrickCollection
|
||||
return $aBricks;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -30,5 +31,4 @@ use Exception;
|
||||
*/
|
||||
class BrickNotFoundException extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,77 +35,76 @@ use DOMFormatException;
|
||||
class BrowseBrick extends PortalBrick
|
||||
{
|
||||
/**
|
||||
* @var string DEFAULT_PAGE_TEMPLATE_PATH
|
||||
* @var string DEFAULT_PAGE_TEMPLATE_PATH
|
||||
* @deprecated 3.2.1
|
||||
*/
|
||||
const DEFAULT_MODE_LIST_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig';
|
||||
public const DEFAULT_MODE_LIST_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig';
|
||||
/**
|
||||
* @var string DEFAULT_MODE_MOSAIC_TEMPLATE_PATH
|
||||
* @deprecated 3.2.1
|
||||
*/
|
||||
const DEFAULT_MODE_MOSAIC_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_mosaic.html.twig';
|
||||
public const DEFAULT_MODE_MOSAIC_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_mosaic.html.twig';
|
||||
/**
|
||||
* @var string DEFAULT_MODE_TREE_TEMPLATE_PATH
|
||||
* @deprecated 3.2.1
|
||||
*/
|
||||
const DEFAULT_MODE_TREE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_tree.html.twig';
|
||||
|
||||
public const DEFAULT_MODE_TREE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_tree.html.twig';
|
||||
|
||||
/** @var string ENUM_BROWSE_MODE_LIST */
|
||||
const ENUM_BROWSE_MODE_LIST = 'list';
|
||||
public const ENUM_BROWSE_MODE_LIST = 'list';
|
||||
/** @var string ENUM_BROWSE_MODE_TREE */
|
||||
const ENUM_BROWSE_MODE_TREE = 'tree';
|
||||
public const ENUM_BROWSE_MODE_TREE = 'tree';
|
||||
/** @var string ENUM_BROWSE_MODE_MOSAIC */
|
||||
const ENUM_BROWSE_MODE_MOSAIC = 'mosaic';
|
||||
public const ENUM_BROWSE_MODE_MOSAIC = 'mosaic';
|
||||
|
||||
/** @var string ENUM_ACTION_VIEW */
|
||||
const ENUM_ACTION_VIEW = 'view';
|
||||
public const ENUM_ACTION_VIEW = 'view';
|
||||
/** @var string ENUM_ACTION_EDIT */
|
||||
const ENUM_ACTION_EDIT = 'edit';
|
||||
public const ENUM_ACTION_EDIT = 'edit';
|
||||
/** @var string ENUM_ACTION_DRILLDOWN */
|
||||
const ENUM_ACTION_DRILLDOWN = 'drilldown';
|
||||
public const ENUM_ACTION_DRILLDOWN = 'drilldown';
|
||||
/** @var string ENUM_ACTION_CREATE_FROM_THIS */
|
||||
const ENUM_ACTION_CREATE_FROM_THIS = 'create_from_this';
|
||||
public const ENUM_ACTION_CREATE_FROM_THIS = 'create_from_this';
|
||||
|
||||
/** @var string ENUM_ACTION_ICON_CLASS_VIEW */
|
||||
const ENUM_ACTION_ICON_CLASS_VIEW = 'glyphicon glyphicon-list-alt';
|
||||
public const ENUM_ACTION_ICON_CLASS_VIEW = 'glyphicon glyphicon-list-alt';
|
||||
/** @var string ENUM_ACTION_ICON_CLASS_EDIT */
|
||||
const ENUM_ACTION_ICON_CLASS_EDIT = 'glyphicon glyphicon-pencil';
|
||||
public const ENUM_ACTION_ICON_CLASS_EDIT = 'glyphicon glyphicon-pencil';
|
||||
/** @var string ENUM_ACTION_ICON_CLASS_DRILLDOWN */
|
||||
const ENUM_ACTION_ICON_CLASS_DRILLDOWN = 'glyphicon glyphicon-menu-down';
|
||||
public const ENUM_ACTION_ICON_CLASS_DRILLDOWN = 'glyphicon glyphicon-menu-down';
|
||||
/** @var string ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS */
|
||||
const ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS = 'glyphicon glyphicon-edit';
|
||||
public const ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS = 'glyphicon glyphicon-edit';
|
||||
|
||||
/** @var string ENUM_FACTORY_TYPE_METHOD */
|
||||
const ENUM_FACTORY_TYPE_METHOD = 'method';
|
||||
public const ENUM_FACTORY_TYPE_METHOD = 'method';
|
||||
/** @var string ENUM_FACTORY_TYPE_CLASS */
|
||||
const ENUM_FACTORY_TYPE_CLASS = 'class';
|
||||
public const ENUM_FACTORY_TYPE_CLASS = 'class';
|
||||
|
||||
// Overloaded constants
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-map';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-map fa-2x';
|
||||
const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_FULL;
|
||||
public const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-map';
|
||||
public const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-map fa-2x';
|
||||
public const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_FULL;
|
||||
|
||||
/** @var string DEFAULT_LEVEL_NAME_ATT */
|
||||
const DEFAULT_LEVEL_NAME_ATT = 'name';
|
||||
public const DEFAULT_LEVEL_NAME_ATT = 'name';
|
||||
/** @var string DEFAULT_BROWSE_MODE */
|
||||
const DEFAULT_BROWSE_MODE = self::ENUM_BROWSE_MODE_LIST;
|
||||
public const DEFAULT_BROWSE_MODE = self::ENUM_BROWSE_MODE_LIST;
|
||||
/** @var string DEFAULT_ACTION */
|
||||
const DEFAULT_ACTION = self::ENUM_ACTION_DRILLDOWN;
|
||||
public const DEFAULT_ACTION = self::ENUM_ACTION_DRILLDOWN;
|
||||
/** @var string DEFAULT_ACTION_OPENING_TARGET */
|
||||
const DEFAULT_ACTION_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL;
|
||||
public const DEFAULT_ACTION_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL;
|
||||
/** @var int DEFAULT_LIST_LENGTH */
|
||||
const DEFAULT_LIST_LENGTH = 20;
|
||||
public const DEFAULT_LIST_LENGTH = 20;
|
||||
|
||||
// Overloaded variables
|
||||
public static $sRouteName = 'p_browse_brick';
|
||||
|
||||
/** @var array $aBrowseModes */
|
||||
public static $aBrowseModes = array(
|
||||
public static $aBrowseModes = [
|
||||
self::ENUM_BROWSE_MODE_LIST,
|
||||
self::ENUM_BROWSE_MODE_TREE,
|
||||
self::ENUM_BROWSE_MODE_MOSAIC,
|
||||
);
|
||||
];
|
||||
|
||||
/** @var array $aLevels */
|
||||
protected $aLevels;
|
||||
@@ -120,11 +119,12 @@ class BrowseBrick extends PortalBrick
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'browse/layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_list', static::TEMPLATES_BASE_PATH . 'browse/mode_list.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_tree', static::TEMPLATES_BASE_PATH . 'browse/mode_tree.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_mosaic', static::TEMPLATES_BASE_PATH . 'browse/mode_mosaic.html.twig'),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH.'browse/layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_list', static::TEMPLATES_BASE_PATH.'browse/mode_list.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_tree', static::TEMPLATES_BASE_PATH.'browse/mode_tree.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_mosaic', static::TEMPLATES_BASE_PATH.'browse/mode_mosaic.html.twig'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -135,15 +135,15 @@ class BrowseBrick extends PortalBrick
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->aLevels = array();
|
||||
$this->aAvailablesBrowseModes = array();
|
||||
$this->aLevels = [];
|
||||
$this->aAvailablesBrowseModes = [];
|
||||
$this->sDefaultBrowseMode = static::DEFAULT_BROWSE_MODE;
|
||||
$this->iDefaultListLength = static::DEFAULT_LIST_LENGTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare function to sort actions by their rank attribute
|
||||
*
|
||||
*
|
||||
* @param array $aAction1
|
||||
* @param array $aAction2
|
||||
*
|
||||
@@ -154,13 +154,10 @@ class BrowseBrick extends PortalBrick
|
||||
$bIsAction1RankSet = array_key_exists('rank', $aAction1);
|
||||
$bIsAction2RankSet = array_key_exists('rank', $aAction2);
|
||||
|
||||
if($bIsAction1RankSet && $bIsAction2RankSet)
|
||||
{
|
||||
//If a1 == a2 return 0, if a1 > a2 return 1 else return -1
|
||||
if ($bIsAction1RankSet && $bIsAction2RankSet) {
|
||||
//If a1 == a2 return 0, if a1 > a2 return 1 else return -1
|
||||
return ($aAction1['rank'] === $aAction2['rank'] ? $aAction1['default_rank'] - $aAction2['default_rank'] : $aAction1['rank'] - $aAction2['rank']);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
//If a1 == a2 == null return 0, if a2 is null and not a1 return 1 else return -1
|
||||
return ($bIsAction1RankSet === $bIsAction2RankSet ? $aAction1['default_rank'] - $aAction2['default_rank'] : ($bIsAction1RankSet ? 1 : -1));
|
||||
}
|
||||
@@ -255,7 +252,8 @@ class BrowseBrick extends PortalBrick
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetDefaultListLength($iDefaultListLength) {
|
||||
public function SetDefaultListLength($iDefaultListLength)
|
||||
{
|
||||
$this->iDefaultListLength = $iDefaultListLength;
|
||||
return $this;
|
||||
}
|
||||
@@ -293,8 +291,7 @@ class BrowseBrick extends PortalBrick
|
||||
*/
|
||||
public function RemoveLevels($sLevel)
|
||||
{
|
||||
if (isset($this->aLevels[$sLevel]))
|
||||
{
|
||||
if (isset($this->aLevels[$sLevel])) {
|
||||
unset($this->aLevels[$sLevel]);
|
||||
}
|
||||
|
||||
@@ -309,7 +306,7 @@ class BrowseBrick extends PortalBrick
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\BrowseBrick
|
||||
*/
|
||||
public function AddAvailableBrowseMode($sModeId, $aData = array())
|
||||
public function AddAvailableBrowseMode($sModeId, $aData = [])
|
||||
{
|
||||
$this->aAvailablesBrowseModes[$sModeId] = $aData;
|
||||
|
||||
@@ -325,8 +322,7 @@ class BrowseBrick extends PortalBrick
|
||||
*/
|
||||
public function RemoveAvailableBrowseMode($sModeId)
|
||||
{
|
||||
if (isset($this->aAvailablesBrowseModes[$sModeId]))
|
||||
{
|
||||
if (isset($this->aAvailablesBrowseModes[$sModeId])) {
|
||||
unset($this->aAvailablesBrowseModes[$sModeId]);
|
||||
}
|
||||
|
||||
@@ -349,43 +345,38 @@ class BrowseBrick extends PortalBrick
|
||||
|
||||
// Checking specific elements
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickSubNode */
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode)
|
||||
{
|
||||
switch ($oBrickSubNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) {
|
||||
switch ($oBrickSubNode->nodeName) {
|
||||
case 'levels':
|
||||
/** @var \Combodo\iTop\DesignElement $oLevelNode */
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oLevelNode)
|
||||
{
|
||||
if ($oLevelNode->nodeName === 'level')
|
||||
{
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oLevelNode) {
|
||||
if ($oLevelNode->nodeName === 'level') {
|
||||
$this->AddLevel($this->LoadLevelFromXml($oLevelNode));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'browse_modes':
|
||||
/** @var \Combodo\iTop\DesignElement $oBrowseModeNode */
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oBrowseModeNode)
|
||||
{
|
||||
switch ($oBrowseModeNode->nodeName)
|
||||
{
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oBrowseModeNode) {
|
||||
switch ($oBrowseModeNode->nodeName) {
|
||||
case 'availables':
|
||||
/** @var \Combodo\iTop\DesignElement $oModeNode */
|
||||
foreach ($oBrowseModeNode->GetNodes('*') as $oModeNode)
|
||||
{
|
||||
if (!$oModeNode->hasAttribute('id'))
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick: Browse mode must have a unique ID attribute', 0,
|
||||
null, $oModeNode);
|
||||
foreach ($oBrowseModeNode->GetNodes('*') as $oModeNode) {
|
||||
if (!$oModeNode->hasAttribute('id')) {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick: Browse mode must have a unique ID attribute',
|
||||
0,
|
||||
null,
|
||||
$oModeNode
|
||||
);
|
||||
}
|
||||
|
||||
$sModeId = $oModeNode->getAttribute('id');
|
||||
$aModeData = array();
|
||||
$aModeData = [];
|
||||
|
||||
// Checking if the browse mode has a specific template
|
||||
$oTemplateNode = $oModeNode->GetOptionalElement('template');
|
||||
if (($oTemplateNode !== null) && ($oTemplateNode->GetText() !== null))
|
||||
{
|
||||
if (($oTemplateNode !== null) && ($oTemplateNode->GetText() !== null)) {
|
||||
$this->SetTemplatePath('page_'.$sModeId, $oTemplateNode->GetText());
|
||||
}
|
||||
|
||||
@@ -400,12 +391,12 @@ class BrowseBrick extends PortalBrick
|
||||
break;
|
||||
case 'default_list_length':
|
||||
$iNodeDefaultListLength = (int)$oBrickSubNode->GetText(static::DEFAULT_LIST_LENGTH);
|
||||
if(!in_array($iNodeDefaultListLength, array(10, 20, 50, -1),true))
|
||||
{
|
||||
if (!in_array($iNodeDefaultListLength, [10, 20, 50, -1], true)) {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick: Default list length must be contained in list length options. Expected -1/10/20/50, '.$iNodeDefaultListLength.' given.',
|
||||
null,
|
||||
null, $oBrickSubNode
|
||||
null,
|
||||
$oBrickSubNode
|
||||
);
|
||||
}
|
||||
$this->SetDefaultListLength($iNodeDefaultListLength);
|
||||
@@ -414,19 +405,18 @@ class BrowseBrick extends PortalBrick
|
||||
}
|
||||
|
||||
// Checking that the brick has at least a browse mode
|
||||
if (count($this->GetAvailablesBrowseModes()) === 0)
|
||||
{
|
||||
if (count($this->GetAvailablesBrowseModes()) === 0) {
|
||||
throw new DOMFormatException('BrowseBrick : Must have at least one browse mode', 0, null, $oMDElement);
|
||||
}
|
||||
// Checking that default browse mode in among the available
|
||||
if (!in_array($this->sDefaultBrowseMode, array_keys($this->aAvailablesBrowseModes)))
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : Default browse mode "'.$this->sDefaultBrowseMode.'" must be one of the available browse modes ('.implode(', ',
|
||||
$this->aAvailablesBrowseModes).')', null, null, $oMDElement);
|
||||
if (!in_array($this->sDefaultBrowseMode, array_keys($this->aAvailablesBrowseModes))) {
|
||||
throw new DOMFormatException('BrowseBrick : Default browse mode "'.$this->sDefaultBrowseMode.'" must be one of the available browse modes ('.implode(
|
||||
', ',
|
||||
$this->aAvailablesBrowseModes
|
||||
).')', null, null, $oMDElement);
|
||||
}
|
||||
// Checking that the brick has at least a level
|
||||
if (count($this->GetLevels()) === 0)
|
||||
{
|
||||
if (count($this->GetLevels()) === 0) {
|
||||
throw new DOMFormatException('BrowseBrick : Must have at least one level', 0, null, $oMDElement);
|
||||
}
|
||||
|
||||
@@ -444,39 +434,41 @@ class BrowseBrick extends PortalBrick
|
||||
*/
|
||||
protected function LoadLevelFromXml(DesignElement $oMDElement)
|
||||
{
|
||||
$aLevel = array(
|
||||
$aLevel = [
|
||||
'parent_att' => null,
|
||||
'tooltip_att' => null,
|
||||
'description_att' => null,
|
||||
'image_att' => null,
|
||||
'title' => null,
|
||||
'name_att' => static::DEFAULT_LEVEL_NAME_ATT,
|
||||
'fields' => array(),
|
||||
'actions' => array('default' => array('type' => static::DEFAULT_ACTION, 'rules' => array())),
|
||||
);
|
||||
'fields' => [],
|
||||
'actions' => ['default' => ['type' => static::DEFAULT_ACTION, 'rules' => []]],
|
||||
];
|
||||
|
||||
// Getting level ID
|
||||
if ($oMDElement->hasAttribute('id') && $oMDElement->getAttribute('id') !== '')
|
||||
{
|
||||
if ($oMDElement->hasAttribute('id') && $oMDElement->getAttribute('id') !== '') {
|
||||
$aLevel['id'] = $oMDElement->getAttribute('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : level tag without "id" attribute. It must have one and it must not be empty', null,
|
||||
null, $oMDElement);
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick : level tag without "id" attribute. It must have one and it must not be empty',
|
||||
null,
|
||||
null,
|
||||
$oMDElement
|
||||
);
|
||||
}
|
||||
// Getting level properties
|
||||
/** @var \Combodo\iTop\DesignElement $oLevelPropertyNode */
|
||||
foreach ($oMDElement->GetNodes('*') as $oLevelPropertyNode)
|
||||
{
|
||||
switch ($oLevelPropertyNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('*') as $oLevelPropertyNode) {
|
||||
switch ($oLevelPropertyNode->nodeName) {
|
||||
case 'class':
|
||||
$sClass = $oLevelPropertyNode->GetText();
|
||||
if ($sClass === '')
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : class tag is empty. Must contain Classname', null, null,
|
||||
$oLevelPropertyNode);
|
||||
if ($sClass === '') {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick : class tag is empty. Must contain Classname',
|
||||
null,
|
||||
null,
|
||||
$oLevelPropertyNode
|
||||
);
|
||||
}
|
||||
|
||||
$aLevel['oql'] = 'SELECT '.$sClass;
|
||||
@@ -484,10 +476,13 @@ class BrowseBrick extends PortalBrick
|
||||
|
||||
case 'oql':
|
||||
$sOql = $oLevelPropertyNode->GetText();
|
||||
if ($sOql === '')
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : oql tag is empty. Must contain OQL statement', null, null,
|
||||
$oLevelPropertyNode);
|
||||
if ($sOql === '') {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick : oql tag is empty. Must contain OQL statement',
|
||||
null,
|
||||
null,
|
||||
$oLevelPropertyNode
|
||||
);
|
||||
}
|
||||
|
||||
$aLevel['oql'] = $sOql;
|
||||
@@ -508,25 +503,23 @@ class BrowseBrick extends PortalBrick
|
||||
case 'fields':
|
||||
$sTagName = $oLevelPropertyNode->nodeName;
|
||||
|
||||
if ($oLevelPropertyNode->hasChildNodes())
|
||||
{
|
||||
$aLevel[$sTagName] = array();
|
||||
if ($oLevelPropertyNode->hasChildNodes()) {
|
||||
$aLevel[$sTagName] = [];
|
||||
/** @var \Combodo\iTop\DesignElement $oFieldNode */
|
||||
foreach ($oLevelPropertyNode->GetNodes('*') as $oFieldNode)
|
||||
{
|
||||
if ($oFieldNode->hasAttribute('id') && $oFieldNode->getAttribute('id') !== '')
|
||||
{
|
||||
$aLevel[$sTagName][$oFieldNode->getAttribute('id')] = array('hidden' => false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : '.$sTagName.'/* tag must have an "id" attribute and it must not be empty',
|
||||
null, null, $oFieldNode);
|
||||
foreach ($oLevelPropertyNode->GetNodes('*') as $oFieldNode) {
|
||||
if ($oFieldNode->hasAttribute('id') && $oFieldNode->getAttribute('id') !== '') {
|
||||
$aLevel[$sTagName][$oFieldNode->getAttribute('id')] = ['hidden' => false];
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick : '.$sTagName.'/* tag must have an "id" attribute and it must not be empty',
|
||||
null,
|
||||
null,
|
||||
$oFieldNode
|
||||
);
|
||||
}
|
||||
|
||||
$oFieldSubNode = $oFieldNode->GetOptionalElement('hidden');
|
||||
if ($oFieldSubNode !== null)
|
||||
{
|
||||
if ($oFieldSubNode !== null) {
|
||||
$aLevel[$sTagName][$oFieldNode->getAttribute('id')]['hidden'] = ($oFieldSubNode->GetText() === 'true') ? true : false;
|
||||
}
|
||||
}
|
||||
@@ -536,94 +529,84 @@ class BrowseBrick extends PortalBrick
|
||||
case 'actions':
|
||||
$sTagName = $oLevelPropertyNode->nodeName;
|
||||
|
||||
if ($oLevelPropertyNode->hasChildNodes())
|
||||
{
|
||||
$aLevel[$sTagName] = array();
|
||||
if ($oLevelPropertyNode->hasChildNodes()) {
|
||||
$aLevel[$sTagName] = [];
|
||||
$iActionDefaultRank = 0;
|
||||
/** @var \Combodo\iTop\DesignElement $oActionNode */
|
||||
foreach ($oLevelPropertyNode->GetNodes('*') as $oActionNode)
|
||||
{
|
||||
if ($oActionNode->hasAttribute('id') && $oActionNode->getAttribute('id') !== '')
|
||||
{
|
||||
$aTmpAction = array(
|
||||
foreach ($oLevelPropertyNode->GetNodes('*') as $oActionNode) {
|
||||
if ($oActionNode->hasAttribute('id') && $oActionNode->getAttribute('id') !== '') {
|
||||
$aTmpAction = [
|
||||
'type' => null,
|
||||
'rules' => array(),
|
||||
);
|
||||
'rules' => [],
|
||||
];
|
||||
|
||||
// Action type
|
||||
$aTmpAction['type'] = ($oActionNode->hasAttribute('xsi:type') && $oActionNode->getAttribute('xsi:type') !== '') ? $oActionNode->getAttribute('xsi:type') : static::DEFAULT_ACTION;
|
||||
// Action destination class
|
||||
if ($aTmpAction['type'] === static::ENUM_ACTION_CREATE_FROM_THIS)
|
||||
{
|
||||
if ($oActionNode->GetOptionalElement('factory_method') !== null)
|
||||
{
|
||||
$aTmpAction['factory'] = array(
|
||||
if ($aTmpAction['type'] === static::ENUM_ACTION_CREATE_FROM_THIS) {
|
||||
if ($oActionNode->GetOptionalElement('factory_method') !== null) {
|
||||
$aTmpAction['factory'] = [
|
||||
'type' => static::ENUM_FACTORY_TYPE_METHOD,
|
||||
'value' => $oActionNode->GetOptionalElement('factory_method')->GetText(),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aTmpAction['factory'] = array(
|
||||
];
|
||||
} else {
|
||||
$aTmpAction['factory'] = [
|
||||
'type' => static::ENUM_FACTORY_TYPE_CLASS,
|
||||
'value' => $oActionNode->GetUniqueElement('class')->GetText(),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
// Action title
|
||||
$oActionTitleNode = $oActionNode->GetOptionalElement('title');
|
||||
if ($oActionTitleNode !== null)
|
||||
{
|
||||
if ($oActionTitleNode !== null) {
|
||||
$aTmpAction['title'] = $oActionTitleNode->GetText();
|
||||
}
|
||||
// Action icon class
|
||||
$oActionIconClassNode = $oActionNode->GetOptionalElement('icon_class');
|
||||
if ($oActionIconClassNode !== null)
|
||||
{
|
||||
if ($oActionIconClassNode !== null) {
|
||||
$aTmpAction['icon_class'] = $oActionIconClassNode->GetText();
|
||||
}
|
||||
// Action opening target
|
||||
$oActionOpeningTargetNode = $oActionNode->GetOptionalElement('opening_target');
|
||||
if ($oActionOpeningTargetNode !== null)
|
||||
{
|
||||
if ($oActionOpeningTargetNode !== null) {
|
||||
$aTmpAction['opening_target'] = $oActionOpeningTargetNode->GetText(static::DEFAULT_ACTION_OPENING_TARGET);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aTmpAction['opening_target'] = static::DEFAULT_ACTION_OPENING_TARGET;
|
||||
}
|
||||
// - Checking that opening target is among authorized modes
|
||||
if (!in_array($aTmpAction['opening_target'], static::$aOpeningTargets))
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : '.$sTagName.'/action/opening_target has a wrong value. "'.$aTmpAction['opening_target'].'" given, '.implode('|',
|
||||
static::$aOpeningTargets).' expected.', null, null, $oActionOpeningTargetNode);
|
||||
if (!in_array($aTmpAction['opening_target'], static::$aOpeningTargets)) {
|
||||
throw new DOMFormatException('BrowseBrick : '.$sTagName.'/action/opening_target has a wrong value. "'.$aTmpAction['opening_target'].'" given, '.implode(
|
||||
'|',
|
||||
static::$aOpeningTargets
|
||||
).' expected.', null, null, $oActionOpeningTargetNode);
|
||||
}
|
||||
$oActionRankNode = $oActionNode->GetOptionalElement('rank');
|
||||
if ($oActionRankNode !== null)
|
||||
{
|
||||
if ($oActionRankNode !== null) {
|
||||
$aTmpAction['rank'] = (int)$oActionRankNode->GetText();
|
||||
}
|
||||
// Action rules
|
||||
/** @var \Combodo\iTop\DesignElement $oRuleNode */
|
||||
foreach ($oActionNode->GetNodes('./rules/rule') as $oRuleNode)
|
||||
{
|
||||
if ($oRuleNode->hasAttribute('id') && $oRuleNode->getAttribute('id') !== '')
|
||||
{
|
||||
foreach ($oActionNode->GetNodes('./rules/rule') as $oRuleNode) {
|
||||
if ($oRuleNode->hasAttribute('id') && $oRuleNode->getAttribute('id') !== '') {
|
||||
$aTmpAction['rules'][] = $oRuleNode->getAttribute('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : '.$sTagName.'/rules/rule tag must have an "id" attribute and it must not be empty',
|
||||
null, null, $oRuleNode);
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick : '.$sTagName.'/rules/rule tag must have an "id" attribute and it must not be empty',
|
||||
null,
|
||||
null,
|
||||
$oRuleNode
|
||||
);
|
||||
}
|
||||
}
|
||||
$aTmpAction['default_rank'] = $iActionDefaultRank++;
|
||||
$aLevel[$sTagName][$oActionNode->getAttribute('id')] = $aTmpAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('BrowseBrick : '.$sTagName.'/* tag must have an "id" attribute and it must not be empty',
|
||||
null, null, $oActionNode);
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'BrowseBrick : '.$sTagName.'/* tag must have an "id" attribute and it must not be empty',
|
||||
null,
|
||||
null,
|
||||
$oActionNode
|
||||
);
|
||||
}
|
||||
}
|
||||
uasort($aLevel[$sTagName], [$this, 'CompareActionsByRank']);
|
||||
@@ -631,10 +614,8 @@ class BrowseBrick extends PortalBrick
|
||||
break;
|
||||
|
||||
case 'levels':
|
||||
foreach ($oLevelPropertyNode->GetNodes('*') as $oSubLevelNode)
|
||||
{
|
||||
if ($oSubLevelNode->nodeName === 'level')
|
||||
{
|
||||
foreach ($oLevelPropertyNode->GetNodes('*') as $oSubLevelNode) {
|
||||
if ($oSubLevelNode->nodeName === 'level') {
|
||||
$aLevel['levels'][] = $this->LoadLevelFromXml($oSubLevelNode);
|
||||
}
|
||||
}
|
||||
@@ -644,8 +625,7 @@ class BrowseBrick extends PortalBrick
|
||||
}
|
||||
|
||||
// Checking if level has an oql
|
||||
if (!isset($aLevel['oql']) || $aLevel['oql'] === '')
|
||||
{
|
||||
if (!isset($aLevel['oql']) || $aLevel['oql'] === '') {
|
||||
throw new DOMFormatException('BrowseBrick : must have a valid <class|oql> tag', null, null, $oMDElement);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ use DOMFormatException;
|
||||
class CreateBrick extends PortalBrick
|
||||
{
|
||||
// Overloaded constants
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-plus';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-plus fa-2x';
|
||||
public const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-plus';
|
||||
public const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-plus fa-2x';
|
||||
/** @var string DEFAULT_CLASS */
|
||||
const DEFAULT_CLASS = '';
|
||||
public const DEFAULT_CLASS = '';
|
||||
|
||||
// Overloaded variables
|
||||
public static $sRouteName = 'p_create_brick';
|
||||
@@ -48,14 +48,15 @@ class CreateBrick extends PortalBrick
|
||||
/** @var array $aRules */
|
||||
protected $aRules;
|
||||
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/create/modal.html.twig';
|
||||
public const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/create/modal.html.twig';
|
||||
|
||||
/** @inheritdoc */
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'create/modal.html.twig')
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH.'create/modal.html.twig')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ class CreateBrick extends PortalBrick
|
||||
parent::__construct();
|
||||
|
||||
$this->sClass = static::DEFAULT_CLASS;
|
||||
$this->aRules = array();
|
||||
$this->aRules = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,26 +135,24 @@ class CreateBrick extends PortalBrick
|
||||
|
||||
// Checking specific elements
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickSubNode */
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode)
|
||||
{
|
||||
switch ($oBrickSubNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) {
|
||||
switch ($oBrickSubNode->nodeName) {
|
||||
case 'class':
|
||||
$this->SetClass($oBrickSubNode->GetText(self::DEFAULT_CLASS));
|
||||
break;
|
||||
|
||||
case 'rules':
|
||||
/** @var \Combodo\iTop\DesignElement $oRuleNode */
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oRuleNode)
|
||||
{
|
||||
if ($oRuleNode->hasAttribute('id') && $oRuleNode->getAttribute('id') !== '')
|
||||
{
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oRuleNode) {
|
||||
if ($oRuleNode->hasAttribute('id') && $oRuleNode->getAttribute('id') !== '') {
|
||||
$this->aRules[] = $oRuleNode->getAttribute('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('CreateBrick: /rules/rule tag must have an "id" attribute and it must not be empty',
|
||||
null, null, $oRuleNode);
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'CreateBrick: /rules/rule tag must have an "id" attribute and it must not be empty',
|
||||
null,
|
||||
null,
|
||||
$oRuleNode
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -35,21 +35,21 @@ use DOMFormatException;
|
||||
class FilterBrick extends PortalBrick
|
||||
{
|
||||
// Overloaded constants
|
||||
const DEFAULT_VISIBLE_NAVIGATION_MENU = false;
|
||||
/**
|
||||
* @deprecated 3.2.1
|
||||
*/
|
||||
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/filter/tile.html.twig';
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-search';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-search fa-2x';
|
||||
/** @var string DEFAULT_TARGET_BRICK_CLASS */
|
||||
const DEFAULT_TARGET_BRICK_CLASS = 'Combodo\\iTop\\Portal\\Brick\\BrowseBrick';
|
||||
public const DEFAULT_VISIBLE_NAVIGATION_MENU = false;
|
||||
/**
|
||||
* @deprecated 3.2.1
|
||||
*/
|
||||
public const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/filter/tile.html.twig';
|
||||
public const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-search';
|
||||
public const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-search fa-2x';
|
||||
/** @var string DEFAULT_TARGET_BRICK_CLASS */
|
||||
public const DEFAULT_TARGET_BRICK_CLASS = 'Combodo\\iTop\\Portal\\Brick\\BrowseBrick';
|
||||
/** @var string DEFAULT_SEARCH_PLACEHOLDER_VALUE */
|
||||
const DEFAULT_SEARCH_PLACEHOLDER_VALUE = 'Brick:Portal:Filter:SearchInput:Placeholder';
|
||||
public const DEFAULT_SEARCH_PLACEHOLDER_VALUE = 'Brick:Portal:Filter:SearchInput:Placeholder';
|
||||
/** @var string DEFAULT_SEARCH_SUBMIT_LABEL */
|
||||
const DEFAULT_SEARCH_SUBMIT_LABEL = 'Brick:Portal:Filter:SearchInput:Submit';
|
||||
public const DEFAULT_SEARCH_SUBMIT_LABEL = 'Brick:Portal:Filter:SearchInput:Submit';
|
||||
/** @var string DEFAULT_SEARCH_SUBMIT_CLASS */
|
||||
const DEFAULT_SEARCH_SUBMIT_CLASS = '';
|
||||
public const DEFAULT_SEARCH_SUBMIT_CLASS = '';
|
||||
|
||||
/** @var string $sTargetBrickId */
|
||||
protected $sTargetBrickId;
|
||||
@@ -68,8 +68,9 @@ class FilterBrick extends PortalBrick
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH . 'filter/tile.html.twig')
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH.'filter/tile.html.twig')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -98,9 +99,9 @@ class FilterBrick extends PortalBrick
|
||||
* @return string
|
||||
*/
|
||||
public function GetTargetBrickClass()
|
||||
{
|
||||
return $this->sTargetBrickClass;
|
||||
}
|
||||
{
|
||||
return $this->sTargetBrickClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
@@ -149,9 +150,9 @@ class FilterBrick extends PortalBrick
|
||||
* @param string $sTargetBrickClass
|
||||
*/
|
||||
public function SetTargetBrickClass($sTargetBrickClass)
|
||||
{
|
||||
$this->sTargetBrickClass = $sTargetBrickClass;
|
||||
}
|
||||
{
|
||||
$this->sTargetBrickClass = $sTargetBrickClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTargetBrickTab
|
||||
@@ -197,38 +198,34 @@ class FilterBrick extends PortalBrick
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the brick's data from the xml passed as a ModuleDesignElement.
|
||||
* This is used to set all the brick attributes at once.
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oMDElement
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\FilterBrick
|
||||
*
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
/**
|
||||
* Load the brick's data from the xml passed as a ModuleDesignElement.
|
||||
* This is used to set all the brick attributes at once.
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oMDElement
|
||||
*
|
||||
* @return \Combodo\iTop\Portal\Brick\FilterBrick
|
||||
*
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
public function LoadFromXml(DesignElement $oMDElement)
|
||||
{
|
||||
parent::LoadFromXml($oMDElement);
|
||||
|
||||
// Checking specific elements
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickSubNode */
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode)
|
||||
{
|
||||
switch ($oBrickSubNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) {
|
||||
switch ($oBrickSubNode->nodeName) {
|
||||
case 'target_brick':
|
||||
/** @var \Combodo\iTop\DesignElement $oTargetBrickNode */
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oTargetBrickNode)
|
||||
{
|
||||
switch ($oTargetBrickNode->nodeName)
|
||||
{
|
||||
case 'id':
|
||||
$this->SetTargetBrickId($oTargetBrickNode->GetText());
|
||||
break;
|
||||
case 'type':
|
||||
$this->SetTargetBrickClass($oTargetBrickNode->GetText());
|
||||
break;
|
||||
foreach ($oBrickSubNode->GetNodes('*') as $oTargetBrickNode) {
|
||||
switch ($oTargetBrickNode->nodeName) {
|
||||
case 'id':
|
||||
$this->SetTargetBrickId($oTargetBrickNode->GetText());
|
||||
break;
|
||||
case 'type':
|
||||
$this->SetTargetBrickClass($oTargetBrickNode->GetText());
|
||||
break;
|
||||
case 'tab':
|
||||
$this->SetTargetBrickTab($oTargetBrickNode->GetText());
|
||||
break;
|
||||
@@ -236,12 +233,12 @@ class FilterBrick extends PortalBrick
|
||||
}
|
||||
break;
|
||||
case 'search_placeholder_value':
|
||||
// Note: We don't put the default value constant if the node is empty because we might actually want this to be empty
|
||||
// Note: We don't put the default value constant if the node is empty because we might actually want this to be empty
|
||||
$this->SetSearchPlaceholderValue($oBrickSubNode->GetText(''));
|
||||
break;
|
||||
case 'search_submit_label':
|
||||
// Note: We don't put the default value constant if the node is empty because we might actually want this to be empty
|
||||
$this->SetSearchSubmitLabel($oBrickSubNode->GetText(''));
|
||||
// Note: We don't put the default value constant if the node is empty because we might actually want this to be empty
|
||||
$this->SetSearchSubmitLabel($oBrickSubNode->GetText(''));
|
||||
break;
|
||||
case 'search_submit_class':
|
||||
$this->SetSearchSubmitClass($oBrickSubNode->GetText(static::DEFAULT_SEARCH_SUBMIT_CLASS));
|
||||
@@ -250,8 +247,7 @@ class FilterBrick extends PortalBrick
|
||||
}
|
||||
|
||||
// Checking that the brick has at least a target brick id
|
||||
if (($this->GetTargetBrickId() === null) || ($this->GetTargetBrickId() === ''))
|
||||
{
|
||||
if (($this->GetTargetBrickId() === null) || ($this->GetTargetBrickId() === '')) {
|
||||
throw new DOMFormatException('FilterBrick : Must have a target brick id', 0, null, $oMDElement);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,126 +32,126 @@ use ModuleDesign;
|
||||
class ManageBrick extends PortalBrick
|
||||
{
|
||||
/** @var string ENUM_ACTION_VIEW */
|
||||
const ENUM_ACTION_VIEW = 'view';
|
||||
public const ENUM_ACTION_VIEW = 'view';
|
||||
/** @var string ENUM_ACTION_EDIT */
|
||||
const ENUM_ACTION_EDIT = 'edit';
|
||||
public const ENUM_ACTION_EDIT = 'edit';
|
||||
|
||||
/** @var string ENUM_TILE_MODE_TEXT */
|
||||
const ENUM_TILE_MODE_TEXT = 'text';
|
||||
public const ENUM_TILE_MODE_TEXT = 'text';
|
||||
/** @var string ENUM_TILE_MODE_BADGE */
|
||||
const ENUM_TILE_MODE_BADGE = 'badge';
|
||||
public const ENUM_TILE_MODE_BADGE = 'badge';
|
||||
/** @var string ENUM_TILE_MODE_PIE */
|
||||
const ENUM_TILE_MODE_PIE = 'pie-chart';
|
||||
public const ENUM_TILE_MODE_PIE = 'pie-chart';
|
||||
/** @var string ENUM_TILE_MODE_BAR */
|
||||
const ENUM_TILE_MODE_BAR = 'bar-chart';
|
||||
public const ENUM_TILE_MODE_BAR = 'bar-chart';
|
||||
/** @var string ENUM_TILE_MODE_TOP */
|
||||
const ENUM_TILE_MODE_TOP = 'top-list';
|
||||
public const ENUM_TILE_MODE_TOP = 'top-list';
|
||||
|
||||
/** @var string ENUM_DISPLAY_MODE_LIST */
|
||||
const ENUM_DISPLAY_MODE_LIST = 'list';
|
||||
public const ENUM_DISPLAY_MODE_LIST = 'list';
|
||||
/** @var string ENUM_DISPLAY_MODE_PIE */
|
||||
const ENUM_DISPLAY_MODE_PIE = 'pie-chart';
|
||||
public const ENUM_DISPLAY_MODE_PIE = 'pie-chart';
|
||||
/** @var string ENUM_DISPLAY_MODE_BAR */
|
||||
const ENUM_DISPLAY_MODE_BAR = 'bar-chart';
|
||||
public const ENUM_DISPLAY_MODE_BAR = 'bar-chart';
|
||||
|
||||
/** @var string ENUM_PAGE_TEMPLATE_PATH_TABLE
|
||||
* @deprecated since 3.2.1
|
||||
* */
|
||||
const ENUM_PAGE_TEMPLATE_PATH_TABLE = 'itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig';
|
||||
public const ENUM_PAGE_TEMPLATE_PATH_TABLE = 'itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig';
|
||||
/** @var string ENUM_PAGE_TEMPLATE_PATH_CHART
|
||||
* @deprecated since 3.2.1
|
||||
* */
|
||||
const ENUM_PAGE_TEMPLATE_PATH_CHART = 'itop-portal-base/portal/templates/bricks/manage/layout-chart.html.twig';
|
||||
public const ENUM_PAGE_TEMPLATE_PATH_CHART = 'itop-portal-base/portal/templates/bricks/manage/layout-chart.html.twig';
|
||||
|
||||
/** Overloaded constants */
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-pen-square';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-pen-square fa-2x';
|
||||
public const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-pen-square';
|
||||
public const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-pen-square fa-2x';
|
||||
/**
|
||||
* @deprecated 3.2.1
|
||||
*/
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = self::ENUM_PAGE_TEMPLATE_PATH_TABLE;
|
||||
const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_LAZY;
|
||||
public const DEFAULT_PAGE_TEMPLATE_PATH = self::ENUM_PAGE_TEMPLATE_PATH_TABLE;
|
||||
public const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_LAZY;
|
||||
/**
|
||||
* @deprecated 3.2.1
|
||||
*/
|
||||
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-default.html.twig';
|
||||
const DEFAULT_TILE_CONTROLLER_ACTION = 'Combodo\\iTop\\Portal\\Controller\\ManageBrickController::TileAction';
|
||||
public const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-default.html.twig';
|
||||
public const DEFAULT_TILE_CONTROLLER_ACTION = 'Combodo\\iTop\\Portal\\Controller\\ManageBrickController::TileAction';
|
||||
|
||||
/** @var string DEFAULT_OQL */
|
||||
const DEFAULT_OQL = '';
|
||||
public const DEFAULT_OQL = '';
|
||||
/** @var string DEFAULT_OPENING_MODE */
|
||||
const DEFAULT_OPENING_MODE = self::ENUM_ACTION_EDIT;
|
||||
public const DEFAULT_OPENING_MODE = self::ENUM_ACTION_EDIT;
|
||||
/** @var int DEFAULT_LIST_LENGTH */
|
||||
const DEFAULT_LIST_LENGTH = 20;
|
||||
public const DEFAULT_LIST_LENGTH = 20;
|
||||
/** @var string DEFAULT_ZLIST_FIELDS */
|
||||
const DEFAULT_ZLIST_FIELDS = 'list';
|
||||
public const DEFAULT_ZLIST_FIELDS = 'list';
|
||||
/** @var bool DEFAULT_SHOW_TAB_COUNTS */
|
||||
const DEFAULT_SHOW_TAB_COUNTS = false;
|
||||
public const DEFAULT_SHOW_TAB_COUNTS = false;
|
||||
/** @var string DEFAULT_DISPLAY_MODE */
|
||||
const DEFAULT_DISPLAY_MODE = self::ENUM_DISPLAY_MODE_LIST;
|
||||
public const DEFAULT_DISPLAY_MODE = self::ENUM_DISPLAY_MODE_LIST;
|
||||
/** @var string DEFAULT_TILE_MODE */
|
||||
const DEFAULT_TILE_MODE = self::ENUM_TILE_MODE_TEXT;
|
||||
public const DEFAULT_TILE_MODE = self::ENUM_TILE_MODE_TEXT;
|
||||
/** @var int DEFAULT_GROUP_LIMIT */
|
||||
const DEFAULT_GROUP_LIMIT = 0;
|
||||
public const DEFAULT_GROUP_LIMIT = 0;
|
||||
/** @var bool DEFAULT_GROUP_SHOW_OTHERS */
|
||||
const DEFAULT_GROUP_SHOW_OTHERS = true;
|
||||
public const DEFAULT_GROUP_SHOW_OTHERS = true;
|
||||
|
||||
/** @var array $aDisplayModes */
|
||||
public static array $aDisplayModes = array(
|
||||
public static array $aDisplayModes = [
|
||||
self::ENUM_DISPLAY_MODE_LIST,
|
||||
self::ENUM_DISPLAY_MODE_PIE,
|
||||
self::ENUM_DISPLAY_MODE_BAR,
|
||||
);
|
||||
];
|
||||
|
||||
/** @var array $aTileModes */
|
||||
public static array $aTileModes = array(
|
||||
public static array $aTileModes = [
|
||||
self::ENUM_TILE_MODE_TEXT,
|
||||
self::ENUM_TILE_MODE_BADGE,
|
||||
self::ENUM_TILE_MODE_PIE,
|
||||
self::ENUM_TILE_MODE_BAR,
|
||||
self::ENUM_TILE_MODE_TOP,
|
||||
);
|
||||
];
|
||||
|
||||
/** @var array $aPresentationData
|
||||
* @deprecated since 3.2.1
|
||||
*/
|
||||
public static $aPresentationData = array(
|
||||
self::ENUM_TILE_MODE_BADGE => array(
|
||||
public static $aPresentationData = [
|
||||
self::ENUM_TILE_MODE_BADGE => [
|
||||
'decorationCssClass' => 'fas fa-id-card fa-2x',
|
||||
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-badge.html.twig',
|
||||
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE,
|
||||
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
|
||||
'need_details' => true,
|
||||
),
|
||||
self::ENUM_TILE_MODE_TOP => array(
|
||||
],
|
||||
self::ENUM_TILE_MODE_TOP => [
|
||||
'decorationCssClass' => 'fas fa-signal fa-rotate-270 fa-2x',
|
||||
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-top-list.html.twig',
|
||||
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE,
|
||||
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
|
||||
'need_details' => true,
|
||||
),
|
||||
self::ENUM_TILE_MODE_PIE => array(
|
||||
],
|
||||
self::ENUM_TILE_MODE_PIE => [
|
||||
'decorationCssClass' => 'fas fa-chart-pie fa-2x',
|
||||
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig',
|
||||
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART,
|
||||
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_PIE,
|
||||
'need_details' => false,
|
||||
),
|
||||
self::ENUM_TILE_MODE_BAR => array(
|
||||
],
|
||||
self::ENUM_TILE_MODE_BAR => [
|
||||
'decorationCssClass' => 'fas fa-chart-bar fa-2x',
|
||||
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig',
|
||||
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART,
|
||||
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_BAR,
|
||||
'need_details' => false,
|
||||
),
|
||||
self::ENUM_TILE_MODE_TEXT => array(
|
||||
],
|
||||
self::ENUM_TILE_MODE_TEXT => [
|
||||
'decorationCssClass' => 'fas fa-pen-square fa-2x',
|
||||
'tileTemplate' => self::DEFAULT_TILE_TEMPLATE_PATH,
|
||||
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE,
|
||||
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
|
||||
'need_details' => true,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
/** @var array $aDefaultTileData */
|
||||
private static array $aDefaultTileData = [
|
||||
@@ -201,7 +201,7 @@ class ManageBrick extends PortalBrick
|
||||
/** @var bool $bShowTabCounts */
|
||||
protected $bShowTabCounts;
|
||||
/** @var array $aAvailableDisplayModes */
|
||||
protected $aAvailableDisplayModes = array();
|
||||
protected $aAvailableDisplayModes = [];
|
||||
/** @var string $sDefaultDisplayMode */
|
||||
protected $sDefaultDisplayMode;
|
||||
/** @var string $sTileMode */
|
||||
@@ -217,16 +217,17 @@ class ManageBrick extends PortalBrick
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH . 'manage/tile-default.html.twig'),
|
||||
TemplateDefinitionDto::Create('tile_badge', static::TEMPLATES_BASE_PATH. 'manage/tile-badge.html.twig'),
|
||||
TemplateDefinitionDto::Create('tile_chart', static::TEMPLATES_BASE_PATH . 'manage/tile-chart.html.twig'),
|
||||
TemplateDefinitionDto::Create('tile_top_list', static::TEMPLATES_BASE_PATH . 'manage/tile-top-list.html.twig'),
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'manage/layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_table', static::TEMPLATES_BASE_PATH . 'manage/layout-table.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_chart', static::TEMPLATES_BASE_PATH . 'manage/layout-chart.html.twig'),
|
||||
TemplateDefinitionDto::Create('mode_chart_bar', static::TEMPLATES_BASE_PATH . 'manage/mode-bar-chart.html.twig', true, self::ENUM_DISPLAY_MODE_BAR),
|
||||
TemplateDefinitionDto::Create('mode_chart_pie', static::TEMPLATES_BASE_PATH . 'manage/mode-pie-chart.html.twig', true,self::ENUM_DISPLAY_MODE_PIE),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH.'manage/tile-default.html.twig'),
|
||||
TemplateDefinitionDto::Create('tile_badge', static::TEMPLATES_BASE_PATH.'manage/tile-badge.html.twig'),
|
||||
TemplateDefinitionDto::Create('tile_chart', static::TEMPLATES_BASE_PATH.'manage/tile-chart.html.twig'),
|
||||
TemplateDefinitionDto::Create('tile_top_list', static::TEMPLATES_BASE_PATH.'manage/tile-top-list.html.twig'),
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH.'manage/layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_table', static::TEMPLATES_BASE_PATH.'manage/layout-table.html.twig'),
|
||||
TemplateDefinitionDto::Create('page_chart', static::TEMPLATES_BASE_PATH.'manage/layout-chart.html.twig'),
|
||||
TemplateDefinitionDto::Create('mode_chart_bar', static::TEMPLATES_BASE_PATH.'manage/mode-bar-chart.html.twig', true, self::ENUM_DISPLAY_MODE_BAR),
|
||||
TemplateDefinitionDto::Create('mode_chart_pie', static::TEMPLATES_BASE_PATH.'manage/mode-pie-chart.html.twig', true, self::ENUM_DISPLAY_MODE_PIE),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -239,9 +240,9 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
$this->sOql = static::DEFAULT_OQL;
|
||||
$this->sOpeningMode = static::DEFAULT_OPENING_MODE;
|
||||
$this->aGrouping = array();
|
||||
$this->aFields = array();
|
||||
$this->aExportFields = array();
|
||||
$this->aGrouping = [];
|
||||
$this->aFields = [];
|
||||
$this->aExportFields = [];
|
||||
$this->bShowTabCounts = static::DEFAULT_SHOW_TAB_COUNTS;
|
||||
$this->sDefaultDisplayMode = static::DEFAULT_DISPLAY_MODE;
|
||||
|
||||
@@ -251,7 +252,7 @@ class ManageBrick extends PortalBrick
|
||||
$this->iDefaultListLength = static::DEFAULT_LIST_LENGTH;
|
||||
|
||||
// This is hardcoded for now, we might allow area grouping on another attribute in the future
|
||||
$this->AddGrouping('areas', array('attribute' => 'finalclass'));
|
||||
$this->AddGrouping('areas', ['attribute' => 'finalclass']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,13 +264,11 @@ class ManageBrick extends PortalBrick
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static public function AreDetailsNeededForDisplayMode($sDisplayMode)
|
||||
public static function AreDetailsNeededForDisplayMode($sDisplayMode)
|
||||
{
|
||||
$bNeedDetails = false;
|
||||
foreach (static::$aPresentationData as $aData)
|
||||
{
|
||||
if ($aData['layoutDisplayMode'] === $sDisplayMode)
|
||||
{
|
||||
foreach (static::$aPresentationData as $aData) {
|
||||
if ($aData['layoutDisplayMode'] === $sDisplayMode) {
|
||||
$bNeedDetails = $aData['need_details'];
|
||||
break;
|
||||
}
|
||||
@@ -278,7 +277,6 @@ class ManageBrick extends PortalBrick
|
||||
return $bNeedDetails;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns if the $sLayoutMode need objects details for rendering.
|
||||
*
|
||||
@@ -301,13 +299,11 @@ class ManageBrick extends PortalBrick
|
||||
* @param string $sDisplayMode
|
||||
* @return string
|
||||
*/
|
||||
static public function GetPageTemplateFromDisplayMode($sDisplayMode)
|
||||
public static function GetPageTemplateFromDisplayMode($sDisplayMode)
|
||||
{
|
||||
$sTemplate = static::DEFAULT_PAGE_TEMPLATE_PATH;
|
||||
foreach (static::$aPresentationData as $aData)
|
||||
{
|
||||
if ($aData['layoutDisplayMode'] === $sDisplayMode)
|
||||
{
|
||||
foreach (static::$aPresentationData as $aData) {
|
||||
if ($aData['layoutDisplayMode'] === $sDisplayMode) {
|
||||
$sTemplate = $aData['layoutTemplate'];
|
||||
break;
|
||||
}
|
||||
@@ -484,8 +480,7 @@ class ManageBrick extends PortalBrick
|
||||
*/
|
||||
public function GetPresentationDataForTileMode($sTileMode)
|
||||
{
|
||||
if (isset(static::$aPresentationData[$sTileMode]))
|
||||
{
|
||||
if (isset(static::$aPresentationData[$sTileMode])) {
|
||||
return static::$aPresentationData[$sTileMode];
|
||||
}
|
||||
|
||||
@@ -580,7 +575,7 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
/**
|
||||
* Returns the default lists length to display
|
||||
*
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function GetDefaultListLength()
|
||||
@@ -590,12 +585,13 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
/**
|
||||
* Sets the default lists length to display
|
||||
*
|
||||
*
|
||||
* @param int $iDefaultListLength
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetDefaultListLength($iDefaultListLength) {
|
||||
public function SetDefaultListLength($iDefaultListLength)
|
||||
{
|
||||
$this->iDefaultListLength = $iDefaultListLength;
|
||||
return $this;
|
||||
}
|
||||
@@ -615,8 +611,7 @@ class ManageBrick extends PortalBrick
|
||||
$this->aGrouping[$sName] = $aGrouping;
|
||||
|
||||
// Sorting
|
||||
if (!$this->IsGroupingByDistinctValues($sName))
|
||||
{
|
||||
if (!$this->IsGroupingByDistinctValues($sName)) {
|
||||
usort($this->aGrouping[$sName]['groups'], function ($a, $b) {
|
||||
if ($a['rank'] === $b['rank']) {
|
||||
return 0;
|
||||
@@ -638,8 +633,7 @@ class ManageBrick extends PortalBrick
|
||||
*/
|
||||
public function RemoveGrouping($sName)
|
||||
{
|
||||
if (isset($this->aGrouping[$sName]))
|
||||
{
|
||||
if (isset($this->aGrouping[$sName])) {
|
||||
unset($this->aGrouping[$sName]);
|
||||
}
|
||||
|
||||
@@ -655,8 +649,7 @@ class ManageBrick extends PortalBrick
|
||||
*/
|
||||
public function AddField($sAttCode)
|
||||
{
|
||||
if (!in_array($sAttCode, $this->aFields))
|
||||
{
|
||||
if (!in_array($sAttCode, $this->aFields)) {
|
||||
$this->aFields[] = $sAttCode;
|
||||
}
|
||||
|
||||
@@ -672,8 +665,7 @@ class ManageBrick extends PortalBrick
|
||||
*/
|
||||
public function RemoveField($sAttCode)
|
||||
{
|
||||
if (isset($this->aFields[$sAttCode]))
|
||||
{
|
||||
if (isset($this->aFields[$sAttCode])) {
|
||||
unset($this->aFields[$sAttCode]);
|
||||
}
|
||||
|
||||
@@ -682,8 +674,7 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
public function AddExportField($sAttCode)
|
||||
{
|
||||
if (!in_array($sAttCode, $this->aExportFields))
|
||||
{
|
||||
if (!in_array($sAttCode, $this->aExportFields)) {
|
||||
$this->aExportFields[] = $sAttCode;
|
||||
}
|
||||
|
||||
@@ -692,8 +683,7 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
public function RemoveExportField($sAttCode)
|
||||
{
|
||||
if (isset($this->aExportFields[$sAttCode]))
|
||||
{
|
||||
if (isset($this->aExportFields[$sAttCode])) {
|
||||
unset($this->aExportFields[$sAttCode]);
|
||||
}
|
||||
|
||||
@@ -749,10 +739,11 @@ class ManageBrick extends PortalBrick
|
||||
*/
|
||||
public function AddAvailableDisplayMode($sModeId)
|
||||
{
|
||||
if (!in_array($sModeId, static::$aDisplayModes))
|
||||
{
|
||||
throw new Exception('ManageBrick: Display mode "'.$sModeId.'" must be one of the allowed display modes ('.implode(', ',
|
||||
static::$aDisplayModes).')');
|
||||
if (!in_array($sModeId, static::$aDisplayModes)) {
|
||||
throw new Exception('ManageBrick: Display mode "'.$sModeId.'" must be one of the allowed display modes ('.implode(
|
||||
', ',
|
||||
static::$aDisplayModes
|
||||
).')');
|
||||
}
|
||||
|
||||
$this->aAvailableDisplayModes[] = $sModeId;
|
||||
@@ -769,8 +760,7 @@ class ManageBrick extends PortalBrick
|
||||
*/
|
||||
public function RemoveAvailableDisplayMode($sModeId)
|
||||
{
|
||||
if (isset($this->aAvailableDisplayModes[$sModeId]))
|
||||
{
|
||||
if (isset($this->aAvailableDisplayModes[$sModeId])) {
|
||||
unset($this->aAvailableDisplayModes[$sModeId]);
|
||||
}
|
||||
|
||||
@@ -843,16 +833,17 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
// Checking specific elements
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickSubNode */
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode)
|
||||
{
|
||||
switch ($oBrickSubNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) {
|
||||
switch ($oBrickSubNode->nodeName) {
|
||||
case 'class':
|
||||
$sClass = $oBrickSubNode->GetText();
|
||||
if ($sClass === '')
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick: class tag is empty. Must contain Classname', null,
|
||||
null, $oBrickSubNode);
|
||||
if ($sClass === '') {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick: class tag is empty. Must contain Classname',
|
||||
null,
|
||||
null,
|
||||
$oBrickSubNode
|
||||
);
|
||||
}
|
||||
|
||||
$this->SetOql('SELECT '.$sClass);
|
||||
@@ -860,10 +851,13 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
case 'oql':
|
||||
$sOql = $oBrickSubNode->GetText();
|
||||
if ($sOql === '')
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick: oql tag is empty. Must contain OQL statement', null,
|
||||
null, $oBrickSubNode);
|
||||
if ($sOql === '') {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick: oql tag is empty. Must contain OQL statement',
|
||||
null,
|
||||
null,
|
||||
$oBrickSubNode
|
||||
);
|
||||
}
|
||||
|
||||
$this->SetOql($sOql);
|
||||
@@ -871,10 +865,13 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
case 'opening_mode':
|
||||
$sOpeningMode = $oBrickSubNode->GetText(static::DEFAULT_OPENING_MODE);
|
||||
if (!in_array($sOpeningMode, array(static::ENUM_ACTION_VIEW, static::ENUM_ACTION_EDIT)))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick: opening_mode tag value must be edit|view ("'.$sOpeningMode.'" given)',
|
||||
null, null, $oBrickSubNode);
|
||||
if (!in_array($sOpeningMode, [static::ENUM_ACTION_VIEW, static::ENUM_ACTION_EDIT])) {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick: opening_mode tag value must be edit|view ("'.$sOpeningMode.'" given)',
|
||||
null,
|
||||
null,
|
||||
$oBrickSubNode
|
||||
);
|
||||
}
|
||||
|
||||
$this->SetOpeningMode($sOpeningMode);
|
||||
@@ -882,26 +879,31 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
case 'display_modes':
|
||||
/** @var \Combodo\iTop\DesignElement $oDisplayNode */
|
||||
foreach ($oBrickSubNode->GetNodes('./*') as $oDisplayNode)
|
||||
{
|
||||
switch ($oDisplayNode->nodeName)
|
||||
{
|
||||
case 'availables';
|
||||
foreach ($oBrickSubNode->GetNodes('./*') as $oDisplayNode) {
|
||||
switch ($oDisplayNode->nodeName) {
|
||||
case 'availables':
|
||||
/** @var \Combodo\iTop\DesignElement $oModeNode */
|
||||
foreach ($oDisplayNode->GetNodes('*') as $oModeNode)
|
||||
{
|
||||
if (!$oModeNode->hasAttribute('id'))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick: Display mode must have a unique ID attribute',
|
||||
0, null, $oModeNode);
|
||||
foreach ($oDisplayNode->GetNodes('*') as $oModeNode) {
|
||||
if (!$oModeNode->hasAttribute('id')) {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick: Display mode must have a unique ID attribute',
|
||||
0,
|
||||
null,
|
||||
$oModeNode
|
||||
);
|
||||
}
|
||||
|
||||
$sModeId = $oModeNode->getAttribute('id');
|
||||
if (!in_array($sModeId, static::$aDisplayModes))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick: Display mode has an invalid value. Expected '.implode('/',
|
||||
static::$aDisplayModes.', "'.$sModeId.'" given.'),
|
||||
null, null, $oModeNode);
|
||||
if (!in_array($sModeId, static::$aDisplayModes)) {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick: Display mode has an invalid value. Expected '.implode(
|
||||
'/',
|
||||
static::$aDisplayModes.', "'.$sModeId.'" given.'
|
||||
),
|
||||
null,
|
||||
null,
|
||||
$oModeNode
|
||||
);
|
||||
}
|
||||
|
||||
$this->AddAvailableDisplayMode($sModeId);
|
||||
@@ -912,9 +914,9 @@ class ManageBrick extends PortalBrick
|
||||
$this->SetDefaultDisplayMode($oDisplayNode->GetText(static::DEFAULT_DISPLAY_MODE));
|
||||
break;
|
||||
|
||||
case 'tile';
|
||||
case 'tile':
|
||||
$this->SetTileMode($oDisplayNode->GetText(static::DEFAULT_TILE_MODE));
|
||||
if($this->sDecorationClassHome === static::DEFAULT_DECORATION_CLASS_HOME){
|
||||
if ($this->sDecorationClassHome === static::DEFAULT_DECORATION_CLASS_HOME) {
|
||||
$this->sDecorationClassHome = static::$aDefaultTileData[$this->GetTileMode()]['decorationCssClass'];
|
||||
$this->SetDecorationClassNavigationMenu(static::$aDefaultTileData[$this->GetTileMode()]['decorationCssClass']);
|
||||
$this->SetDecorationClassHome(static::$aDefaultTileData[$this->GetTileMode()]['decorationCssClass']);
|
||||
@@ -926,12 +928,14 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
case 'fields':
|
||||
/** @var \Combodo\iTop\DesignElement $oFieldNode */
|
||||
foreach ($oBrickSubNode->GetNodes('./field') as $oFieldNode)
|
||||
{
|
||||
if (!$oFieldNode->hasAttribute('id'))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick : Field must have a unique ID attribute', 0,
|
||||
null, $oFieldNode);
|
||||
foreach ($oBrickSubNode->GetNodes('./field') as $oFieldNode) {
|
||||
if (!$oFieldNode->hasAttribute('id')) {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick : Field must have a unique ID attribute',
|
||||
0,
|
||||
null,
|
||||
$oFieldNode
|
||||
);
|
||||
}
|
||||
$this->AddField($oFieldNode->getAttribute('id'));
|
||||
}
|
||||
@@ -939,19 +943,18 @@ class ManageBrick extends PortalBrick
|
||||
|
||||
case 'export':
|
||||
/** @var \Combodo\iTop\DesignElement $oExportNode */
|
||||
foreach ($oBrickSubNode->GetNodes('./*') as $oExportNode)
|
||||
{
|
||||
switch ($oExportNode->nodeName)
|
||||
{
|
||||
foreach ($oBrickSubNode->GetNodes('./*') as $oExportNode) {
|
||||
switch ($oExportNode->nodeName) {
|
||||
case 'fields':
|
||||
/** @var \Combodo\iTop\DesignElement $oFieldNode */
|
||||
foreach ($oExportNode->GetNodes('./field') as $oFieldNode)
|
||||
{
|
||||
if (!$oFieldNode->hasAttribute('id'))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick : Field must have a unique ID attribute',
|
||||
foreach ($oExportNode->GetNodes('./field') as $oFieldNode) {
|
||||
if (!$oFieldNode->hasAttribute('id')) {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick : Field must have a unique ID attribute',
|
||||
0,
|
||||
null, $oFieldNode);
|
||||
null,
|
||||
$oFieldNode
|
||||
);
|
||||
}
|
||||
$this->AddExportField($oFieldNode->getAttribute('id'));
|
||||
}
|
||||
@@ -966,12 +969,12 @@ class ManageBrick extends PortalBrick
|
||||
break;
|
||||
case 'default_list_length':
|
||||
$iNodeDefaultListLength = (int)$oBrickSubNode->GetText(static::DEFAULT_LIST_LENGTH);
|
||||
if(!in_array($iNodeDefaultListLength, array(10, 20, 50, -1),true))
|
||||
{
|
||||
if (!in_array($iNodeDefaultListLength, [10, 20, 50, -1], true)) {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick : Default list length must be contained in list length options. Expected -1/10/20/50, '.$iNodeDefaultListLength.' given.',
|
||||
null,
|
||||
null, $oBrickSubNode
|
||||
null,
|
||||
$oBrickSubNode
|
||||
);
|
||||
}
|
||||
$this->SetDefaultListLength($iNodeDefaultListLength);
|
||||
@@ -979,25 +982,21 @@ class ManageBrick extends PortalBrick
|
||||
case 'grouping':
|
||||
// Tabs grouping
|
||||
/** @var \Combodo\iTop\DesignElement $oGroupingNode */
|
||||
foreach ($oBrickSubNode->GetNodes('./tabs/*') as $oGroupingNode)
|
||||
{
|
||||
switch ($oGroupingNode->nodeName)
|
||||
{
|
||||
case 'show_tab_counts';
|
||||
foreach ($oBrickSubNode->GetNodes('./tabs/*') as $oGroupingNode) {
|
||||
switch ($oGroupingNode->nodeName) {
|
||||
case 'show_tab_counts':
|
||||
$bShowTabCounts = ($oGroupingNode->GetText(static::DEFAULT_SHOW_TAB_COUNTS) === 'true') ? true : false;
|
||||
$this->SetShowTabCounts($bShowTabCounts);
|
||||
break;
|
||||
case 'attribute':
|
||||
$sAttribute = $oGroupingNode->GetText();
|
||||
if ($sAttribute !== '')
|
||||
{
|
||||
$this->AddGrouping('tabs', array('attribute' => $sAttribute));
|
||||
if ($sAttribute !== '') {
|
||||
$this->AddGrouping('tabs', ['attribute' => $sAttribute]);
|
||||
}
|
||||
break;
|
||||
case 'limit':
|
||||
$iLimit = $oGroupingNode->GetText();
|
||||
if (is_numeric($iLimit))
|
||||
{
|
||||
if (is_numeric($iLimit)) {
|
||||
$this->iGroupLimit = $iLimit;
|
||||
}
|
||||
break;
|
||||
@@ -1005,24 +1004,24 @@ class ManageBrick extends PortalBrick
|
||||
$this->bGroupShowOthers = ($oGroupingNode->GetText() === 'true') ? true : false;
|
||||
break;
|
||||
case 'groups':
|
||||
$aGroups = array();
|
||||
$aGroups = [];
|
||||
/** @var \Combodo\iTop\DesignElement $oGroupNode */
|
||||
foreach ($oGroupingNode->GetNodes('./group') as $oGroupNode)
|
||||
{
|
||||
if (!$oGroupNode->hasAttribute('id'))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick : Group must have a unique ID attribute',
|
||||
0, null, $oGroupNode);
|
||||
foreach ($oGroupingNode->GetNodes('./group') as $oGroupNode) {
|
||||
if (!$oGroupNode->hasAttribute('id')) {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick : Group must have a unique ID attribute',
|
||||
0,
|
||||
null,
|
||||
$oGroupNode
|
||||
);
|
||||
}
|
||||
$sGroupId = $oGroupNode->getAttribute('id');
|
||||
|
||||
$aGroup = array();
|
||||
$aGroup = [];
|
||||
$aGroup['id'] = $sGroupId; // We don't put the group id as the $aGroups key because the array will be sorted later in AddGrouping, which replace array keys by integer ordered keys
|
||||
/** @var \Combodo\iTop\DesignElement $oGroupProperty */
|
||||
foreach ($oGroupNode->GetNodes('*') as $oGroupProperty)
|
||||
{
|
||||
switch ($oGroupProperty->nodeName)
|
||||
{
|
||||
foreach ($oGroupNode->GetNodes('*') as $oGroupProperty) {
|
||||
switch ($oGroupProperty->nodeName) {
|
||||
case 'rank':
|
||||
$aGroup[$oGroupProperty->nodeName] = (int)$oGroupProperty->GetText(0);
|
||||
break;
|
||||
@@ -1035,19 +1034,25 @@ class ManageBrick extends PortalBrick
|
||||
}
|
||||
|
||||
// Checking constitancy
|
||||
if (!isset($aGroup['title']) || $aGroup['title'] === '')
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick : Group must have a title tag and it must not be empty',
|
||||
0, null, $oGroupNode);
|
||||
if (!isset($aGroup['title']) || $aGroup['title'] === '') {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick : Group must have a title tag and it must not be empty',
|
||||
0,
|
||||
null,
|
||||
$oGroupNode
|
||||
);
|
||||
}
|
||||
if (!isset($aGroup['condition']) || $aGroup['condition'] === '')
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick : Group must have a condition tag and it must not be empty',
|
||||
0, null, $oGroupNode);
|
||||
if (!isset($aGroup['condition']) || $aGroup['condition'] === '') {
|
||||
throw new DOMFormatException(
|
||||
'ManageBrick : Group must have a condition tag and it must not be empty',
|
||||
0,
|
||||
null,
|
||||
$oGroupNode
|
||||
);
|
||||
}
|
||||
$aGroups[] = $aGroup;
|
||||
}
|
||||
$this->AddGrouping('tabs', array('groups' => $aGroups));
|
||||
$this->AddGrouping('tabs', ['groups' => $aGroups]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1069,62 +1074,58 @@ class ManageBrick extends PortalBrick
|
||||
}
|
||||
|
||||
// Checking if has an oql
|
||||
if ($this->GetOql() === '')
|
||||
{
|
||||
if ($this->GetOql() === '') {
|
||||
throw new DOMFormatException('ManageBrick: must have a valid <class|oql> tag', null, null, $oMDElement);
|
||||
}
|
||||
|
||||
// Checking that the brick has at least a display mode
|
||||
if (count($this->GetAvailablesDisplayModes()) === 0)
|
||||
{
|
||||
if (count($this->GetAvailablesDisplayModes()) === 0) {
|
||||
$this->AddAvailableDisplayMode(static::DEFAULT_DISPLAY_MODE);
|
||||
}
|
||||
// Checking that default display mode in among the availables
|
||||
if (!in_array($this->sDefaultDisplayMode, $this->aAvailableDisplayModes))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick: Default display mode "'.$this->sDefaultDisplayMode.'" must be one of the available display modes ('.implode(', ',
|
||||
$this->aAvailableDisplayModes).')', null, null, $oMDElement);
|
||||
if (!in_array($this->sDefaultDisplayMode, $this->aAvailableDisplayModes)) {
|
||||
throw new DOMFormatException('ManageBrick: Default display mode "'.$this->sDefaultDisplayMode.'" must be one of the available display modes ('.implode(
|
||||
', ',
|
||||
$this->aAvailableDisplayModes
|
||||
).')', null, null, $oMDElement);
|
||||
}
|
||||
// Checking that tile mode in among the availables
|
||||
if (!in_array($this->sTileMode, static::$aTileModes))
|
||||
{
|
||||
throw new DOMFormatException('ManageBrick: Tile mode "'.$this->sTileMode.'" must be one of the allowed tile modes ('.implode(', ',
|
||||
static::$aTileModes).')', null, null, $oMDElement);
|
||||
if (!in_array($this->sTileMode, static::$aTileModes)) {
|
||||
throw new DOMFormatException('ManageBrick: Tile mode "'.$this->sTileMode.'" must be one of the allowed tile modes ('.implode(
|
||||
', ',
|
||||
static::$aTileModes
|
||||
).')', null, null, $oMDElement);
|
||||
}
|
||||
|
||||
// Checking if specified fields, if not we put those from the details zlist
|
||||
if (empty($this->aFields))
|
||||
{
|
||||
if (empty($this->aFields)) {
|
||||
$sClass = DBSearch::FromOQL($this->GetOql());
|
||||
$aFields = MetaModel::FlattenZList(MetaModel::GetZListItems($sClass->GetClass(),
|
||||
static::DEFAULT_ZLIST_FIELDS));
|
||||
$aFields = MetaModel::FlattenZList(MetaModel::GetZListItems(
|
||||
$sClass->GetClass(),
|
||||
static::DEFAULT_ZLIST_FIELDS
|
||||
));
|
||||
$this->SetFields($aFields);
|
||||
}
|
||||
|
||||
// Default Export Fields
|
||||
if ($bUseListFieldsForExport)
|
||||
{
|
||||
foreach ($this->GetFields() as $sAttCode)
|
||||
{
|
||||
if ($bUseListFieldsForExport) {
|
||||
foreach ($this->GetFields() as $sAttCode) {
|
||||
$this->AddExportField($sAttCode);
|
||||
}
|
||||
}
|
||||
|
||||
// Checking the navigation icon
|
||||
$sDecorationClassNavigationMenu = $this->GetDecorationClassNavigationMenu();
|
||||
if (empty($sDecorationClassNavigationMenu) && isset(static::$aDefaultTileData[$this->sTileMode]))
|
||||
{
|
||||
if (empty($sDecorationClassNavigationMenu) && isset(static::$aDefaultTileData[$this->sTileMode])) {
|
||||
/** @var string $sDecorationClassNavigationMenu */
|
||||
$sDecorationClassNavigationMenu = static::$aDefaultTileData[$this->sTileMode]['decorationCssClass'];
|
||||
if (!empty($sDecorationClassNavigationMenu))
|
||||
{
|
||||
if (!empty($sDecorationClassNavigationMenu)) {
|
||||
$this->SetDecorationClassNavigationMenu($sDecorationClassNavigationMenu);
|
||||
}
|
||||
}
|
||||
|
||||
$sTitle = $this->GetTitleHome();
|
||||
if (empty($sTitle))
|
||||
{
|
||||
if (empty($sTitle)) {
|
||||
$sOql = $this->GetOql();
|
||||
$oSearch = DBSearch::FromOQL($sOql);
|
||||
$sClassName = MetaModel::GetName($oSearch->GetClass());
|
||||
|
||||
@@ -38,37 +38,37 @@ use ModuleDesign;
|
||||
abstract class PortalBrick extends AbstractBrick
|
||||
{
|
||||
/** @var string ENUM_OPENING_TARGET_MODAL */
|
||||
const ENUM_OPENING_TARGET_MODAL = 'modal';
|
||||
public const ENUM_OPENING_TARGET_MODAL = 'modal';
|
||||
/** @var string ENUM_OPENING_TARGET_SELF */
|
||||
const ENUM_OPENING_TARGET_SELF = 'self';
|
||||
public const ENUM_OPENING_TARGET_SELF = 'self';
|
||||
/** @var string ENUM_OPENING_TARGET_NEW */
|
||||
const ENUM_OPENING_TARGET_NEW = 'new';
|
||||
public const ENUM_OPENING_TARGET_NEW = 'new';
|
||||
|
||||
/** @var int DEFAULT_WIDTH */
|
||||
const DEFAULT_WIDTH = 6;
|
||||
public const DEFAULT_WIDTH = 6;
|
||||
/** @var int DEFAULT_HEIGHT */
|
||||
const DEFAULT_HEIGHT = 1;
|
||||
public const DEFAULT_HEIGHT = 1;
|
||||
/** @var bool DEFAULT_MODAL */
|
||||
const DEFAULT_MODAL = false;
|
||||
public const DEFAULT_MODAL = false;
|
||||
/** @var bool DEFAULT_VISIBLE_HOME */
|
||||
const DEFAULT_VISIBLE_HOME = true;
|
||||
public const DEFAULT_VISIBLE_HOME = true;
|
||||
/** @var bool DEFAULT_VISIBLE_NAVIGATION_MENU */
|
||||
const DEFAULT_VISIBLE_NAVIGATION_MENU = true;
|
||||
public const DEFAULT_VISIBLE_NAVIGATION_MENU = true;
|
||||
/** @var string DEFAULT_DECORATION_CLASS_HOME */
|
||||
const DEFAULT_DECORATION_CLASS_HOME = '';
|
||||
public const DEFAULT_DECORATION_CLASS_HOME = '';
|
||||
/** @var string DEFAULT_DECORATION_CLASS_NAVIGATION_MENU */
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = '';
|
||||
public const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = '';
|
||||
/** @var string DEFAULT_TILE_TEMPLATE_PATH */
|
||||
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/tile.html.twig';
|
||||
public const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/tile.html.twig';
|
||||
/** @var string|null DEFAULT_TILE_CONTROLLER_ACTION */
|
||||
const DEFAULT_TILE_CONTROLLER_ACTION = null;
|
||||
public const DEFAULT_TILE_CONTROLLER_ACTION = null;
|
||||
/** @var string DEFAULT_OPENING_TARGET */
|
||||
const DEFAULT_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL;
|
||||
public const DEFAULT_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL;
|
||||
|
||||
/** @var string|null $sRouteName */
|
||||
static $sRouteName = null;
|
||||
public static $sRouteName = null;
|
||||
/** @var array $aOpeningTargets */
|
||||
static $aOpeningTargets = array(self::ENUM_OPENING_TARGET_MODAL, self::ENUM_OPENING_TARGET_SELF, self::ENUM_OPENING_TARGET_NEW);
|
||||
public static $aOpeningTargets = [self::ENUM_OPENING_TARGET_MODAL, self::ENUM_OPENING_TARGET_SELF, self::ENUM_OPENING_TARGET_NEW];
|
||||
|
||||
/** @var int $iWidth */
|
||||
protected $iWidth;
|
||||
@@ -103,14 +103,13 @@ abstract class PortalBrick extends AbstractBrick
|
||||
/** @var string $sTitleNavigationMenu */
|
||||
protected $sTitleNavigationMenu;
|
||||
|
||||
|
||||
|
||||
/** @inheritdoc */
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH . 'tile.html.twig'),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH.'tile.html.twig'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -500,10 +499,8 @@ abstract class PortalBrick extends AbstractBrick
|
||||
|
||||
// Checking specific elements
|
||||
/** @var \Combodo\iTop\DesignElement $oBrickSubNode */
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode)
|
||||
{
|
||||
switch ($oBrickSubNode->nodeName)
|
||||
{
|
||||
foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) {
|
||||
switch ($oBrickSubNode->nodeName) {
|
||||
case 'width':
|
||||
$sWidth = $oBrickSubNode->GetText(static::DEFAULT_WIDTH);
|
||||
$this->bIsWidthPixel = str_contains($sWidth, 'px');
|
||||
@@ -522,23 +519,20 @@ abstract class PortalBrick extends AbstractBrick
|
||||
case 'visible':
|
||||
// Default value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('default');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = ($oOptionalNode->GetText() === 'false') ? false : true;
|
||||
$this->SetVisibleHome($optionalNodeValue);
|
||||
$this->SetVisibleNavigationMenu($optionalNodeValue);
|
||||
}
|
||||
// Home value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('home');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = ($oOptionalNode->GetText() === 'false') ? false : true;
|
||||
$this->SetVisibleHome($optionalNodeValue);
|
||||
}
|
||||
// Navigation menu value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('navigation_menu');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = ($oOptionalNode->GetText() === 'false') ? false : true;
|
||||
$this->SetVisibleNavigationMenu($optionalNodeValue);
|
||||
}
|
||||
@@ -546,8 +540,7 @@ abstract class PortalBrick extends AbstractBrick
|
||||
|
||||
case 'templates':
|
||||
$oTemplateNodeList = $oBrickSubNode->GetNodes('template[@id='.ModuleDesign::XPathQuote('tile').']');
|
||||
if ($oTemplateNodeList->length > 0)
|
||||
{
|
||||
if ($oTemplateNodeList->length > 0) {
|
||||
/** @var \Combodo\iTop\DesignElement $oTemplateNode */
|
||||
$oTemplateNode = $oTemplateNodeList->item(0);
|
||||
$this->SetTemplatePath('tile', $oTemplateNode->GetText(static::DEFAULT_TILE_TEMPLATE_PATH));
|
||||
@@ -560,23 +553,20 @@ abstract class PortalBrick extends AbstractBrick
|
||||
$this->SetRankNavigationMenu($this->fRank);
|
||||
// Default value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('default');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_RANK);
|
||||
$this->SetRankHome($optionalNodeValue);
|
||||
$this->SetRankNavigationMenu($optionalNodeValue);
|
||||
}
|
||||
// Home value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('home');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_RANK);
|
||||
$this->SetRankHome($optionalNodeValue);
|
||||
}
|
||||
// Navigation menu value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('navigation_menu');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_RANK);
|
||||
$this->SetRankNavigationMenu($optionalNodeValue);
|
||||
}
|
||||
@@ -588,23 +578,20 @@ abstract class PortalBrick extends AbstractBrick
|
||||
$this->SetTitleNavigationMenu($this->sTitle);
|
||||
// Default value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('default');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_TITLE);
|
||||
$this->SetTitleHome($optionalNodeValue);
|
||||
$this->SetTitleNavigationMenu($optionalNodeValue);
|
||||
}
|
||||
// Home value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('home');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_TITLE);
|
||||
$this->SetTitleHome($optionalNodeValue);
|
||||
}
|
||||
// Navigation menu value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('navigation_menu');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_TITLE);
|
||||
$this->SetTitleNavigationMenu($optionalNodeValue);
|
||||
$this->SetTitle($optionalNodeValue);
|
||||
@@ -617,23 +604,20 @@ abstract class PortalBrick extends AbstractBrick
|
||||
$this->SetDecorationClassNavigationMenu(static::DEFAULT_DECORATION_CLASS_NAVIGATION_MENU);
|
||||
// Default value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('default');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_DECORATION_CLASS_NAVIGATION_MENU);
|
||||
$this->SetDecorationClassHome($optionalNodeValue);
|
||||
$this->SetDecorationClassNavigationMenu($optionalNodeValue);
|
||||
}
|
||||
// Home value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('home');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_DECORATION_CLASS_HOME);
|
||||
$this->SetDecorationClassHome($optionalNodeValue);
|
||||
}
|
||||
// Navigation menu value
|
||||
$oOptionalNode = $oBrickSubNode->GetOptionalElement('navigation_menu');
|
||||
if ($oOptionalNode !== null)
|
||||
{
|
||||
if ($oOptionalNode !== null) {
|
||||
$optionalNodeValue = $oOptionalNode->GetText(static::DEFAULT_DECORATION_CLASS_NAVIGATION_MENU);
|
||||
$this->SetDecorationClassNavigationMenu($optionalNodeValue);
|
||||
}
|
||||
@@ -645,11 +629,16 @@ abstract class PortalBrick extends AbstractBrick
|
||||
|
||||
case 'opening_target':
|
||||
$sOpeningTarget = $oBrickSubNode->GetText(static::DEFAULT_OPENING_TARGET);
|
||||
if (!in_array($sOpeningTarget,
|
||||
array(static::ENUM_OPENING_TARGET_MODAL, static::ENUM_OPENING_TARGET_NEW, static::ENUM_OPENING_TARGET_SELF)))
|
||||
{
|
||||
throw new DOMFormatException('PortalBrick : opening_target tag value must be modal|new|self ("'.$sOpeningTarget.'" given)',
|
||||
null, null, $oBrickSubNode);
|
||||
if (!in_array(
|
||||
$sOpeningTarget,
|
||||
[static::ENUM_OPENING_TARGET_MODAL, static::ENUM_OPENING_TARGET_NEW, static::ENUM_OPENING_TARGET_SELF]
|
||||
)) {
|
||||
throw new DOMFormatException(
|
||||
'PortalBrick : opening_target tag value must be modal|new|self ("'.$sOpeningTarget.'" given)',
|
||||
null,
|
||||
null,
|
||||
$oBrickSubNode
|
||||
);
|
||||
}
|
||||
|
||||
$this->SetOpeningTarget($sOpeningTarget);
|
||||
|
||||
@@ -31,5 +31,4 @@ use Exception;
|
||||
*/
|
||||
class PropertyNotFoundException extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -34,19 +35,19 @@ use DOMFormatException;
|
||||
class UserProfileBrick extends PortalBrick
|
||||
{
|
||||
// Overloaded constants
|
||||
const DEFAULT_VISIBLE_NAVIGATION_MENU = false;
|
||||
const DEFAULT_VISIBLE_HOME = false;
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'glyphicon glyphicon-user';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'glyphicon glyphicon-user';
|
||||
public const DEFAULT_VISIBLE_NAVIGATION_MENU = false;
|
||||
public const DEFAULT_VISIBLE_HOME = false;
|
||||
public const DEFAULT_DECORATION_CLASS_HOME = 'glyphicon glyphicon-user';
|
||||
public const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'glyphicon glyphicon-user';
|
||||
/** @var bool DEFAULT_SHOW_PICTURE_FORM */
|
||||
const DEFAULT_SHOW_PICTURE_FORM = true;
|
||||
public const DEFAULT_SHOW_PICTURE_FORM = true;
|
||||
/** @var bool DEFAULT_SHOW_PREFERENCES_FORM */
|
||||
const DEFAULT_SHOW_PREFERENCES_FORM = true;
|
||||
public const DEFAULT_SHOW_PREFERENCES_FORM = true;
|
||||
/** @var bool DEFAULT_SHOW_PASSWORD_FORM */
|
||||
const DEFAULT_SHOW_PASSWORD_FORM = true;
|
||||
public const DEFAULT_SHOW_PASSWORD_FORM = true;
|
||||
|
||||
// Overloaded variables
|
||||
static $sRouteName = 'p_user_profile_brick';
|
||||
public static $sRouteName = 'p_user_profile_brick';
|
||||
|
||||
/** @var array $aForm */
|
||||
protected $aForm;
|
||||
@@ -61,8 +62,9 @@ class UserProfileBrick extends PortalBrick
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'user-profile/layout.html.twig'),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH.'user-profile/layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('user_info', static::TEMPLATES_BASE_PATH.'user-profile/user_info.html.twig'),
|
||||
TemplateDefinitionDto::Create('user_info_ready_js', static::TEMPLATES_BASE_PATH.'user-profile/user_info.ready.js.twig'),
|
||||
);
|
||||
@@ -75,12 +77,12 @@ class UserProfileBrick extends PortalBrick
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->aForm = array(
|
||||
$this->aForm = [
|
||||
'id' => 'default-user-profile',
|
||||
'type' => 'zlist',
|
||||
'fields' => 'details',
|
||||
'layout' => null,
|
||||
);
|
||||
];
|
||||
$this->bShowPictureForm = static::DEFAULT_SHOW_PICTURE_FORM;
|
||||
$this->bShowPreferencesForm = static::DEFAULT_SHOW_PREFERENCES_FORM;
|
||||
$this->bShowPasswordForm = static::DEFAULT_SHOW_PASSWORD_FORM;
|
||||
@@ -191,13 +193,13 @@ class UserProfileBrick extends PortalBrick
|
||||
// Enumerating fields
|
||||
if ($oBrickSubNode->GetOptionalElement('fields') !== null) {
|
||||
$this->aForm['type'] = 'custom_list';
|
||||
$this->aForm['fields'] = array();
|
||||
$this->aForm['fields'] = [];
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oFieldNode */
|
||||
foreach ($oBrickSubNode->GetOptionalElement('fields')->GetNodes('field') as $oFieldNode) {
|
||||
$sFieldId = $oFieldNode->getAttribute('id');
|
||||
if ($sFieldId !== '') {
|
||||
$aField = array();
|
||||
$aField = [];
|
||||
// Parsing field options like read_only, hidden and mandatory
|
||||
if ($oFieldNode->GetOptionalElement('read_only')) {
|
||||
$aField['readonly'] = ($oFieldNode->GetOptionalElement('read_only')->GetText('true') === 'true') ? true : false;
|
||||
@@ -223,10 +225,10 @@ class UserProfileBrick extends PortalBrick
|
||||
$sXml = preg_replace('/^.+\n/', '', $sXml);
|
||||
$sXml = preg_replace('/\n.+$/', '', $sXml);
|
||||
|
||||
$this->aForm['layout'] = array(
|
||||
$this->aForm['layout'] = [
|
||||
'type' => (preg_match('/\{\{|\{\#|\{\%/', $sXml) === 1) ? 'twig' : 'xhtml',
|
||||
'content' => $sXml,
|
||||
);
|
||||
];
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -37,14 +37,15 @@ use Symfony\Contracts\Service\Attribute\Required;
|
||||
*/
|
||||
abstract class AbstractController extends SymfonyAbstractController implements TemplatesProviderInterface
|
||||
{
|
||||
const TEMPLATES_BASE_PATH = 'itop-portal-base/portal/templates/';
|
||||
public const TEMPLATES_BASE_PATH = 'itop-portal-base/portal/templates/';
|
||||
|
||||
/** @inheritdoc */
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('modal', static::TEMPLATES_BASE_PATH . 'modal/layout.html.twig'),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH.'layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('modal', static::TEMPLATES_BASE_PATH.'modal/layout.html.twig'),
|
||||
TemplateDefinitionDto::Create('loader', static::TEMPLATES_BASE_PATH.'helpers/loader.html.twig'),
|
||||
TemplateDefinitionDto::Create('tagset_clic_handler_js', static::TEMPLATES_BASE_PATH.'helpers/tagset_clic_handler.js.twig'),
|
||||
TemplateDefinitionDto::Create('session_message', static::TEMPLATES_BASE_PATH.'helpers/session_messages/session_message.html.twig'),
|
||||
|
||||
@@ -29,7 +29,6 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use UserRights;
|
||||
|
||||
|
||||
/**
|
||||
* Class AggregatePageBrickController
|
||||
*
|
||||
@@ -41,7 +40,6 @@ use UserRights;
|
||||
*/
|
||||
class AggregatePageBrickController extends BrickController
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -51,8 +49,7 @@ class AggregatePageBrickController extends BrickController
|
||||
*/
|
||||
public function __construct(
|
||||
protected BrickCollection $oBrickCollection
|
||||
)
|
||||
{
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
@@ -76,11 +73,11 @@ class AggregatePageBrickController extends BrickController
|
||||
$aTilesRendering = $this->GetBricksTileRendering($oRequest, $aAggregatePageBricks);
|
||||
|
||||
$sLayoutTemplate = $oBrick->GetTemplatePath('page');
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'oBrick' => $oBrick,
|
||||
'aggregatepage_bricks' => $aAggregatePageBricks,
|
||||
'aTilesRendering' => $aTilesRendering,
|
||||
);
|
||||
];
|
||||
$oResponse = $this->render($sLayoutTemplate, $aData);
|
||||
|
||||
return $oResponse;
|
||||
@@ -94,15 +91,11 @@ class AggregatePageBrickController extends BrickController
|
||||
*/
|
||||
private function GetOrderedAggregatePageBricksObjectsById($aAggregatePageBricksConf)
|
||||
{
|
||||
$aAggregatePageBricks = array();
|
||||
foreach ($aAggregatePageBricksConf as $sBrickId => $iBrickRank)
|
||||
{
|
||||
try
|
||||
{
|
||||
$aAggregatePageBricks = [];
|
||||
foreach ($aAggregatePageBricksConf as $sBrickId => $iBrickRank) {
|
||||
try {
|
||||
$oPortalBrick = $this->oBrickCollection->GetBrickById($sBrickId);
|
||||
}
|
||||
catch (BrickNotFoundException $oException)
|
||||
{
|
||||
} catch (BrickNotFoundException $oException) {
|
||||
IssueLog::Debug('AggregatePageBrick: Could not display brick, either wrong id or user profile not allowed', LogChannels::PORTAL, [
|
||||
'brick_id' => $sBrickId,
|
||||
'user_profiles' => UserRights::ListProfiles(),
|
||||
@@ -124,21 +117,17 @@ class AggregatePageBrickController extends BrickController
|
||||
*/
|
||||
private function GetBricksTileRendering(Request $oRequest, $aBricks)
|
||||
{
|
||||
$aTilesRendering = array();
|
||||
foreach ($aBricks as $oBrick)
|
||||
{
|
||||
if ($oBrick->GetTileControllerAction() !== null)
|
||||
{
|
||||
$aTilesRendering = [];
|
||||
foreach ($aBricks as $oBrick) {
|
||||
if ($oBrick->GetTileControllerAction() !== null) {
|
||||
$aControllerActionParts = explode('::', $oBrick->GetTileControllerAction());
|
||||
if (count($aControllerActionParts) !== 2)
|
||||
{
|
||||
if (count($aControllerActionParts) !== 2) {
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Tile controller action must be of form "\Namespace\ControllerClass::FunctionName" for brick "'.$oBrick->GetId().'"');
|
||||
}
|
||||
|
||||
$aRouteParams = array();
|
||||
$aRouteParams = [];
|
||||
// Add sBrickId in the route params as it is necessary for each brick actions
|
||||
if (is_a($aControllerActionParts[0], BrickController::class, true))
|
||||
{
|
||||
if (is_a($aControllerActionParts[0], BrickController::class, true)) {
|
||||
$aRouteParams['sBrickId'] = $oBrick->GetId();
|
||||
}
|
||||
|
||||
@@ -150,4 +139,4 @@ class AggregatePageBrickController extends BrickController
|
||||
|
||||
return $aTilesRendering;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,5 +29,4 @@ namespace Combodo\iTop\Portal\Controller;
|
||||
*/
|
||||
abstract class BrickController extends AbstractController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ use VariableExpression;
|
||||
*/
|
||||
class BrowseBrickController extends BrickController
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -67,12 +66,10 @@ class BrowseBrickController extends BrickController
|
||||
protected RequestManipulatorHelper $oRequestManipulatorHelper,
|
||||
protected BrickControllerHelper $oBrickControllerHelper,
|
||||
protected BrickCollection $oBrickCollection
|
||||
)
|
||||
{
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
* @param string $sBrickId
|
||||
@@ -103,85 +100,92 @@ class BrowseBrickController extends BrickController
|
||||
// Getting current browse mode (First from router parameter, then default brick value)
|
||||
$sBrowseMode = (!empty($sBrowseMode)) ? $sBrowseMode : $oBrick->GetDefaultBrowseMode();
|
||||
// Getting current dataloading mode (First from router parameter, then query parameter, then default brick value)
|
||||
$sDataLoading = ($sDataLoading !== null) ? $sDataLoading : $this->oRequestManipulatorHelper->ReadParam('sDataLoading',
|
||||
$oBrick->GetDataLoading());
|
||||
$sDataLoading = ($sDataLoading !== null) ? $sDataLoading : $this->oRequestManipulatorHelper->ReadParam(
|
||||
'sDataLoading',
|
||||
$oBrick->GetDataLoading()
|
||||
);
|
||||
// Getting search value
|
||||
$sRawSearchValue = $this->oRequestManipulatorHelper->ReadParam('sSearchValue', '');
|
||||
$sSearchValue = html_entity_decode($sRawSearchValue);
|
||||
if (strlen($sSearchValue) > 0)
|
||||
{
|
||||
if (strlen($sSearchValue) > 0) {
|
||||
$sDataLoading = AbstractBrick::ENUM_DATA_LOADING_LAZY;
|
||||
}
|
||||
|
||||
$aData = array();
|
||||
$aLevelsProperties = array();
|
||||
$aLevelsClasses = array();
|
||||
$aData = [];
|
||||
$aLevelsProperties = [];
|
||||
$aLevelsClasses = [];
|
||||
$this->oBrowseBrickHelper->TreeToFlatLevelsProperties($oBrick->GetLevels(), $aLevelsProperties);
|
||||
|
||||
// Consistency checks
|
||||
if (!in_array($sBrowseMode, array_keys($aBrowseModes)))
|
||||
{
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Browse brick "'.$sBrickId.'" : Unknown browse mode "'.$sBrowseMode.'", availables are '.implode(' / ',
|
||||
array_keys($aBrowseModes)));
|
||||
if (!in_array($sBrowseMode, array_keys($aBrowseModes))) {
|
||||
throw new HttpException(
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Browse brick "'.$sBrickId.'" : Unknown browse mode "'.$sBrowseMode.'", availables are '.implode(
|
||||
' / ',
|
||||
array_keys($aBrowseModes)
|
||||
)
|
||||
);
|
||||
}
|
||||
if (empty($aLevelsProperties))
|
||||
{
|
||||
if (empty($aLevelsProperties)) {
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Browse brick "'.$sBrickId.'" : No levels to display.');
|
||||
}
|
||||
|
||||
// Building DBObjectSearch
|
||||
$oQuery = null;
|
||||
// ... In this case only we have to build a specific query for the current level only
|
||||
if (in_array($sBrowseMode, array(
|
||||
if (in_array($sBrowseMode, [
|
||||
BrowseBrick::ENUM_BROWSE_MODE_TREE,
|
||||
BrowseBrick::ENUM_BROWSE_MODE_MOSAIC,
|
||||
)) && ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY))
|
||||
{
|
||||
]) && ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY)) {
|
||||
// Will be handled later in the pagination part
|
||||
}
|
||||
// .. Otherwise
|
||||
else
|
||||
{
|
||||
else {
|
||||
// We iterate (in reverse mode /!\) over the levels to build the whole query, starting from the bottom
|
||||
$aLevelsPropertiesKeys = array_keys($aLevelsProperties);
|
||||
$iLoopMax = count($aLevelsPropertiesKeys) - 1;
|
||||
$oFullBinExpr = null;
|
||||
for ($i = $iLoopMax; $i >= 0; $i--)
|
||||
{
|
||||
for ($i = $iLoopMax; $i >= 0; $i--) {
|
||||
// Retrieving class alias for all depth
|
||||
array_unshift($aLevelsClasses, $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->GetClassAlias());
|
||||
|
||||
// Joining queries from bottom-up
|
||||
if ($i < $iLoopMax)
|
||||
{
|
||||
$aRealiasingMap = array();
|
||||
if ($i < $iLoopMax) {
|
||||
$aRealiasingMap = [];
|
||||
$oParentAtt = MetaModel::GetAttributeDef($aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['search']->GetClass(), $aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['parent_att']);
|
||||
// If we work on a n:n link
|
||||
if($oParentAtt instanceof AttributeLinkedSetIndirect)
|
||||
{
|
||||
if ($oParentAtt instanceof AttributeLinkedSetIndirect) {
|
||||
// Create a DBSearch from Link class
|
||||
$oSubSearch = new DBObjectSearch($oParentAtt->GetLinkedClass());
|
||||
// Join it to the bottom query
|
||||
$oSubSearch = $oSubSearch->Join($aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['search'],
|
||||
DBSearch::JOIN_POINTING_TO, $oParentAtt->GetExtKeyToMe(), TREE_OPERATOR_EQUALS, $aRealiasingMap);
|
||||
$oSubSearch = $oSubSearch->Join(
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['search'],
|
||||
DBSearch::JOIN_POINTING_TO,
|
||||
$oParentAtt->GetExtKeyToMe(),
|
||||
TREE_OPERATOR_EQUALS,
|
||||
$aRealiasingMap
|
||||
);
|
||||
// Join our Link class + bottom query to the up query
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] ->Join($oSubSearch, DBSearch::JOIN_REFERENCED_BY,
|
||||
$oParentAtt->GetExtKeyToRemote(), TREE_OPERATOR_EQUALS, $aRealiasingMap);
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] ->Join(
|
||||
$oSubSearch,
|
||||
DBSearch::JOIN_REFERENCED_BY,
|
||||
$oParentAtt->GetExtKeyToRemote(),
|
||||
TREE_OPERATOR_EQUALS,
|
||||
$aRealiasingMap
|
||||
);
|
||||
} else {
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->Join(
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['search'],
|
||||
DBSearch::JOIN_REFERENCED_BY,
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['parent_att'],
|
||||
TREE_OPERATOR_EQUALS,
|
||||
$aRealiasingMap
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->Join($aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['search'],
|
||||
DBSearch::JOIN_REFERENCED_BY, $aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['parent_att'],
|
||||
TREE_OPERATOR_EQUALS, $aRealiasingMap);
|
||||
}
|
||||
foreach ($aLevelsPropertiesKeys as $sLevelAlias)
|
||||
{
|
||||
if (array_key_exists($sLevelAlias, $aRealiasingMap))
|
||||
{
|
||||
foreach ($aLevelsPropertiesKeys as $sLevelAlias) {
|
||||
if (array_key_exists($sLevelAlias, $aRealiasingMap)) {
|
||||
/** @since 2.7.2 */
|
||||
foreach ($aRealiasingMap[$sLevelAlias] as $sAliasToChange)
|
||||
{
|
||||
foreach ($aRealiasingMap[$sLevelAlias] as $sAliasToChange) {
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->RenameAlias($sAliasToChange, $sLevelAlias);
|
||||
}
|
||||
}
|
||||
@@ -190,8 +194,7 @@ class BrowseBrickController extends BrickController
|
||||
|
||||
// Adding search clause
|
||||
// Note : For know the search is naive and looks only for the exact match. It doesn't search for words separately
|
||||
if (strlen($sSearchValue) > 0)
|
||||
{
|
||||
if (strlen($sSearchValue) > 0) {
|
||||
// - Cleaning the search value by exploding and trimming spaces
|
||||
$aExplodedSearchValues = explode(' ', $sSearchValue);
|
||||
$aSearchValues = [];
|
||||
@@ -202,25 +205,21 @@ class BrowseBrickController extends BrickController
|
||||
}
|
||||
|
||||
// - Retrieving fields to search
|
||||
$aSearchFields = array($aLevelsProperties[$aLevelsPropertiesKeys[$i]]['name_att']);
|
||||
if (!empty($aLevelsProperties[$aLevelsPropertiesKeys[$i]]['fields']))
|
||||
{
|
||||
$aSearchFields = [$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['name_att']];
|
||||
if (!empty($aLevelsProperties[$aLevelsPropertiesKeys[$i]]['fields'])) {
|
||||
$sTmpFieldClass = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->GetClass();
|
||||
foreach ($aLevelsProperties[$aLevelsPropertiesKeys[$i]]['fields'] as $aTmpField)
|
||||
{
|
||||
foreach ($aLevelsProperties[$aLevelsPropertiesKeys[$i]]['fields'] as $aTmpField) {
|
||||
$sTmpFieldAttCode = $aTmpField['code'];
|
||||
|
||||
// Skip invalid attcodes
|
||||
if(!MetaModel::IsValidAttCode($sTmpFieldClass, $sTmpFieldAttCode))
|
||||
{
|
||||
if (!MetaModel::IsValidAttCode($sTmpFieldClass, $sTmpFieldAttCode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For external key, force search on the friendlyname instead of the ID.
|
||||
// This should be addressed more globally with the bigger issue, see N°1970
|
||||
$oTmpFieldAttDef = MetaModel::GetAttributeDef($sTmpFieldClass, $sTmpFieldAttCode);
|
||||
if($oTmpFieldAttDef instanceof AttributeExternalKey)
|
||||
{
|
||||
if ($oTmpFieldAttDef instanceof AttributeExternalKey) {
|
||||
$sTmpFieldAttCode .= '_friendlyname';
|
||||
}
|
||||
|
||||
@@ -231,60 +230,49 @@ class BrowseBrickController extends BrickController
|
||||
$oLevelBinExpr = null;
|
||||
$iFieldLoopMax = count($aSearchFields) - 1;
|
||||
$iSearchLoopMax = count($aSearchValues) - 1;
|
||||
for ($j = 0; $j <= $iFieldLoopMax; $j++)
|
||||
{
|
||||
for ($j = 0; $j <= $iFieldLoopMax; $j++) {
|
||||
$sTmpFieldAttCode = $aSearchFields[$j];
|
||||
$oFieldBinExpr = null;
|
||||
//$oFieldBinExpr = new BinaryExpression(new FieldExpression($aSearchFields[$j], $aLevelsPropertiesKeys[$i]), )
|
||||
|
||||
for ($k = 0; $k <= $iSearchLoopMax; $k++)
|
||||
{
|
||||
$oSearchBinExpr = new BinaryExpression(new FieldExpression($sTmpFieldAttCode, $aLevelsPropertiesKeys[$i]),
|
||||
'LIKE', new VariableExpression('search_value_'.$k));
|
||||
if ($k === 0)
|
||||
{
|
||||
for ($k = 0; $k <= $iSearchLoopMax; $k++) {
|
||||
$oSearchBinExpr = new BinaryExpression(
|
||||
new FieldExpression($sTmpFieldAttCode, $aLevelsPropertiesKeys[$i]),
|
||||
'LIKE',
|
||||
new VariableExpression('search_value_'.$k)
|
||||
);
|
||||
if ($k === 0) {
|
||||
$oFieldBinExpr = $oSearchBinExpr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oFieldBinExpr = new BinaryExpression($oFieldBinExpr, 'AND', $oSearchBinExpr);
|
||||
}
|
||||
}
|
||||
|
||||
if ($j === 0)
|
||||
{
|
||||
if ($j === 0) {
|
||||
$oLevelBinExpr = $oFieldBinExpr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oLevelBinExpr = new BinaryExpression($oLevelBinExpr, 'OR', $oFieldBinExpr);
|
||||
}
|
||||
}
|
||||
|
||||
// - Building query for the level
|
||||
if ($i === $iLoopMax)
|
||||
{
|
||||
if ($i === $iLoopMax) {
|
||||
$oFullBinExpr = $oLevelBinExpr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oFullBinExpr = new BinaryExpression($oFullBinExpr, 'OR', $oLevelBinExpr);
|
||||
}
|
||||
|
||||
// - Adding it to the query when complete
|
||||
if ($i === 0)
|
||||
{
|
||||
if ($i === 0) {
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->AddConditionExpression($oFullBinExpr);
|
||||
}
|
||||
}
|
||||
|
||||
// Setting selected classes and binding parameters
|
||||
if ($i === 0)
|
||||
{
|
||||
if ($i === 0) {
|
||||
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->SetSelectedClasses($aLevelsClasses);
|
||||
|
||||
if (strlen($sSearchValue) > 0)
|
||||
{
|
||||
if (strlen($sSearchValue) > 0) {
|
||||
// Note : This could be way more simpler if we had a SetInternalParam($sParam, $value) verb
|
||||
$aQueryParams = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->GetInternalParams();
|
||||
// Note : $iSearchloopMax was initialized on the previous loop
|
||||
@@ -302,23 +290,26 @@ class BrowseBrickController extends BrickController
|
||||
// - Check how many records there is.
|
||||
// - Update $sDataLoading with its new value regarding the number of record and the threshold
|
||||
$oCountSet = new DBObjectSet($oQuery);
|
||||
$fThreshold = (float)MetaModel::GetModuleSetting($sPortalId,
|
||||
'lazy_loading_threshold');
|
||||
$fThreshold = (float)MetaModel::GetModuleSetting(
|
||||
$sPortalId,
|
||||
'lazy_loading_threshold'
|
||||
);
|
||||
$sDataLoading = ($oCountSet->Count() > $fThreshold) ? AbstractBrick::ENUM_DATA_LOADING_LAZY : AbstractBrick::ENUM_DATA_LOADING_FULL;
|
||||
unset($oCountSet);
|
||||
}
|
||||
}
|
||||
|
||||
// Setting query pagination if needed
|
||||
if ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY)
|
||||
{
|
||||
switch ($sBrowseMode)
|
||||
{
|
||||
if ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY) {
|
||||
switch ($sBrowseMode) {
|
||||
case BrowseBrick::ENUM_BROWSE_MODE_LIST:
|
||||
// Retrieving parameters
|
||||
$iPageNumber = (int)$this->oRequestManipulatorHelper->ReadParam('iPageNumber', 1, FILTER_SANITIZE_NUMBER_INT);
|
||||
$iListLength = (int)$this->oRequestManipulatorHelper->ReadParam('iListLength', BrowseBrick::DEFAULT_LIST_LENGTH,
|
||||
FILTER_SANITIZE_NUMBER_INT);
|
||||
$iListLength = (int)$this->oRequestManipulatorHelper->ReadParam(
|
||||
'iListLength',
|
||||
BrowseBrick::DEFAULT_LIST_LENGTH,
|
||||
FILTER_SANITIZE_NUMBER_INT
|
||||
);
|
||||
|
||||
// Getting total records number
|
||||
$oCountSet = new DBObjectSet($oQuery);
|
||||
@@ -337,36 +328,26 @@ class BrowseBrickController extends BrickController
|
||||
$sNodeId = $this->oRequestManipulatorHelper->ReadParam('sNodeId', '');
|
||||
|
||||
// If no values for those parameters, we might be loading page in lazy mode for the first time, therefore the URL doesn't have those information.
|
||||
if (empty($sLevelAlias))
|
||||
{
|
||||
if (empty($sLevelAlias)) {
|
||||
reset($aLevelsProperties);
|
||||
$oQuery = $aLevelsProperties[key($aLevelsProperties)]['search'];
|
||||
if (!empty($sNodeId))
|
||||
{
|
||||
if (!empty($sNodeId)) {
|
||||
$oQuery->AddCondition('id', $sNodeId);
|
||||
}
|
||||
}
|
||||
// Else we need to find the OQL for that particular level
|
||||
else
|
||||
{
|
||||
else {
|
||||
$bFoundLevel = false;
|
||||
foreach ($aLevelsProperties as $aLevelProperties)
|
||||
{
|
||||
if ($aLevelProperties['alias'] === $sLevelAlias)
|
||||
{
|
||||
if (isset($aLevelProperties['levels']) && !empty($aLevelProperties['levels']) && isset($aLevelsProperties[$aLevelProperties['levels'][0]]))
|
||||
{
|
||||
foreach ($aLevelsProperties as $aLevelProperties) {
|
||||
if ($aLevelProperties['alias'] === $sLevelAlias) {
|
||||
if (isset($aLevelProperties['levels']) && !empty($aLevelProperties['levels']) && isset($aLevelsProperties[$aLevelProperties['levels'][0]])) {
|
||||
$oQuery = $aLevelsProperties[$aLevelProperties['levels'][0]]['search'];
|
||||
if (!empty($sNodeId))
|
||||
{
|
||||
if (!empty($sNodeId)) {
|
||||
$sParentAttCode = $aLevelsProperties[$aLevelProperties['levels'][0]]['parent_att'];
|
||||
$oParentAtt = MetaModel::GetAttributeDef($oQuery->GetClass(), $sParentAttCode);
|
||||
if($oParentAtt instanceof AttributeLinkedSetIndirect)
|
||||
{
|
||||
if ($oParentAtt instanceof AttributeLinkedSetIndirect) {
|
||||
$oQuery->AddConditionAdvanced($sParentAttCode.'->'.$oParentAtt->GetExtKeyToRemote(), $sNodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oQuery->AddCondition($sParentAttCode, $sNodeId);
|
||||
}
|
||||
}
|
||||
@@ -376,10 +357,11 @@ class BrowseBrickController extends BrickController
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bFoundLevel)
|
||||
{
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Browse brick "'.$sBrickId.'" : Level alias "'.$sLevelAlias.'" is not defined for that brick.');
|
||||
if (!$bFoundLevel) {
|
||||
throw new HttpException(
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Browse brick "'.$sBrickId.'" : Level alias "'.$sLevelAlias.'" is not defined for that brick.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,34 +376,26 @@ class BrowseBrickController extends BrickController
|
||||
$oSet = new DBObjectSet($oQuery);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oSet = new DBObjectSet($oQuery);
|
||||
}
|
||||
|
||||
// Optimizing the ObjectSet to retrieve only necessary columns
|
||||
$aColumnAttrs = array();
|
||||
foreach ($oSet->GetFilter()->GetSelectedClasses() as $sTmpClassAlias => $sTmpClassName)
|
||||
{
|
||||
if (isset($aLevelsProperties[$sTmpClassAlias]))
|
||||
{
|
||||
$aColumnAttrs = [];
|
||||
foreach ($oSet->GetFilter()->GetSelectedClasses() as $sTmpClassAlias => $sTmpClassName) {
|
||||
if (isset($aLevelsProperties[$sTmpClassAlias])) {
|
||||
$aTmpLevelProperties = $aLevelsProperties[$sTmpClassAlias];
|
||||
// Mandatory main attribute
|
||||
$aTmpColumnAttrs = array($aTmpLevelProperties['name_att']);
|
||||
$aTmpColumnAttrs = [$aTmpLevelProperties['name_att']];
|
||||
// Optional attributes, only if in list mode
|
||||
if ($sBrowseMode === BrowseBrick::ENUM_BROWSE_MODE_LIST)
|
||||
{
|
||||
foreach ($aTmpLevelProperties['fields'] as $aTmpField)
|
||||
{
|
||||
if ($sBrowseMode === BrowseBrick::ENUM_BROWSE_MODE_LIST) {
|
||||
foreach ($aTmpLevelProperties['fields'] as $aTmpField) {
|
||||
$aTmpColumnAttrs[] = $aTmpField['code'];
|
||||
}
|
||||
}
|
||||
// Optional attributes
|
||||
foreach (BrowseBrickHelper::OPTIONAL_ATTRIBUTES as $sOptionalAttribute)
|
||||
{
|
||||
if ($aTmpLevelProperties[$sOptionalAttribute] !== null)
|
||||
{
|
||||
foreach (BrowseBrickHelper::OPTIONAL_ATTRIBUTES as $sOptionalAttribute) {
|
||||
if ($aTmpLevelProperties[$sOptionalAttribute] !== null) {
|
||||
$aTmpColumnAttrs[] = $aTmpLevelProperties[$sOptionalAttribute];
|
||||
}
|
||||
}
|
||||
@@ -434,20 +408,15 @@ class BrowseBrickController extends BrickController
|
||||
|
||||
// Setting specified column sort, setting default datamodel one otherwise
|
||||
$aSortedParams = $this->oBrickControllerHelper->ExtractSortParams();
|
||||
if (!empty($aSortedParams))
|
||||
{
|
||||
if (!empty($aSortedParams)) {
|
||||
$oSet->SetOrderBy($aSortedParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oSet->SetOrderByClasses();
|
||||
}
|
||||
// Retrieving results and organizing them for templating
|
||||
$aItems = array();
|
||||
while ($aCurrentRow = $oSet->FetchAssoc())
|
||||
{
|
||||
switch ($sBrowseMode)
|
||||
{
|
||||
$aItems = [];
|
||||
while ($aCurrentRow = $oSet->FetchAssoc()) {
|
||||
switch ($sBrowseMode) {
|
||||
case BrowseBrick::ENUM_BROWSE_MODE_TREE:
|
||||
case BrowseBrick::ENUM_BROWSE_MODE_MOSAIC:
|
||||
$this->oBrowseBrickHelper->AddToTreeItems($aItems, $aCurrentRow, $aLevelsProperties, null);
|
||||
@@ -460,22 +429,21 @@ class BrowseBrickController extends BrickController
|
||||
}
|
||||
}
|
||||
|
||||
IssueLog::Debug('Portal BrowseBrick query', LogChannels::PORTAL, array(
|
||||
IssueLog::Debug('Portal BrowseBrick query', LogChannels::PORTAL, [
|
||||
'sPortalId' => $sPortalId,
|
||||
'sBrickId' => $sBrickId,
|
||||
'oql' => $oSet->GetFilter()->ToOQL(),
|
||||
));
|
||||
|
||||
]);
|
||||
|
||||
// Preparing response
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aData = $aData + array(
|
||||
$aData = $aData + [
|
||||
'data' => $aItems,
|
||||
'levelsProperties' => $aLevelsProperties,
|
||||
);
|
||||
];
|
||||
$oResponse = new JsonResponse($aData);
|
||||
} else {
|
||||
$aData = $aData + array(
|
||||
$aData = $aData + [
|
||||
'oBrick' => $oBrick,
|
||||
'sBrickId' => $sBrickId,
|
||||
'sBrowseMode' => $sBrowseMode,
|
||||
@@ -486,7 +454,7 @@ class BrowseBrickController extends BrickController
|
||||
'iItemsCount' => count($aItems),
|
||||
'aLevelsProperties' => json_encode($aLevelsProperties),
|
||||
'iDefaultLengthList' => $oBrick->GetDefaultListLength(),
|
||||
);
|
||||
];
|
||||
|
||||
// Note : To extend this brick's template, depending on what you want to do :
|
||||
// a) Modify the whole template :
|
||||
@@ -495,13 +463,10 @@ class BrowseBrickController extends BrickController
|
||||
// - Create a template for that browse mode,
|
||||
// - Add the mode to those available in the brick configuration,
|
||||
// - Create a router and add a route for the new browse mode
|
||||
if ($oBrick->HasInstanceOverriddenTemplate('page'))
|
||||
{
|
||||
if ($oBrick->HasInstanceOverriddenTemplate('page')) {
|
||||
$sTemplatePath = $oBrick->GetTemplatePath('page');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sTemplatePath = $oBrick->GetTemplatePath('page_' .$sBrowseMode);
|
||||
} else {
|
||||
$sTemplatePath = $oBrick->GetTemplatePath('page_'.$sBrowseMode);
|
||||
}
|
||||
$oResponse = $this->render($sTemplatePath, $aData);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
*/
|
||||
class CreateBrickController extends BrickController
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -43,8 +42,7 @@ class CreateBrickController extends BrickController
|
||||
*/
|
||||
public function __construct(
|
||||
protected BrickCollection $oBrickCollection
|
||||
)
|
||||
{
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,16 +58,15 @@ class CreateBrickController extends BrickController
|
||||
/** @var \Combodo\iTop\Portal\Brick\CreateBrick $oBrick */
|
||||
$oBrick = $this->oBrickCollection->GetBrickById($sBrickId);
|
||||
|
||||
$aRouteParams = array(
|
||||
$aRouteParams = [
|
||||
'sBrickId' => $sBrickId,
|
||||
'sObjectClass' => $oBrick->GetClass(),
|
||||
'ar_token' => null,
|
||||
);
|
||||
];
|
||||
|
||||
// Checking for actions rules
|
||||
$aRules = $oBrick->GetRules();
|
||||
if (!empty($aRules))
|
||||
{
|
||||
if (!empty($aRules)) {
|
||||
$aRouteParams['ar_token'] = ContextManipulatorHelper::PrepareAndEncodeRulesToken($aRules);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,9 @@ class DefaultController extends AbstractController
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('home', static::TEMPLATES_BASE_PATH . 'home/layout.html.twig'),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('home', static::TEMPLATES_BASE_PATH.'home/layout.html.twig'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,26 +54,24 @@ class DefaultController extends AbstractController
|
||||
*/
|
||||
public function HomeAction(Request $oRequest, BrickCollection $oBricksCollection)
|
||||
{
|
||||
$aData = array();
|
||||
$aData = [];
|
||||
|
||||
// Rendering tiles
|
||||
$aData['aTilesRendering'] = array();
|
||||
foreach ($oBricksCollection->GetBricks() as $oBrick)
|
||||
{
|
||||
$aData['aTilesRendering'] = [];
|
||||
foreach ($oBricksCollection->GetBricks() as $oBrick) {
|
||||
// Doing it only for tile visible on home page to avoid unnecessary rendering
|
||||
if (($oBrick->GetVisibleHome() === true) && ($oBrick->GetTileControllerAction() !== null))
|
||||
{
|
||||
if (($oBrick->GetVisibleHome() === true) && ($oBrick->GetTileControllerAction() !== null)) {
|
||||
$aControllerActionParts = explode('::', $oBrick->GetTileControllerAction());
|
||||
if (count($aControllerActionParts) !== 2)
|
||||
{
|
||||
return new Response('Tile controller action must be of form "\Namespace\ControllerClass::FunctionName" for brick "'.$oBrick->GetId().'"',
|
||||
500);
|
||||
if (count($aControllerActionParts) !== 2) {
|
||||
return new Response(
|
||||
'Tile controller action must be of form "\Namespace\ControllerClass::FunctionName" for brick "'.$oBrick->GetId().'"',
|
||||
500
|
||||
);
|
||||
}
|
||||
|
||||
$aRouteParams = array();
|
||||
$aRouteParams = [];
|
||||
// Add sBrickId in the route params as it is necessary for each brick actions
|
||||
if (is_a($aControllerActionParts[0], BrickController::class, true))
|
||||
{
|
||||
if (is_a($aControllerActionParts[0], BrickController::class, true)) {
|
||||
$aRouteParams['sBrickId'] = $oBrick->GetId();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,18 +72,19 @@ use utils;
|
||||
*/
|
||||
class ManageBrickController extends BrickController
|
||||
{
|
||||
/**
|
||||
* @var string EXCEL_EXPORT_TEMPLATE_PATH
|
||||
/**
|
||||
* @var string EXCEL_EXPORT_TEMPLATE_PATH
|
||||
* @deprecated since 3.2.1
|
||||
*/
|
||||
const EXCEL_EXPORT_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/popup-export-excel.html.twig';
|
||||
|
||||
public const EXCEL_EXPORT_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/popup-export-excel.html.twig';
|
||||
|
||||
/** @inheritdoc */
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
|
||||
{
|
||||
parent::RegisterTemplates($oTemplatesRegister);
|
||||
$oTemplatesRegister->RegisterTemplates(self::class,
|
||||
TemplateDefinitionDto::Create('modal_export_excel', static::TEMPLATES_BASE_PATH . 'bricks/manage/popup-export-excel.html.twig'),
|
||||
$oTemplatesRegister->RegisterTemplates(
|
||||
self::class,
|
||||
TemplateDefinitionDto::Create('modal_export_excel', static::TEMPLATES_BASE_PATH.'bricks/manage/popup-export-excel.html.twig'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,8 +105,7 @@ class ManageBrickController extends BrickController
|
||||
protected RequestManipulatorHelper $oRequestManipulatorHelper,
|
||||
protected SecurityHelper $oSecurityHelper,
|
||||
protected BrickControllerHelper $oBrickControllerHelper
|
||||
)
|
||||
{
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
@@ -138,17 +138,15 @@ class ManageBrickController extends BrickController
|
||||
$aData = $this->GetData($oRequest, $sBrickId, $sGroupingTab, $oBrick->IsDetailsNeeded($sDisplayMode));
|
||||
|
||||
$aExportFields = $oBrick->GetExportFields();
|
||||
$aData = $aData + array(
|
||||
$aData = $aData + [
|
||||
'sDisplayMode' => $sDisplayMode,
|
||||
'bCanExport' => !empty($aExportFields),
|
||||
'iDefaultListLength' => $oBrick->GetDefaultListLength(),
|
||||
);
|
||||
];
|
||||
// Preparing response
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oResponse = new JsonResponse($aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sLayoutTemplate = $oBrick->GetPageTemplate($sDisplayMode);
|
||||
$oResponse = $this->render($sLayoutTemplate, $aData);
|
||||
}
|
||||
@@ -171,14 +169,11 @@ class ManageBrickController extends BrickController
|
||||
/** @var \Combodo\iTop\Portal\Brick\ManageBrick $oBrick */
|
||||
$oBrick = $this->oBrickCollection->GetBrickById($sBrickId);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
$aData = $this->GetData($oRequest, $sBrickId, null);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
// TODO Default values
|
||||
$aData = array();
|
||||
$aData = [];
|
||||
}
|
||||
|
||||
return $this->render($oBrick->GetTileTemplate(), $aData);
|
||||
@@ -210,37 +205,28 @@ class ManageBrickController extends BrickController
|
||||
$sClass = $oQuery->GetClass();
|
||||
$aData = $this->GetData($oRequest, $sBrickId, $sGroupingTab, true);
|
||||
|
||||
if (isset($aData['aQueries']) && count($aData['aQueries']) === 1)
|
||||
{
|
||||
if (isset($aData['aQueries']) && count($aData['aQueries']) === 1) {
|
||||
$aQueries = $aData['aQueries'];
|
||||
reset($aQueries);
|
||||
$sKey = key($aQueries);
|
||||
$oSearch = $aData['aQueries'][$sKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->oScopeValidatorHelper->AddScopeToQuery($oQuery, $sClass);
|
||||
$aData = array();
|
||||
$aData = [];
|
||||
$this->ManageSearchValue($aData, $oQuery, $sClass);
|
||||
|
||||
// Grouping tab
|
||||
if ($oBrick->HasGroupingTabs())
|
||||
{
|
||||
if ($oBrick->HasGroupingTabs()) {
|
||||
$aGroupingTabs = $oBrick->GetGroupingTabs();
|
||||
|
||||
// If tabs are made of the distinct values of an attribute, we have a find them via a query
|
||||
if ($oBrick->IsGroupingTabsByDistinctValues())
|
||||
{
|
||||
if ($oBrick->IsGroupingTabsByDistinctValues()) {
|
||||
$sGroupingTabAttCode = $aGroupingTabs['attribute'];
|
||||
$aGroupingTabsValues = $this->GroupByAttribute($oQuery, $sGroupingTabAttCode, $oBrick);
|
||||
$oQuery = $oQuery->Intersect($aGroupingTabsValues[$sGroupingTab]['condition']);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($aGroupingTabs['groups'] as $aGroup)
|
||||
{
|
||||
if ($aGroup['id'] === $sGroupingTab)
|
||||
{
|
||||
} else {
|
||||
foreach ($aGroupingTabs['groups'] as $aGroup) {
|
||||
if ($aGroup['id'] === $sGroupingTab) {
|
||||
$oConditionQuery = $oQuery->Intersect(DBSearch::FromOQL($aGroup['condition']));
|
||||
$oQuery = $oQuery->Intersect($oConditionQuery);
|
||||
break;
|
||||
@@ -251,29 +237,27 @@ class ManageBrickController extends BrickController
|
||||
|
||||
// Finalclass
|
||||
$oConditionQuery = DBSearch::CloneWithAlias($oQuery, 'GARE');
|
||||
$oExpression = new BinaryExpression(new FieldExpression('finalclass', 'GARE'), '=',
|
||||
new UnaryExpression($sGroupingArea));
|
||||
$oExpression = new BinaryExpression(
|
||||
new FieldExpression('finalclass', 'GARE'),
|
||||
'=',
|
||||
new UnaryExpression($sGroupingArea)
|
||||
);
|
||||
$oConditionQuery->AddConditionExpression($oExpression);
|
||||
/** @var DBSearch $oSearch */
|
||||
$oSearch = $oQuery->Intersect($oConditionQuery);
|
||||
}
|
||||
|
||||
$aColumnsAttrs = $oBrick->GetExportFields();
|
||||
$aFields = array();
|
||||
$aFields = [];
|
||||
$sTitleAttrCode = 'friendlyname';
|
||||
if (!in_array($sTitleAttrCode, $aColumnsAttrs))
|
||||
{
|
||||
if (!in_array($sTitleAttrCode, $aColumnsAttrs)) {
|
||||
$aFields[] = $sTitleAttrCode;
|
||||
}
|
||||
foreach ($aColumnsAttrs as $sAttCode)
|
||||
{
|
||||
foreach ($aColumnsAttrs as $sAttCode) {
|
||||
$oAttributeDef = MetaModel::GetAttributeDef($sGroupingArea, $sAttCode);
|
||||
if ($oAttributeDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
||||
{
|
||||
if ($oAttributeDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
|
||||
$aFields[] = $sAttCode.'_friendlyname';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aFields[] = $sAttCode;
|
||||
}
|
||||
}
|
||||
@@ -288,12 +272,12 @@ class ManageBrickController extends BrickController
|
||||
$oExporter->SetLocalizeOutput(true);
|
||||
$oExporter->SetFields($sFields);
|
||||
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'oBrick' => $oBrick,
|
||||
'sBrickId' => $sBrickId,
|
||||
'sToken' => $oExporter->SaveState(),
|
||||
'sWikiUrl' => 'https://www.itophub.io/wiki/page?id='.utils::GetItopVersionWikiSyntax().'%3Auser%3Alists#excel_export',
|
||||
);
|
||||
'sWikiUrl' => 'https://www.itophub.io/wiki/page?id='.utils::GetItopVersionWikiSyntax().'%3Auser%3Alists#excel_export',
|
||||
];
|
||||
|
||||
return $this->render($this->GetTemplatePath('modal_export_excel'), $aData);
|
||||
}
|
||||
@@ -323,10 +307,10 @@ class ManageBrickController extends BrickController
|
||||
/** @var \Combodo\iTop\Portal\Brick\ManageBrick $oBrick */
|
||||
$oBrick = $this->oBrickCollection->GetBrickById($sBrickId);
|
||||
|
||||
$aData = array();
|
||||
$aGroupingTabsValues = array();
|
||||
$aGroupingAreasValues = array();
|
||||
$aQueries = array();
|
||||
$aData = [];
|
||||
$aGroupingTabsValues = [];
|
||||
$aGroupingAreasValues = [];
|
||||
$aQueries = [];
|
||||
$bHasScope = true;
|
||||
|
||||
// Getting current data loading mode (First from router parameter, then query parameter, then default brick value)
|
||||
@@ -334,8 +318,7 @@ class ManageBrickController extends BrickController
|
||||
|
||||
// - Retrieving the grouping areas to display
|
||||
$sGroupingArea = $this->oRequestManipulatorHelper->ReadParam('sGroupingArea', '');
|
||||
if (!empty($sGroupingArea))
|
||||
{
|
||||
if (!empty($sGroupingArea)) {
|
||||
$bNeedDetails = true;
|
||||
}
|
||||
|
||||
@@ -343,9 +326,8 @@ class ManageBrickController extends BrickController
|
||||
$aColumnsAttrs = $oBrick->GetFields();
|
||||
// Adding friendlyname attribute to the list if not already in it
|
||||
$sTitleAttrCode = 'friendlyname';
|
||||
if (($sTitleAttrCode !== null) && !in_array($sTitleAttrCode, $aColumnsAttrs))
|
||||
{
|
||||
$aColumnsAttrs = array_merge(array($sTitleAttrCode), $aColumnsAttrs);
|
||||
if (($sTitleAttrCode !== null) && !in_array($sTitleAttrCode, $aColumnsAttrs)) {
|
||||
$aColumnsAttrs = array_merge([$sTitleAttrCode], $aColumnsAttrs);
|
||||
}
|
||||
|
||||
// Starting to build query
|
||||
@@ -356,100 +338,78 @@ class ManageBrickController extends BrickController
|
||||
// Preparing tabs
|
||||
// - We need to retrieve distinct values for the grouping attribute
|
||||
$iCount = 0;
|
||||
if ($oBrick->HasGroupingTabs())
|
||||
{
|
||||
if ($oBrick->HasGroupingTabs()) {
|
||||
$aGroupingTabs = $oBrick->GetGroupingTabs();
|
||||
|
||||
// If tabs are made of the distinct values of an attribute, we have a find them via a query
|
||||
if ($oBrick->IsGroupingTabsByDistinctValues())
|
||||
{
|
||||
if ($oBrick->IsGroupingTabsByDistinctValues()) {
|
||||
$sGroupingTabAttCode = $aGroupingTabs['attribute'];
|
||||
$aGroupingTabsValues = $this->GroupByAttribute($oQuery, $sGroupingTabAttCode, $oBrick);
|
||||
foreach ($aGroupingTabsValues as $aResult)
|
||||
{
|
||||
foreach ($aGroupingTabsValues as $aResult) {
|
||||
$iCount += $aResult['count'];
|
||||
}
|
||||
}
|
||||
// Otherwise we create the tabs from the SQL expressions
|
||||
else
|
||||
{
|
||||
$aConditionQueryGrouping = array();
|
||||
foreach ($aGroupingTabs['groups'] as $aGroup)
|
||||
{
|
||||
else {
|
||||
$aConditionQueryGrouping = [];
|
||||
foreach ($aGroupingTabs['groups'] as $aGroup) {
|
||||
$oDBSearch = DBSearch::FromOQL($aGroup['condition']);
|
||||
$oConditionQuery = $oQuery->Intersect($oDBSearch);
|
||||
// - Restricting query to scope
|
||||
array_push($aConditionQueryGrouping,$oDBSearch);
|
||||
array_push($aConditionQueryGrouping, $oDBSearch);
|
||||
$bHasScope = $this->oScopeValidatorHelper->AddScopeToQuery($oConditionQuery, $oConditionQuery->GetClass());
|
||||
if ($bHasScope)
|
||||
{
|
||||
if ($bHasScope) {
|
||||
// - Building ObjectSet
|
||||
$oConditionSet = new DBObjectSet($oConditionQuery);
|
||||
$iGroupCount = $oConditionSet->Count();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oConditionSet = null;
|
||||
$iGroupCount = 0;
|
||||
}
|
||||
$aGroupingTabsValues[$aGroup['id']] = array(
|
||||
$aGroupingTabsValues[$aGroup['id']] = [
|
||||
'value' => $aGroup['id'],
|
||||
'label' => Dict::S($aGroup['title']),
|
||||
'label_html' => Dict::S($aGroup['title']),
|
||||
'description' => array_key_exists('description',$aGroup) ? Dict::S($aGroup['description']) : null,
|
||||
'description' => array_key_exists('description', $aGroup) ? Dict::S($aGroup['description']) : null,
|
||||
'condition' => $oConditionQuery,
|
||||
'count' => $iGroupCount,
|
||||
);
|
||||
];
|
||||
}
|
||||
try
|
||||
{
|
||||
try {
|
||||
$oConditionQuery = $oQuery->Intersect(new DBUnionSearch($aConditionQueryGrouping));
|
||||
$bHasScope = $this->oScopeValidatorHelper->AddScopeToQuery($oConditionQuery, $oConditionQuery->GetClass());
|
||||
if ($bHasScope)
|
||||
{
|
||||
if ($bHasScope) {
|
||||
// - Building ObjectSet
|
||||
$oConditionSet = new DBObjectSet($oConditionQuery);
|
||||
$iCount = $oConditionSet->Count();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oConditionSet = null;
|
||||
$iCount = 0;
|
||||
}
|
||||
}
|
||||
catch (Exception $e){
|
||||
} catch (Exception $e) {
|
||||
$oConditionSet = null;
|
||||
$iCount = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oConditionQuery = $this->GetScopedQuery($oBrick, $sClass);
|
||||
if (!is_null($oConditionQuery))
|
||||
{
|
||||
if (!is_null($oConditionQuery)) {
|
||||
$oSet = new DBObjectSet($oConditionQuery);
|
||||
$iCount = $oSet->Count();
|
||||
}
|
||||
}
|
||||
|
||||
// - Retrieving the current grouping tab to display if necessary and altering the query to do so
|
||||
if (empty($sGroupingTab))
|
||||
{
|
||||
if ($oBrick->HasGroupingTabs())
|
||||
{
|
||||
if (empty($sGroupingTab)) {
|
||||
if ($oBrick->HasGroupingTabs()) {
|
||||
reset($aGroupingTabsValues);
|
||||
$sGroupingTab = key($aGroupingTabsValues);
|
||||
if ($aGroupingTabsValues[$sGroupingTab]['condition'] !== null)
|
||||
{
|
||||
if ($aGroupingTabsValues[$sGroupingTab]['condition'] !== null) {
|
||||
$oQuery = $aGroupingTabsValues[$sGroupingTab]['condition']->DeepClone();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($aGroupingTabsValues[$sGroupingTab]['condition'] !== null)
|
||||
{
|
||||
} else {
|
||||
if ($aGroupingTabsValues[$sGroupingTab]['condition'] !== null) {
|
||||
$oQuery = $aGroupingTabsValues[$sGroupingTab]['condition']->DeepClone();
|
||||
}
|
||||
}
|
||||
@@ -464,60 +424,56 @@ class ManageBrickController extends BrickController
|
||||
// - We need to retrieve distinct values for the grouping attribute
|
||||
// Note : Will have to be changed when we consider grouping on something else than the finalclass
|
||||
$sParentAlias = $oQuery->GetClassAlias();
|
||||
if ($bNeedDetails)
|
||||
{
|
||||
if ($bNeedDetails) {
|
||||
$sGroupingAreaAttCode = 'finalclass';
|
||||
|
||||
// For root classes
|
||||
if (MetaModel::IsValidAttCode($sClass, $sGroupingAreaAttCode))
|
||||
{
|
||||
if (MetaModel::IsValidAttCode($sClass, $sGroupingAreaAttCode)) {
|
||||
$oDistinctQuery = $this->GetScopedQuery($oBrick, $sClass);
|
||||
// Adding grouping conditions
|
||||
$oFieldExp = new FieldExpression($sGroupingAreaAttCode, $oDistinctQuery->GetClassAlias());
|
||||
$sDistinctSql = $oDistinctQuery->MakeGroupByQuery(array(), array('grouped_by_1' => $oFieldExp), true);
|
||||
$sDistinctSql = $oDistinctQuery->MakeGroupByQuery([], ['grouped_by_1' => $oFieldExp], true);
|
||||
$aDistinctResults = CMDBSource::QueryToArray($sDistinctSql);
|
||||
|
||||
foreach ($aDistinctResults as $aDistinctResult)
|
||||
{
|
||||
foreach ($aDistinctResults as $aDistinctResult) {
|
||||
$oConditionQuery = DBSearch::CloneWithAlias($oQuery, 'GARE');
|
||||
$oExpression = new BinaryExpression(new FieldExpression($sGroupingAreaAttCode, 'GARE'), '=',
|
||||
new UnaryExpression($aDistinctResult['grouped_by_1']));
|
||||
$oExpression = new BinaryExpression(
|
||||
new FieldExpression($sGroupingAreaAttCode, 'GARE'),
|
||||
'=',
|
||||
new UnaryExpression($aDistinctResult['grouped_by_1'])
|
||||
);
|
||||
$oConditionQuery->AddConditionExpression($oExpression);
|
||||
|
||||
$aGroupingAreasValues[$aDistinctResult['grouped_by_1']] = array(
|
||||
$aGroupingAreasValues[$aDistinctResult['grouped_by_1']] = [
|
||||
'value' => $aDistinctResult['grouped_by_1'],
|
||||
'label' => MetaModel::GetName($aDistinctResult['grouped_by_1']),
|
||||
// Caution : This works only because we froze the grouping areas on the finalclass attribute.
|
||||
'condition' => $oConditionQuery,
|
||||
'count' => $aDistinctResult['_itop_count_'],
|
||||
);
|
||||
];
|
||||
unset($oConditionQuery);
|
||||
}
|
||||
unset($aDistinctResults);
|
||||
}
|
||||
// For leaf classes
|
||||
else
|
||||
{
|
||||
$aGroupingAreasValues[$sClass] = array(
|
||||
else {
|
||||
$aGroupingAreasValues[$sClass] = [
|
||||
'value' => $sClass,
|
||||
'label' => MetaModel::GetName($sClass),
|
||||
// Caution : This works only because we froze the grouping areas on the finalclass attribute.
|
||||
'condition' => null,
|
||||
'count' => 0,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
// - If specified or lazy loading, we truncate the $aGroupingAreasValues to keep only this one
|
||||
if (!empty($sGroupingArea))
|
||||
{
|
||||
$aGroupingAreasValues = array($sGroupingArea => $aGroupingAreasValues[$sGroupingArea]);
|
||||
if (!empty($sGroupingArea)) {
|
||||
$aGroupingAreasValues = [$sGroupingArea => $aGroupingAreasValues[$sGroupingArea]];
|
||||
}
|
||||
// - Preparing the queries
|
||||
foreach ($aGroupingAreasValues as $sKey => $aGroupingAreasValue)
|
||||
{
|
||||
foreach ($aGroupingAreasValues as $sKey => $aGroupingAreasValue) {
|
||||
$oAreaQuery = DBSearch::CloneWithAlias($oQuery, $sParentAlias);
|
||||
if ($aGroupingAreasValue['condition'] !== null)
|
||||
{
|
||||
if ($aGroupingAreasValue['condition'] !== null) {
|
||||
$oAreaQuery = $aGroupingAreasValue['condition']->DeepClone();
|
||||
}
|
||||
|
||||
@@ -525,8 +481,7 @@ class ManageBrickController extends BrickController
|
||||
// Note: Will need to moved the scope restriction on queries elsewhere when we consider grouping on something else than finalclass
|
||||
// Note: We now get view scope instead of edit scope as we allowed users to view/edit objects in the brick regarding their rights
|
||||
$bHasScope = $this->oScopeValidatorHelper->AddScopeToQuery($oAreaQuery, $aGroupingAreasValue['value']);
|
||||
if (!$bHasScope)
|
||||
{
|
||||
if (!$bHasScope) {
|
||||
// if no scope apply does not allow any data
|
||||
$oAreaQuery = null;
|
||||
}
|
||||
@@ -538,71 +493,64 @@ class ManageBrickController extends BrickController
|
||||
|
||||
// Testing appropriate data loading mode if we are in auto
|
||||
// - For all (html) tables, this doesn't care for the grouping ares (finalclass)
|
||||
if ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_AUTO)
|
||||
{
|
||||
if ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_AUTO) {
|
||||
// - Check how many records there is.
|
||||
// - Update $sDataLoading with its new value regarding the number of record and the threshold
|
||||
$oCountSet = new DBObjectSet($oQuery);
|
||||
$oCountSet->OptimizeColumnLoad(array($oQuery->GetClassAlias() => array()));
|
||||
$fThreshold = (float)MetaModel::GetModuleSetting($sPortalId,
|
||||
'lazy_loading_threshold');
|
||||
$oCountSet->OptimizeColumnLoad([$oQuery->GetClassAlias() => []]);
|
||||
$fThreshold = (float)MetaModel::GetModuleSetting(
|
||||
$sPortalId,
|
||||
'lazy_loading_threshold'
|
||||
);
|
||||
$sDataLoading = ($oCountSet->Count() > $fThreshold) ? AbstractBrick::ENUM_DATA_LOADING_LAZY : AbstractBrick::ENUM_DATA_LOADING_FULL;
|
||||
unset($oCountSet);
|
||||
}
|
||||
|
||||
// Preparing data sets
|
||||
$aSets = array();
|
||||
$aSets = [];
|
||||
/** @var DBSearch $oQuery */
|
||||
foreach ($aQueries as $sKey => $oQuery)
|
||||
{
|
||||
foreach ($aQueries as $sKey => $oQuery) {
|
||||
// Checking if we have a valid query
|
||||
if ($oQuery !== null)
|
||||
{
|
||||
if ($oQuery !== null) {
|
||||
// - Adding search clause if necessary
|
||||
$this->ManageSearchValue($aData, $oQuery, $sKey, $aColumnsAttrs);
|
||||
|
||||
|
||||
// Setting query pagination if needed
|
||||
if ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY)
|
||||
{
|
||||
if ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY) {
|
||||
// Retrieving parameters
|
||||
$iPageNumber = (int)$this->oRequestManipulatorHelper->ReadParam('iPageNumber', 1, FILTER_SANITIZE_NUMBER_INT);
|
||||
$iListLength = (int)$this->oRequestManipulatorHelper->ReadParam('iListLength', ManageBrick::DEFAULT_LIST_LENGTH,
|
||||
FILTER_SANITIZE_NUMBER_INT);
|
||||
$iListLength = (int)$this->oRequestManipulatorHelper->ReadParam(
|
||||
'iListLength',
|
||||
ManageBrick::DEFAULT_LIST_LENGTH,
|
||||
FILTER_SANITIZE_NUMBER_INT
|
||||
);
|
||||
|
||||
// Getting total records number
|
||||
$oCountSet = new DBObjectSet($oQuery);
|
||||
$oCountSet->OptimizeColumnLoad(array($oQuery->GetClassAlias() => $aColumnsAttrs));
|
||||
$oCountSet->OptimizeColumnLoad([$oQuery->GetClassAlias() => $aColumnsAttrs]);
|
||||
$aData['recordsTotal'] = $oCountSet->Count();
|
||||
$aData['recordsFiltered'] = $oCountSet->Count();
|
||||
unset($oCountSet);
|
||||
|
||||
$oSet = new DBObjectSet($oQuery);
|
||||
$oSet->SetLimit($iListLength, $iListLength * ($iPageNumber - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oSet = new DBObjectSet($oQuery);
|
||||
}
|
||||
|
||||
// Setting specified column sort, setting default datamodel one otherwise
|
||||
if (!empty($aSortedParams))
|
||||
{
|
||||
if (!empty($aSortedParams)) {
|
||||
$oSet->SetOrderBy($aSortedParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oSet->SetOrderByClasses();
|
||||
}
|
||||
|
||||
// Adding always_in_tables attributes
|
||||
$aColumnsToLoad = array($oQuery->GetClassAlias() => $aColumnsAttrs);
|
||||
foreach ($oQuery->GetSelectedClasses() as $sAlias => $sClassSelected)
|
||||
{
|
||||
$aColumnsToLoad = [$oQuery->GetClassAlias() => $aColumnsAttrs];
|
||||
foreach ($oQuery->GetSelectedClasses() as $sAlias => $sClassSelected) {
|
||||
/** @var AttributeDefinition $oAttDef */
|
||||
foreach (MetaModel::ListAttributeDefs($sClassSelected) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef->AlwaysLoadInTables())
|
||||
{
|
||||
foreach (MetaModel::ListAttributeDefs($sClassSelected) as $sAttCode => $oAttDef) {
|
||||
if ($oAttDef->AlwaysLoadInTables()) {
|
||||
$aColumnsToLoad[$sAlias][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
@@ -610,17 +558,18 @@ class ManageBrickController extends BrickController
|
||||
// Note: $aColumnToLoad already contains array of aliases => attcodes
|
||||
$oSet->OptimizeColumnLoad($aColumnsToLoad);
|
||||
|
||||
$this->oSecurityHelper->PreloadForCache($oSet->GetFilter(),
|
||||
$aColumnsToLoad[$oQuery->GetClassAlias()] /* preloading only extkeys from the main class */);
|
||||
$this->oSecurityHelper->PreloadForCache(
|
||||
$oSet->GetFilter(),
|
||||
$aColumnsToLoad[$oQuery->GetClassAlias()] /* preloading only extkeys from the main class */
|
||||
);
|
||||
$aSets[$sKey] = $oSet;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieving and preparing data for rendering
|
||||
$aGroupingAreasData = array();
|
||||
$aGroupingAreasData = [];
|
||||
$bHasObjectListItemExtension = false;
|
||||
foreach ($aSets as $sKey => $oSet)
|
||||
{
|
||||
foreach ($aSets as $sKey => $oSet) {
|
||||
// Set properties
|
||||
$sCurrentClass = $sKey;
|
||||
|
||||
@@ -628,94 +577,88 @@ class ManageBrickController extends BrickController
|
||||
$sMainActionAttrCode = $aColumnsAttrs[0];
|
||||
|
||||
// Loading columns definition
|
||||
$aColumnsDefinition = array();
|
||||
foreach ($aColumnsAttrs as $sColumnAttr)
|
||||
{
|
||||
$aColumnsDefinition = [];
|
||||
foreach ($aColumnsAttrs as $sColumnAttr) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sKey, $sColumnAttr);
|
||||
$aColumnsDefinition[$sColumnAttr] = array(
|
||||
$aColumnsDefinition[$sColumnAttr] = [
|
||||
'title' => $oAttDef->GetLabel(),
|
||||
'type' => ($oAttDef instanceof AttributeDateTime) ? 'moment-'.$oAttDef->GetFormat()->ToMomentJS() : 'html',
|
||||
// Special sorting for Date & Time
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
// Getting items
|
||||
$aItems = array();
|
||||
$aItems = [];
|
||||
// ... For each item
|
||||
/** @var DBObject $oCurrentRow */
|
||||
while ($oCurrentRow = $oSet->Fetch())
|
||||
{
|
||||
while ($oCurrentRow = $oSet->Fetch()) {
|
||||
$sCurrentObjectClass = get_class($oCurrentRow);
|
||||
$sCurrentObjectId = $oCurrentRow->GetKey();
|
||||
|
||||
// ... Retrieving item's attributes values
|
||||
$aItemAttrs = array();
|
||||
foreach ($aColumnsAttrs as $sItemAttr)
|
||||
{
|
||||
$aActions = array();
|
||||
$aItemAttrs = [];
|
||||
foreach ($aColumnsAttrs as $sItemAttr) {
|
||||
$aActions = [];
|
||||
// Set the edit action to the main (first) attribute only
|
||||
//if ($sItemAttr === $sTitleAttrCode)
|
||||
if ($sItemAttr === $sMainActionAttrCode)
|
||||
{
|
||||
if ($sItemAttr === $sMainActionAttrCode) {
|
||||
// Checking if we can edit the object
|
||||
if (($oBrick->GetOpeningMode() === ManageBrick::ENUM_ACTION_EDIT) && $this->oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY,
|
||||
$sCurrentClass, $oCurrentRow->GetKey()))
|
||||
{
|
||||
if (($oBrick->GetOpeningMode() === ManageBrick::ENUM_ACTION_EDIT) && $this->oSecurityHelper->IsActionAllowed(
|
||||
UR_ACTION_MODIFY,
|
||||
$sCurrentClass,
|
||||
$oCurrentRow->GetKey()
|
||||
)) {
|
||||
$sActionType = ManageBrick::ENUM_ACTION_EDIT;
|
||||
}
|
||||
// - Otherwise, check if view is allowed
|
||||
elseif ($this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sCurrentClass,
|
||||
$oCurrentRow->GetKey()))
|
||||
{
|
||||
elseif ($this->oSecurityHelper->IsActionAllowed(
|
||||
UR_ACTION_READ,
|
||||
$sCurrentClass,
|
||||
$oCurrentRow->GetKey()
|
||||
)) {
|
||||
$sActionType = ManageBrick::ENUM_ACTION_VIEW;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sActionType = null;
|
||||
}
|
||||
// - Then set allowed action
|
||||
if ($sActionType !== null)
|
||||
{
|
||||
$aActions[] = array(
|
||||
if ($sActionType !== null) {
|
||||
$aActions[] = [
|
||||
'type' => $sActionType,
|
||||
'class' => $sCurrentClass,
|
||||
'id' => $oCurrentRow->GetKey(),
|
||||
'opening_target' => $oBrick->GetOpeningTarget(),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/** @var \AttributeDefinition $oAttDef */
|
||||
$oAttDef = MetaModel::GetAttributeDef($sCurrentClass, $sItemAttr);
|
||||
$sAttDefClass = get_class($oAttDef);
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
if ($oAttDef->IsExternalKey()) {
|
||||
/** @var \AttributeExternalKey $oAttDef */
|
||||
$sValue = $oCurrentRow->GetAsHTML($sItemAttr.'_friendlyname');
|
||||
$sSortValue = $oCurrentRow->Get($sItemAttr.'_friendlyname');
|
||||
|
||||
// Adding a view action on the external keys
|
||||
if ($oCurrentRow->Get($sItemAttr) !== $oAttDef->GetNullValue())
|
||||
{
|
||||
if ($oCurrentRow->Get($sItemAttr) !== $oAttDef->GetNullValue()) {
|
||||
// Checking if we can view the object
|
||||
if (($this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $oAttDef->GetTargetClass(),
|
||||
$oCurrentRow->Get($sItemAttr))))
|
||||
{
|
||||
$aActions[] = array(
|
||||
if (($this->oSecurityHelper->IsActionAllowed(
|
||||
UR_ACTION_READ,
|
||||
$oAttDef->GetTargetClass(),
|
||||
$oCurrentRow->Get($sItemAttr)
|
||||
))) {
|
||||
$aActions[] = [
|
||||
'type' => ManageBrick::ENUM_ACTION_VIEW,
|
||||
'class' => $oAttDef->GetTargetClass(),
|
||||
'id' => $oCurrentRow->Get($sItemAttr),
|
||||
'opening_target' => $oBrick->GetOpeningTarget(),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($oAttDef instanceof AttributeImage)
|
||||
{
|
||||
} elseif ($oAttDef instanceof AttributeImage) {
|
||||
/** @var \ormDocument $oOrmDoc */
|
||||
$oOrmDoc = $oCurrentRow->Get($sItemAttr);
|
||||
if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty())
|
||||
{
|
||||
if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty()) {
|
||||
$sUrl = $this->oUrlGenerator->generate('p_object_document_display', [
|
||||
'sObjectClass' => get_class($oCurrentRow),
|
||||
'sObjectId' => $oCurrentRow->GetKey(),
|
||||
@@ -723,16 +666,12 @@ class ManageBrickController extends BrickController
|
||||
'cache' => 86400,
|
||||
's' => $oOrmDoc->GetSignature(),
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sUrl = $oAttDef->Get('default_image');
|
||||
}
|
||||
$sValue = '<img src="'.$sUrl.'" />';
|
||||
$sSortValue = null;
|
||||
}
|
||||
elseif ($oAttDef instanceof AttributeTagSet)
|
||||
{
|
||||
} elseif ($oAttDef instanceof AttributeTagSet) {
|
||||
/** @var \ormTagSet $oSetValues */
|
||||
$oSetValues = $oCurrentRow->Get($sItemAttr);
|
||||
$aCodes = $oSetValues->GetTags();
|
||||
@@ -754,17 +693,15 @@ class ManageBrickController extends BrickController
|
||||
|
||||
// For simple fields, we get the raw (stored) value as well
|
||||
$bExcludeRawValue = false;
|
||||
foreach (ApplicationHelper::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
|
||||
{
|
||||
if (is_a($sAttDefClass, $sAttDefClassToExclude, true))
|
||||
{
|
||||
foreach (ApplicationHelper::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) {
|
||||
if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) {
|
||||
$bExcludeRawValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$attValueRaw = ($bExcludeRawValue === false) ? $oCurrentRow->Get($sItemAttr) : null;
|
||||
|
||||
$aItemAttrs[$sItemAttr] = array(
|
||||
$aItemAttrs[$sItemAttr] = [
|
||||
'object_class' => $sCurrentObjectClass,
|
||||
'object_id' => $sCurrentObjectId,
|
||||
'attribute_code' => $sItemAttr,
|
||||
@@ -773,114 +710,105 @@ class ManageBrickController extends BrickController
|
||||
'value_html' => $sValue,
|
||||
'sort_value' => $sSortValue,
|
||||
'actions' => $aActions,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
// ... Checking menu extensions
|
||||
$aItemButtons = array();
|
||||
$aItemButtons = [];
|
||||
/** @var iPopupMenuExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance)
|
||||
{
|
||||
foreach ($oExtensionInstance->EnumItems(iPopupMenuExtension::PORTAL_OBJLISTITEM_ACTIONS, array(
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) {
|
||||
foreach ($oExtensionInstance->EnumItems(iPopupMenuExtension::PORTAL_OBJLISTITEM_ACTIONS, [
|
||||
'portal_id' => $sPortalId,
|
||||
'object' => $oCurrentRow,
|
||||
)) as $oMenuItem)
|
||||
{
|
||||
if (is_object($oMenuItem))
|
||||
{
|
||||
if ($oMenuItem instanceof JSButtonItem)
|
||||
{
|
||||
$aItemButtons[] = $oMenuItem->GetMenuItem() + array(
|
||||
]) as $oMenuItem) {
|
||||
if (is_object($oMenuItem)) {
|
||||
if ($oMenuItem instanceof JSButtonItem) {
|
||||
$aItemButtons[] = $oMenuItem->GetMenuItem() + [
|
||||
'js_files' => $oMenuItem->GetLinkedScripts(),
|
||||
'type' => 'button',
|
||||
);
|
||||
}
|
||||
elseif ($oMenuItem instanceof URLButtonItem)
|
||||
{
|
||||
$aItemButtons[] = $oMenuItem->GetMenuItem() + array('type' => 'link');
|
||||
];
|
||||
} elseif ($oMenuItem instanceof URLButtonItem) {
|
||||
$aItemButtons[] = $oMenuItem->GetMenuItem() + ['type' => 'link'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ... And item's properties
|
||||
$aItems[] = array(
|
||||
$aItems[] = [
|
||||
'id' => $oCurrentRow->GetKey(),
|
||||
'class' => $sCurrentClass,
|
||||
'attributes' => $aItemAttrs,
|
||||
'highlight_class' => $oCurrentRow->GetHilightClass(),
|
||||
'actions' => $aItemButtons,
|
||||
);
|
||||
];
|
||||
|
||||
if (!empty($aItemButtons))
|
||||
{
|
||||
if (!empty($aItemButtons)) {
|
||||
$bHasObjectListItemExtension = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Adding an extra column for object list item extensions
|
||||
if ($bHasObjectListItemExtension === true)
|
||||
{
|
||||
$aColumnsDefinition['_ui_extensions'] = array(
|
||||
if ($bHasObjectListItemExtension === true) {
|
||||
$aColumnsDefinition['_ui_extensions'] = [
|
||||
'title' => Dict::S('Brick:Portal:Manage:Table:ItemActions'),
|
||||
'type' => 'html',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
$aGroupingAreasData[$sKey] = array(
|
||||
$aGroupingAreasData[$sKey] = [
|
||||
'sId' => $sKey,
|
||||
'sTitle' => $aGroupingAreasValues[$sKey]['label'],
|
||||
'aItems' => $aItems,
|
||||
'iItemsCount' => $oSet->Count(),
|
||||
'aColumnsDefinition' => $aColumnsDefinition,
|
||||
);
|
||||
];
|
||||
|
||||
IssueLog::Debug('Portal ManageBrick query', LogChannels::PORTAL, array(
|
||||
IssueLog::Debug('Portal ManageBrick query', LogChannels::PORTAL, [
|
||||
'sPortalId' => $sPortalId,
|
||||
'sBrickId' => $sBrickId,
|
||||
'sGroupingTab' => $sGroupingTab,
|
||||
'oql' => $oSet->GetFilter()->ToOQL(),
|
||||
'aGroupingTabs' => $aGroupingTabs,
|
||||
));
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$aGroupingAreasData = array();
|
||||
$aGroupingAreasData = [];
|
||||
$sGroupingArea = null;
|
||||
}
|
||||
|
||||
// Preparing response
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aData = $aData + array(
|
||||
$aData = $aData + [
|
||||
'data' => $aGroupingAreasData[$sGroupingArea]['aItems'],
|
||||
);
|
||||
];
|
||||
} else {
|
||||
$aDisplayValues = array();
|
||||
$aUrls = array();
|
||||
$aColumns = array();
|
||||
$aNames = array();
|
||||
$aDisplayValues = [];
|
||||
$aUrls = [];
|
||||
$aColumns = [];
|
||||
$aNames = [];
|
||||
if ($bHasScope) {
|
||||
foreach ($aGroupingTabsValues as $aValues) {
|
||||
$aDisplayValues[] = array(
|
||||
$aDisplayValues[] = [
|
||||
'value' => $aValues['count'],
|
||||
'label' => $aValues['label'],
|
||||
'label_html' => $aValues['label_html'],
|
||||
);
|
||||
$aUrls[] = $this->oUrlGenerator->generate('p_manage_brick_display_as', array(
|
||||
];
|
||||
$aUrls[] = $this->oUrlGenerator->generate('p_manage_brick_display_as', [
|
||||
'sBrickId' => $sBrickId,
|
||||
'sDisplayMode' => 'list',
|
||||
'sGroupingTab' => $aValues['value'],
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ($aDisplayValues as $idx => $aValue)
|
||||
{
|
||||
$aColumns[] = array('series_'.$idx, (int)$aValue['value']);
|
||||
foreach ($aDisplayValues as $idx => $aValue) {
|
||||
$aColumns[] = ['series_'.$idx, (int)$aValue['value']];
|
||||
$aNames['series_'.$idx] = $aValue['label'];
|
||||
}
|
||||
}
|
||||
|
||||
// Preparing data to pass to the templating service
|
||||
$aData = $aData + array(
|
||||
$aData = $aData + [
|
||||
'sFct' => 'count',
|
||||
'sIconURL' => $sIconURL,
|
||||
'aColumns' => $aColumns,
|
||||
@@ -896,7 +824,7 @@ class ManageBrickController extends BrickController
|
||||
'sDateFormat' => AttributeDate::GetFormat()->ToMomentJS(),
|
||||
'sDateTimeFormat' => AttributeDateTime::GetFormat()->ToMomentJS(),
|
||||
'iCount' => $iCount,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return $aData;
|
||||
@@ -911,7 +839,7 @@ class ManageBrickController extends BrickController
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function ManageSearchValue(&$aData, DBSearch &$oQuery, $sClass, $aColumnsAttrs = array())
|
||||
protected function ManageSearchValue(&$aData, DBSearch &$oQuery, $sClass, $aColumnsAttrs = [])
|
||||
{
|
||||
// Getting search value
|
||||
$sRawSearchValue = trim($this->oRequestManipulatorHelper->ReadParam('sSearchValue', ''));
|
||||
@@ -975,24 +903,22 @@ class ManageBrickController extends BrickController
|
||||
* @throws \OQLException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function GroupByAttribute(DBSearch $oQuery, $sGroupingTabAttCode, ManageBrick $oBrick) {
|
||||
protected function GroupByAttribute(DBSearch $oQuery, $sGroupingTabAttCode, ManageBrick $oBrick)
|
||||
{
|
||||
|
||||
$aGroupingTabsValues = array();
|
||||
$aDistinctResults = array();
|
||||
$aGroupingTabsValues = [];
|
||||
$aDistinctResults = [];
|
||||
$oDistinctQuery = DBSearch::FromOQL($oBrick->GetOql());
|
||||
$bHasScope = $this->oScopeValidatorHelper->AddScopeToQuery($oDistinctQuery, $oDistinctQuery->GetClass());
|
||||
if ($bHasScope)
|
||||
{
|
||||
if ($bHasScope) {
|
||||
// - Adding field condition
|
||||
$oFieldExp = new FieldExpression($sGroupingTabAttCode, $oDistinctQuery->GetClassAlias());
|
||||
$sDistinctSql = $oDistinctQuery->MakeGroupByQuery(array(), array('grouped_by_1' => $oFieldExp), true);
|
||||
$sDistinctSql = $oDistinctQuery->MakeGroupByQuery([], ['grouped_by_1' => $oFieldExp], true);
|
||||
$aDistinctResults = CMDBSource::QueryToArray($sDistinctSql);
|
||||
if (!empty($aDistinctResults))
|
||||
{
|
||||
if (!empty($aDistinctResults)) {
|
||||
$iLimit = $oBrick->GetGroupLimit();
|
||||
$aOthers = array();
|
||||
if ($iLimit > 0)
|
||||
{
|
||||
$aOthers = [];
|
||||
if ($iLimit > 0) {
|
||||
uasort($aDistinctResults, function ($a, $b) {
|
||||
$v1 = $a['_itop_count_'];
|
||||
$v2 = $b['_itop_count_'];
|
||||
@@ -1000,77 +926,72 @@ class ManageBrickController extends BrickController
|
||||
return ($v1 == $v2) ? 0 : (($v1 > $v2) ? -1 : 1);
|
||||
});
|
||||
|
||||
if (count($aDistinctResults) > $iLimit)
|
||||
{
|
||||
if ($oBrick->ShowGroupOthers())
|
||||
{
|
||||
if (count($aDistinctResults) > $iLimit) {
|
||||
if ($oBrick->ShowGroupOthers()) {
|
||||
$aOthers = array_slice($aDistinctResults, $iLimit);
|
||||
}
|
||||
$aDistinctResults = array_slice($aDistinctResults, 0, $iLimit);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($aDistinctResults as $aDistinctResult)
|
||||
{
|
||||
foreach ($aDistinctResults as $aDistinctResult) {
|
||||
$oConditionQuery = DBSearch::CloneWithAlias($oQuery, 'GTAB');
|
||||
$oExpression = new BinaryExpression(new FieldExpression($sGroupingTabAttCode,
|
||||
$oConditionQuery->GetClassAlias()), '=', new UnaryExpression($aDistinctResult['grouped_by_1']));
|
||||
$oExpression = new BinaryExpression(new FieldExpression(
|
||||
$sGroupingTabAttCode,
|
||||
$oConditionQuery->GetClassAlias()
|
||||
), '=', new UnaryExpression($aDistinctResult['grouped_by_1']));
|
||||
$oConditionQuery->AddConditionExpression($oExpression);
|
||||
|
||||
$sHtmlLabel = $oFieldExp->MakeValueLabel($oDistinctQuery, $aDistinctResult['grouped_by_1'], '');
|
||||
$aGroupingTabsValues[$aDistinctResult['grouped_by_1']] = array(
|
||||
$aGroupingTabsValues[$aDistinctResult['grouped_by_1']] = [
|
||||
'value' => $aDistinctResult['grouped_by_1'],
|
||||
'label_html' => $sHtmlLabel,
|
||||
'label' => strip_tags(html_entity_decode($sHtmlLabel, ENT_QUOTES, 'UTF-8')),
|
||||
'condition' => $oConditionQuery,
|
||||
'count' => $aDistinctResult['_itop_count_'],
|
||||
);
|
||||
];
|
||||
unset($oConditionQuery);
|
||||
}
|
||||
if (!empty($aOthers))
|
||||
{
|
||||
if (!empty($aOthers)) {
|
||||
// Aggregate others
|
||||
$oConditionQuery = DBSearch::CloneWithAlias($oQuery, 'GTAB');
|
||||
$oExpression = null;
|
||||
$iOtherCount = 0;
|
||||
foreach ($aOthers as $aResult)
|
||||
{
|
||||
foreach ($aOthers as $aResult) {
|
||||
$iOtherCount += $aResult['_itop_count_'];
|
||||
$oExpr = new BinaryExpression(new FieldExpression($sGroupingTabAttCode,
|
||||
$oConditionQuery->GetClassAlias()), '=', new UnaryExpression($aResult['grouped_by_1']));
|
||||
if (is_null($oExpression))
|
||||
{
|
||||
$oExpr = new BinaryExpression(new FieldExpression(
|
||||
$sGroupingTabAttCode,
|
||||
$oConditionQuery->GetClassAlias()
|
||||
), '=', new UnaryExpression($aResult['grouped_by_1']));
|
||||
if (is_null($oExpression)) {
|
||||
$oExpression = $oExpr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oExpression = new BinaryExpression($oExpression, 'OR', $oExpr);
|
||||
}
|
||||
}
|
||||
$oConditionQuery->AddConditionExpression($oExpression);
|
||||
|
||||
$sLabel = Dict::S('Brick:Portal:Manage:Others');
|
||||
$aGroupingTabsValues['Others'] = array(
|
||||
$aGroupingTabsValues['Others'] = [
|
||||
'value' => 'Others',
|
||||
'label_html' => $sLabel,
|
||||
'label' => $sLabel,
|
||||
'condition' => $oConditionQuery,
|
||||
'count' => $iOtherCount,
|
||||
);
|
||||
];
|
||||
unset($oConditionQuery);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($aDistinctResults))
|
||||
{
|
||||
if (empty($aDistinctResults)) {
|
||||
$sLabel = Dict::S('Brick:Portal:Manage:All');
|
||||
$aGroupingTabsValues['undefined'] = array(
|
||||
$aGroupingTabsValues['undefined'] = [
|
||||
'value' => 'All',
|
||||
'label_html' => $sLabel,
|
||||
'label' => $sLabel,
|
||||
'condition' => null,
|
||||
'count' => 0,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return $aGroupingTabsValues;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,6 @@ use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
*/
|
||||
class SessionMessageController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \Combodo\iTop\Portal\Helper\RequestManipulatorHelper $oRequestManipulatorHelper
|
||||
* @param \Combodo\iTop\Portal\Helper\SessionMessageHelper $oSessionMessageHelper
|
||||
@@ -46,8 +45,7 @@ class SessionMessageController extends AbstractController
|
||||
public function __construct(
|
||||
protected RequestManipulatorHelper $oRequestManipulatorHelper,
|
||||
protected SessionMessageHelper $oSessionMessageHelper
|
||||
)
|
||||
{
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,15 +55,14 @@ class SessionMessageController extends AbstractController
|
||||
*/
|
||||
public function AddMessageAction(Request $oRequest)
|
||||
{
|
||||
$aData = array();
|
||||
$aData = [];
|
||||
|
||||
// Retrieve parameters
|
||||
$sMessageSeverity = $this->oRequestManipulatorHelper->ReadParam('sSeverity');
|
||||
$sMessageContent = $this->oRequestManipulatorHelper->ReadParam('sContent');
|
||||
|
||||
// Check parameters consistency
|
||||
if (empty($sMessageSeverity) || empty($sMessageContent))
|
||||
{
|
||||
if (empty($sMessageSeverity) || empty($sMessageContent)) {
|
||||
throw new HttpException(Response::HTTP_BAD_REQUEST, 'Message must have a severity and a content, make sure both sSeverity & sContent parameters are sent.');
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use UserRights;
|
||||
use utils;
|
||||
use Dict;
|
||||
|
||||
/**
|
||||
* Class UserProfileBrickController
|
||||
*
|
||||
@@ -60,7 +61,7 @@ class UserProfileBrickController extends BrickController
|
||||
* @param \Combodo\iTop\Portal\Brick\BrickCollection $oBrickCollection
|
||||
* @param \Combodo\iTop\Portal\Routing\UrlGenerator $oUrlGenerator
|
||||
* @param \Combodo\iTop\Portal\Helper\SecurityHelper $oSecurityHelper
|
||||
|
||||
|
||||
*
|
||||
* @since 3.2.0 N°6933
|
||||
*/
|
||||
@@ -70,12 +71,11 @@ class UserProfileBrickController extends BrickController
|
||||
protected BrickCollection $oBrickCollection,
|
||||
protected UrlGenerator $oUrlGenerator,
|
||||
protected SecurityHelper $oSecurityHelper
|
||||
)
|
||||
{
|
||||
) {
|
||||
}
|
||||
|
||||
/** @var string ENUM_FORM_TYPE_PICTURE */
|
||||
const ENUM_FORM_TYPE_PICTURE = 'picture';
|
||||
public const ENUM_FORM_TYPE_PICTURE = 'picture';
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
@@ -92,26 +92,20 @@ class UserProfileBrickController extends BrickController
|
||||
public function DisplayAction(Request $oRequest, $sBrickId)
|
||||
{
|
||||
// If the brick id was not specified, we get the first one registered that is an instance of UserProfileBrick as default
|
||||
if ($sBrickId === null)
|
||||
{
|
||||
if ($sBrickId === null) {
|
||||
/** @var \Combodo\iTop\Portal\Brick\PortalBrick $oTmpBrick */
|
||||
foreach ($this->oBrickCollection->GetBricks() as $oTmpBrick)
|
||||
{
|
||||
if ($oTmpBrick instanceof UserProfileBrick)
|
||||
{
|
||||
foreach ($this->oBrickCollection->GetBricks() as $oTmpBrick) {
|
||||
if ($oTmpBrick instanceof UserProfileBrick) {
|
||||
$oBrick = $oTmpBrick;
|
||||
}
|
||||
}
|
||||
|
||||
// We make sure a UserProfileBrick was found
|
||||
if (!isset($oBrick) || $oBrick === null)
|
||||
{
|
||||
if (!isset($oBrick) || $oBrick === null) {
|
||||
$oBrick = new UserProfileBrick();
|
||||
//throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'UserProfileBrick : Brick could not be loaded as there was no UserProfileBrick loaded in the application.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oBrick = $this->oBrickCollection->GetBrickById($sBrickId);
|
||||
}
|
||||
|
||||
@@ -124,11 +118,14 @@ class UserProfileBrickController extends BrickController
|
||||
$sTab = $this->oRequestManipulatorHelper->ReadParam('sTab', 'user-info', FILTER_UNSAFE_RAW, FILTER_FLAG_EMPTY_STRING_NULL);
|
||||
|
||||
// If this is ajax call, we are just submitting preferences or password forms
|
||||
if ($oRequest->isXmlHttpRequest())
|
||||
{
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
if ($sTab === "user-info") {
|
||||
$aCurrentValues = $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW,
|
||||
FILTER_REQUIRE_ARRAY);
|
||||
$aCurrentValues = $this->oRequestManipulatorHelper->ReadParam(
|
||||
'current_values',
|
||||
[],
|
||||
FILTER_UNSAFE_RAW,
|
||||
FILTER_REQUIRE_ARRAY
|
||||
);
|
||||
$sFormType = $aCurrentValues['form_type'];
|
||||
if ($sFormType === PreferencesFormManager::FORM_TYPE) {
|
||||
$aData['form'] = $this->HandlePreferencesForm($oRequest, $sFormMode);
|
||||
@@ -143,8 +140,7 @@ class UserProfileBrickController extends BrickController
|
||||
$oResponse = new JsonResponse($aData);
|
||||
}
|
||||
// Else, we are displaying page for first time
|
||||
else
|
||||
{
|
||||
else {
|
||||
if ($sTab === "user-info") {
|
||||
// Retrieving current contact
|
||||
/** @var \DBObject $oCurContact */
|
||||
@@ -175,7 +171,6 @@ class UserProfileBrickController extends BrickController
|
||||
return $oResponse;
|
||||
}
|
||||
|
||||
|
||||
private function ManageUserProfileBrickExtensibility(string $sTab, array &$aData): void
|
||||
{
|
||||
$aData['sTab'] = $sTab;
|
||||
@@ -193,7 +188,7 @@ class UserProfileBrickController extends BrickController
|
||||
|
||||
// Read the current tab content From iPortalTabSectionExtension
|
||||
$aTabSectionExtensions = ExtensibilityHelper::GetInstance()->GetPortalTabContentExtensions(iUserProfileTabContentExtension::class, $sTab);
|
||||
if (count($aTabSectionExtensions) !== 0 && count($_POST) !== 0){
|
||||
if (count($aTabSectionExtensions) !== 0 && count($_POST) !== 0) {
|
||||
$sTransactionId = utils::ReadPostedParam('transaction_id', null, utils::ENUM_SANITIZATION_FILTER_TRANSACTION_ID);
|
||||
IssueLog::Debug(__FUNCTION__.": transaction [$sTransactionId]");
|
||||
if (utils::IsNullOrEmptyString($sTransactionId) || !utils::IsTransactionValid($sTransactionId, false)) {
|
||||
@@ -214,30 +209,28 @@ class UserProfileBrickController extends BrickController
|
||||
}
|
||||
}
|
||||
|
||||
public function EditPerson(Request $oRequest)
|
||||
{
|
||||
$oCurContact = UserRights::GetContactObject();
|
||||
$sObjectClass = get_class($oCurContact);
|
||||
$sObjectId = $oCurContact->GetKey();
|
||||
|
||||
public function EditPerson(Request $oRequest)
|
||||
{
|
||||
$oCurContact = UserRights::GetContactObject();
|
||||
$sObjectClass = get_class($oCurContact);
|
||||
$sObjectId = $oCurContact->GetKey();
|
||||
// Checking security layers
|
||||
// Warning : This is a dirty quick fix to allow editing its own contact information
|
||||
$bAllowWrite = ($sObjectClass === 'Person' && $sObjectId == UserRights::GetContactId());
|
||||
if (!$this->oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sObjectClass, $sObjectId) && !$bAllowWrite) {
|
||||
IssueLog::Warning(__METHOD__.' at line '.__LINE__.' : User #'.UserRights::GetUserId().' not allowed to modify '.$sObjectClass.'::'.$sObjectId.' object.');
|
||||
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||
}
|
||||
|
||||
// Checking security layers
|
||||
// Warning : This is a dirty quick fix to allow editing its own contact information
|
||||
$bAllowWrite = ($sObjectClass === 'Person' && $sObjectId == UserRights::GetContactId());
|
||||
if (!$this->oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sObjectClass, $sObjectId) && !$bAllowWrite) {
|
||||
IssueLog::Warning(__METHOD__ . ' at line ' . __LINE__ . ' : User #' . UserRights::GetUserId() . ' not allowed to modify ' . $sObjectClass . '::' . $sObjectId . ' object.');
|
||||
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||
}
|
||||
$aForm = $this->GetBrick()->GetForm();
|
||||
$aForm['submit_endpoint'] = $this->generateUrl('p_user_profile_brick_edit_person');
|
||||
|
||||
$aForm = $this->GetBrick()->GetForm();
|
||||
$aForm['submit_endpoint'] = $this->generateUrl('p_user_profile_brick_edit_person');
|
||||
|
||||
$aData = ['sMode' => 'edit'];
|
||||
$aData['form'] = $this->ObjectFormHandlerHelper->HandleForm($oRequest, $aData['sMode'], $sObjectClass, $sObjectId, $aForm);
|
||||
|
||||
return new JsonResponse($aData);
|
||||
}
|
||||
$aData = ['sMode' => 'edit'];
|
||||
$aData['form'] = $this->ObjectFormHandlerHelper->HandleForm($oRequest, $aData['sMode'], $sObjectClass, $sObjectId, $aForm);
|
||||
|
||||
return new JsonResponse($aData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
@@ -249,13 +242,12 @@ class UserProfileBrickController extends BrickController
|
||||
*/
|
||||
public function HandlePreferencesForm(Request $oRequest, $sFormMode)
|
||||
{
|
||||
$aFormData = array();
|
||||
$aFormData = [];
|
||||
|
||||
// Handling form
|
||||
$sOperation = $this->oRequestManipulatorHelper->ReadParam('operation', null);
|
||||
// - Create
|
||||
if ($sOperation === null)
|
||||
{
|
||||
if ($sOperation === null) {
|
||||
// - Creating renderer
|
||||
$oFormRenderer = new BsFormRenderer();
|
||||
$oFormRenderer->SetEndpoint($this->oUrlGenerator->generate('p_user_profile_brick'));
|
||||
@@ -264,50 +256,47 @@ class UserProfileBrickController extends BrickController
|
||||
$oFormManager->SetRenderer($oFormRenderer)
|
||||
->Build();
|
||||
// - Checking if we have to make the form read only
|
||||
if ($sFormMode === ObjectFormHandlerHelper::ENUM_MODE_VIEW)
|
||||
{
|
||||
if ($sFormMode === ObjectFormHandlerHelper::ENUM_MODE_VIEW) {
|
||||
$oFormManager->GetForm()->MakeReadOnly();
|
||||
}
|
||||
}
|
||||
// - Submit
|
||||
else
|
||||
{
|
||||
if ($sOperation === 'submit')
|
||||
{
|
||||
else {
|
||||
if ($sOperation === 'submit') {
|
||||
$sFormManagerClass = $this->oRequestManipulatorHelper->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW);
|
||||
$sFormManagerData = $this->oRequestManipulatorHelper->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW);
|
||||
if ($sFormManagerClass === null || $sFormManagerData === null)
|
||||
{
|
||||
if ($sFormManagerClass === null || $sFormManagerData === null) {
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameters formmanager_class and formmanager_data must be defined.');
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Parameters formmanager_class and formmanager_data must be defined.');
|
||||
throw new HttpException(
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Parameters formmanager_class and formmanager_data must be defined.'
|
||||
);
|
||||
}
|
||||
|
||||
// Rebuilding manager from json
|
||||
/** @var \Combodo\iTop\Form\FormManager $oFormManager */
|
||||
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData);
|
||||
// Applying modification to object
|
||||
$aFormData['validation'] = $oFormManager->OnSubmit(array(
|
||||
'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
));
|
||||
$aFormData['validation'] = $oFormManager->OnSubmit([
|
||||
'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
]);
|
||||
// Reloading page only if preferences were changed
|
||||
if (($aFormData['validation']['valid'] === true) && !empty($aFormData['validation']['messages']['success']))
|
||||
{
|
||||
$aFormData['validation']['redirection'] = array(
|
||||
if (($aFormData['validation']['valid'] === true) && !empty($aFormData['validation']['messages']['success'])) {
|
||||
$aFormData['validation']['redirection'] = [
|
||||
'url' => $this->oUrlGenerator->generate('p_user_profile_brick'),
|
||||
'timeout_duration' => 1000, //since there are several ajax request, we use a longer timeout in hope that they will all be finished in time. A promise would have been more reliable, but since this change is made in a minor version, this approach is less error prone.
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Else, submit from another form
|
||||
|
||||
// Preparing field_set data
|
||||
$aFieldSetData = array(
|
||||
$aFieldSetData = [
|
||||
'fields_list' => $oFormManager->GetRenderer()->Render(),
|
||||
'fields_impacts' => $oFormManager->GetForm()->GetFieldsImpacts(),
|
||||
'form_path' => $oFormManager->GetForm()->GetId(),
|
||||
);
|
||||
];
|
||||
|
||||
// Preparing form data
|
||||
$aFormData['id'] = $oFormManager->GetForm()->GetId();
|
||||
@@ -329,14 +318,13 @@ class UserProfileBrickController extends BrickController
|
||||
*/
|
||||
public function HandlePasswordForm(Request $oRequest, $sFormMode)
|
||||
{
|
||||
$aFormData = array();
|
||||
$aFormData = [];
|
||||
|
||||
// Handling form
|
||||
$sOperation = /** @var \Combodo\iTop\Portal\Helper\RequestManipulatorHelper $oRequestManipulator */
|
||||
$this->oRequestManipulatorHelper->ReadParam('operation', null);
|
||||
// - Create
|
||||
if ($sOperation === null)
|
||||
{
|
||||
if ($sOperation === null) {
|
||||
// - Creating renderer
|
||||
$oFormRenderer = new BsFormRenderer();
|
||||
$oFormRenderer->SetEndpoint($this->oUrlGenerator->generate('p_user_profile_brick'));
|
||||
@@ -345,41 +333,40 @@ class UserProfileBrickController extends BrickController
|
||||
$oFormManager->SetRenderer($oFormRenderer)
|
||||
->Build();
|
||||
// - Checking if we have to make the form read only
|
||||
if ($sFormMode === ObjectFormHandlerHelper::ENUM_MODE_VIEW)
|
||||
{
|
||||
if ($sFormMode === ObjectFormHandlerHelper::ENUM_MODE_VIEW) {
|
||||
$oFormManager->GetForm()->MakeReadOnly();
|
||||
}
|
||||
}
|
||||
// - Submit
|
||||
else
|
||||
{
|
||||
if ($sOperation === 'submit')
|
||||
{
|
||||
else {
|
||||
if ($sOperation === 'submit') {
|
||||
$sFormManagerClass = $this->oRequestManipulatorHelper->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW);
|
||||
$sFormManagerData = $this->oRequestManipulatorHelper->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW);
|
||||
if ($sFormManagerClass === null || $sFormManagerData === null) {
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameters formmanager_class and formmanager_data must be defined.');
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Parameters formmanager_class and formmanager_data must be defined.');
|
||||
throw new HttpException(
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'Parameters formmanager_class and formmanager_data must be defined.'
|
||||
);
|
||||
}
|
||||
|
||||
// Rebuilding manager from json
|
||||
/** @var \Combodo\iTop\Form\FormManager $oFormManager */
|
||||
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData);
|
||||
// Applying modification to object
|
||||
$aFormData['validation'] = $oFormManager->OnSubmit(array(
|
||||
'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
));
|
||||
$aFormData['validation'] = $oFormManager->OnSubmit([
|
||||
'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Else, submit from another form
|
||||
|
||||
// Preparing field_set data
|
||||
$aFieldSetData = array(
|
||||
$aFieldSetData = [
|
||||
'fields_list' => $oFormManager->GetRenderer()->Render(),
|
||||
'fields_impacts' => $oFormManager->GetForm()->GetFieldsImpacts(),
|
||||
'form_path' => $oFormManager->GetForm()->GetId(),
|
||||
);
|
||||
];
|
||||
|
||||
// Preparing form data
|
||||
$aFormData['id'] = $oFormManager->GetForm()->GetId();
|
||||
@@ -400,32 +387,27 @@ class UserProfileBrickController extends BrickController
|
||||
*/
|
||||
public function HandlePictureForm(Request $oRequest)
|
||||
{
|
||||
$aFormData = array();
|
||||
$aFormData = [];
|
||||
$sPictureAttCode = 'picture';
|
||||
|
||||
// Handling form
|
||||
$sOperation = $this->oRequestManipulatorHelper->ReadParam('operation', null);
|
||||
// - No operation specified
|
||||
if ($sOperation === null)
|
||||
{
|
||||
if ($sOperation === null) {
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Operation parameter must be specified.');
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Operation parameter must be specified.');
|
||||
}
|
||||
// - Submit
|
||||
else
|
||||
{
|
||||
if ($sOperation === 'submit')
|
||||
{
|
||||
else {
|
||||
if ($sOperation === 'submit') {
|
||||
$oRequestFiles = $oRequest->files;
|
||||
$oPictureFile = $oRequestFiles->get($sPictureAttCode);
|
||||
if ($oPictureFile === null)
|
||||
{
|
||||
if ($oPictureFile === null) {
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameter picture must be defined.');
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameter picture must be defined.');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
// Retrieving image as an ORMDocument
|
||||
$oImage = utils::ReadPostedDocument($sPictureAttCode);
|
||||
// Retrieving current contact
|
||||
@@ -434,16 +416,19 @@ class UserProfileBrickController extends BrickController
|
||||
// Resizing image
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurContact), $sPictureAttCode);
|
||||
$aSize = utils::GetImageSize($oImage->GetData());
|
||||
$oImage = utils::ResizeImageToFit($oImage, $aSize[0], $aSize[1], $oAttDef->Get('storage_max_width'),
|
||||
$oAttDef->Get('storage_max_height'));
|
||||
$oImage = utils::ResizeImageToFit(
|
||||
$oImage,
|
||||
$aSize[0],
|
||||
$aSize[1],
|
||||
$oAttDef->Get('storage_max_width'),
|
||||
$oAttDef->Get('storage_max_height')
|
||||
);
|
||||
// Setting it to the contact
|
||||
$oCurContact->Set($sPictureAttCode, $oImage);
|
||||
// Forcing allowed writing on the object if necessary.
|
||||
$oCurContact->AllowWrite(true);
|
||||
$oCurContact->DBUpdate();
|
||||
}
|
||||
catch (FileUploadException $e)
|
||||
{
|
||||
} catch (FileUploadException $e) {
|
||||
$aFormData['error'] = $e->GetMessage();
|
||||
}
|
||||
|
||||
@@ -456,10 +441,10 @@ class UserProfileBrickController extends BrickController
|
||||
'cache' => 86400,
|
||||
's' => $oOrmDoc->GetSignature(),
|
||||
]);
|
||||
$aFormData['validation'] = array(
|
||||
$aFormData['validation'] = [
|
||||
'valid' => true,
|
||||
'messages' => array(),
|
||||
);
|
||||
'messages' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,30 +453,30 @@ class UserProfileBrickController extends BrickController
|
||||
return $aFormData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sBrickId
|
||||
* @return \Combodo\iTop\Portal\Brick\PortalBrick|UserProfileBrick
|
||||
* @throws \Combodo\iTop\Portal\Brick\BrickNotFoundException
|
||||
*/
|
||||
public function GetBrick($sBrickId = null)
|
||||
{
|
||||
// If the brick id was not specified, we get the first one registered that is an instance of UserProfileBrick as default
|
||||
if ($sBrickId === null) {
|
||||
/** @var \Combodo\iTop\Portal\Brick\PortalBrick $oTmpBrick */
|
||||
foreach ($this->oBrickCollection->GetBricks() as $oTmpBrick) {
|
||||
if ($oTmpBrick instanceof UserProfileBrick) {
|
||||
$oBrick = $oTmpBrick;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param $sBrickId
|
||||
* @return \Combodo\iTop\Portal\Brick\PortalBrick|UserProfileBrick
|
||||
* @throws \Combodo\iTop\Portal\Brick\BrickNotFoundException
|
||||
*/
|
||||
public function GetBrick($sBrickId = null)
|
||||
{
|
||||
// If the brick id was not specified, we get the first one registered that is an instance of UserProfileBrick as default
|
||||
if ($sBrickId === null) {
|
||||
/** @var \Combodo\iTop\Portal\Brick\PortalBrick $oTmpBrick */
|
||||
foreach ($this->oBrickCollection->GetBricks() as $oTmpBrick) {
|
||||
if ($oTmpBrick instanceof UserProfileBrick) {
|
||||
$oBrick = $oTmpBrick;
|
||||
}
|
||||
}
|
||||
|
||||
// We make sure a UserProfileBrick was found
|
||||
if (!isset($oBrick) || $oBrick === null) {
|
||||
$oBrick = new UserProfileBrick();
|
||||
//throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'UserProfileBrick : Brick could not be loaded as there was no UserProfileBrick loaded in the application.');
|
||||
}
|
||||
} else {
|
||||
$oBrick = $this->oBrickCollection->GetBrickById($sBrickId);
|
||||
}
|
||||
return $oBrick;
|
||||
}
|
||||
// We make sure a UserProfileBrick was found
|
||||
if (!isset($oBrick) || $oBrick === null) {
|
||||
$oBrick = new UserProfileBrick();
|
||||
//throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'UserProfileBrick : Brick could not be loaded as there was no UserProfileBrick loaded in the application.');
|
||||
}
|
||||
} else {
|
||||
$oBrick = $this->oBrickCollection->GetBrickById($sBrickId);
|
||||
}
|
||||
return $oBrick;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ use Throwable;
|
||||
*/
|
||||
class PortalCollector extends AbstractDataCollector
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -90,13 +89,13 @@ class PortalCollector extends AbstractDataCollector
|
||||
$iOverridesCount = 0;
|
||||
$aExtensions = [];
|
||||
|
||||
foreach($aTemplatesDefinitions as $templates){
|
||||
foreach ($aTemplatesDefinitions as $templates) {
|
||||
foreach ($templates as $template) {
|
||||
|
||||
$aMatches = [];
|
||||
preg_match('#([\w-]+)/#', $template->GetPath(), $aMatches);
|
||||
|
||||
if(!in_array($aMatches[1], $aExtensions)){
|
||||
if (!in_array($aMatches[1], $aExtensions)) {
|
||||
$aExtensions[] = $aMatches[1];
|
||||
}
|
||||
|
||||
@@ -124,4 +123,4 @@ class PortalCollector extends AbstractDataCollector
|
||||
return 'portal';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,4 +52,4 @@ class AbstractConfiguration
|
||||
return $this->oModuleDesign;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -44,8 +45,7 @@ class Basic extends AbstractConfiguration
|
||||
*/
|
||||
public function Process(Container $oContainer)
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
// Parsing file
|
||||
// - Default values
|
||||
$aPortalConf = $this->GetInitialPortalConf();
|
||||
@@ -55,9 +55,7 @@ class Basic extends AbstractConfiguration
|
||||
$aPortalConf = $this->AppendLogoUri($aPortalConf);
|
||||
// - Rectifying portal favicon url
|
||||
$aPortalConf = $this->AppendFavIconUri($aPortalConf);
|
||||
}
|
||||
catch (Exception $oException)
|
||||
{
|
||||
} catch (Exception $oException) {
|
||||
throw new Exception('Error while parsing portal configuration file : '.$oException->getMessage());
|
||||
}
|
||||
|
||||
@@ -72,35 +70,35 @@ class Basic extends AbstractConfiguration
|
||||
*/
|
||||
private function GetInitialPortalConf()
|
||||
{
|
||||
$aPortalConf = array(
|
||||
'properties' => array(
|
||||
$aPortalConf = [
|
||||
'properties' => [
|
||||
'id' => $_ENV['PORTAL_ID'],
|
||||
'ui_version' => '2017',
|
||||
'name' => 'Page:DefaultTitle',
|
||||
'logo' => Branding::GetPortalLogoAbsoluteUrl(),
|
||||
'favicon' => Branding::GetPortalFavIconAbsoluteUrl(),
|
||||
'themes' => array(
|
||||
'themes' => [
|
||||
'bootstrap' => 'itop-portal-base/portal/public/css/bootstrap-theme-combodo.scss',
|
||||
'portal' => 'itop-portal-base/portal/public/css/portal.scss',
|
||||
'others' => array(),
|
||||
),
|
||||
'templates' => array(
|
||||
'others' => [],
|
||||
],
|
||||
'templates' => [
|
||||
'layout' => 'itop-portal-base/portal/templates/layout.html.twig',
|
||||
'home' => 'itop-portal-base/portal/templates/home/layout.html.twig',
|
||||
),
|
||||
],
|
||||
'urlmaker_class' => null,
|
||||
'triggers_query' => null,
|
||||
'attachments' => array(
|
||||
'attachments' => [
|
||||
'allow_delete' => true,
|
||||
),
|
||||
'allowed_portals' => array(
|
||||
],
|
||||
'allowed_portals' => [
|
||||
'opening_mode' => null,
|
||||
),
|
||||
),
|
||||
'forms' => array(),
|
||||
'bricks' => array(),
|
||||
],
|
||||
],
|
||||
'forms' => [],
|
||||
'bricks' => [],
|
||||
'bricks_total_width' => 0,
|
||||
);
|
||||
];
|
||||
|
||||
return $aPortalConf;
|
||||
}
|
||||
@@ -114,10 +112,8 @@ class Basic extends AbstractConfiguration
|
||||
private function ParseGlobalProperties(array $aPortalConf)
|
||||
{
|
||||
/** @var \MFElement $oPropertyNode */
|
||||
foreach ($this->GetModuleDesign()->GetNodes('/module_design/properties/*') as $oPropertyNode)
|
||||
{
|
||||
switch ($oPropertyNode->nodeName)
|
||||
{
|
||||
foreach ($this->GetModuleDesign()->GetNodes('/module_design/properties/*') as $oPropertyNode) {
|
||||
switch ($oPropertyNode->nodeName) {
|
||||
case 'ui_version':
|
||||
case 'name':
|
||||
case 'urlmaker_class':
|
||||
@@ -154,22 +150,20 @@ class Basic extends AbstractConfiguration
|
||||
private function ParseTemplateAndTheme(array $aPortalConf, DesignElement $oPropertyNode)
|
||||
{
|
||||
/** @var \MFElement $oSubNode */
|
||||
foreach ($oPropertyNode->GetNodes('template|theme') as $oSubNode)
|
||||
{
|
||||
if (!$oSubNode->hasAttribute('id') || $oSubNode->GetText(null) === null)
|
||||
{
|
||||
foreach ($oPropertyNode->GetNodes('template|theme') as $oSubNode) {
|
||||
if (!$oSubNode->hasAttribute('id') || $oSubNode->GetText(null) === null) {
|
||||
throw new DOMFormatException(
|
||||
'Tag '.$oSubNode->nodeName.' must have a "id" attribute as well as a value',
|
||||
null, null, $oSubNode
|
||||
null,
|
||||
null,
|
||||
$oSubNode
|
||||
);
|
||||
}
|
||||
|
||||
$sNodeId = $oSubNode->getAttribute('id');
|
||||
switch ($oSubNode->nodeName)
|
||||
{
|
||||
switch ($oSubNode->nodeName) {
|
||||
case 'theme':
|
||||
switch ($sNodeId)
|
||||
{
|
||||
switch ($sNodeId) {
|
||||
case 'bootstrap':
|
||||
case 'portal':
|
||||
case 'custom':
|
||||
@@ -181,8 +175,7 @@ class Basic extends AbstractConfiguration
|
||||
}
|
||||
break;
|
||||
case 'template':
|
||||
switch ($sNodeId)
|
||||
{
|
||||
switch ($sNodeId) {
|
||||
case 'layout':
|
||||
case 'home':
|
||||
$aPortalConf['properties']['templates'][$sNodeId] = $oSubNode->GetText(null);
|
||||
@@ -190,19 +183,21 @@ class Basic extends AbstractConfiguration
|
||||
default:
|
||||
$aMatches = [];
|
||||
// allowed format is: <class implementing TemplatesProviderInterface>:<template_id>
|
||||
if(preg_match('#([\w\\\d_]+):(\w+)#', $sNodeId, $aMatches)){
|
||||
try{
|
||||
if (preg_match('#([\w\\\d_]+):(\w+)#', $sNodeId, $aMatches)) {
|
||||
try {
|
||||
$oClass = new ReflectionClass($aMatches[1]);
|
||||
if($oClass->implementsInterface(TemplatesProviderInterface::class)){
|
||||
if ($oClass->implementsInterface(TemplatesProviderInterface::class)) {
|
||||
$aPortalConf['properties']['templates'][$aMatches[1]][$aMatches[2]] = $oSubNode->GetText(null);
|
||||
break;
|
||||
}
|
||||
} catch (Exception) {
|
||||
}
|
||||
catch(Exception){}
|
||||
}
|
||||
throw new DOMFormatException(
|
||||
'Template ID "'.$sNodeId.'" is not handled in module design templates property',
|
||||
null, null, $oSubNode
|
||||
null,
|
||||
null,
|
||||
$oSubNode
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -221,16 +216,13 @@ class Basic extends AbstractConfiguration
|
||||
private function ParseAttachments(array $aPortalConf, DesignElement $oPropertyNode)
|
||||
{
|
||||
/** @var \MFElement $oSubNode */
|
||||
foreach ($oPropertyNode->GetNodes('*') as $oSubNode)
|
||||
{
|
||||
switch ($oSubNode->nodeName)
|
||||
{
|
||||
foreach ($oPropertyNode->GetNodes('*') as $oSubNode) {
|
||||
switch ($oSubNode->nodeName) {
|
||||
case 'allow_delete':
|
||||
$sValue = $oSubNode->GetText();
|
||||
// If the text is null, we keep the default value
|
||||
// Else we set it
|
||||
if ($sValue !== null)
|
||||
{
|
||||
if ($sValue !== null) {
|
||||
$aPortalConf['properties']['attachments'][$oSubNode->nodeName] = ($sValue === 'true') ? true : false;
|
||||
}
|
||||
break;
|
||||
@@ -249,16 +241,13 @@ class Basic extends AbstractConfiguration
|
||||
private function ParseAllowedPortalsOptions(array $aPortalConf, DesignElement $oPropertyNode)
|
||||
{
|
||||
/** @var \MFElement $oSubNode */
|
||||
foreach ($oPropertyNode->GetNodes('*') as $oSubNode)
|
||||
{
|
||||
switch ($oSubNode->nodeName)
|
||||
{
|
||||
foreach ($oPropertyNode->GetNodes('*') as $oSubNode) {
|
||||
switch ($oSubNode->nodeName) {
|
||||
case 'opening_mode':
|
||||
$sValue = $oSubNode->GetText();
|
||||
// If the text is null, we keep the default value
|
||||
// Else we set it
|
||||
if ($sValue !== null)
|
||||
{
|
||||
if ($sValue !== null) {
|
||||
$aPortalConf['properties']['allowed_portals'][$oSubNode->nodeName] = ($sValue === 'self') ? 'self' : 'tab';
|
||||
}
|
||||
break;
|
||||
@@ -304,4 +293,4 @@ class Basic extends AbstractConfiguration
|
||||
|
||||
return $aPortalConf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -42,23 +43,19 @@ class Forms extends AbstractConfiguration
|
||||
*/
|
||||
public function Process(Container $oContainer)
|
||||
{
|
||||
$aForms = array();
|
||||
$aForms = [];
|
||||
|
||||
/** @var \MFElement $oFormNode */
|
||||
foreach ($this->GetModuleDesign()->GetNodes('/module_design/forms/form') as $oFormNode)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach ($this->GetModuleDesign()->GetNodes('/module_design/forms/form') as $oFormNode) {
|
||||
try {
|
||||
// Parsing form id
|
||||
$sFormId = $oFormNode->getAttribute('id');
|
||||
if ($oFormNode->getAttribute('id') === '')
|
||||
{
|
||||
if ($oFormNode->getAttribute('id') === '') {
|
||||
throw new DOMFormatException('form tag must have an id attribute', 0, null, $oFormNode);
|
||||
}
|
||||
|
||||
// Parsing form object class
|
||||
if ($oFormNode->GetUniqueElement('class')->GetText() === null)
|
||||
{
|
||||
if ($oFormNode->GetUniqueElement('class')->GetText() === null) {
|
||||
throw new DOMFormatException('Class tag must be defined', 0, null, $oFormNode);
|
||||
}
|
||||
|
||||
@@ -66,29 +63,26 @@ class Forms extends AbstractConfiguration
|
||||
$sFormClass = $oFormNode->GetUniqueElement('class')->GetText();
|
||||
|
||||
// Parsing properties
|
||||
$aFormProperties = array(
|
||||
$aFormProperties = [
|
||||
'display_mode' => ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE,
|
||||
'always_show_submit' => ApplicationHelper::FORM_DEFAULT_ALWAYS_SHOW_SUBMIT,
|
||||
'navigation_rules' => array(
|
||||
'submit' => array(
|
||||
'navigation_rules' => [
|
||||
'submit' => [
|
||||
NavigationRuleHelper::ENUM_ORIGIN_PAGE => null,
|
||||
NavigationRuleHelper::ENUM_ORIGIN_MODAL => null,
|
||||
),
|
||||
'cancel' => array(
|
||||
],
|
||||
'cancel' => [
|
||||
NavigationRuleHelper::ENUM_ORIGIN_PAGE => null,
|
||||
NavigationRuleHelper::ENUM_ORIGIN_MODAL => null,
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$aAllowedNavRulesButtonCodes = array_keys($aFormProperties['navigation_rules']);
|
||||
if ($oFormNode->GetOptionalElement('properties') !== null)
|
||||
{
|
||||
if ($oFormNode->GetOptionalElement('properties') !== null) {
|
||||
/** @var \MFElement $oPropertyNode */
|
||||
foreach ($oFormNode->GetOptionalElement('properties')->GetNodes('*') as $oPropertyNode)
|
||||
{
|
||||
switch ($oPropertyNode->nodeName)
|
||||
{
|
||||
foreach ($oFormNode->GetOptionalElement('properties')->GetNodes('*') as $oPropertyNode) {
|
||||
switch ($oPropertyNode->nodeName) {
|
||||
case 'display_mode':
|
||||
$aFormProperties['display_mode'] = $oPropertyNode->GetText(ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE);
|
||||
break;
|
||||
@@ -99,28 +93,23 @@ class Forms extends AbstractConfiguration
|
||||
|
||||
case 'navigation_rules':
|
||||
/** @var \MFElement $oNavRuleButtonNode */
|
||||
foreach($oPropertyNode->GetNodes('*') as $oNavRuleButtonNode)
|
||||
{
|
||||
foreach ($oPropertyNode->GetNodes('*') as $oNavRuleButtonNode) {
|
||||
$sNavRuleButtonCode = $oNavRuleButtonNode->nodeName;
|
||||
if(!in_array($sNavRuleButtonCode, $aAllowedNavRulesButtonCodes))
|
||||
{
|
||||
if (!in_array($sNavRuleButtonCode, $aAllowedNavRulesButtonCodes)) {
|
||||
throw new DOMFormatException('navigation_rules tag must only contain '.implode('|', $aAllowedNavRulesButtonCodes).' tags, "'.$sNavRuleButtonCode.'" given.', null, null, $oPropertyNode);
|
||||
}
|
||||
|
||||
/** @var \MFElement $oNavRuleOriginNode */
|
||||
foreach($oNavRuleButtonNode->GetNodes('*') as $oNavRuleOriginNode)
|
||||
{
|
||||
foreach ($oNavRuleButtonNode->GetNodes('*') as $oNavRuleOriginNode) {
|
||||
$sNavRuleOrigin = $oNavRuleOriginNode->nodeName;
|
||||
if(!in_array($sNavRuleOrigin, NavigationRuleHelper::GetAllowedOrigins()))
|
||||
{
|
||||
throw new DOMFormatException($sNavRuleButtonCode. ' tag must only contain '.implode('|', NavigationRuleHelper::GetAllowedOrigins()).' tags, "'.$sNavRuleOrigin.'" given.', null, null, $oPropertyNode);
|
||||
if (!in_array($sNavRuleOrigin, NavigationRuleHelper::GetAllowedOrigins())) {
|
||||
throw new DOMFormatException($sNavRuleButtonCode.' tag must only contain '.implode('|', NavigationRuleHelper::GetAllowedOrigins()).' tags, "'.$sNavRuleOrigin.'" given.', null, null, $oPropertyNode);
|
||||
}
|
||||
|
||||
$sNavRuleId = $oNavRuleOriginNode->GetText();
|
||||
// Note: We don't check is rule exists as it would introduce a dependency to the NavigationRuleHelper service.
|
||||
// Maybe we will consider it later.
|
||||
if(empty($sNavRuleId))
|
||||
{
|
||||
if (empty($sNavRuleId)) {
|
||||
throw new DOMFormatException($sNavRuleButtonCode.' tag cannot be empty.', null, null, $oPropertyNode);
|
||||
}
|
||||
|
||||
@@ -129,8 +118,7 @@ class Forms extends AbstractConfiguration
|
||||
|
||||
// Set modal rule as the same as default is not present.
|
||||
// We preset it so we don't have to make checks elsewhere in the code when using it.
|
||||
if(empty($aFormProperties['navigation_rules'][$sNavRuleButtonCode][NavigationRuleHelper::ENUM_ORIGIN_MODAL]))
|
||||
{
|
||||
if (empty($aFormProperties['navigation_rules'][$sNavRuleButtonCode][NavigationRuleHelper::ENUM_ORIGIN_MODAL])) {
|
||||
$aFormProperties['navigation_rules'][$sNavRuleButtonCode][NavigationRuleHelper::ENUM_ORIGIN_MODAL] = $aFormProperties['navigation_rules'][$sNavRuleButtonCode][NavigationRuleHelper::ENUM_ORIGIN_PAGE];
|
||||
}
|
||||
}
|
||||
@@ -139,36 +127,33 @@ class Forms extends AbstractConfiguration
|
||||
}
|
||||
|
||||
// Parsing available modes for that form (view, edit, create, apply_stimulus)
|
||||
$aFormStimuli = array();
|
||||
if (($oFormNode->GetOptionalElement('modes') !== null) && ($oFormNode->GetOptionalElement('modes')->GetNodes('mode')->length > 0))
|
||||
{
|
||||
$aModes = array();
|
||||
$aFormStimuli = [];
|
||||
if (($oFormNode->GetOptionalElement('modes') !== null) && ($oFormNode->GetOptionalElement('modes')->GetNodes('mode')->length > 0)) {
|
||||
$aModes = [];
|
||||
/** @var \MFElement $oModeNode */
|
||||
foreach ($oFormNode->GetOptionalElement('modes')->GetNodes('mode') as $oModeNode)
|
||||
{
|
||||
foreach ($oFormNode->GetOptionalElement('modes')->GetNodes('mode') as $oModeNode) {
|
||||
$sModeId = $oModeNode->getAttribute('id');
|
||||
if ($sModeId === '')
|
||||
{
|
||||
throw new DOMFormatException('mode tag must have an id attribute', 0, null,
|
||||
$oFormNode);
|
||||
if ($sModeId === '') {
|
||||
throw new DOMFormatException(
|
||||
'mode tag must have an id attribute',
|
||||
0,
|
||||
null,
|
||||
$oFormNode
|
||||
);
|
||||
}
|
||||
$aModes[] = $sModeId;
|
||||
|
||||
// If apply_stimulus mode, checking if stimuli are defined
|
||||
if ($sModeId === 'apply_stimulus')
|
||||
{
|
||||
if ($sModeId === 'apply_stimulus') {
|
||||
$oStimuliNode = $oModeNode->GetOptionalElement('stimuli');
|
||||
// If stimuli are defined, we overwrite the form that could have been set by the generic form
|
||||
if ($oStimuliNode !== null)
|
||||
{
|
||||
if ($oStimuliNode !== null) {
|
||||
/** @var \MFElement $oStimulusNode */
|
||||
foreach ($oStimuliNode->GetNodes('stimulus') as $oStimulusNode)
|
||||
{
|
||||
foreach ($oStimuliNode->GetNodes('stimulus') as $oStimulusNode) {
|
||||
$sStimulusCode = $oStimulusNode->getAttribute('id');
|
||||
|
||||
// Removing default form if present (in case the default forms were parsed before the current one (from current or parent class))
|
||||
if (isset($aForms[$sFormClass]['apply_stimulus'][$sStimulusCode]))
|
||||
{
|
||||
if (isset($aForms[$sFormClass]['apply_stimulus'][$sStimulusCode])) {
|
||||
unset($aForms[$sFormClass]['apply_stimulus'][$sStimulusCode]);
|
||||
}
|
||||
|
||||
@@ -177,111 +162,95 @@ class Forms extends AbstractConfiguration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// If no mode was specified, we set it all but stimuli as it would have no sense that every transition forms
|
||||
// have as many fields displayed as a regular edit form for example.
|
||||
$aModes = array('view', 'edit', 'create');
|
||||
$aModes = ['view', 'edit', 'create'];
|
||||
}
|
||||
|
||||
// Parsing fields
|
||||
$aFields = array(
|
||||
$aFields = [
|
||||
'_brought_by' => $sFormClass,
|
||||
'id' => $sFormId,
|
||||
'type' => null,
|
||||
'properties' => $aFormProperties,
|
||||
'fields' => null,
|
||||
'layout' => null,
|
||||
);
|
||||
];
|
||||
// ... either enumerated fields ...
|
||||
if ($oFormNode->GetOptionalElement('fields') !== null)
|
||||
{
|
||||
if ($oFormNode->GetOptionalElement('fields') !== null) {
|
||||
$aFields['type'] = 'custom_list';
|
||||
$aFields['fields'] = array();
|
||||
$aFields['fields'] = [];
|
||||
|
||||
/** @var \MFElement $oFieldNode */
|
||||
foreach ($oFormNode->GetOptionalElement('fields')->GetNodes('field') as $oFieldNode)
|
||||
{
|
||||
foreach ($oFormNode->GetOptionalElement('fields')->GetNodes('field') as $oFieldNode) {
|
||||
$sFieldId = $oFieldNode->getAttribute('id');
|
||||
if ($sFieldId !== '')
|
||||
{
|
||||
$aField = array();
|
||||
if ($sFieldId !== '') {
|
||||
$aField = [];
|
||||
// Parsing field options like read_only, hidden and mandatory
|
||||
if ($oFieldNode->GetOptionalElement('read_only'))
|
||||
{
|
||||
if ($oFieldNode->GetOptionalElement('read_only')) {
|
||||
$aField['readonly'] = ($oFieldNode->GetOptionalElement('read_only')->GetText('true') === 'true') ? true : false;
|
||||
}
|
||||
if ($oFieldNode->GetOptionalElement('mandatory'))
|
||||
{
|
||||
if ($oFieldNode->GetOptionalElement('mandatory')) {
|
||||
$aField['mandatory'] = ($oFieldNode->GetOptionalElement('mandatory')->GetText('true') === 'true') ? true : false;
|
||||
}
|
||||
if ($oFieldNode->GetOptionalElement('hidden'))
|
||||
{
|
||||
if ($oFieldNode->GetOptionalElement('hidden')) {
|
||||
$aField['hidden'] = ($oFieldNode->GetOptionalElement('hidden')->GetText('true') === 'true') ? true : false;
|
||||
}
|
||||
|
||||
$aFields['fields'][$sFieldId] = $aField;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('Field tag must have an id attribute', 0, null,
|
||||
$oFormNode);
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'Field tag must have an id attribute',
|
||||
0,
|
||||
null,
|
||||
$oFormNode
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// ... or the default zlist
|
||||
else
|
||||
{
|
||||
else {
|
||||
$aFields['type'] = 'zlist';
|
||||
$aFields['fields'] = 'details';
|
||||
}
|
||||
|
||||
// Parsing presentation
|
||||
if ($oFormNode->GetOptionalElement('twig') !== null)
|
||||
{
|
||||
if ($oFormNode->GetOptionalElement('twig') !== null) {
|
||||
// Extracting the twig template and removing the first and last lines (twig tags)
|
||||
$sXml = $this->GetModuleDesign()->saveXML($oFormNode->GetOptionalElement('twig'));
|
||||
$sXml = preg_replace('/^.+\n/', '', $sXml);
|
||||
$sXml = preg_replace('/\n.+$/', '', $sXml);
|
||||
|
||||
$aFields['layout'] = array(
|
||||
$aFields['layout'] = [
|
||||
'type' => (preg_match('/{{|{#|{%/', $sXml) === 1) ? 'twig' : 'xhtml',
|
||||
'content' => $sXml,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
// Adding form for each class / mode
|
||||
foreach ($aModes as $sMode)
|
||||
{
|
||||
foreach ($aModes as $sMode) {
|
||||
// Initializing current class if necessary
|
||||
if (!isset($aForms[$sFormClass]))
|
||||
{
|
||||
$aForms[$sFormClass] = array();
|
||||
if (!isset($aForms[$sFormClass])) {
|
||||
$aForms[$sFormClass] = [];
|
||||
}
|
||||
|
||||
// For stimuli we need to fill the matrix as only some stimuli might have been given
|
||||
if ($sMode === 'apply_stimulus')
|
||||
{
|
||||
if ($sMode === 'apply_stimulus') {
|
||||
// Iterating over current class and child classes
|
||||
foreach (MetaModel::EnumChildClasses($sFormClass, ENUM_CHILD_CLASSES_ALL) as $sChildClass)
|
||||
{
|
||||
foreach (MetaModel::EnumChildClasses($sFormClass, ENUM_CHILD_CLASSES_ALL) as $sChildClass) {
|
||||
// Initializing child class if necessary
|
||||
if (!isset($aForms[$sChildClass][$sMode]))
|
||||
{
|
||||
$aForms[$sChildClass][$sMode] = array();
|
||||
if (!isset($aForms[$sChildClass][$sMode])) {
|
||||
$aForms[$sChildClass][$sMode] = [];
|
||||
}
|
||||
|
||||
// If no explicit stimulus defined in this form, than it's the generic stimulus form
|
||||
// we need to find which stimulus are missing
|
||||
if(empty($aFormStimuli))
|
||||
{
|
||||
$aExistingStimuli = array();
|
||||
if (empty($aFormStimuli)) {
|
||||
$aExistingStimuli = [];
|
||||
// Keep only stimuli brought by the class itself
|
||||
foreach($aForms[$sChildClass][$sMode] as $sExistingStimulus => $aExistingForm)
|
||||
{
|
||||
if(!in_array($aExistingForm['_brought_by'], MetaModel::EnumParentClasses($sFormClass, ENUM_PARENT_CLASSES_EXCLUDELEAF)))
|
||||
{
|
||||
foreach ($aForms[$sChildClass][$sMode] as $sExistingStimulus => $aExistingForm) {
|
||||
if (!in_array($aExistingForm['_brought_by'], MetaModel::EnumParentClasses($sFormClass, ENUM_PARENT_CLASSES_EXCLUDELEAF))) {
|
||||
//continue;
|
||||
$aExistingStimuli[] = $sExistingStimulus;
|
||||
}
|
||||
@@ -290,51 +259,43 @@ class Forms extends AbstractConfiguration
|
||||
$aMissingStimulusForms = array_diff($aDatamodelStimuli, $aExistingStimuli);
|
||||
}
|
||||
// Otherwise, we process only the ones for this form
|
||||
else
|
||||
{
|
||||
else {
|
||||
$aMissingStimulusForms = $aFormStimuli;
|
||||
}
|
||||
|
||||
// Retrieve missing stimuli of the child class to fill the matrix
|
||||
foreach ($aMissingStimulusForms as $sDatamodelStimulus)
|
||||
{
|
||||
foreach ($aMissingStimulusForms as $sDatamodelStimulus) {
|
||||
// Check some facts about the target form
|
||||
$bFormExists = isset($aForms[$sChildClass][$sMode][$sDatamodelStimulus]);
|
||||
$bWasFormBroughtByParent = $bFormExists && in_array($aForms[$sChildClass][$sMode][$sDatamodelStimulus]['_brought_by'], MetaModel::EnumParentClasses($sFormClass, ENUM_PARENT_CLASSES_EXCLUDELEAF));
|
||||
|
||||
// Check if we need to overwrite (form created by parent)
|
||||
$bOverwriteNecessary = false;
|
||||
if($bWasFormBroughtByParent || in_array($sDatamodelStimulus, $aFormStimuli))
|
||||
{
|
||||
if ($bWasFormBroughtByParent || in_array($sDatamodelStimulus, $aFormStimuli)) {
|
||||
$bOverwriteNecessary = true;
|
||||
}
|
||||
|
||||
// Setting form if not defined OR if it was defined by a parent (abstract) class
|
||||
if (!$bFormExists || $bOverwriteNecessary)
|
||||
{
|
||||
if (!$bFormExists || $bOverwriteNecessary) {
|
||||
$aForms[$sChildClass][$sMode][$sDatamodelStimulus] = $aFields;
|
||||
$aForms[$sChildClass][$sMode][$sDatamodelStimulus]['id'] = 'apply_stimulus-'.$sChildClass.'-'.$sDatamodelStimulus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (!isset($aForms[$sFormClass][$sMode]))
|
||||
{
|
||||
} elseif (!isset($aForms[$sFormClass][$sMode])) {
|
||||
$aForms[$sFormClass][$sMode] = $aFields;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('There is already a form for the class "'.$sFormClass.'" in "'.$sMode.'"',
|
||||
null, null, $oFormNode);
|
||||
} else {
|
||||
throw new DOMFormatException(
|
||||
'There is already a form for the class "'.$sFormClass.'" in "'.$sMode.'"',
|
||||
null,
|
||||
null,
|
||||
$oFormNode
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (DOMFormatException $e)
|
||||
{
|
||||
} catch (DOMFormatException $e) {
|
||||
throw new Exception('Could not create from [id="'.$oFormNode->getAttribute('id').'"] from XML because of a DOM problem : '.$e->getMessage());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Could not create from from XML : '.$oFormNode->Dump().' '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -343,4 +304,4 @@ class Forms extends AbstractConfiguration
|
||||
$aPortalConf['forms'] = $aForms;
|
||||
$oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -39,51 +40,52 @@ class Lists extends AbstractConfiguration
|
||||
public function Process(Container $oContainer)
|
||||
{
|
||||
$iDefaultItemRank = 0;
|
||||
$aClassesLists = array();
|
||||
$aClassesLists = [];
|
||||
|
||||
// Parsing XML file
|
||||
// - Each classes
|
||||
/** @var \MFElement $oClassNode */
|
||||
foreach ($this->GetModuleDesign()->GetNodes('/module_design/classes/class') as $oClassNode)
|
||||
{
|
||||
$aClassLists = array();
|
||||
foreach ($this->GetModuleDesign()->GetNodes('/module_design/classes/class') as $oClassNode) {
|
||||
$aClassLists = [];
|
||||
$sClassId = $oClassNode->getAttribute('id');
|
||||
if ($sClassId === null)
|
||||
{
|
||||
if ($sClassId === null) {
|
||||
throw new DOMFormatException('Class tag must have an id attribute', 0, null, $oClassNode);
|
||||
}
|
||||
|
||||
// - Each lists
|
||||
/** @var \MFElement $oListNode */
|
||||
foreach ($oClassNode->GetNodes('./lists/list') as $oListNode)
|
||||
{
|
||||
$aListItems = array();
|
||||
foreach ($oClassNode->GetNodes('./lists/list') as $oListNode) {
|
||||
$aListItems = [];
|
||||
$sListId = $oListNode->getAttribute('id');
|
||||
if ($sListId === null)
|
||||
{
|
||||
throw new DOMFormatException('List tag of "'.$sClassId.'" class must have an id attribute', null,
|
||||
null, $oListNode);
|
||||
if ($sListId === null) {
|
||||
throw new DOMFormatException(
|
||||
'List tag of "'.$sClassId.'" class must have an id attribute',
|
||||
null,
|
||||
null,
|
||||
$oListNode
|
||||
);
|
||||
}
|
||||
|
||||
// - Each items
|
||||
/** @var \MFElement $oItemNode */
|
||||
foreach ($oListNode->GetNodes('./items/item') as $oItemNode)
|
||||
{
|
||||
foreach ($oListNode->GetNodes('./items/item') as $oItemNode) {
|
||||
$sItemId = $oItemNode->getAttribute('id');
|
||||
if ($sItemId === null)
|
||||
{
|
||||
throw new DOMFormatException('Item tag of "'.$sItemId.'" list must have an id attribute', null,
|
||||
null, $oItemNode);
|
||||
if ($sItemId === null) {
|
||||
throw new DOMFormatException(
|
||||
'Item tag of "'.$sItemId.'" list must have an id attribute',
|
||||
null,
|
||||
null,
|
||||
$oItemNode
|
||||
);
|
||||
}
|
||||
|
||||
$aItem = array(
|
||||
$aItem = [
|
||||
'att_code' => $sItemId,
|
||||
'rank' => $iDefaultItemRank,
|
||||
);
|
||||
];
|
||||
|
||||
$oRankNode = $oItemNode->GetOptionalElement('rank');
|
||||
if ($oRankNode !== null)
|
||||
{
|
||||
if ($oRankNode !== null) {
|
||||
$aItem['rank'] = $oRankNode->GetText($iDefaultItemRank);
|
||||
}
|
||||
|
||||
@@ -100,8 +102,7 @@ class Lists extends AbstractConfiguration
|
||||
}
|
||||
|
||||
// - Adding class only if it has at least one list
|
||||
if (!empty($aClassLists))
|
||||
{
|
||||
if (!empty($aClassLists)) {
|
||||
$aClassesLists[$sClassId] = $aClassLists;
|
||||
}
|
||||
}
|
||||
@@ -110,4 +111,4 @@ class Lists extends AbstractConfiguration
|
||||
$oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -46,4 +47,4 @@ class ApplicationContextSetPluginPropertyClass
|
||||
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', UserRights::GetUserLanguage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -31,16 +32,16 @@ use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
*/
|
||||
class ApplicationContextSetUrlMakerClass
|
||||
{
|
||||
/** @var array $aCombodoPortalInstanceConf */
|
||||
private $aCombodoPortalInstanceConf;
|
||||
/** @var array $aCombodoPortalInstanceConf */
|
||||
private $aCombodoPortalInstanceConf;
|
||||
|
||||
/**
|
||||
* @param array $aCombodoPortalInstanceConf
|
||||
*/
|
||||
public function __construct($aCombodoPortalInstanceConf)
|
||||
{
|
||||
$this->aCombodoPortalInstanceConf = $aCombodoPortalInstanceConf;
|
||||
}
|
||||
/**
|
||||
* @param array $aCombodoPortalInstanceConf
|
||||
*/
|
||||
public function __construct($aCombodoPortalInstanceConf)
|
||||
{
|
||||
$this->aCombodoPortalInstanceConf = $aCombodoPortalInstanceConf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestEvent $oRequestEvent
|
||||
@@ -51,4 +52,4 @@ class ApplicationContextSetUrlMakerClass
|
||||
ApplicationContext::SetUrlMakerClass($this->aCombodoPortalInstanceConf['properties']['urlmaker_class']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -56,19 +57,15 @@ class CssFromSassCompiler
|
||||
return;
|
||||
}
|
||||
|
||||
$aImportPaths = array($_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/');
|
||||
$aImportPaths = [$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/'];
|
||||
foreach ($this->aCombodoPortalInstanceConf['properties']['themes'] as $sKey => $value) {
|
||||
if (!is_array($value))
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$value, $aImportPaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($value as $sSubValue)
|
||||
{
|
||||
} else {
|
||||
foreach ($value as $sSubValue) {
|
||||
utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$sSubValue, $aImportPaths);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,8 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Portal\EventListener;
|
||||
|
||||
|
||||
use Dict;
|
||||
use ExceptionLog;
|
||||
use Symfony\Component\ErrorHandler\Exception\FlattenException;
|
||||
@@ -40,7 +38,6 @@ use Twig\Environment;
|
||||
*/
|
||||
class ExceptionListener
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -48,8 +45,7 @@ class ExceptionListener
|
||||
*/
|
||||
public function __construct(
|
||||
protected Environment $oTwig
|
||||
)
|
||||
{
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +55,7 @@ class ExceptionListener
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function onKernelException(ExceptionEvent $oEvent) : void
|
||||
public function onKernelException(ExceptionEvent $oEvent): void
|
||||
{
|
||||
// Get the exception object from the received event
|
||||
$oException = $oEvent->getThrowable();
|
||||
@@ -87,13 +83,11 @@ class ExceptionListener
|
||||
// Prepare flatten exception
|
||||
$oFlattenException = ($_SERVER['APP_DEBUG'] == 1) ? FlattenException::createFromThrowable($oException) : null;
|
||||
// Remove APPROOT from file paths if in production (SF context)
|
||||
if (!is_null($oFlattenException) && ($_SERVER['APP_ENV'] === 'prod'))
|
||||
{
|
||||
if (!is_null($oFlattenException) && ($_SERVER['APP_ENV'] === 'prod')) {
|
||||
$oFlattenException->setFile($this->removeAppRootFromPath($oFlattenException->getFile()));
|
||||
|
||||
$aTrace = $oFlattenException->getTrace();
|
||||
foreach ($aTrace as $iIdx => $aEntry)
|
||||
{
|
||||
foreach ($aTrace as $iIdx => $aEntry) {
|
||||
$aTrace[$iIdx]['file'] = $this->removeAppRootFromPath($aEntry['file']);
|
||||
}
|
||||
$oFlattenException->setTrace($aTrace, $oFlattenException->getFile(), $oFlattenException->getLine());
|
||||
@@ -105,20 +99,17 @@ class ExceptionListener
|
||||
]);
|
||||
|
||||
// Prepare data for template
|
||||
$aData = array(
|
||||
$aData = [
|
||||
'exception' => $oFlattenException,
|
||||
'code' => $iStatusCode,
|
||||
'error_title' => $sErrorTitle,
|
||||
'error_message' => $sErrorMessage,
|
||||
);
|
||||
];
|
||||
|
||||
// Generate the response
|
||||
if ($oEvent->getRequest()->isXmlHttpRequest())
|
||||
{
|
||||
if ($oEvent->getRequest()->isXmlHttpRequest()) {
|
||||
$oResponse = new JsonResponse($aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oResponse = new Response();
|
||||
$oResponse->setContent($this->oTwig->render('itop-portal-base/portal/templates/errors/layout.html.twig', $aData));
|
||||
}
|
||||
@@ -164,5 +155,4 @@ class ExceptionListener
|
||||
return str_replace($sNormalizedAppRoot, '', $sNormalizedInputPath);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -78,7 +79,7 @@ class UserProvider
|
||||
// - Checking user rights and prompt if needed (401 HTTP code returned if XHR request)
|
||||
$iExitMethod = ($oRequestEvent->getRequest()->isXmlHttpRequest()) ? LoginWebPage::EXIT_RETURN : LoginWebPage::EXIT_PROMPT;
|
||||
$iLogonRes = LoginWebPage::DoLoginEx($this->sPortalId, false, $iExitMethod);
|
||||
if( ($iExitMethod === LoginWebPage::EXIT_RETURN) && ($iLogonRes != 0) ) {
|
||||
if (($iExitMethod === LoginWebPage::EXIT_RETURN) && ($iLogonRes != 0)) {
|
||||
die(Dict::S('Portal:ErrorUserLoggedOut'));
|
||||
}
|
||||
// - User must be associated with a Contact
|
||||
@@ -92,8 +93,8 @@ class UserProvider
|
||||
throw new Exception('Could not load connected user.');
|
||||
}
|
||||
|
||||
// User allowed to log off or not
|
||||
$this->bUserCanLogOff = utils::CanLogOff();
|
||||
// User allowed to log off or not
|
||||
$this->bUserCanLogOff = utils::CanLogOff();
|
||||
|
||||
// Allowed portals
|
||||
$aAllowedPortals = UserRights::GetAllowedPortals();
|
||||
@@ -146,5 +147,4 @@ class UserProvider
|
||||
return $this->aAllowedPortals;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
use const UR_ACTION_READ;
|
||||
|
||||
/**
|
||||
@@ -62,13 +63,13 @@ use const UR_ACTION_READ;
|
||||
class ObjectFormManager extends FormManager
|
||||
{
|
||||
/** @var string ENUM_MODE_VIEW */
|
||||
const ENUM_MODE_VIEW = 'view';
|
||||
public const ENUM_MODE_VIEW = 'view';
|
||||
/** @var string ENUM_MODE_EDIT */
|
||||
const ENUM_MODE_EDIT = 'edit';
|
||||
public const ENUM_MODE_EDIT = 'edit';
|
||||
/** @var string ENUM_MODE_CREATE */
|
||||
const ENUM_MODE_CREATE = 'create';
|
||||
public const ENUM_MODE_CREATE = 'create';
|
||||
/** @var string ENUM_MODE_APPLY_STIMULUS */
|
||||
const ENUM_MODE_APPLY_STIMULUS = 'apply_stimulus';
|
||||
public const ENUM_MODE_APPLY_STIMULUS = 'apply_stimulus';
|
||||
|
||||
/** @var \cmdbAbstractObject $oObject */
|
||||
protected $oObject;
|
||||
@@ -79,14 +80,14 @@ class ObjectFormManager extends FormManager
|
||||
/** @var array $aFormProperties */
|
||||
protected $aFormProperties;
|
||||
/** @var array $aCallbackUrls */
|
||||
protected $aCallbackUrls = array();
|
||||
protected $aCallbackUrls = [];
|
||||
/**
|
||||
* List of hidden fields, used for form update (eg. remove them from the form regarding they dependencies)
|
||||
*
|
||||
* @var array $aHiddenFieldsId
|
||||
* @since 2.7.5
|
||||
*/
|
||||
protected $aHiddenFieldsId = array();
|
||||
protected $aHiddenFieldsId = [];
|
||||
|
||||
/**
|
||||
* @var ObjectFormHandlerHelper $oFormHandlerHelper
|
||||
@@ -95,7 +96,7 @@ class ObjectFormManager extends FormManager
|
||||
private $oFormHandlerHelper;
|
||||
|
||||
/** @var array $aPlugins plugins data */
|
||||
private array $aPlugins = array();
|
||||
private array $aPlugins = [];
|
||||
private array $aFieldsAtts = [];
|
||||
private array $aExtraData = [];
|
||||
private DOMDocument $oHtmlDocument;
|
||||
@@ -143,27 +144,22 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
$sObjectClass = $aJson['formobject_class'];
|
||||
|
||||
if (!isset($aJson['formobject_id']))
|
||||
{
|
||||
if (!isset($aJson['formobject_id'])) {
|
||||
$oObject = MetaModel::NewObject($sObjectClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Note : AllowAllData set to true here instead of checking scope's flag because we are displaying a value that has been set and validated
|
||||
$oObject = MetaModel::GetObject($sObjectClass, $aJson['formobject_id'], true, true);
|
||||
}
|
||||
$oFormManager->SetObject($oObject);
|
||||
|
||||
// Retrieving form mode
|
||||
if (!isset($aJson['formmode']))
|
||||
{
|
||||
if (!isset($aJson['formmode'])) {
|
||||
throw new Exception('Form mode must be defined in order to generate the form');
|
||||
}
|
||||
$oFormManager->SetMode($aJson['formmode']);
|
||||
|
||||
// Retrieving actions rules
|
||||
if (isset($aJson['formactionrulestoken']))
|
||||
{
|
||||
if (isset($aJson['formactionrulestoken'])) {
|
||||
$oFormManager->SetActionRulesToken($aJson['formactionrulestoken']);
|
||||
}
|
||||
|
||||
@@ -316,8 +312,7 @@ class ObjectFormManager extends FormManager
|
||||
{
|
||||
$aJson = parent::ToJSON();
|
||||
$aJson['formobject_class'] = get_class($this->oObject);
|
||||
if ($this->oObject->GetKey() > 0)
|
||||
{
|
||||
if ($this->oObject->GetKey() > 0) {
|
||||
$aJson['formobject_id'] = $this->oObject->GetKey();
|
||||
}
|
||||
$aJson['formmode'] = $this->sMode;
|
||||
@@ -338,11 +333,9 @@ class ObjectFormManager extends FormManager
|
||||
|
||||
// Building form from its properties
|
||||
// - Consistency checks for stimulus form
|
||||
if (isset($this->aFormProperties['stimulus_code']))
|
||||
{
|
||||
if (isset($this->aFormProperties['stimulus_code'])) {
|
||||
$aTransitions = MetaModel::EnumTransitions($sObjectClass, $this->oObject->GetState());
|
||||
if (!isset($aTransitions[$this->aFormProperties['stimulus_code']]))
|
||||
{
|
||||
if (!isset($aTransitions[$this->aFormProperties['stimulus_code']])) {
|
||||
$aStimuli = Metamodel::EnumStimuli($sObjectClass);
|
||||
$sStimulusLabel = $aStimuli[$this->aFormProperties['stimulus_code']]->GetLabel();
|
||||
|
||||
@@ -351,24 +344,22 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Adding rendered template to the form renderer as the base layout
|
||||
$this->oRenderer->SetBaseLayout($this->oHtmlDocument->saveHTML());
|
||||
|
||||
// Building the form
|
||||
foreach ($this->aFieldsAtts as $sAttCode => $iFieldFlags)
|
||||
{
|
||||
foreach ($this->aFieldsAtts as $sAttCode => $iFieldFlags) {
|
||||
// handle plugins fields
|
||||
if($this->sMode !== 'apply_stimulus'
|
||||
if ($this->sMode !== 'apply_stimulus'
|
||||
&& array_key_exists($sAttCode, $this->aExtraData)
|
||||
&& array_key_exists('plugin', $this->aExtraData[$sAttCode])){
|
||||
&& array_key_exists('plugin', $this->aExtraData[$sAttCode])) {
|
||||
$sPluginName = $this->aExtraData[$sAttCode]['plugin'];
|
||||
switch($sPluginName){
|
||||
switch ($sPluginName) {
|
||||
case AttachmentPlugIn::class:
|
||||
$this->AddAttachmentField($this->oForm, $sAttCode, $this->aExtraData);
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Unknown plugin ' . $sPluginName);
|
||||
throw new Exception('Unknown plugin '.$sPluginName);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -377,57 +368,44 @@ class ObjectFormManager extends FormManager
|
||||
|
||||
/** @var Field $oField */
|
||||
$oField = null;
|
||||
if (is_callable([$oAttDef, 'MakeFormField']))
|
||||
{
|
||||
if (is_callable([$oAttDef, 'MakeFormField'])) {
|
||||
$oField = $oAttDef->MakeFormField($this->oObject);
|
||||
}
|
||||
|
||||
// Failsafe for AttributeType that would not have MakeFormField and therefore could not be used in a form
|
||||
if ($oField !== null)
|
||||
{
|
||||
if ($this->sMode !== static::ENUM_MODE_VIEW)
|
||||
{
|
||||
if ($oField !== null) {
|
||||
if ($this->sMode !== static::ENUM_MODE_VIEW) {
|
||||
// Field dependencies
|
||||
$aFieldDependencies = $oAttDef->GetPrerequisiteAttributes();
|
||||
if (!empty($aFieldDependencies))
|
||||
{
|
||||
if (!empty($aFieldDependencies)) {
|
||||
$this->oForm->AddFieldDependencies($oField->GetId(), $aFieldDependencies);
|
||||
}
|
||||
|
||||
// Setting the field flags
|
||||
// - If it's locked because slave, we force it as read only
|
||||
if (($iFieldFlags & OPT_ATT_SLAVE) === OPT_ATT_SLAVE)
|
||||
{
|
||||
if (($iFieldFlags & OPT_ATT_SLAVE) === OPT_ATT_SLAVE) {
|
||||
$oField->SetReadOnly(true);
|
||||
}
|
||||
// - Else if it's must change (transition), we force it as mustchange, not readonly and not hidden
|
||||
elseif (($iFieldFlags & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE && $this->IsTransitionForm())
|
||||
{
|
||||
elseif (($iFieldFlags & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE && $this->IsTransitionForm()) {
|
||||
$oField->SetMustChange(true);
|
||||
$oField->SetReadOnly(false);
|
||||
$oField->SetHidden(false);
|
||||
}
|
||||
// - Else if it's must prompt (transition), we force it as not readonly and not hidden
|
||||
elseif (($iFieldFlags & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT && $this->IsTransitionForm())
|
||||
{
|
||||
elseif (($iFieldFlags & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT && $this->IsTransitionForm()) {
|
||||
$oField->SetReadOnly(false);
|
||||
$oField->SetHidden(false);
|
||||
}
|
||||
// - Else if it wasn't mandatory or already had a value, and it's hidden, we force it as hidden
|
||||
elseif (($iFieldFlags & OPT_ATT_HIDDEN) === OPT_ATT_HIDDEN)
|
||||
{
|
||||
elseif (($iFieldFlags & OPT_ATT_HIDDEN) === OPT_ATT_HIDDEN) {
|
||||
$oField->SetHidden(true);
|
||||
}
|
||||
elseif (($iFieldFlags & OPT_ATT_READONLY) === OPT_ATT_READONLY)
|
||||
{
|
||||
} elseif (($iFieldFlags & OPT_ATT_READONLY) === OPT_ATT_READONLY) {
|
||||
$oField->SetReadOnly(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Normal field, use "flags" set by AttDef::MakeFormField()
|
||||
// Except if we are in a transition be cause $oAttDef doesn't know if the form is for a transition
|
||||
if ($this->IsTransitionForm())
|
||||
{
|
||||
if ($this->IsTransitionForm()) {
|
||||
$oField->SetReadOnly(false);
|
||||
$oField->SetHidden(false);
|
||||
$oField->SetMandatory(false);
|
||||
@@ -435,114 +413,110 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
|
||||
// Finally, if it's mandatory ...
|
||||
if (($iFieldFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY)
|
||||
{
|
||||
if (($iFieldFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY) {
|
||||
// ... and when in a transition, we force it as mandatory
|
||||
if ($this->IsTransitionForm() && $oAttDef->IsNull($this->oObject->Get($sAttCode)))
|
||||
{
|
||||
if ($this->IsTransitionForm() && $oAttDef->IsNull($this->oObject->Get($sAttCode))) {
|
||||
$oField->SetMandatory(true);
|
||||
}
|
||||
// .. and has no value, we force it as mandatory
|
||||
elseif ($oAttDef->IsNull($this->oObject->Get($sAttCode)))
|
||||
{
|
||||
elseif ($oAttDef->IsNull($this->oObject->Get($sAttCode))) {
|
||||
$oField->SetMandatory(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Specific operation on field
|
||||
// - Field that require a transaction id
|
||||
if (in_array(get_class($oField),
|
||||
array('Combodo\\iTop\\Form\\Field\\TextAreaField', 'Combodo\\iTop\\Form\\Field\\CaseLogField')))
|
||||
{
|
||||
if (in_array(
|
||||
get_class($oField),
|
||||
['Combodo\\iTop\\Form\\Field\\TextAreaField', 'Combodo\\iTop\\Form\\Field\\CaseLogField']
|
||||
)) {
|
||||
/** @var \Combodo\iTop\Form\Field\TextAreaField|\Combodo\iTop\Form\Field\CaseLogField $oField */
|
||||
$oField->SetTransactionId($this->oForm->GetTransactionId());
|
||||
}
|
||||
// - Field that require a search endpoint
|
||||
if (in_array(get_class($oField),
|
||||
array('Combodo\\iTop\\Form\\Field\\SelectObjectField', 'Combodo\\iTop\\Form\\Field\\LinkedSetField'))) {
|
||||
if (in_array(
|
||||
get_class($oField),
|
||||
['Combodo\\iTop\\Form\\Field\\SelectObjectField', 'Combodo\\iTop\\Form\\Field\\LinkedSetField']
|
||||
)) {
|
||||
/** @var \Combodo\iTop\Form\Field\SelectObjectField|\Combodo\iTop\Form\Field\LinkedSetField $oField */
|
||||
if ($this->oFormHandlerHelper !== null) {
|
||||
$sSearchEndpoint = $this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_search_generic', array(
|
||||
$sSearchEndpoint = $this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_search_generic', [
|
||||
'sTargetAttCode' => $oAttDef->GetCode(),
|
||||
'sHostObjectClass' => get_class($this->oObject),
|
||||
'sHostObjectId' => ($this->oObject->IsNew()) ? null : $this->oObject->GetKey(),
|
||||
'ar_token' => $this->GetActionRulesToken(),
|
||||
));
|
||||
]);
|
||||
$oField->SetSearchEndpoint($sSearchEndpoint);
|
||||
}
|
||||
}
|
||||
// - Field that require an information endpoint
|
||||
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\LinkedSetField'))) {
|
||||
if (in_array(get_class($oField), ['Combodo\\iTop\\Form\\Field\\LinkedSetField'])) {
|
||||
/** @var \Combodo\iTop\Form\Field\LinkedSetField $oField */
|
||||
if ($this->oFormHandlerHelper !== null) {
|
||||
$oField->SetInformationEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_get_information_for_linked_set_json'));
|
||||
}
|
||||
}
|
||||
// - Field that require to apply scope on its DM OQL
|
||||
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField')))
|
||||
{
|
||||
if (in_array(get_class($oField), ['Combodo\\iTop\\Form\\Field\\SelectObjectField'])) {
|
||||
/** @var \Combodo\iTop\Form\Field\SelectObjectField $oField */
|
||||
if ($this->oFormHandlerHelper !== null) {
|
||||
$oScopeOriginal = ($oField->GetSearch() !== null) ? $oField->GetSearch() : DBSearch::FromOQL($oAttDef->GetValuesDef()->GetFilterExpression());
|
||||
|
||||
/** @var \DBSearch $oScopeSearch */
|
||||
$oScopeSearch = $this->oFormHandlerHelper->GetScopeValidator()->GetScopeFilterForProfiles(UserRights::ListProfiles(),
|
||||
$oScopeOriginal->GetClass(), UR_ACTION_READ);
|
||||
$oScopeSearch = $this->oFormHandlerHelper->GetScopeValidator()->GetScopeFilterForProfiles(
|
||||
UserRights::ListProfiles(),
|
||||
$oScopeOriginal->GetClass(),
|
||||
UR_ACTION_READ
|
||||
);
|
||||
if ($oScopeSearch === null) {
|
||||
IssueLog::Info(__METHOD__.' at line '.__LINE__.' : User #'.UserRights::GetUserId().' has no scope query for '.$oScopeOriginal->GetClass().' class.');
|
||||
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||
}
|
||||
$oScopeOriginal = $oScopeOriginal->Intersect($oScopeSearch);
|
||||
// Note : This is to skip the silo restriction on the final query
|
||||
if ($oScopeSearch->IsAllDataAllowed())
|
||||
{
|
||||
if ($oScopeSearch->IsAllDataAllowed()) {
|
||||
$oScopeOriginal->AllowAllData();
|
||||
}
|
||||
$oScopeOriginal->SetInternalParams(array('this' => $this->oObject));
|
||||
$oScopeOriginal->SetInternalParams(['this' => $this->oObject]);
|
||||
$oField->SetSearch($oScopeOriginal);
|
||||
}
|
||||
}
|
||||
// - Field that require to check if the current value is among allowed ones
|
||||
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField')))
|
||||
{
|
||||
if (in_array(get_class($oField), ['Combodo\\iTop\\Form\\Field\\SelectObjectField'])) {
|
||||
// Note: We can't do this in AttributeExternalKey::MakeFormField() in the Field::SetOnFinalizeCallback() because at this point we have no information about the portal scope and ignore_silos flag, hence it always applies silos.
|
||||
// As a workaround we have to manually check if the field's current value is among the scope
|
||||
$oField->ResetCurrentValueIfNotAmongAllowedValues();
|
||||
}
|
||||
// - Field that require processing on their subfields
|
||||
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SubFormField')))
|
||||
{
|
||||
if (in_array(get_class($oField), ['Combodo\\iTop\\Form\\Field\\SubFormField'])) {
|
||||
/** @var \Combodo\iTop\Form\Field\SubFormField $oField */
|
||||
$oSubForm = $oField->GetForm();
|
||||
if ($oAttDef->GetEditClass() === 'CustomFields')
|
||||
{
|
||||
if ($oAttDef->GetEditClass() === 'CustomFields') {
|
||||
// Retrieving only user data fields (not the metadata fields of the template)
|
||||
if ($oSubForm->HasField('user_data'))
|
||||
{
|
||||
if ($oSubForm->HasField('user_data')) {
|
||||
/** @var \Combodo\iTop\Form\Field\SubFormField $oUserDataField */
|
||||
$oUserDataField = $oSubForm->GetField('user_data');
|
||||
$oUserDataForm = $oUserDataField->GetForm();
|
||||
foreach ($oUserDataForm->GetFields() as $oCustomField)
|
||||
{
|
||||
foreach ($oUserDataForm->GetFields() as $oCustomField) {
|
||||
// - Field that require a search endpoint (OQL based dropdown list fields)
|
||||
if (in_array(get_class($oCustomField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField')))
|
||||
{
|
||||
if (in_array(get_class($oCustomField), ['Combodo\\iTop\\Form\\Field\\SelectObjectField'])) {
|
||||
/** @var \Combodo\iTop\Form\Field\SelectObjectField $oCustomField */
|
||||
if ($this->oFormHandlerHelper->GetUrlGenerator() !== null) {
|
||||
|
||||
$sSearchEndpoint = $this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_search_generic',
|
||||
array(
|
||||
$sSearchEndpoint = $this->oFormHandlerHelper->GetUrlGenerator()->generate(
|
||||
'p_object_search_generic',
|
||||
[
|
||||
'sTargetAttCode' => $oAttDef->GetCode(),
|
||||
'sHostObjectClass' => get_class($this->oObject),
|
||||
'sHostObjectId' => ($this->oObject->IsNew()) ? null : $this->oObject->GetKey(),
|
||||
'ar_token' => $this->GetActionRulesToken(),
|
||||
));
|
||||
]
|
||||
);
|
||||
$oCustomField->SetSearchEndpoint($sSearchEndpoint);
|
||||
}
|
||||
}
|
||||
// - Field that require to check if the current value is among allowed ones
|
||||
if (in_array(get_class($oCustomField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField')))
|
||||
{
|
||||
if (in_array(get_class($oCustomField), ['Combodo\\iTop\\Form\\Field\\SelectObjectField'])) {
|
||||
/** @var \Combodo\iTop\Form\Field\SelectObjectField $oCustomField */
|
||||
$oCustomField->ResetCurrentValueIfNotAmongAllowedValues();
|
||||
}
|
||||
@@ -550,37 +524,34 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($iFieldFlags & OPT_ATT_HIDDEN) === OPT_ATT_HIDDEN)
|
||||
{
|
||||
} else {
|
||||
if (($iFieldFlags & OPT_ATT_HIDDEN) === OPT_ATT_HIDDEN) {
|
||||
$oField->SetHidden(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oField->SetReadOnly(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Specific operation on field
|
||||
// - LinkedSet
|
||||
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\LinkedSetField')))
|
||||
{
|
||||
if (in_array(get_class($oField), ['Combodo\\iTop\\Form\\Field\\LinkedSetField'])) {
|
||||
/** @var \Combodo\iTop\Form\Field\LinkedSetField $oField */
|
||||
/** @var \AttributeLinkedSetIndirect $oAttDef */
|
||||
// - Overriding attributes to display
|
||||
if ($this->oFormHandlerHelper !== null) {
|
||||
// Note : This snippet is inspired from AttributeLinkedSet::MakeFormField()
|
||||
$aAttCodesToDisplay = ApplicationHelper::GetLoadedListFromClass($this->oFormHandlerHelper->getCombodoPortalConf()['lists'],
|
||||
$oField->GetTargetClass(), 'list');
|
||||
$aAttCodesToDisplay = ApplicationHelper::GetLoadedListFromClass(
|
||||
$this->oFormHandlerHelper->getCombodoPortalConf()['lists'],
|
||||
$oField->GetTargetClass(),
|
||||
'list'
|
||||
);
|
||||
// - Adding friendlyname attribute to the list is not already in it
|
||||
$sTitleAttCode = 'friendlyname';
|
||||
if (($sTitleAttCode !== null) && !in_array($sTitleAttCode, $aAttCodesToDisplay)) {
|
||||
$aAttCodesToDisplay = array_merge(array($sTitleAttCode), $aAttCodesToDisplay);
|
||||
$aAttCodesToDisplay = array_merge([$sTitleAttCode], $aAttCodesToDisplay);
|
||||
}
|
||||
// - Adding attribute labels
|
||||
$aAttributesToDisplay = array();
|
||||
$aAttributesToDisplay = [];
|
||||
foreach ($aAttCodesToDisplay as $sAttCodeToDisplay) {
|
||||
$oAttDefToDisplay = MetaModel::GetAttributeDef($oField->GetTargetClass(), $sAttCodeToDisplay);
|
||||
$aAttributesToDisplay[$sAttCodeToDisplay] = [
|
||||
@@ -598,7 +569,7 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
// - Filtering links regarding scopes
|
||||
if ($this->oFormHandlerHelper !== null) {
|
||||
$aLimitedAccessItemIDs = array();
|
||||
$aLimitedAccessItemIDs = [];
|
||||
|
||||
/** @var \ormLinkSet $oFieldOriginalSet */
|
||||
$oFieldOriginalSet = $oField->GetCurrentValue();
|
||||
@@ -617,19 +588,16 @@ class ObjectFormManager extends FormManager
|
||||
$oField->SetLimitedAccessItemIDs($aLimitedAccessItemIDs);
|
||||
}
|
||||
// - Displaying as opened
|
||||
if (array_key_exists($sAttCode, $this->aExtraData) && array_key_exists('opened', $this->aExtraData[$sAttCode]))
|
||||
{
|
||||
if (array_key_exists($sAttCode, $this->aExtraData) && array_key_exists('opened', $this->aExtraData[$sAttCode])) {
|
||||
$oField->SetDisplayOpened(true);
|
||||
}
|
||||
// - Displaying out of scopes items
|
||||
if (array_key_exists($sAttCode, $this->aExtraData) && array_key_exists('ignore_scopes', $this->aExtraData[$sAttCode]))
|
||||
{
|
||||
if (array_key_exists($sAttCode, $this->aExtraData) && array_key_exists('ignore_scopes', $this->aExtraData[$sAttCode])) {
|
||||
$oField->SetDisplayLimitedAccessItems(true);
|
||||
}
|
||||
}
|
||||
// - BlobField
|
||||
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\BlobField', 'Combodo\\iTop\\Form\\Field\\ImageField')))
|
||||
{
|
||||
if (in_array(get_class($oField), ['Combodo\\iTop\\Form\\Field\\BlobField', 'Combodo\\iTop\\Form\\Field\\ImageField'])) {
|
||||
// - Overriding attributes to display
|
||||
if ($this->oFormHandlerHelper !== null) {
|
||||
// Override hardcoded URLs in ormDocument pointing to back office console
|
||||
@@ -654,9 +622,7 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oField = new LabelField($sAttCode);
|
||||
$oField->SetReadOnly(true)
|
||||
->SetHidden(false)
|
||||
@@ -665,8 +631,7 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
|
||||
// Setting field display mode
|
||||
if (array_key_exists($sAttCode, $this->aExtraData) && array_key_exists('display_mode', $this->aExtraData[$sAttCode]))
|
||||
{
|
||||
if (array_key_exists($sAttCode, $this->aExtraData) && array_key_exists('display_mode', $this->aExtraData[$sAttCode])) {
|
||||
$oField->SetDisplayMode($this->aExtraData[$sAttCode]['display_mode']);
|
||||
}
|
||||
|
||||
@@ -678,32 +643,25 @@ class ObjectFormManager extends FormManager
|
||||
|
||||
// Do not add hidden fields as they are of no use, if one is necessary because another depends on it, it will be automatically added.
|
||||
// Note: We do this at the end because during the process an hidden field could have become writable if mandatory and empty for example.
|
||||
if($oField->GetHidden() === false)
|
||||
{
|
||||
if ($oField->GetHidden() === false) {
|
||||
$this->oForm->AddField($oField);
|
||||
} else {
|
||||
$this->aHiddenFieldsId[]=$oField->GetId();
|
||||
$this->aHiddenFieldsId[] = $oField->GetId();
|
||||
}
|
||||
}
|
||||
|
||||
// Checking dependencies to ensure that all needed fields are in the form
|
||||
// (This is kind of a garbage collector for dependencies)
|
||||
foreach ($this->oForm->GetDependencies() as $sImpactedFieldId => $aDependencies)
|
||||
{
|
||||
foreach ($aDependencies as $sDependencyFieldId)
|
||||
{
|
||||
if (!$this->oForm->HasField($sDependencyFieldId))
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach ($this->oForm->GetDependencies() as $sImpactedFieldId => $aDependencies) {
|
||||
foreach ($aDependencies as $sDependencyFieldId) {
|
||||
if (!$this->oForm->HasField($sDependencyFieldId)) {
|
||||
try {
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this->oObject), $sDependencyFieldId);
|
||||
$oField = $oAttDef->MakeFormField($this->oObject);
|
||||
$oField->SetHidden(true);
|
||||
|
||||
$this->oForm->AddField($oField);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
// Avoid blocking a form if a RequestTemplate reference a bad attribute (e.g. :this->id)
|
||||
IssueLog::Error('May be a bad OQL (referencing :this->id) in a RequestTemplate causes the following error');
|
||||
IssueLog::Error($e);
|
||||
@@ -717,7 +675,7 @@ class ObjectFormManager extends FormManager
|
||||
if ($this->sMode !== 'apply_stimulus'
|
||||
&& class_exists('Attachment') && class_exists('AttachmentPlugIn')
|
||||
&& !$this->IsPluginInitialized(AttachmentPlugIn::class)
|
||||
&& AttachmentPlugIn::IsAttachmentAllowedForObject($this->oObject)){
|
||||
&& AttachmentPlugIn::IsAttachmentAllowedForObject($this->oObject)) {
|
||||
$this->AddAttachmentField($this->oForm, 'attachments_plugin', $this->aExtraData);
|
||||
}
|
||||
|
||||
@@ -732,7 +690,7 @@ class ObjectFormManager extends FormManager
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function IsPluginInitialized(string $sPluginName) : bool
|
||||
private function IsPluginInitialized(string $sPluginName): bool
|
||||
{
|
||||
return array_key_exists($sPluginName, $this->aPlugins);
|
||||
}
|
||||
@@ -746,48 +704,54 @@ class ObjectFormManager extends FormManager
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function AddAttachmentField($oForm, $sId, $aFieldsExtraData) : void
|
||||
private function AddAttachmentField($oForm, $sId, $aFieldsExtraData): void
|
||||
{
|
||||
// only one instance allowed
|
||||
if($this->IsPluginInitialized(AttachmentPlugIn::class)){
|
||||
throw new Exception("Unable to process field `$sId`, AttachmentPlugIn has already been initialized with field `" . $this->aPlugins[AttachmentPlugIn::class]['field']->GetId() . '`');
|
||||
if ($this->IsPluginInitialized(AttachmentPlugIn::class)) {
|
||||
throw new Exception("Unable to process field `$sId`, AttachmentPlugIn has already been initialized with field `".$this->aPlugins[AttachmentPlugIn::class]['field']->GetId().'`');
|
||||
}
|
||||
|
||||
// not allowed for object class
|
||||
if(!AttachmentPlugIn::IsAttachmentAllowedForObject($this->oObject)){
|
||||
throw new Exception("Unable to process field `$sId`, AttachmentPlugIn is not allowed for class `" . $this->oObject::class . '`');
|
||||
if (!AttachmentPlugIn::IsAttachmentAllowedForObject($this->oObject)) {
|
||||
throw new Exception("Unable to process field `$sId`, AttachmentPlugIn is not allowed for class `".$this->oObject::class.'`');
|
||||
}
|
||||
|
||||
// set id to a unique key - avoid collisions with another attribute that could exist with the name 'attachments'
|
||||
$oField = new FileUploadField($sId);
|
||||
$oField->SetLabel(Dict::S('Portal:Attachments'))
|
||||
->SetUploadEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_attachment_add'))
|
||||
->SetDownloadEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_attachment_download',
|
||||
array('sAttachmentId' => '-sAttachmentId-')))
|
||||
->SetDisplayEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_attachment_display',
|
||||
array('sAttachmentId' => '-sAttachmentId-')))
|
||||
->SetDownloadEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate(
|
||||
'p_object_attachment_download',
|
||||
['sAttachmentId' => '-sAttachmentId-']
|
||||
))
|
||||
->SetDisplayEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate(
|
||||
'p_object_attachment_display',
|
||||
['sAttachmentId' => '-sAttachmentId-']
|
||||
))
|
||||
->SetTransactionId($oForm->GetTransactionId())
|
||||
->SetAllowDelete($this->oFormHandlerHelper->getCombodoPortalConf()['properties']['attachments']['allow_delete'])
|
||||
->SetObject($this->oObject);
|
||||
|
||||
// Checking if we can edit attachments in the current state
|
||||
$oObjectFormManager = $this;
|
||||
$oField->SetOnFinalizeCallback(function() use ($oObjectFormManager, $oForm, $oField){
|
||||
$oField->SetOnFinalizeCallback(function () use ($oObjectFormManager, $oForm, $oField) {
|
||||
if (($oObjectFormManager->sMode === static::ENUM_MODE_VIEW)
|
||||
|| AttachmentPlugIn::IsReadonlyState($oObjectFormManager->oObject, $oObjectFormManager->oObject->GetState(),
|
||||
AttachmentPlugIn::ENUM_GUI_PORTALS) === true
|
||||
|| $oForm->GetEditableFieldCount(true) === 0)
|
||||
{
|
||||
|| AttachmentPlugIn::IsReadonlyState(
|
||||
$oObjectFormManager->oObject,
|
||||
$oObjectFormManager->oObject->GetState(),
|
||||
AttachmentPlugIn::ENUM_GUI_PORTALS
|
||||
) === true
|
||||
|| $oForm->GetEditableFieldCount(true) === 0) {
|
||||
$oField->SetReadOnly(true);
|
||||
}
|
||||
});
|
||||
|
||||
if (array_key_exists($sId, $aFieldsExtraData) && array_key_exists('opened', $aFieldsExtraData[$sId])){
|
||||
if (array_key_exists($sId, $aFieldsExtraData) && array_key_exists('opened', $aFieldsExtraData[$sId])) {
|
||||
$oField->SetDisplayOpened(true);
|
||||
}
|
||||
|
||||
// Adding attachments field in transition only if it is editable
|
||||
if (!$this->IsTransitionForm() || !$oField->GetReadOnly()){
|
||||
if (!$this->IsTransitionForm() || !$oField->GetReadOnly()) {
|
||||
$oForm->AddField($oField);
|
||||
}
|
||||
|
||||
@@ -810,8 +774,7 @@ class ObjectFormManager extends FormManager
|
||||
{
|
||||
// Ask to each field to clean itself
|
||||
/** @var \Combodo\iTop\Form\Field\Field $oField */
|
||||
foreach ($this->oForm->GetFields() as $oField)
|
||||
{
|
||||
foreach ($this->oForm->GetFields() as $oField) {
|
||||
$oField->OnCancel();
|
||||
}
|
||||
// Then clean inline images from rich text editor such as TextareaField
|
||||
@@ -837,7 +800,7 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
|
||||
$aData['messages']['error'] += [
|
||||
'_main' => [$sError]
|
||||
'_main' => [$sError],
|
||||
];
|
||||
$aData['valid'] = false;
|
||||
}
|
||||
@@ -875,8 +838,7 @@ class ObjectFormManager extends FormManager
|
||||
$this->OnUpdate($aArgs);
|
||||
|
||||
// Check if form valid
|
||||
if (! $this->oForm->Validate())
|
||||
{
|
||||
if (! $this->oForm->Validate()) {
|
||||
// Handle errors
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += $this->oForm->GetErrorMessages();
|
||||
@@ -901,8 +863,7 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
|
||||
// Writing object to DB
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->oObject->DBWrite();
|
||||
} catch (CoreCannotSaveObjectException $e) {
|
||||
throw new Exception($e->getTextMessage());
|
||||
@@ -929,34 +890,29 @@ class ObjectFormManager extends FormManager
|
||||
InlineImage::FinalizeInlineImages($this->oObject);
|
||||
// Finalizing attachments link to object
|
||||
// TODO : This has to be refactored when the function from itop-attachments has been migrated into the core
|
||||
if (isset($aArgs['attachmentIds']))
|
||||
{
|
||||
if (isset($aArgs['attachmentIds'])) {
|
||||
$this->FinalizeAttachments($aArgs['attachmentIds']);
|
||||
}
|
||||
|
||||
// Checking if we have to apply a stimulus
|
||||
if (isset($aArgs['applyStimulus']))
|
||||
{
|
||||
if (isset($aArgs['applyStimulus'])) {
|
||||
$this->oObject->ApplyStimulus($aArgs['applyStimulus']['code']);
|
||||
}
|
||||
// Activating triggers only on update
|
||||
if ($bActivateTriggers)
|
||||
{
|
||||
if ($bActivateTriggers) {
|
||||
$sTriggersQuery = $this->oFormHandlerHelper->getCombodoPortalConf()['properties']['triggers_query'];
|
||||
if ($sTriggersQuery !== null)
|
||||
{
|
||||
if ($sTriggersQuery !== null) {
|
||||
$aParentClasses = MetaModel::EnumParentClasses($sObjectClass, ENUM_PARENT_CLASSES_ALL);
|
||||
$oTriggerSet = new DBObjectSet(DBObjectSearch::FromOQL($sTriggersQuery), array(),
|
||||
array('parent_classes' => $aParentClasses));
|
||||
$oTriggerSet = new DBObjectSet(
|
||||
DBObjectSearch::FromOQL($sTriggersQuery),
|
||||
[],
|
||||
['parent_classes' => $aParentClasses]
|
||||
);
|
||||
/** @var \Trigger $oTrigger */
|
||||
while ($oTrigger = $oTriggerSet->Fetch())
|
||||
{
|
||||
try
|
||||
{
|
||||
while ($oTrigger = $oTriggerSet->Fetch()) {
|
||||
try {
|
||||
$oTrigger->DoActivate($this->oObject->ToArgs('this'));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
utils::EnrichRaisedException($oTrigger, $e);
|
||||
}
|
||||
}
|
||||
@@ -966,30 +922,24 @@ class ObjectFormManager extends FormManager
|
||||
// Resetting caselog fields value, otherwise the value will stay in it after submit.
|
||||
$this->oForm->ResetCaseLogFields();
|
||||
|
||||
if ($bWasModified)
|
||||
{
|
||||
if ($bWasModified) {
|
||||
//=if (isNew) because $bActivateTriggers = (!$this->oObject->IsNew() && $this->oObject->IsModified())
|
||||
if(!$bActivateTriggers)
|
||||
{
|
||||
$aData['messages']['success'] += array( '_main' => array(Dict::Format('UI:Title:Object_Of_Class_Created', $this->oObject->GetName(),MetaModel::GetName(get_class($this->oObject)))));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aData['messages']['success'] += array('_main' => array(Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($this->oObject)), $this->oObject->GetName())));
|
||||
if (!$bActivateTriggers) {
|
||||
$aData['messages']['success'] += [ '_main' => [Dict::Format('UI:Title:Object_Of_Class_Created', $this->oObject->GetName(), MetaModel::GetName(get_class($this->oObject)))]];
|
||||
} else {
|
||||
$aData['messages']['success'] += ['_main' => [Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($this->oObject)), $this->oObject->GetName())]];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CoreCannotSaveObjectException $e) {
|
||||
} catch (CoreCannotSaveObjectException $e) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array('_main' => array($e->getTextMessage()));
|
||||
$aData['messages']['error'] += ['_main' => [$e->getTextMessage()]];
|
||||
if (false === $bExceptionLogged) {
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += [
|
||||
'_main' => [ ($e instanceof CoreCannotSaveObjectException) ? $e->getTextMessage() : $e->getMessage()]
|
||||
'_main' => [ ($e instanceof CoreCannotSaveObjectException) ? $e->getTextMessage() : $e->getMessage()],
|
||||
];
|
||||
if (false === $bExceptionLogged) {
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : '.$e->getMessage());
|
||||
@@ -1016,11 +966,9 @@ class ObjectFormManager extends FormManager
|
||||
{
|
||||
$aFormProperties = [];
|
||||
|
||||
if (is_array($aArgs))
|
||||
{
|
||||
if (is_array($aArgs)) {
|
||||
// Then we retrieve properties of the form to build
|
||||
if (isset($aArgs['formProperties']))
|
||||
{
|
||||
if (isset($aArgs['formProperties'])) {
|
||||
$aFormProperties = $aArgs['formProperties'];
|
||||
}
|
||||
}
|
||||
@@ -1054,20 +1002,17 @@ class ObjectFormManager extends FormManager
|
||||
*/
|
||||
protected function FinalizeAttachments($aAttachmentIds)
|
||||
{
|
||||
$aRemovedAttachmentsIds = (isset($aAttachmentIds['removed_attachments_ids'])) ? $aAttachmentIds['removed_attachments_ids'] : array();
|
||||
$aRemovedAttachmentsIds = (isset($aAttachmentIds['removed_attachments_ids'])) ? $aAttachmentIds['removed_attachments_ids'] : [];
|
||||
// Not used for now. //$aActualAttachmentsIds = (isset($aAttachmentIds['actual_attachments_ids'])) ? $aAttachmentIds['actual_attachments_ids'] : array();
|
||||
$aActions = array();
|
||||
$aActions = [];
|
||||
|
||||
// Removing attachments from currents
|
||||
if (!empty($aRemovedAttachmentsIds))
|
||||
{
|
||||
if (!empty($aRemovedAttachmentsIds)) {
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($this->oObject), 'item_id' => $this->oObject->GetKey()));
|
||||
while ($oAttachment = $oSet->Fetch())
|
||||
{
|
||||
$oSet = new DBObjectSet($oSearch, [], ['class' => get_class($this->oObject), 'item_id' => $this->oObject->GetKey()]);
|
||||
while ($oAttachment = $oSet->Fetch()) {
|
||||
// Remove attachments that are no longer attached to the current object
|
||||
if (in_array($oAttachment->GetKey(), $aRemovedAttachmentsIds))
|
||||
{
|
||||
if (in_array($oAttachment->GetKey(), $aRemovedAttachmentsIds)) {
|
||||
$aData = ['attachment' => $oAttachment];
|
||||
$this->oObject->FireEvent(EVENT_REMOVE_ATTACHMENT_FROM_OBJECT, $aData);
|
||||
$oAttachment->DBDelete();
|
||||
@@ -1080,16 +1025,12 @@ class ObjectFormManager extends FormManager
|
||||
$sTempId = utils::GetUploadTempId($this->oForm->GetTransactionId());
|
||||
$sOQL = 'SELECT Attachment WHERE temp_id = :temp_id';
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('temp_id' => $sTempId));
|
||||
while ($oAttachment = $oSet->Fetch())
|
||||
{
|
||||
$oSet = new DBObjectSet($oSearch, [], ['temp_id' => $sTempId]);
|
||||
while ($oAttachment = $oSet->Fetch()) {
|
||||
// Temp attachment removed
|
||||
if (in_array($oAttachment->GetKey(), $aRemovedAttachmentsIds))
|
||||
{
|
||||
if (in_array($oAttachment->GetKey(), $aRemovedAttachmentsIds)) {
|
||||
$oAttachment->DBDelete();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oAttachment->SetItem($this->oObject);
|
||||
$oAttachment->Set('temp_id', '');
|
||||
$oAttachment->DBUpdate();
|
||||
@@ -1101,8 +1042,7 @@ class ObjectFormManager extends FormManager
|
||||
|
||||
// Save changes to current object history
|
||||
// inspired from itop-attachments/main.attachments.php / RecordHistory
|
||||
foreach ($aActions as $oChangeOp)
|
||||
{
|
||||
foreach ($aActions as $oChangeOp) {
|
||||
$oChangeOp->Set("objclass", get_class($this->oObject));
|
||||
$oChangeOp->Set("objkey", $this->oObject->GetKey());
|
||||
$oChangeOp->DBInsertNoReload();
|
||||
@@ -1125,9 +1065,8 @@ class ObjectFormManager extends FormManager
|
||||
$sTempId = utils::GetUploadTempId($this->oForm->GetTransactionId());
|
||||
$sOQL = 'SELECT Attachment WHERE temp_id = :temp_id';
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('temp_id' => $sTempId));
|
||||
while ($oAttachment = $oSet->Fetch())
|
||||
{
|
||||
$oSet = new DBObjectSet($oSearch, [], ['temp_id' => $sTempId]);
|
||||
while ($oAttachment = $oSet->Fetch()) {
|
||||
$oAttachment->DBDelete();
|
||||
}
|
||||
}
|
||||
@@ -1147,14 +1086,11 @@ class ObjectFormManager extends FormManager
|
||||
{
|
||||
$oBlob = $oAttachment->Get('contents');
|
||||
$sFileName = $oBlob->GetFileName();
|
||||
if ($bCreate)
|
||||
{
|
||||
if ($bCreate) {
|
||||
$oChangeOp = new CMDBChangeOpAttachmentAdded();
|
||||
$oChangeOp->Set('attachment_id', $oAttachment->GetKey());
|
||||
$oChangeOp->Set('filename', $sFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oChangeOp = new CMDBChangeOpAttachmentRemoved();
|
||||
$oChangeOp->Set('filename', $sFileName);
|
||||
}
|
||||
@@ -1238,8 +1174,7 @@ class ObjectFormManager extends FormManager
|
||||
{
|
||||
$sObjectClass = get_class($this->oObject);
|
||||
|
||||
foreach ($aCurrentValues as $sAttCode => $value)
|
||||
{
|
||||
foreach ($aCurrentValues as $sAttCode => $value) {
|
||||
if (count($this->aFieldsAtts) !== 0) {
|
||||
if (!array_key_exists($sAttCode, $this->aFieldsAtts)) {
|
||||
continue;
|
||||
@@ -1342,8 +1277,7 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
$oOrmSet->ApplyDelta(json_decode($value, true));
|
||||
$this->oObject->Set($sAttCode, $oOrmSet);
|
||||
} elseif ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
||||
{
|
||||
} elseif ($oAttDef instanceof AttributeDateTime) { // AttributeDate is derived from AttributeDateTime
|
||||
if ($value != null) {
|
||||
$value = $oAttDef->GetFormat()->Parse($value);
|
||||
if (is_object($value)) {
|
||||
@@ -1351,11 +1285,9 @@ class ObjectFormManager extends FormManager
|
||||
}
|
||||
}
|
||||
$this->oObject->Set($sAttCode, $value);
|
||||
}
|
||||
elseif ($oAttDef->IsScalar() && is_array($value)) {
|
||||
} elseif ($oAttDef->IsScalar() && is_array($value)) {
|
||||
$this->oObject->Set($sAttCode, current($value));
|
||||
}
|
||||
elseif ($oAttDef->GetEditClass() === 'CustomFields') {
|
||||
} elseif ($oAttDef->GetEditClass() === 'CustomFields') {
|
||||
// We don't update attribute as ormCustomField comparaison is not working as excepted.
|
||||
// When several templates available, "template_id" is not sent by the portal has it is a read-only select input
|
||||
// therefore, the TemplateFieldsHandler::CompareValues() doesn't work.
|
||||
@@ -1377,8 +1309,7 @@ class ObjectFormManager extends FormManager
|
||||
$this->oObject->Set($sAttCode, $value);
|
||||
}
|
||||
// Else don't update! Otherwise we might loose current value
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->oObject->Set($sAttCode, $value);
|
||||
}
|
||||
}
|
||||
@@ -1400,9 +1331,9 @@ class ObjectFormManager extends FormManager
|
||||
public function PrepareFields(): void
|
||||
{
|
||||
$sObjectClass = get_class($this->oObject);
|
||||
$this->aFieldsAtts = array();
|
||||
$this->aExtraData = array();
|
||||
$aFieldsDMOnlyAttCodes = array();
|
||||
$this->aFieldsAtts = [];
|
||||
$this->aExtraData = [];
|
||||
$aFieldsDMOnlyAttCodes = [];
|
||||
if (array_key_exists('type', $this->aFormProperties)) {
|
||||
switch ($this->aFormProperties['type']) {
|
||||
case 'custom_list':
|
||||
@@ -1518,8 +1449,7 @@ class ObjectFormManager extends FormManager
|
||||
if (array_key_exists('type', $this->aFormProperties) && $this->aFormProperties['type'] !== 'static') {
|
||||
if ($this->IsTransitionForm()) {
|
||||
$aDatamodelAttCodes = $this->oObject->GetTransitionAttributes($this->aFormProperties['stimulus_code']);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$aDatamodelAttCodes = MetaModel::ListAttributeDefs($sObjectClass);
|
||||
}
|
||||
|
||||
@@ -1536,12 +1466,10 @@ class ObjectFormManager extends FormManager
|
||||
// Retrieving only mandatory flag from DM when on a transition
|
||||
$iFieldFlags = $value & OPT_ATT_MANDATORY;
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this->oObject), $sAttCode);
|
||||
}
|
||||
elseif ($this->oObject->IsNew()) {
|
||||
} elseif ($this->oObject->IsNew()) {
|
||||
$iFieldFlags = $this->oObject->GetInitialStateAttributeFlags($sAttCode);
|
||||
$oAttDef = $value;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$iFieldFlags = $this->oObject->GetAttributeFlags($sAttCode);
|
||||
$oAttDef = $value;
|
||||
}
|
||||
@@ -1581,11 +1509,9 @@ class ObjectFormManager extends FormManager
|
||||
if ($this->IsTransitionForm()) {
|
||||
$aTransitionAtts = $this->oObject->GetTransitionAttributes($this->aFormProperties['stimulus_code']);
|
||||
$iFieldFlags = $aTransitionAtts[$sAttCode];
|
||||
}
|
||||
elseif ($this->oObject->IsNew()) {
|
||||
} elseif ($this->oObject->IsNew()) {
|
||||
$iFieldFlags = $this->oObject->GetInitialStateAttributeFlags($sAttCode);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$iFieldFlags = $this->oObject->GetAttributeFlags($sAttCode);
|
||||
}
|
||||
|
||||
@@ -1629,7 +1555,7 @@ class ObjectFormManager extends FormManager
|
||||
$sRendered = $this->oFormHandlerHelper->RenderFormFromTwig(
|
||||
999, // doesn't matter here
|
||||
$this->aFormProperties['layout']['content'],
|
||||
array('oRenderer' => $this->oRenderer, 'oObject' => $this->oObject)
|
||||
['oRenderer' => $this->oRenderer, 'oObject' => $this->oObject]
|
||||
);
|
||||
} else {
|
||||
$sRendered = 'Form not rendered because of missing container';
|
||||
|
||||
@@ -39,7 +39,7 @@ use UserRights;
|
||||
class PasswordFormManager extends FormManager
|
||||
{
|
||||
/** @var string FORM_TYPE */
|
||||
const FORM_TYPE = 'change_password';
|
||||
public const FORM_TYPE = 'change_password';
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
@@ -106,87 +106,66 @@ class PasswordFormManager extends FormManager
|
||||
$this->OnUpdate($aArgs);
|
||||
|
||||
// Check if form valid
|
||||
if ($this->oForm->Validate())
|
||||
{
|
||||
if ($this->oForm->Validate()) {
|
||||
// The try catch is essentially to start a MySQL transaction
|
||||
try
|
||||
{
|
||||
try {
|
||||
// Updating password
|
||||
$sAuthUser = Session::Get('auth_user');
|
||||
$sOldPassword = $this->oForm->GetField('old_password')->GetCurrentValue();
|
||||
$sNewPassword = $this->oForm->GetField('new_password')->GetCurrentValue();
|
||||
$sConfirmPassword = $this->oForm->GetField('confirm_password')->GetCurrentValue();
|
||||
|
||||
if ($sOldPassword !== '' && $sNewPassword !== '' && $sConfirmPassword !== '')
|
||||
{
|
||||
if (!UserRights::CanChangePassword())
|
||||
{
|
||||
if ($sOldPassword !== '' && $sNewPassword !== '' && $sConfirmPassword !== '') {
|
||||
if (!UserRights::CanChangePassword()) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array(
|
||||
'_main' => array(
|
||||
$aData['messages']['error'] += [
|
||||
'_main' => [
|
||||
Dict::Format('Brick:Portal:UserProfile:Password:CantChangeContactAdministrator', ITOP_APPLICATION_SHORT),
|
||||
),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!UserRights::CheckCredentials($sAuthUser, $sOldPassword))
|
||||
{
|
||||
],
|
||||
];
|
||||
} else {
|
||||
if (!UserRights::CheckCredentials($sAuthUser, $sOldPassword)) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array('old_password' => array(Dict::S('UI:Login:IncorrectOldPassword')));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($sNewPassword !== $sConfirmPassword)
|
||||
{
|
||||
$aData['messages']['error'] += ['old_password' => [Dict::S('UI:Login:IncorrectOldPassword')]];
|
||||
} else {
|
||||
if ($sNewPassword !== $sConfirmPassword) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array('confirm_password' => array(Dict::S('UI:Login:RetypePwdDoesNotMatch')));
|
||||
}
|
||||
elseif ($sNewPassword === $sOldPassword)
|
||||
{
|
||||
$aData['messages']['error'] += ['confirm_password' => [Dict::S('UI:Login:RetypePwdDoesNotMatch')]];
|
||||
} elseif ($sNewPassword === $sOldPassword) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array('new_password' => array(Dict::S('UI:Login:PasswordNotChanged')));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aData['messages']['error'] += ['new_password' => [Dict::S('UI:Login:PasswordNotChanged')]];
|
||||
} else {
|
||||
try {
|
||||
if (!UserRights::ChangePassword($sOldPassword, $sNewPassword))
|
||||
{
|
||||
if (!UserRights::ChangePassword($sOldPassword, $sNewPassword)) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array(
|
||||
'confirm_password' => array(
|
||||
Dict::Format('Brick:Portal:UserProfile:Password:CantChangeForUnknownReason',
|
||||
ITOP_APPLICATION_SHORT),
|
||||
),
|
||||
);
|
||||
$aData['messages']['error'] += [
|
||||
'confirm_password' => [
|
||||
Dict::Format(
|
||||
'Brick:Portal:UserProfile:Password:CantChangeForUnknownReason',
|
||||
ITOP_APPLICATION_SHORT
|
||||
),
|
||||
],
|
||||
];
|
||||
} else {
|
||||
$aData['messages']['success'] += ['_main' => [Dict::S('Brick:Portal:Object:Form:Message:Saved')]];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aData['messages']['success'] += array('_main' => array(Dict::S('Brick:Portal:Object:Form:Message:Saved')));
|
||||
}
|
||||
}
|
||||
catch (\CoreCannotSaveObjectException $e)
|
||||
{
|
||||
} catch (\CoreCannotSaveObjectException $e) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array(
|
||||
$aData['messages']['error'] += [
|
||||
'new_password' => $e->getIssues(),
|
||||
'confirm_password' => array(),
|
||||
);
|
||||
'confirm_password' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array('_main' => array($e->getMessage()));
|
||||
$aData['messages']['error'] += ['_main' => [$e->getMessage()]];
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Exception during submit ('.$e->getMessage().')');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Handle errors
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += $this->oForm->GetErrorMessages();
|
||||
@@ -207,12 +186,9 @@ class PasswordFormManager extends FormManager
|
||||
$this->Build();
|
||||
|
||||
// Then we update it with new values
|
||||
if (is_array($aArgs))
|
||||
{
|
||||
if (isset($aArgs['currentValues']))
|
||||
{
|
||||
foreach ($aArgs['currentValues'] as $sPreferenceName => $value)
|
||||
{
|
||||
if (is_array($aArgs)) {
|
||||
if (isset($aArgs['currentValues'])) {
|
||||
foreach ($aArgs['currentValues'] as $sPreferenceName => $value) {
|
||||
$this->oForm->GetField($sPreferenceName)->SetCurrentValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ use UserRights;
|
||||
class PreferencesFormManager extends FormManager
|
||||
{
|
||||
/** @var string FORM_TYPE */
|
||||
const FORM_TYPE = 'preferences';
|
||||
public const FORM_TYPE = 'preferences';
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
@@ -63,9 +63,8 @@ class PreferencesFormManager extends FormManager
|
||||
->SetCurrentValue(Dict::GetUserLanguage())
|
||||
->SetStartsWithNullChoice(false);
|
||||
// - Preparing choices
|
||||
$aChoices = array();
|
||||
foreach (Dict::GetLanguages() as $sCode => $aLanguage)
|
||||
{
|
||||
$aChoices = [];
|
||||
foreach (Dict::GetLanguages() as $sCode => $aLanguage) {
|
||||
$aChoices[$sCode] = $aLanguage['description'].' ('.$aLanguage['localized_description'].')';
|
||||
}
|
||||
asort($aChoices);
|
||||
@@ -109,11 +108,9 @@ class PreferencesFormManager extends FormManager
|
||||
$this->OnUpdate($aArgs);
|
||||
|
||||
// Check if form valid
|
||||
if ($this->oForm->Validate())
|
||||
{
|
||||
if ($this->oForm->Validate()) {
|
||||
// The try catch is essentially to start a MySQL transaction
|
||||
try
|
||||
{
|
||||
try {
|
||||
// Starting transaction
|
||||
CMDBSource::Query('START TRANSACTION');
|
||||
$iFieldChanged = 0;
|
||||
@@ -123,34 +120,28 @@ class PreferencesFormManager extends FormManager
|
||||
$oCurUser = UserRights::GetUserObject();
|
||||
// - Language
|
||||
$sLanguage = $this->oForm->GetField('language')->GetCurrentValue();
|
||||
if (($sLanguage !== null) && ($oCurUser->Get('language') !== $sLanguage))
|
||||
{
|
||||
if (($sLanguage !== null) && ($oCurUser->Get('language') !== $sLanguage)) {
|
||||
$oCurUser->Set('language', $sLanguage);
|
||||
$iFieldChanged++;
|
||||
}
|
||||
|
||||
// Updating only if preferences changed
|
||||
if ($iFieldChanged > 0)
|
||||
{
|
||||
if ($iFieldChanged > 0) {
|
||||
$oCurUser->AllowWrite(true);
|
||||
$oCurUser->DBUpdate();
|
||||
$aData['messages']['success'] += array('_main' => array(Dict::S('Brick:Portal:Object:Form:Message:Saved')));
|
||||
$aData['messages']['success'] += ['_main' => [Dict::S('Brick:Portal:Object:Form:Message:Saved')]];
|
||||
}
|
||||
|
||||
// Ending transaction with a commit as everything was fine
|
||||
CMDBSource::Query('COMMIT');
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
// End transaction with a rollback as something failed
|
||||
CMDBSource::Query('ROLLBACK');
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += array('_main' => array($e->getMessage()));
|
||||
$aData['messages']['error'] += ['_main' => [$e->getMessage()]];
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Rollback during submit ('.$e->getMessage().')');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Handle errors
|
||||
$aData['valid'] = false;
|
||||
$aData['messages']['error'] += $this->oForm->GetErrorMessages();
|
||||
@@ -171,12 +162,9 @@ class PreferencesFormManager extends FormManager
|
||||
$this->Build();
|
||||
|
||||
// Then we update it with new values
|
||||
if (is_array($aArgs))
|
||||
{
|
||||
if (isset($aArgs['currentValues']))
|
||||
{
|
||||
foreach ($aArgs['currentValues'] as $sPreferenceName => $value)
|
||||
{
|
||||
if (is_array($aArgs)) {
|
||||
if (isset($aArgs['currentValues'])) {
|
||||
foreach ($aArgs['currentValues'] as $sPreferenceName => $value) {
|
||||
$this->oForm->GetField($sPreferenceName)->SetCurrentValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,13 +41,13 @@ use utils;
|
||||
class ApplicationHelper
|
||||
{
|
||||
/** @var string FORM_ENUM_DISPLAY_MODE_COSY */
|
||||
const FORM_ENUM_DISPLAY_MODE_COSY = 'cosy';
|
||||
public const FORM_ENUM_DISPLAY_MODE_COSY = 'cosy';
|
||||
/** @var string FORM_ENUM_DISPLAY_MODE_COMPACT */
|
||||
const FORM_ENUM_DISPLAY_MODE_COMPACT = 'compact';
|
||||
public const FORM_ENUM_DISPLAY_MODE_COMPACT = 'compact';
|
||||
/** @var string FORM_DEFAULT_DISPLAY_MODE */
|
||||
const FORM_DEFAULT_DISPLAY_MODE = self::FORM_ENUM_DISPLAY_MODE_COSY;
|
||||
public const FORM_DEFAULT_DISPLAY_MODE = self::FORM_ENUM_DISPLAY_MODE_COSY;
|
||||
/** @var bool FORM_DEFAULT_ALWAYS_SHOW_SUBMIT */
|
||||
const FORM_DEFAULT_ALWAYS_SHOW_SUBMIT = false;
|
||||
public const FORM_DEFAULT_ALWAYS_SHOW_SUBMIT = false;
|
||||
|
||||
/**
|
||||
* Loads classes from the base portal
|
||||
@@ -72,16 +72,11 @@ class ApplicationHelper
|
||||
);
|
||||
|
||||
// Loading classes from base portal
|
||||
foreach (scandir($sScannedDir) as $sFile)
|
||||
{
|
||||
if (strpos($sFile, $sFilePattern) !== false && file_exists($sFilepath = $sScannedDir.'/'.$sFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (scandir($sScannedDir) as $sFile) {
|
||||
if (strpos($sFile, $sFilePattern) !== false && file_exists($sFilepath = $sScannedDir.'/'.$sFile)) {
|
||||
try {
|
||||
require_once $sFilepath;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Error while trying to load '.$sType.' '.$sFile);
|
||||
}
|
||||
}
|
||||
@@ -97,32 +92,25 @@ class ApplicationHelper
|
||||
*/
|
||||
public static function LoadBrickSecurity(AbstractBrick $oBrick)
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
// Allowed profiles
|
||||
if (utils::IsNotNullOrEmptyString($oBrick->GetAllowedProfilesOql()))
|
||||
{
|
||||
if (utils::IsNotNullOrEmptyString($oBrick->GetAllowedProfilesOql())) {
|
||||
$oSearch = DBObjectSearch::FromOQL_AllData($oBrick->GetAllowedProfilesOql());
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
while ($oProfile = $oSet->Fetch())
|
||||
{
|
||||
while ($oProfile = $oSet->Fetch()) {
|
||||
$oBrick->AddAllowedProfile($oProfile->Get('name'));
|
||||
}
|
||||
}
|
||||
|
||||
// Denied profiles
|
||||
if (utils::IsNotNullOrEmptyString($oBrick->GetDeniedProfilesOql()))
|
||||
{
|
||||
if (utils::IsNotNullOrEmptyString($oBrick->GetDeniedProfilesOql())) {
|
||||
$oSearch = DBObjectSearch::FromOQL_AllData($oBrick->GetDeniedProfilesOql());
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
while ($oProfile = $oSet->Fetch())
|
||||
{
|
||||
while ($oProfile = $oSet->Fetch()) {
|
||||
$oBrick->AddDeniedProfile($oProfile->Get('name'));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Error while loading security from '.$oBrick->GetId().' brick');
|
||||
}
|
||||
}
|
||||
@@ -147,18 +135,14 @@ class ApplicationHelper
|
||||
$aForm = null;
|
||||
|
||||
// We try to find the form for that class
|
||||
if (isset($aForms[$sClass]) && isset($aForms[$sClass][$sMode]))
|
||||
{
|
||||
if (isset($aForms[$sClass]) && isset($aForms[$sClass][$sMode])) {
|
||||
$aForm = $aForms[$sClass][$sMode];
|
||||
}
|
||||
// If not found, we try find one from the closest parent class
|
||||
else
|
||||
{
|
||||
else {
|
||||
$bFound = false;
|
||||
foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_EXCLUDELEAF, false) as $sParentClass)
|
||||
{
|
||||
if (isset($aForms[$sParentClass]) && isset($aForms[$sParentClass][$sMode]))
|
||||
{
|
||||
foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_EXCLUDELEAF, false) as $sParentClass) {
|
||||
if (isset($aForms[$sParentClass]) && isset($aForms[$sParentClass][$sMode])) {
|
||||
$aForm = $aForms[$sParentClass][$sMode];
|
||||
$bFound = true;
|
||||
break;
|
||||
@@ -166,8 +150,7 @@ class ApplicationHelper
|
||||
}
|
||||
|
||||
// If we have still not found one, we return a default form
|
||||
if (!$bFound)
|
||||
{
|
||||
if (!$bFound) {
|
||||
$aForm = static::GenerateDefaultFormForClass($sClass);
|
||||
}
|
||||
}
|
||||
@@ -192,32 +175,26 @@ class ApplicationHelper
|
||||
public static function GetLoadedListFromClass($aLists, $sClass, $sList = 'default')
|
||||
{
|
||||
$aFoundList = null;
|
||||
$aAttCodes = array();
|
||||
$aAttCodes = [];
|
||||
|
||||
// We try to find the list for that class
|
||||
if (isset($aLists[$sClass]) && isset($aLists[$sClass][$sList]))
|
||||
{
|
||||
if (isset($aLists[$sClass]) && isset($aLists[$sClass][$sList])) {
|
||||
$aFoundList = $aLists[$sClass][$sList];
|
||||
}
|
||||
// Else we try to found the default list for that class
|
||||
elseif (isset($aLists[$sClass]) && isset($aLists[$sClass]['default']))
|
||||
{
|
||||
elseif (isset($aLists[$sClass]) && isset($aLists[$sClass]['default'])) {
|
||||
$aFoundList = $aLists[$sClass]['default'];
|
||||
}
|
||||
// If not found, we try find one from the closest parent class
|
||||
else
|
||||
{
|
||||
foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass)
|
||||
{
|
||||
else {
|
||||
foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass) {
|
||||
// Trying to find the right list
|
||||
if (isset($aLists[$sParentClass]) && isset($aLists[$sParentClass][$sList]))
|
||||
{
|
||||
if (isset($aLists[$sParentClass]) && isset($aLists[$sParentClass][$sList])) {
|
||||
$aFoundList = $aLists[$sParentClass][$sList];
|
||||
break;
|
||||
}
|
||||
// Or the default list
|
||||
elseif (isset($aLists[$sParentClass]) && isset($aLists[$sParentClass]['default']))
|
||||
{
|
||||
elseif (isset($aLists[$sParentClass]) && isset($aLists[$sParentClass]['default'])) {
|
||||
$aFoundList = $aLists[$sParentClass]['default'];
|
||||
break;
|
||||
}
|
||||
@@ -225,15 +202,11 @@ class ApplicationHelper
|
||||
}
|
||||
|
||||
// If found, we flatten the list to keep only the attribute codes (not the rank)
|
||||
if ($aFoundList !== null)
|
||||
{
|
||||
foreach ($aFoundList as $aItem)
|
||||
{
|
||||
if ($aFoundList !== null) {
|
||||
foreach ($aFoundList as $aItem) {
|
||||
$aAttCodes[] = $aItem['att_code'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aAttCodes = MetaModel::FlattenZList(MetaModel::GetZListItems($sClass, 'list'));
|
||||
}
|
||||
|
||||
@@ -252,32 +225,31 @@ class ApplicationHelper
|
||||
*/
|
||||
protected static function GenerateDefaultFormForClass($sClass, $bAddLinksets = false)
|
||||
{
|
||||
$aForm = array(
|
||||
$aForm = [
|
||||
'id' => strtolower($sClass)."-default-".uniqid(),
|
||||
'type' => 'custom_list',
|
||||
'properties' => array(
|
||||
'properties' => [
|
||||
'display_mode' => static::FORM_DEFAULT_DISPLAY_MODE,
|
||||
'always_show_submit' => static::FORM_DEFAULT_ALWAYS_SHOW_SUBMIT,
|
||||
'navigation_rules' => array(
|
||||
'navigation_rules' => [
|
||||
'submit' => null,
|
||||
'cancel' => null,
|
||||
),
|
||||
),
|
||||
'fields' => array(),
|
||||
'layout' => array(
|
||||
],
|
||||
],
|
||||
'fields' => [],
|
||||
'layout' => [
|
||||
'type' => 'xhtml',
|
||||
'content' => '',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// Generate layout
|
||||
$sContent = "";
|
||||
|
||||
// - Retrieve zlist details
|
||||
$aDetailsList = MetaModel::GetZListItems($sClass, 'details');
|
||||
$aDetailsStruct = cmdbAbstractObject::ProcessZlist($aDetailsList, array(), 'UI:PropertiesTab', 'col1', '');
|
||||
if(!isset($aDetailsStruct['UI:PropertiesTab']))
|
||||
{
|
||||
$aDetailsStruct = cmdbAbstractObject::ProcessZlist($aDetailsList, [], 'UI:PropertiesTab', 'col1', '');
|
||||
if (!isset($aDetailsStruct['UI:PropertiesTab'])) {
|
||||
// For the iTop administrator
|
||||
IssueLog::Error('Could not generate default form for "'.$sClass.'" class. Is the "details" zlist empty?');
|
||||
// For the end-user
|
||||
@@ -287,14 +259,10 @@ class ApplicationHelper
|
||||
|
||||
// Count cols (not linksets)
|
||||
$iColCount = 0;
|
||||
foreach ($aPropertiesStruct as $sColId => $aColFieldsets)
|
||||
{
|
||||
if (substr($sColId, 0, 1) !== '_')
|
||||
{
|
||||
foreach ($aColFieldsets as $sFieldsetName => $aAttCodes)
|
||||
{
|
||||
if (substr($sFieldsetName, 0, 1) !== '_')
|
||||
{
|
||||
foreach ($aPropertiesStruct as $sColId => $aColFieldsets) {
|
||||
if (substr($sColId, 0, 1) !== '_') {
|
||||
foreach ($aColFieldsets as $sFieldsetName => $aAttCodes) {
|
||||
if (substr($sFieldsetName, 0, 1) !== '_') {
|
||||
$iColCount++;
|
||||
break;
|
||||
}
|
||||
@@ -302,28 +270,24 @@ class ApplicationHelper
|
||||
}
|
||||
}
|
||||
// If no cols, return a default form with all fields one after another
|
||||
if ($iColCount === 0)
|
||||
{
|
||||
return array(
|
||||
if ($iColCount === 0) {
|
||||
return [
|
||||
'id' => 'default',
|
||||
'type' => 'zlist',
|
||||
'fields' => 'details',
|
||||
'layout' => null,
|
||||
);
|
||||
];
|
||||
}
|
||||
// Warning, this might not be great when 12 modulo $iColCount is greater than 0.
|
||||
$sColCSSClass = 'col-sm-'.floor(12 / $iColCount);
|
||||
|
||||
$sLinksetsHTML = "";
|
||||
$sRowHTML = "<div class=\"row\">\n";
|
||||
foreach ($aPropertiesStruct as $sColId => $aColFieldsets)
|
||||
{
|
||||
foreach ($aPropertiesStruct as $sColId => $aColFieldsets) {
|
||||
$sColsHTML = "\t<div class=\"".$sColCSSClass."\">\n";
|
||||
foreach ($aColFieldsets as $sFieldsetName => $aAttCodes)
|
||||
{
|
||||
foreach ($aColFieldsets as $sFieldsetName => $aAttCodes) {
|
||||
// Add fieldset, not linkset
|
||||
if (substr($sFieldsetName, 0, 1) !== '_')
|
||||
{
|
||||
if (substr($sFieldsetName, 0, 1) !== '_') {
|
||||
$sFieldsetHTML = "\t\t<fieldset>\n";
|
||||
$sFieldsetHTML .= "\t\t\t<legend>".utils::EscapeHtml(Dict::S($sFieldsetName))."</legend>\n";
|
||||
|
||||
@@ -335,11 +299,8 @@ class ApplicationHelper
|
||||
|
||||
// Add to col
|
||||
$sColsHTML .= $sFieldsetHTML;
|
||||
}
|
||||
elseif ($bAddLinksets)
|
||||
{
|
||||
foreach ($aAttCodes as $sAttCode)
|
||||
{
|
||||
} elseif ($bAddLinksets) {
|
||||
foreach ($aAttCodes as $sAttCode) {
|
||||
$sLinksetsHTML .= "<div class=\"form_field\" data-field-id=\"".$sAttCode."\"></div>\n";
|
||||
}
|
||||
}
|
||||
@@ -368,8 +329,9 @@ class ApplicationHelper
|
||||
* @return array
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public static function GetAttDefClassesToExcludeFromMarkupMetadataRawValue(){
|
||||
return array(
|
||||
public static function GetAttDefClassesToExcludeFromMarkupMetadataRawValue()
|
||||
{
|
||||
return [
|
||||
'AttributeBlob',
|
||||
'AttributeCustomFields',
|
||||
'AttributeDashboard',
|
||||
@@ -377,7 +339,7 @@ class ApplicationHelper
|
||||
'AttributeStopWatch',
|
||||
'AttributeSubItem',
|
||||
'AttributeTable',
|
||||
'AttributeText'
|
||||
);
|
||||
'AttributeText',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Portal\Helper;
|
||||
|
||||
/**
|
||||
@@ -53,14 +52,13 @@ class BrickControllerHelper
|
||||
public function ExtractSortParams()
|
||||
{
|
||||
// Getting sort params
|
||||
$aSortParams = $this->oRequestManipulator->ReadParam('aSortParams', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
|
||||
$aSortParams = $this->oRequestManipulator->ReadParam('aSortParams', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
|
||||
|
||||
// Converting sort direction to proper format for DBObjectSet as it only accept real booleans
|
||||
foreach ($aSortParams as $sAttributeAlias => $sDirection)
|
||||
{
|
||||
foreach ($aSortParams as $sAttributeAlias => $sDirection) {
|
||||
$aSortParams[$sAttributeAlias] = ($sDirection === 'true');
|
||||
}
|
||||
|
||||
return $aSortParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,8 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Portal\Helper;
|
||||
|
||||
|
||||
use AttributeImage;
|
||||
use AttributeSet;
|
||||
use AttributeTagSet;
|
||||
@@ -44,9 +42,9 @@ use utils;
|
||||
class BrowseBrickHelper
|
||||
{
|
||||
/** @var string LEVEL_SEPARATOR */
|
||||
const LEVEL_SEPARATOR = '-';
|
||||
public const LEVEL_SEPARATOR = '-';
|
||||
/** @var array OPTIONAL_ATTRIBUTES */
|
||||
const OPTIONAL_ATTRIBUTES = array('tooltip_att', 'description_att', 'image_att');
|
||||
public const OPTIONAL_ATTRIBUTES = ['tooltip_att', 'description_att', 'image_att'];
|
||||
|
||||
/** @var \Combodo\iTop\Portal\Helper\SecurityHelper */
|
||||
private $oSecurityHelper;
|
||||
@@ -62,7 +60,10 @@ class BrowseBrickHelper
|
||||
* @param \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator
|
||||
* @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oUrlGenerator
|
||||
*/
|
||||
public function __construct(SecurityHelper $oSecurityHelper, ScopeValidatorHelper $oScopeValidator, UrlGeneratorInterface $oUrlGenerator
|
||||
public function __construct(
|
||||
SecurityHelper $oSecurityHelper,
|
||||
ScopeValidatorHelper $oScopeValidator,
|
||||
UrlGeneratorInterface $oUrlGenerator
|
||||
) {
|
||||
$this->oSecurityHelper = $oSecurityHelper;
|
||||
$this->oScopeValidator = $oScopeValidator;
|
||||
@@ -89,24 +90,24 @@ class BrowseBrickHelper
|
||||
*/
|
||||
public function TreeToFlatLevelsProperties(array $aLevels, array &$aLevelsProperties, $sLevelAliasPrefix = 'L')
|
||||
{
|
||||
foreach ($aLevels as $aLevel)
|
||||
{
|
||||
foreach ($aLevels as $aLevel) {
|
||||
$sCurrentLevelAlias = $sLevelAliasPrefix.static::LEVEL_SEPARATOR.$aLevel['id'];
|
||||
$oSearch = DBSearch::CloneWithAlias(DBSearch::FromOQL($aLevel['oql']), $sCurrentLevelAlias);
|
||||
|
||||
// Restricting to the allowed scope
|
||||
$oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $oSearch->GetClass(),
|
||||
UR_ACTION_READ);
|
||||
$oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(
|
||||
UserRights::ListProfiles(),
|
||||
$oSearch->GetClass(),
|
||||
UR_ACTION_READ
|
||||
);
|
||||
$oSearch = ($oScopeSearch !== null) ? $oSearch->Intersect($oScopeSearch) : null;
|
||||
// - Allowing all data if necessary
|
||||
if ($oScopeSearch !== null && $oScopeSearch->IsAllDataAllowed())
|
||||
{
|
||||
if ($oScopeSearch !== null && $oScopeSearch->IsAllDataAllowed()) {
|
||||
$oSearch->AllowAllData();
|
||||
}
|
||||
|
||||
if ($oSearch !== null)
|
||||
{
|
||||
$aLevelsProperties[$sCurrentLevelAlias] = array(
|
||||
if ($oSearch !== null) {
|
||||
$aLevelsProperties[$sCurrentLevelAlias] = [
|
||||
'alias' => $sCurrentLevelAlias,
|
||||
'title' => ($aLevel['title'] !== null) ? Dict::S($aLevel['title']) : MetaModel::GetName($oSearch->GetClass()),
|
||||
'parent_att' => $aLevel['parent_att'],
|
||||
@@ -115,42 +116,35 @@ class BrowseBrickHelper
|
||||
'description_att' => $aLevel['description_att'],
|
||||
'image_att' => $aLevel['image_att'],
|
||||
'search' => $oSearch,
|
||||
'fields' => array(),
|
||||
'actions' => array(),
|
||||
);
|
||||
'fields' => [],
|
||||
'actions' => [],
|
||||
];
|
||||
|
||||
// Adding current level's fields
|
||||
if (isset($aLevel['fields']))
|
||||
{
|
||||
$aLevelsProperties[$sCurrentLevelAlias]['fields'] = array();
|
||||
if (isset($aLevel['fields'])) {
|
||||
$aLevelsProperties[$sCurrentLevelAlias]['fields'] = [];
|
||||
|
||||
foreach ($aLevel['fields'] as $sFieldAttCode => $aFieldProperties)
|
||||
{
|
||||
$aLevelsProperties[$sCurrentLevelAlias]['fields'][] = array(
|
||||
foreach ($aLevel['fields'] as $sFieldAttCode => $aFieldProperties) {
|
||||
$aLevelsProperties[$sCurrentLevelAlias]['fields'][] = [
|
||||
'code' => $sFieldAttCode,
|
||||
'label' => MetaModel::GetAttributeDef($oSearch->GetClass(), $sFieldAttCode)->GetLabel(),
|
||||
'hidden' => $aFieldProperties['hidden'],
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Flattening and adding sub levels
|
||||
if (isset($aLevel['levels']))
|
||||
{
|
||||
foreach ($aLevel['levels'] as $aChildLevel)
|
||||
{
|
||||
if (isset($aLevel['levels'])) {
|
||||
foreach ($aLevel['levels'] as $aChildLevel) {
|
||||
// Checking if the sub level if allowed
|
||||
$oChildSearch = DBSearch::FromOQL($aChildLevel['oql']);
|
||||
if ($this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $oChildSearch->GetClass()))
|
||||
{
|
||||
if ($this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $oChildSearch->GetClass())) {
|
||||
// Adding the sub level to this one
|
||||
$aLevelsProperties[$sCurrentLevelAlias]['levels'][] = $sCurrentLevelAlias.static::LEVEL_SEPARATOR.$aChildLevel['id'];
|
||||
|
||||
// Adding drill down action if necessary
|
||||
foreach ($aLevel['actions'] as $sId => $aAction)
|
||||
{
|
||||
if ($aAction['type'] === BrowseBrick::ENUM_ACTION_DRILLDOWN)
|
||||
{
|
||||
foreach ($aLevel['actions'] as $sId => $aAction) {
|
||||
if ($aAction['type'] === BrowseBrick::ENUM_ACTION_DRILLDOWN) {
|
||||
$aLevelsProperties[$sCurrentLevelAlias]['actions'][$sId] = $aAction;
|
||||
break;
|
||||
}
|
||||
@@ -162,49 +156,43 @@ class BrowseBrickHelper
|
||||
}
|
||||
|
||||
// Adding actions to the level
|
||||
foreach ($aLevel['actions'] as $sId => $aAction)
|
||||
{
|
||||
foreach ($aLevel['actions'] as $sId => $aAction) {
|
||||
// ... Only if it's not already there (eg. the drilldown added with the sublevels)
|
||||
if (!array_key_exists($sId, $aLevelsProperties[$sCurrentLevelAlias]['actions']))
|
||||
{
|
||||
if (!array_key_exists($sId, $aLevelsProperties[$sCurrentLevelAlias]['actions'])) {
|
||||
// Adding action only if allowed
|
||||
if (($aAction['type'] === BrowseBrick::ENUM_ACTION_VIEW) && !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ,
|
||||
$oSearch->GetClass()))
|
||||
{
|
||||
if (($aAction['type'] === BrowseBrick::ENUM_ACTION_VIEW) && !$this->oSecurityHelper->IsActionAllowed(
|
||||
UR_ACTION_READ,
|
||||
$oSearch->GetClass()
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
elseif (($aAction['type'] === BrowseBrick::ENUM_ACTION_EDIT) && !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY,
|
||||
$oSearch->GetClass()))
|
||||
{
|
||||
} elseif (($aAction['type'] === BrowseBrick::ENUM_ACTION_EDIT) && !$this->oSecurityHelper->IsActionAllowed(
|
||||
UR_ACTION_MODIFY,
|
||||
$oSearch->GetClass()
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
elseif ($aAction['type'] === BrowseBrick::ENUM_ACTION_DRILLDOWN)
|
||||
{
|
||||
} elseif ($aAction['type'] === BrowseBrick::ENUM_ACTION_DRILLDOWN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Setting action title
|
||||
if (isset($aAction['title']))
|
||||
{
|
||||
if (isset($aAction['title'])) {
|
||||
// Note : There could be an enhancement here, by checking if the string code has the '%1' needle and use Dict::S or Dict::Format accordingly.
|
||||
// But it would require to benchmark a potential performance drop as it will be done for all items
|
||||
$aAction['title'] = Dict::S($aAction['title']);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ($aAction['type'])
|
||||
{
|
||||
} else {
|
||||
switch ($aAction['type']) {
|
||||
case BrowseBrick::ENUM_ACTION_CREATE_FROM_THIS:
|
||||
// We can only make translate a dictionary entry with a class placeholder when the action has a class tag. if it has a factory method, we don't know yet what class is going to be created
|
||||
if ($aAction['factory']['type'] === BrowseBrick::ENUM_FACTORY_TYPE_CLASS)
|
||||
{
|
||||
$aAction['title'] = Dict::Format('Brick:Portal:Browse:Action:CreateObjectFromThis',
|
||||
MetaModel::GetName($aAction['factory']['value']));
|
||||
$aAction['url'] = $this->oUrlGenerator->generate('p_object_create',
|
||||
array('sObjectClass' => $aAction['factory']['value']));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($aAction['factory']['type'] === BrowseBrick::ENUM_FACTORY_TYPE_CLASS) {
|
||||
$aAction['title'] = Dict::Format(
|
||||
'Brick:Portal:Browse:Action:CreateObjectFromThis',
|
||||
MetaModel::GetName($aAction['factory']['value'])
|
||||
);
|
||||
$aAction['url'] = $this->oUrlGenerator->generate(
|
||||
'p_object_create',
|
||||
['sObjectClass' => $aAction['factory']['value']]
|
||||
);
|
||||
} else {
|
||||
$aAction['title'] = Dict::S('Brick:Portal:Browse:Action:Create');
|
||||
}
|
||||
break;
|
||||
@@ -221,10 +209,8 @@ class BrowseBrickHelper
|
||||
}
|
||||
|
||||
// Setting action icon class
|
||||
if (!isset($aAction['icon_class']))
|
||||
{
|
||||
switch ($aAction['type'])
|
||||
{
|
||||
if (!isset($aAction['icon_class'])) {
|
||||
switch ($aAction['type']) {
|
||||
case BrowseBrick::ENUM_ACTION_CREATE_FROM_THIS:
|
||||
$aAction['icon_class'] = BrowseBrick::ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS;
|
||||
break;
|
||||
@@ -241,21 +227,19 @@ class BrowseBrickHelper
|
||||
}
|
||||
|
||||
// Setting action url
|
||||
switch ($aAction['type'])
|
||||
{
|
||||
switch ($aAction['type']) {
|
||||
case BrowseBrick::ENUM_ACTION_CREATE_FROM_THIS:
|
||||
if ($aAction['factory']['type'] === BrowseBrick::ENUM_FACTORY_TYPE_CLASS)
|
||||
{
|
||||
$aAction['url'] = $this->oUrlGenerator->generate('p_object_create',
|
||||
array('sObjectClass' => $aAction['factory']['value']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aAction['url'] = $this->oUrlGenerator->generate('p_object_create_from_factory', array(
|
||||
if ($aAction['factory']['type'] === BrowseBrick::ENUM_FACTORY_TYPE_CLASS) {
|
||||
$aAction['url'] = $this->oUrlGenerator->generate(
|
||||
'p_object_create',
|
||||
['sObjectClass' => $aAction['factory']['value']]
|
||||
);
|
||||
} else {
|
||||
$aAction['url'] = $this->oUrlGenerator->generate('p_object_create_from_factory', [
|
||||
'sEncodedMethodName' => base64_encode($aAction['factory']['value']),
|
||||
'sObjectClass' => '-objectClass-',
|
||||
'sObjectId' => '-objectId-',
|
||||
));
|
||||
]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -278,10 +262,9 @@ class BrowseBrickHelper
|
||||
*/
|
||||
public function PrepareActionRulesForItems(array $aItems, $sLevelsAlias, array &$aLevelsProperties)
|
||||
{
|
||||
$aActionRules = array();
|
||||
$aActionRules = [];
|
||||
|
||||
foreach ($aLevelsProperties[$sLevelsAlias]['actions'] as $sId => $aAction)
|
||||
{
|
||||
foreach ($aLevelsProperties[$sLevelsAlias]['actions'] as $sId => $aAction) {
|
||||
$aActionRules[$sId] = ContextManipulatorHelper::PrepareAndEncodeRulesToken($aAction['rules'], $aItems);
|
||||
}
|
||||
|
||||
@@ -317,11 +300,10 @@ class BrowseBrickHelper
|
||||
*/
|
||||
public function AddToFlatItems(array $aCurrentRow, array &$aLevelsProperties)
|
||||
{
|
||||
$aRow = array();
|
||||
$aRow = [];
|
||||
|
||||
/** @var \DBObject $value */
|
||||
foreach ($aCurrentRow as $key => $value)
|
||||
{
|
||||
foreach ($aCurrentRow as $key => $value) {
|
||||
// Retrieving objects from all levels
|
||||
$aItems = array_values($aCurrentRow);
|
||||
|
||||
@@ -332,36 +314,31 @@ class BrowseBrickHelper
|
||||
$sNameAttDef = MetaModel::GetAttributeDef($sCurrentObjectClass, $sNameAttCode);
|
||||
$sNameAttDefClass = get_class($sNameAttDef);
|
||||
|
||||
$aRow[$key] = array(
|
||||
$aRow[$key] = [
|
||||
'level_alias' => $key,
|
||||
'id' => $sCurrentObjectId,
|
||||
'name' => utils::EscapeHtml($value->Get($sNameAttCode)),
|
||||
'class' => $sCurrentObjectClass,
|
||||
'action_rules_token' => $this->PrepareActionRulesForItems($aItems, $key, $aLevelsProperties),
|
||||
'metadata' => array(
|
||||
'metadata' => [
|
||||
'object_class' => $sCurrentObjectClass,
|
||||
'object_id' => $sCurrentObjectId,
|
||||
'attribute_code' => $sNameAttCode,
|
||||
'attribute_type' => $sNameAttDefClass,
|
||||
'value_raw' => $value->Get($sNameAttCode),
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// Adding optional attributes if necessary
|
||||
foreach (static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute)
|
||||
{
|
||||
if ($aLevelsProperties[$key][$sOptionalAttribute] !== null)
|
||||
{
|
||||
foreach (static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute) {
|
||||
if ($aLevelsProperties[$key][$sOptionalAttribute] !== null) {
|
||||
$sPropertyName = substr($sOptionalAttribute, 0, -4);
|
||||
$oAttDef = MetaModel::GetAttributeDef($sCurrentObjectClass, $aLevelsProperties[$key][$sOptionalAttribute]);
|
||||
|
||||
if ($oAttDef instanceof AttributeImage)
|
||||
{
|
||||
if ($oAttDef instanceof AttributeImage) {
|
||||
$tmpAttValue = $value->Get($aLevelsProperties[$key][$sOptionalAttribute]);
|
||||
if ($sOptionalAttribute === 'image_att')
|
||||
{
|
||||
if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty())
|
||||
{
|
||||
if ($sOptionalAttribute === 'image_att') {
|
||||
if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty()) {
|
||||
$oOrmDoc = $tmpAttValue;
|
||||
$tmpAttValue = $this->oUrlGenerator->generate('p_object_document_display', [
|
||||
'sObjectClass' => $sCurrentObjectClass,
|
||||
@@ -370,15 +347,11 @@ class BrowseBrickHelper
|
||||
'cache' => 86400,
|
||||
's' => $oOrmDoc->GetSignature(),
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$tmpAttValue = $oAttDef->Get('default_image');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$tmpAttValue = $value->GetAsHTML($aLevelsProperties[$key][$sOptionalAttribute]);
|
||||
}
|
||||
|
||||
@@ -386,16 +359,13 @@ class BrowseBrickHelper
|
||||
}
|
||||
}
|
||||
// Adding fields attributes if necessary
|
||||
if (!empty($aLevelsProperties[$key]['fields']))
|
||||
{
|
||||
$aRow[$key]['fields'] = array();
|
||||
foreach ($aLevelsProperties[$key]['fields'] as $aField)
|
||||
{
|
||||
if (!empty($aLevelsProperties[$key]['fields'])) {
|
||||
$aRow[$key]['fields'] = [];
|
||||
foreach ($aLevelsProperties[$key]['fields'] as $aField) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sCurrentObjectClass, $aField['code']);
|
||||
$sAttDefClass = get_class($oAttDef);
|
||||
|
||||
switch (true)
|
||||
{
|
||||
switch (true) {
|
||||
case $oAttDef instanceof AttributeTagSet:
|
||||
/** @var \ormTagSet $oSetValues */
|
||||
$oSetValues = $value->Get($aField['code']);
|
||||
@@ -412,8 +382,7 @@ class BrowseBrickHelper
|
||||
case $oAttDef instanceof AttributeImage:
|
||||
// Todo: This should be refactored, it has been seen multiple times in the portal
|
||||
$oOrmDoc = $value->Get($aField['code']);
|
||||
if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty())
|
||||
{
|
||||
if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty()) {
|
||||
$sUrl = $this->oUrlGenerator->generate('p_object_document_display', [
|
||||
'sObjectClass' => $sCurrentObjectClass,
|
||||
'sObjectId' => $sCurrentObjectId,
|
||||
@@ -421,9 +390,7 @@ class BrowseBrickHelper
|
||||
'cache' => 86400,
|
||||
's' => $oOrmDoc->GetSignature(),
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sUrl = $oAttDef->Get('default_image');
|
||||
}
|
||||
$sHtmlForFieldValue = '<img src="'.$sUrl.'" />';
|
||||
@@ -436,24 +403,22 @@ class BrowseBrickHelper
|
||||
|
||||
// For simple fields, we get the raw (stored) value as well
|
||||
$bExcludeRawValue = false;
|
||||
foreach (ApplicationHelper::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
|
||||
{
|
||||
if (is_a($sAttDefClass, $sAttDefClassToExclude, true))
|
||||
{
|
||||
foreach (ApplicationHelper::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) {
|
||||
if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) {
|
||||
$bExcludeRawValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$attValueRaw = ($bExcludeRawValue === false) ? $value->Get($aField['code']) : null;
|
||||
|
||||
$aRow[$key]['fields'][$aField['code']] = array(
|
||||
$aRow[$key]['fields'][$aField['code']] = [
|
||||
'object_class' => $sCurrentObjectClass,
|
||||
'object_id' => $sCurrentObjectId,
|
||||
'attribute_code' => $aField['code'],
|
||||
'attribute_type' => $sAttDefClass,
|
||||
'value_raw' => $attValueRaw,
|
||||
'value_html' => $sHtmlForFieldValue,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,39 +468,34 @@ class BrowseBrickHelper
|
||||
|
||||
// We make sure to keep all row objects through levels by copying them when processing the first level.
|
||||
// Otherwise they will be sliced through levels, one by one.
|
||||
if ($aCurrentRowObjects === null)
|
||||
{
|
||||
if ($aCurrentRowObjects === null) {
|
||||
$aCurrentRowObjects = $aCurrentRowValues;
|
||||
}
|
||||
|
||||
if (!isset($aItems[$sCurrentIndex]))
|
||||
{
|
||||
$aItems[$sCurrentIndex] = array(
|
||||
if (!isset($aItems[$sCurrentIndex])) {
|
||||
$aItems[$sCurrentIndex] = [
|
||||
'level_alias' => $aCurrentRowKeys[0],
|
||||
'id' => $aCurrentRowValues[0]->GetKey(),
|
||||
'name' => utils::EscapeHtml($aCurrentRowValues[0]->Get($aLevelsProperties[$aCurrentRowKeys[0]]['name_att'])),
|
||||
'class' => get_class($aCurrentRowValues[0]),
|
||||
'subitems' => array(),
|
||||
'subitems' => [],
|
||||
'filter_data' => $this->GetFilterData($aLevelsProperties[$aCurrentRowKeys[0]], $aCurrentRowKeys[0], $aCurrentRowValues[0]),
|
||||
'action_rules_token' => $this->PrepareActionRulesForItems($aCurrentRowObjects, $aCurrentRowKeys[0], $aLevelsProperties),
|
||||
);
|
||||
];
|
||||
|
||||
// Adding optional attributes if necessary
|
||||
foreach (static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute)
|
||||
{
|
||||
if ($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute] !== null)
|
||||
{
|
||||
foreach (static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute) {
|
||||
if ($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute] !== null) {
|
||||
$sPropertyName = substr($sOptionalAttribute, 0, -4);
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($aCurrentRowValues[0]),
|
||||
$aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]);
|
||||
$oAttDef = MetaModel::GetAttributeDef(
|
||||
get_class($aCurrentRowValues[0]),
|
||||
$aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]
|
||||
);
|
||||
|
||||
if ($oAttDef instanceof AttributeImage)
|
||||
{
|
||||
if ($oAttDef instanceof AttributeImage) {
|
||||
$tmpAttValue = $aCurrentRowValues[0]->Get($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]);
|
||||
if ($sOptionalAttribute === 'image_att')
|
||||
{
|
||||
if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty())
|
||||
{
|
||||
if ($sOptionalAttribute === 'image_att') {
|
||||
if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty()) {
|
||||
$oOrmDoc = $tmpAttValue;
|
||||
$tmpAttValue = $this->oUrlGenerator->generate('p_object_document_display', [
|
||||
'sObjectClass' => get_class($aCurrentRowValues[0]),
|
||||
@@ -544,15 +504,11 @@ class BrowseBrickHelper
|
||||
'cache' => 86400,
|
||||
's' => $oOrmDoc->GetSignature(),
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$tmpAttValue = $oAttDef->Get('default_image');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$tmpAttValue = $aCurrentRowValues[0]->GetAsHTML($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]);
|
||||
}
|
||||
|
||||
@@ -562,8 +518,7 @@ class BrowseBrickHelper
|
||||
}
|
||||
|
||||
$aCurrentRowSliced = array_slice($aCurrentRow, 1);
|
||||
if (!empty($aCurrentRowSliced))
|
||||
{
|
||||
if (!empty($aCurrentRowSliced)) {
|
||||
$this->AddToTreeItems($aItems[$sCurrentIndex]['subitems'], $aCurrentRowSliced, $aLevelsProperties, $aCurrentRowObjects);
|
||||
}
|
||||
}
|
||||
@@ -580,7 +535,7 @@ class BrowseBrickHelper
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function GetFilterData(array $aLevelProperties, string $sRowKey, DBObject $oRowValue) : array
|
||||
private function GetFilterData(array $aLevelProperties, string $sRowKey, DBObject $oRowValue): array
|
||||
{
|
||||
// result
|
||||
$sValues = "";
|
||||
@@ -599,17 +554,17 @@ class BrowseBrickHelper
|
||||
$sValue = $oAttDef->GetAsHTML($oRowValue->Get($aField['code']));
|
||||
|
||||
// do not print empty fields
|
||||
if(!utils::IsNullOrEmptyString($sValue)){
|
||||
if (!utils::IsNullOrEmptyString($sValue)) {
|
||||
|
||||
// append to result
|
||||
$sValues .= $sValue;
|
||||
$sValuesAndCodes .= '<span><span class="tree-item-filter-data-label">' . $aField['label'] . ':</span> ' . $sValue . '</span>';
|
||||
$sValuesAndCodes .= '<span><span class="tree-item-filter-data-label">'.$aField['label'].':</span> '.$sValue.'</span>';
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'values' => $sValues,
|
||||
'values_and_codes' => $sValuesAndCodes
|
||||
'values_and_codes' => $sValuesAndCodes,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ use SimpleCrypt;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use TrueExpression;
|
||||
use UserRights;
|
||||
|
||||
use const UR_ACTION_READ;
|
||||
|
||||
/**
|
||||
@@ -40,19 +41,19 @@ use const UR_ACTION_READ;
|
||||
class ContextManipulatorHelper
|
||||
{
|
||||
/** @var string ENUM_RULE_CALLBACK_BACK */
|
||||
const ENUM_RULE_CALLBACK_BACK = 'back';
|
||||
public const ENUM_RULE_CALLBACK_BACK = 'back';
|
||||
/** @var string ENUM_RULE_CALLBACK_GOTO */
|
||||
const ENUM_RULE_CALLBACK_GOTO = 'goto';
|
||||
public const ENUM_RULE_CALLBACK_GOTO = 'goto';
|
||||
/** @var string ENUM_RULE_CALLBACK_OPEN */
|
||||
const ENUM_RULE_CALLBACK_OPEN = 'open';
|
||||
public const ENUM_RULE_CALLBACK_OPEN = 'open';
|
||||
/** @var string ENUM_RULE_CALLBACK_OPEN_VIEW */
|
||||
const ENUM_RULE_CALLBACK_OPEN_VIEW = 'view';
|
||||
public const ENUM_RULE_CALLBACK_OPEN_VIEW = 'view';
|
||||
/** @var string ENUM_RULE_CALLBACK_OPEN_EDIT */
|
||||
const ENUM_RULE_CALLBACK_OPEN_EDIT = 'edit';
|
||||
public const ENUM_RULE_CALLBACK_OPEN_EDIT = 'edit';
|
||||
/** @var string DEFAULT_RULE_CALLBACK_OPEN */
|
||||
const DEFAULT_RULE_CALLBACK_OPEN = self::ENUM_RULE_CALLBACK_OPEN_VIEW;
|
||||
public const DEFAULT_RULE_CALLBACK_OPEN = self::ENUM_RULE_CALLBACK_OPEN_VIEW;
|
||||
|
||||
const PRIVATE_KEY = 'portal-priv-key';
|
||||
public const PRIVATE_KEY = 'portal-priv-key';
|
||||
|
||||
/** @var array $aRules */
|
||||
protected $aRules;
|
||||
@@ -76,8 +77,9 @@ class ContextManipulatorHelper
|
||||
*
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
public function __construct(ModuleDesign $oModuleDesign, RouterInterface $oRouter, BrickCollection $oBrickCollection, ScopeValidatorHelper $oScopeValidator) {
|
||||
$this->aRules = array();
|
||||
public function __construct(ModuleDesign $oModuleDesign, RouterInterface $oRouter, BrickCollection $oBrickCollection, ScopeValidatorHelper $oScopeValidator)
|
||||
{
|
||||
$this->aRules = [];
|
||||
$this->oRouter = $oRouter;
|
||||
$this->oBrickCollection = $oBrickCollection;
|
||||
|
||||
@@ -95,38 +97,34 @@ class ContextManipulatorHelper
|
||||
*/
|
||||
public function Init(DOMNodeList $oNodes)
|
||||
{
|
||||
$this->aRules = array();
|
||||
$this->aRules = [];
|
||||
|
||||
// Iterating over the scope nodes
|
||||
/** @var \Combodo\iTop\DesignElement $oRuleNode */
|
||||
foreach ($oNodes as $oRuleNode)
|
||||
{
|
||||
foreach ($oNodes as $oRuleNode) {
|
||||
// Retrieving mandatory id attribute
|
||||
$sRuleId = $oRuleNode->getAttribute('id');
|
||||
if ($sRuleId === '')
|
||||
{
|
||||
if ($sRuleId === '') {
|
||||
throw new DOMFormatException('Rule tag must have an id attribute.', null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
// Setting if the rule needs a source object
|
||||
$bNeedsSource = false;
|
||||
// Note : preset and retrofit are no longer plurals as it should match as much as possible iTopObjectCopier specs. We use plurals only in the xml for the collection tags
|
||||
$aRule = array(
|
||||
$aRule = [
|
||||
'source_oql' => null,
|
||||
'dest_class' => null,
|
||||
'preset' => array(),
|
||||
'retrofit' => array(),
|
||||
'preset' => [],
|
||||
'retrofit' => [],
|
||||
'submit' => null,
|
||||
'cancel' => null,
|
||||
);
|
||||
];
|
||||
|
||||
// Iterating over the rule's nodes
|
||||
/** @var \Combodo\iTop\DesignElement $oSubNode */
|
||||
foreach ($oRuleNode->GetNodes('*') as $oSubNode)
|
||||
{
|
||||
foreach ($oRuleNode->GetNodes('*') as $oSubNode) {
|
||||
$sSubNodeName = $oSubNode->nodeName;
|
||||
switch ($sSubNodeName)
|
||||
{
|
||||
switch ($sSubNodeName) {
|
||||
case 'source_class':
|
||||
$aRule['source_oql'] = 'SELECT '.$oSubNode->GetText();
|
||||
break;
|
||||
@@ -139,17 +137,14 @@ class ContextManipulatorHelper
|
||||
case 'presets':
|
||||
case 'retrofits':
|
||||
/** @var \Combodo\iTop\DesignElement $oActionNode */
|
||||
foreach ($oSubNode->GetNodes('*') as $oActionNode)
|
||||
{
|
||||
foreach ($oSubNode->GetNodes('*') as $oActionNode) {
|
||||
// Note : Caution, the index of $aRule is now $oActionNode->nodeName instead of $sSubNodeName, as we want to match iTopObjectCopier specs like told previously
|
||||
if (in_array($oActionNode->nodeName, array('preset', 'retrofit')))
|
||||
{
|
||||
if (in_array($oActionNode->nodeName, ['preset', 'retrofit'])) {
|
||||
$sActionText = $oActionNode->GetText();
|
||||
$aRule[$oActionNode->nodeName][] = $sActionText;
|
||||
|
||||
// Checking if the rule needs a source object
|
||||
if (substr($sActionText, 0, 4) === 'copy')
|
||||
{
|
||||
if (substr($sActionText, 0, 4) === 'copy') {
|
||||
$bNeedsSource = true;
|
||||
}
|
||||
}
|
||||
@@ -160,25 +155,21 @@ class ContextManipulatorHelper
|
||||
case 'cancel':
|
||||
// Retrieving callback type and checking that it is allowed
|
||||
$sType = $oSubNode->getAttribute('xsi:type');
|
||||
if ($sType === '')
|
||||
{
|
||||
if ($sType === '') {
|
||||
throw new DOMFormatException($sSubNodeName.' must have an xsi:type attribute.', null, null, $oSubNode);
|
||||
}
|
||||
if (($sType === static::ENUM_RULE_CALLBACK_OPEN) && ($sSubNodeName === 'cancel'))
|
||||
{
|
||||
if (($sType === static::ENUM_RULE_CALLBACK_OPEN) && ($sSubNodeName === 'cancel')) {
|
||||
throw new DOMFormatException('Cancel tag cannot be of type '.$sType.'.', null, null, $oSubNode);
|
||||
}
|
||||
|
||||
$aRule[$sSubNodeName] = array('type' => $sType);
|
||||
switch ($sType)
|
||||
{
|
||||
$aRule[$sSubNodeName] = ['type' => $sType];
|
||||
switch ($sType) {
|
||||
case static::ENUM_RULE_CALLBACK_BACK:
|
||||
// Default value
|
||||
$sRefresh = false;
|
||||
// Retrieving value
|
||||
$oRefreshNode = $oSubNode->GetOptionalElement('refresh');
|
||||
if (($oRefreshNode !== null) && ($oRefreshNode->GetText() !== null))
|
||||
{
|
||||
if (($oRefreshNode !== null) && ($oRefreshNode->GetText() !== null)) {
|
||||
$sRefresh = $oRefreshNode->GetText();
|
||||
}
|
||||
|
||||
@@ -187,8 +178,7 @@ class ContextManipulatorHelper
|
||||
case static::ENUM_RULE_CALLBACK_GOTO:
|
||||
// Retrieving value
|
||||
$sBrickId = $oSubNode->GetUniqueElement('brick')->GetText();
|
||||
if ($sBrickId === null)
|
||||
{
|
||||
if ($sBrickId === null) {
|
||||
throw new DOMFormatException('Brick tag value must not be empty.', null, null, $oSubNode);
|
||||
}
|
||||
|
||||
@@ -199,8 +189,7 @@ class ContextManipulatorHelper
|
||||
$sMode = static::ENUM_RULE_CALLBACK_OPEN_VIEW;
|
||||
// Retrieving value
|
||||
$oModeNode = $oSubNode->GetOptionalElement('mode');
|
||||
if (($oModeNode !== null) && ($oModeNode->GetText() !== null))
|
||||
{
|
||||
if (($oModeNode !== null) && ($oModeNode->GetText() !== null)) {
|
||||
$sMode = $oModeNode->GetText();
|
||||
}
|
||||
|
||||
@@ -212,8 +201,7 @@ class ContextManipulatorHelper
|
||||
}
|
||||
|
||||
// If there is no source information we check if there is a preset that requires a copy in order to throw an exception
|
||||
if (($aRule['source_oql'] === null) && ($bNeedsSource === true))
|
||||
{
|
||||
if (($aRule['source_oql'] === null) && ($bNeedsSource === true)) {
|
||||
throw new DOMFormatException('Rule tag must have either a "source_oql" or a "source_class" child node.', null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
@@ -221,7 +209,6 @@ class ContextManipulatorHelper
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash array of rules
|
||||
*
|
||||
@@ -242,8 +229,7 @@ class ContextManipulatorHelper
|
||||
*/
|
||||
public function GetRule($sId)
|
||||
{
|
||||
if (!array_key_exists($sId, $this->aRules))
|
||||
{
|
||||
if (!array_key_exists($sId, $this->aRules)) {
|
||||
throw new Exception('Context creator : Could not find "'.$sId.'" in the rules list');
|
||||
}
|
||||
|
||||
@@ -276,30 +262,26 @@ class ContextManipulatorHelper
|
||||
*/
|
||||
public function PrepareObject(array $aData, DBObject $oObject)
|
||||
{
|
||||
if (isset($aData['rules']) && isset($aData['sources']))
|
||||
{
|
||||
if (isset($aData['rules']) && isset($aData['sources'])) {
|
||||
$aRules = $aData['rules'];
|
||||
$aSources = $aData['sources'];
|
||||
$aActionRulesErrors = array();
|
||||
foreach ($aRules as $sRuleId)
|
||||
{
|
||||
try
|
||||
{
|
||||
$aActionRulesErrors = [];
|
||||
foreach ($aRules as $sRuleId) {
|
||||
try {
|
||||
$this->PrepareAndExecActionRule($sRuleId, $aSources, $oObject);
|
||||
}
|
||||
catch (CorePortalInvalidActionRuleException $e)
|
||||
{
|
||||
} catch (CorePortalInvalidActionRuleException $e) {
|
||||
$aActionRulesErrors[$sRuleId] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
if (!empty($aActionRulesErrors))
|
||||
{
|
||||
if (!empty($aActionRulesErrors)) {
|
||||
$sDestinationObjectDesc = '';
|
||||
$sDestinationObjectDesc .= get_class($oObject);
|
||||
$sDestinationObjectDesc .= '['.$oObject->GetKey().']';
|
||||
throw new CorePortalInvalidActionRuleException('Some action rules were not executed',
|
||||
throw new CorePortalInvalidActionRuleException(
|
||||
'Some action rules were not executed',
|
||||
$aActionRulesErrors,
|
||||
'destination object: '.$sDestinationObjectDesc);
|
||||
'destination object: '.$sDestinationObjectDesc
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -323,8 +305,7 @@ class ContextManipulatorHelper
|
||||
$aRule = $this->GetRule($sRuleId);
|
||||
|
||||
// Retrieving source object if needed
|
||||
if ($aRule['source_oql'] !== null)
|
||||
{
|
||||
if ($aRule['source_oql'] !== null) {
|
||||
// Preparing query to retrieve source object(s)
|
||||
/** @var \DBObjectSearch $oSearch */
|
||||
$oSearch = DBSearch::FromOQL($aRule['source_oql']);
|
||||
@@ -336,45 +317,37 @@ class ContextManipulatorHelper
|
||||
$sSearchClass = $oSearch->GetClass();
|
||||
$aSearchParams = $oSearch->GetInternalParams();
|
||||
|
||||
if (array_key_exists($sSearchClass, $aSources))
|
||||
{
|
||||
if (array_key_exists($sSearchClass, $aSources)) {
|
||||
$sourceId = $aSources[$sSearchClass];
|
||||
|
||||
if (array_key_exists('id', $oSearch->GetQueryParams()))
|
||||
{
|
||||
if (is_array($sourceId))
|
||||
{
|
||||
if (array_key_exists('id', $oSearch->GetQueryParams())) {
|
||||
if (is_array($sourceId)) {
|
||||
throw new Exception('Context creator : ":id" parameter in rule "'.$sRuleId.'" cannot be an array (This is a limitation of DBSearch)');
|
||||
}
|
||||
|
||||
$aSearchParams['id'] = $sourceId;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_array($sourceId))
|
||||
{
|
||||
$sourceId = array($sourceId);
|
||||
} else {
|
||||
if (!is_array($sourceId)) {
|
||||
$sourceId = [$sourceId];
|
||||
}
|
||||
|
||||
$iLoopMax = count($sourceId);
|
||||
$oFullBinExpr = null;
|
||||
for ($i = 0; $i < $iLoopMax; $i++)
|
||||
{
|
||||
for ($i = 0; $i < $iLoopMax; $i++) {
|
||||
// - Building full search expression
|
||||
$oBinExpr = new BinaryExpression(new FieldExpression('id', $oSearch->GetClassAlias()), '=',
|
||||
new ScalarExpression($sourceId[$i]));
|
||||
if ($i === 0)
|
||||
{
|
||||
$oBinExpr = new BinaryExpression(
|
||||
new FieldExpression('id', $oSearch->GetClassAlias()),
|
||||
'=',
|
||||
new ScalarExpression($sourceId[$i])
|
||||
);
|
||||
if ($i === 0) {
|
||||
$oFullBinExpr = $oBinExpr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oFullBinExpr = new BinaryExpression($oFullBinExpr, 'OR', $oBinExpr);
|
||||
}
|
||||
|
||||
// - Adding it to the query when complete
|
||||
if ($i === ($iLoopMax - 1))
|
||||
{
|
||||
if ($i === ($iLoopMax - 1)) {
|
||||
$oSearch->AddConditionExpression($oFullBinExpr);
|
||||
}
|
||||
}
|
||||
@@ -382,8 +355,7 @@ class ContextManipulatorHelper
|
||||
}
|
||||
|
||||
$oSearchRootCondition = $oSearch->GetCriteria();
|
||||
if (($oSearchRootCondition === null) || ($oSearchRootCondition instanceof TrueExpression))
|
||||
{
|
||||
if (($oSearchRootCondition === null) || ($oSearchRootCondition instanceof TrueExpression)) {
|
||||
// N°2555 : disallow searches without any condition
|
||||
$sErrMsg = "Portal query was stopped: action_rule '$sRuleId' searches for '$sSearchClass' without any condition is forbidden";
|
||||
IssueLog::Error($sErrMsg);
|
||||
@@ -391,35 +363,31 @@ class ContextManipulatorHelper
|
||||
}
|
||||
|
||||
// Checking for silos
|
||||
$oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sSearchClass,
|
||||
UR_ACTION_READ);
|
||||
if ($oScopeSearch->IsAllDataAllowed())
|
||||
{
|
||||
$oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(
|
||||
UserRights::ListProfiles(),
|
||||
$sSearchClass,
|
||||
UR_ACTION_READ
|
||||
);
|
||||
if ($oScopeSearch->IsAllDataAllowed()) {
|
||||
$oSearch->AllowAllData();
|
||||
}
|
||||
|
||||
// Retrieving source object(s) and applying rules
|
||||
$oSet = new DBObjectSet($oSearch, array(), $aSearchParams);
|
||||
while ($oSourceObject = $oSet->Fetch()) // we need a loop for certain preset verbs like add_to_list, see N°2555
|
||||
{
|
||||
$oSet = new DBObjectSet($oSearch, [], $aSearchParams);
|
||||
while ($oSourceObject = $oSet->Fetch()) { // we need a loop for certain preset verbs like add_to_list, see N°2555
|
||||
// Presets
|
||||
if (isset($aRule['preset']) && !empty($aRule['preset']))
|
||||
{
|
||||
$oDestinationObject->ExecActions($aRule['preset'], array('source' => $oSourceObject));
|
||||
if (isset($aRule['preset']) && !empty($aRule['preset'])) {
|
||||
$oDestinationObject->ExecActions($aRule['preset'], ['source' => $oSourceObject]);
|
||||
}
|
||||
// Retrofits
|
||||
if (isset($aRule['retrofit']) && !empty($aRule['retrofit']))
|
||||
{
|
||||
$oSourceObject->ExecActions($aRule['retrofit'], array('source' => $oDestinationObject));
|
||||
if (isset($aRule['retrofit']) && !empty($aRule['retrofit'])) {
|
||||
$oSourceObject->ExecActions($aRule['retrofit'], ['source' => $oDestinationObject]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Presets
|
||||
if (isset($aRule['preset']) && !empty($aRule['preset']))
|
||||
{
|
||||
$oDestinationObject->ExecActions($aRule['preset'], array('source' => $oDestinationObject));
|
||||
if (isset($aRule['preset']) && !empty($aRule['preset'])) {
|
||||
$oDestinationObject->ExecActions($aRule['preset'], ['source' => $oDestinationObject]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -447,10 +415,10 @@ class ContextManipulatorHelper
|
||||
public function GetCallbackUrls(array $aData, DBObject $oObject, $bModal = false)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('Use navigation rules for form callbacks');
|
||||
$aResults = array(
|
||||
$aResults = [
|
||||
'submit' => null,
|
||||
'cancel' => null,
|
||||
);
|
||||
];
|
||||
|
||||
if (isset($aData['rules'])) {
|
||||
foreach ($aData['rules'] as $sId) {
|
||||
@@ -458,29 +426,27 @@ class ContextManipulatorHelper
|
||||
$aRule = $this->GetRule($sId);
|
||||
|
||||
// For each type of callbacks, we check if there is a rule to apply
|
||||
foreach (array('submit', 'cancel') as $sCallbackName)
|
||||
{
|
||||
if (is_array($aRule[$sCallbackName]))
|
||||
{
|
||||
foreach (['submit', 'cancel'] as $sCallbackName) {
|
||||
if (is_array($aRule[$sCallbackName])) {
|
||||
// Previously declared rule on a callback is overwritten by the last
|
||||
$sCallbackUrl = null;
|
||||
switch ($aRule[$sCallbackName]['type'])
|
||||
{
|
||||
switch ($aRule[$sCallbackName]['type']) {
|
||||
case static::ENUM_RULE_CALLBACK_BACK:
|
||||
if (!$bModal)
|
||||
{
|
||||
if (!$bModal) {
|
||||
$sCallbackUrl = ($_SERVER['HTTP_REFERER'] !== '') ? $_SERVER['HTTP_REFERER'] : null;
|
||||
}
|
||||
break;
|
||||
|
||||
case static::ENUM_RULE_CALLBACK_GOTO:
|
||||
$oBrick = $this->oBrickCollection->GetBrickById($aRule[$sCallbackName]['brick_id']);
|
||||
$sCallbackUrl = $this->oRouter->generate($oBrick->GetRouteName(), array('sBrickId' => $oBrick->GetId()));
|
||||
$sCallbackUrl = $this->oRouter->generate($oBrick->GetRouteName(), ['sBrickId' => $oBrick->GetId()]);
|
||||
break;
|
||||
|
||||
case static::ENUM_RULE_CALLBACK_OPEN:
|
||||
$sCallbackUrl = ($oObject->IsNew()) ? null : $this->oRouter->generate('p_object_'.$aRule[$sCallbackName]['mode'],
|
||||
array('sObjectClass' => get_class($oObject), 'sObjectId' => $oObject->GetKey()));
|
||||
$sCallbackUrl = ($oObject->IsNew()) ? null : $this->oRouter->generate(
|
||||
'p_object_'.$aRule[$sCallbackName]['mode'],
|
||||
['sObjectClass' => get_class($oObject), 'sObjectId' => $oObject->GetKey()]
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -501,20 +467,19 @@ class ContextManipulatorHelper
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function PrepareRulesForToken($aRules, $aObjects = array())
|
||||
public static function PrepareRulesForToken($aRules, $aObjects = [])
|
||||
{
|
||||
// Getting necessary information from objects
|
||||
$aSources = array();
|
||||
foreach ($aObjects as $oObject)
|
||||
{
|
||||
$aSources = [];
|
||||
foreach ($aObjects as $oObject) {
|
||||
$aSources[get_class($oObject)] = $oObject->GetKey();
|
||||
}
|
||||
|
||||
// Preparing data
|
||||
$aTokenRules = array(
|
||||
$aTokenRules = [
|
||||
'rules' => $aRules,
|
||||
'sources' => $aSources,
|
||||
);
|
||||
];
|
||||
|
||||
return $aTokenRules;
|
||||
}
|
||||
@@ -545,7 +510,7 @@ class ContextManipulatorHelper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function PrepareAndEncodeRulesToken($aRules, $aObjects = array())
|
||||
public static function PrepareAndEncodeRulesToken($aRules, $aObjects = [])
|
||||
{
|
||||
// Preparing rules before making a token
|
||||
$aTokenRules = static::PrepareRulesForToken($aRules, $aObjects);
|
||||
@@ -572,19 +537,20 @@ class ContextManipulatorHelper
|
||||
$sDecryptedToken = $oCrypt->Decrypt($sPrivateKey, self::base64url_decode($sToken));
|
||||
|
||||
$aTokenRules = json_decode($sDecryptedToken, true);
|
||||
if (!is_array($aTokenRules))
|
||||
{
|
||||
if (!is_array($aTokenRules)) {
|
||||
throw new Exception('DecodeRulesToken not a proper json structure.');
|
||||
}
|
||||
|
||||
return $aTokenRules;
|
||||
}
|
||||
|
||||
private static function base64url_encode($sData) {
|
||||
private static function base64url_encode($sData)
|
||||
{
|
||||
return rtrim(strtr(base64_encode($sData), '+/', '-_'), '=');
|
||||
}
|
||||
|
||||
private static function base64url_decode($sData) {
|
||||
private static function base64url_decode($sData)
|
||||
{
|
||||
return base64_decode(str_pad(strtr($sData, '-_', '+/'), strlen($sData) % 4, '=', STR_PAD_RIGHT));
|
||||
}
|
||||
|
||||
@@ -596,7 +562,7 @@ class ContextManipulatorHelper
|
||||
*/
|
||||
private static function GetPrivateKey()
|
||||
{
|
||||
if(self::$sPrivateKey === null) {
|
||||
if (self::$sPrivateKey === null) {
|
||||
self::$sPrivateKey = DBProperty::GetProperty(self::PRIVATE_KEY);
|
||||
if (is_null(self::$sPrivateKey)) {
|
||||
self::$sPrivateKey = bin2hex(random_bytes(32));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -93,4 +94,4 @@ class ExtensibilityHelper
|
||||
|
||||
return $aTabSectionExtensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ use MetaModel;
|
||||
class LifecycleValidatorHelper
|
||||
{
|
||||
/** @var string DEFAULT_GENERATED_CLASS */
|
||||
const DEFAULT_GENERATED_CLASS = 'PortalLifecycleValues';
|
||||
public const DEFAULT_GENERATED_CLASS = 'PortalLifecycleValues';
|
||||
|
||||
/** @var string|null $sCachePath */
|
||||
protected $sCachePath;
|
||||
@@ -64,9 +64,10 @@ class LifecycleValidatorHelper
|
||||
{
|
||||
$this->sFilename = "{$sPortalId}.lifecycle.php";
|
||||
$this->sCachePath = $sPortalCachePath;
|
||||
$this->sInstancePrefix = "{$sPortalId}-";;
|
||||
$this->sInstancePrefix = "{$sPortalId}-";
|
||||
;
|
||||
$this->sGeneratedClass = static::DEFAULT_GENERATED_CLASS;
|
||||
$this->aProfilesMatrix = array();
|
||||
$this->aProfilesMatrix = [];
|
||||
|
||||
$this->Init($moduleDesign->GetNodes('/module_design/classes/class'));
|
||||
}
|
||||
@@ -143,8 +144,7 @@ class LifecycleValidatorHelper
|
||||
public function Init(DOMNodeList $oNodes)
|
||||
{
|
||||
// Checking cache path
|
||||
if ($this->sCachePath === null)
|
||||
{
|
||||
if ($this->sCachePath === null) {
|
||||
$this->sCachePath = utils::GetCachePath();
|
||||
}
|
||||
// Building full pathname for file
|
||||
@@ -152,61 +152,48 @@ class LifecycleValidatorHelper
|
||||
|
||||
// Creating file if not existing
|
||||
// Note: This is a temporary cache system, it should soon evolve to a cache provider (fs, apc, memcache, ...)
|
||||
if (!file_exists($sFilePath))
|
||||
{
|
||||
if (!file_exists($sFilePath)) {
|
||||
// - Build php array from xml
|
||||
$aProfiles = array();
|
||||
$aProfiles = [];
|
||||
// This will be used to know which classes have been set, so we can set the missing ones.
|
||||
$aProfileClasses = array();
|
||||
$aProfileClasses = [];
|
||||
// Iterating over the class nodes
|
||||
/** @var \Combodo\iTop\DesignElement $oClassNode */
|
||||
foreach ($oNodes as $oClassNode)
|
||||
{
|
||||
foreach ($oNodes as $oClassNode) {
|
||||
// Retrieving mandatory class id attribute
|
||||
$sClass = $oClassNode->getAttribute('id');
|
||||
if ($sClass === '')
|
||||
{
|
||||
if ($sClass === '') {
|
||||
throw new DOMFormatException('Class tag must have an id attribute.', null, null, $oClassNode);
|
||||
}
|
||||
|
||||
// Retrieving lifecycle node of the class
|
||||
$oLifecycleNode = $oClassNode->GetOptionalElement('lifecycle');
|
||||
if ($oLifecycleNode !== null)
|
||||
{
|
||||
if ($oLifecycleNode !== null) {
|
||||
// Iterating over scope nodes of the class
|
||||
$oStimuliNode = $oLifecycleNode->GetOptionalElement('stimuli');
|
||||
if ($oStimuliNode !== null)
|
||||
{
|
||||
if ($oStimuliNode !== null) {
|
||||
/** @var \Combodo\iTop\DesignElement $oStimulusNode */
|
||||
foreach ($oStimuliNode->GetNodes('./stimulus') as $oStimulusNode)
|
||||
{
|
||||
foreach ($oStimuliNode->GetNodes('./stimulus') as $oStimulusNode) {
|
||||
// Retrieving mandatory scope id attribute
|
||||
$sStimulusId = $oStimulusNode->getAttribute('id');
|
||||
if ($sStimulusId === '')
|
||||
{
|
||||
if ($sStimulusId === '') {
|
||||
throw new DOMFormatException('Stimulus tag must have an id attribute.', null, null, $oStimulusNode);
|
||||
}
|
||||
|
||||
// Retrieving profiles for the stimulus
|
||||
$oProfilesNode = $oStimulusNode->GetOptionalElement('denied_profiles');
|
||||
$aProfilesNames = array();
|
||||
$aProfilesNames = [];
|
||||
// If no profile is specified, we consider that it's for ALL the profiles
|
||||
if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./denied_profile')->length === 0))
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./denied_profile')->length === 0)) {
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) {
|
||||
$aProfilesNames[] = $aValue['name'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/** @var \Combodo\iTop\DesignElement $oProfileNode */
|
||||
foreach ($oProfilesNode->GetNodes('./denied_profile') as $oProfileNode)
|
||||
{
|
||||
foreach ($oProfilesNode->GetNodes('./denied_profile') as $oProfileNode) {
|
||||
// Retrieving mandatory profile id attribute
|
||||
$sProfileId = $oProfileNode->getAttribute('id');
|
||||
if ($sProfileId === '')
|
||||
{
|
||||
if ($sProfileId === '') {
|
||||
throw new DOMFormatException('Profile tag must have an id attribute.', null, null, $oProfileNode);
|
||||
}
|
||||
$aProfilesNames[] = $sProfileId;
|
||||
@@ -214,21 +201,18 @@ class LifecycleValidatorHelper
|
||||
}
|
||||
|
||||
//
|
||||
foreach ($aProfilesNames as $sProfileName)
|
||||
{
|
||||
foreach ($aProfilesNames as $sProfileName) {
|
||||
// Stimulus profile id
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfileName);
|
||||
|
||||
// Now that we have the queries infos, we are going to build the queries for that profile / class
|
||||
$sMatrixPrefix = $iProfileId.'_'.$sClass;
|
||||
// - Creating profile / class entry if not already present
|
||||
if (!array_key_exists($sMatrixPrefix, $aProfiles))
|
||||
{
|
||||
$aProfiles[$sMatrixPrefix] = array();
|
||||
if (!array_key_exists($sMatrixPrefix, $aProfiles)) {
|
||||
$aProfiles[$sMatrixPrefix] = [];
|
||||
}
|
||||
// - Adding stimulus if not already present
|
||||
if (!in_array($sStimulusId, $aProfiles[$sMatrixPrefix]))
|
||||
{
|
||||
if (!in_array($sStimulusId, $aProfiles[$sMatrixPrefix])) {
|
||||
$aProfiles[$sMatrixPrefix][] = $sStimulusId;
|
||||
}
|
||||
}
|
||||
@@ -244,20 +228,15 @@ class LifecycleValidatorHelper
|
||||
// If not, we add them
|
||||
//
|
||||
// Note: Classes / Stimuli not in the matrix are implicitly ALLOWED. That can happen by omitting the <lifecycle> in a <class>
|
||||
foreach ($aProfileClasses as $sProfileClass)
|
||||
{
|
||||
foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass)
|
||||
{
|
||||
foreach ($aProfileClasses as $sProfileClass) {
|
||||
foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass) {
|
||||
// If the child class is not in the scope, we are going to try to add it
|
||||
if (!in_array($sChildClass, $aProfileClasses))
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
if (!in_array($sChildClass, $aProfileClasses)) {
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) {
|
||||
$iProfileId = $iKey;
|
||||
|
||||
// If the current profile has scope for that class in that mode, we duplicate it
|
||||
if (isset($aProfiles[$iProfileId.'_'.$sProfileClass]))
|
||||
{
|
||||
if (isset($aProfiles[$iProfileId.'_'.$sProfileClass])) {
|
||||
$aProfiles[$iProfileId.'_'.$sChildClass] = $aProfiles[$iProfileId.'_'.$sProfileClass];
|
||||
}
|
||||
}
|
||||
@@ -270,14 +249,12 @@ class LifecycleValidatorHelper
|
||||
|
||||
// - Write file on disk
|
||||
// - Creating dir if necessary
|
||||
if (!is_dir($this->sCachePath))
|
||||
{
|
||||
if (!is_dir($this->sCachePath)) {
|
||||
mkdir($this->sCachePath, 0777, true);
|
||||
}
|
||||
// -- Then creating the file
|
||||
$ret = file_put_contents($sFilePath, $sPHP);
|
||||
if ($ret === false)
|
||||
{
|
||||
if ($ret === false) {
|
||||
$iLen = strlen($sPHP);
|
||||
$fFree = @disk_free_space(dirname($sFilePath));
|
||||
$aErr = error_get_last();
|
||||
@@ -285,8 +262,7 @@ class LifecycleValidatorHelper
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists($this->sGeneratedClass))
|
||||
{
|
||||
if (!class_exists($this->sGeneratedClass)) {
|
||||
require_once $this->sCachePath.$this->sFilename;
|
||||
}
|
||||
}
|
||||
@@ -303,7 +279,7 @@ class LifecycleValidatorHelper
|
||||
*/
|
||||
public function GetStimuliForProfile($sProfile, $sClass)
|
||||
{
|
||||
return $this->GetStimuliForProfiles(array($sProfile), $sClass);
|
||||
return $this->GetStimuliForProfiles([$sProfile], $sClass);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,17 +295,15 @@ class LifecycleValidatorHelper
|
||||
*/
|
||||
public function GetStimuliForProfiles($aProfiles, $sClass)
|
||||
{
|
||||
$aStimuli = array();
|
||||
$aStimuli = [];
|
||||
|
||||
// Preparing available stimuli
|
||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $aData)
|
||||
{
|
||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $aData) {
|
||||
$aStimuli[$sStimulusCode] = true;
|
||||
}
|
||||
|
||||
// Iterating on profiles to retrieving the different OQLs parts
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
foreach ($aProfiles as $sProfile) {
|
||||
// Retrieving matrix information
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfile);
|
||||
|
||||
@@ -337,10 +311,8 @@ class LifecycleValidatorHelper
|
||||
$sLifecycleValuesClass = $this->sGeneratedClass;
|
||||
$aProfileMatrix = $sLifecycleValuesClass::GetProfileStimuli($iProfileId, $sClass);
|
||||
|
||||
foreach ($aProfileMatrix as $sStimulusCode)
|
||||
{
|
||||
if (array_key_exists($sStimulusCode, $aStimuli))
|
||||
{
|
||||
foreach ($aProfileMatrix as $sStimulusCode) {
|
||||
if (array_key_exists($sStimulusCode, $aStimuli)) {
|
||||
unset($aStimuli[$sStimulusCode]);
|
||||
}
|
||||
}
|
||||
@@ -364,18 +336,12 @@ class LifecycleValidatorHelper
|
||||
|
||||
// We try to find the profile from its name in order to retrieve it's id
|
||||
// - If the regular UserRights add-on is installed we check the profiles array
|
||||
if (class_exists('ProfilesConfig'))
|
||||
{
|
||||
if (defined($sProfile) && in_array($sProfile, ProfilesConfig::GetProfilesValues()))
|
||||
{
|
||||
if (class_exists('ProfilesConfig')) {
|
||||
if (defined($sProfile) && in_array($sProfile, ProfilesConfig::GetProfilesValues())) {
|
||||
$iProfileId = constant($sProfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
if ($aValue['name'] === $sProfile)
|
||||
{
|
||||
} else {
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) {
|
||||
if ($aValue['name'] === $sProfile) {
|
||||
$iProfileId = $iKey;
|
||||
break;
|
||||
}
|
||||
@@ -383,14 +349,12 @@ class LifecycleValidatorHelper
|
||||
}
|
||||
}
|
||||
// - Else, we can't find the id from the name as we don't know the used UserRights add-on. It has to be a constant
|
||||
else
|
||||
{
|
||||
else {
|
||||
throw new Exception('Lifecycle validator : Unknown UserRights addon, lifecycle\'s profile must be a constant');
|
||||
}
|
||||
|
||||
// If profile was not found from its name or from a constant, we throw an exception
|
||||
if ($iProfileId === null)
|
||||
{
|
||||
if ($iProfileId === null) {
|
||||
throw new Exception('Lifecycle validator : Could not find "'.$sProfile.'" in the profiles list');
|
||||
}
|
||||
|
||||
@@ -404,7 +368,7 @@ class LifecycleValidatorHelper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function BuildPHPClass($aProfiles = array())
|
||||
protected function BuildPHPClass($aProfiles = [])
|
||||
{
|
||||
$sProfiles = var_export($aProfiles, true);
|
||||
$sClassName = $this->sGeneratedClass;
|
||||
@@ -447,4 +411,3 @@ EOF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -44,50 +44,50 @@ use utils;
|
||||
class NavigationRuleHelper
|
||||
{
|
||||
// Available point of origin for the navigation
|
||||
const ENUM_ORIGIN_PAGE = 'default';
|
||||
const ENUM_ORIGIN_MODAL = 'modal';
|
||||
public const ENUM_ORIGIN_PAGE = 'default';
|
||||
public const ENUM_ORIGIN_MODAL = 'modal';
|
||||
|
||||
// Available rule categories (of rule types)
|
||||
/** @var string ENUM_RULE_CAT_CLOSE (eg. close modal/window) */
|
||||
const ENUM_RULE_CAT_CLOSE = 'close';
|
||||
public const ENUM_RULE_CAT_CLOSE = 'close';
|
||||
/** @var string ENUM_RULE_CAT_REDIRECT (eg. go-to-homepage, go-to-object, go-to-brick, ...) */
|
||||
const ENUM_RULE_CAT_REDIRECT = 'redirect';
|
||||
public const ENUM_RULE_CAT_REDIRECT = 'redirect';
|
||||
|
||||
// Available rule types
|
||||
/** @var string ENUM_RULE_CLOSE */
|
||||
const ENUM_RULE_CLOSE = 'close';
|
||||
public const ENUM_RULE_CLOSE = 'close';
|
||||
/** @var string ENUM_RULE_GO_TO_HOMEPAGE */
|
||||
const ENUM_RULE_GO_TO_HOMEPAGE = 'go-to-homepage';
|
||||
public const ENUM_RULE_GO_TO_HOMEPAGE = 'go-to-homepage';
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT */
|
||||
const ENUM_RULE_GO_TO_OBJECT = 'go-to-object';
|
||||
public const ENUM_RULE_GO_TO_OBJECT = 'go-to-object';
|
||||
/** @var string ENUM_RULE_GO_TO_BRICK */
|
||||
const ENUM_RULE_GO_TO_BRICK = 'go-to-brick';
|
||||
public const ENUM_RULE_GO_TO_BRICK = 'go-to-brick';
|
||||
/** @var string ENUM_RULE_GO_TO_MANAGE_BRICK */
|
||||
const ENUM_RULE_GO_TO_MANAGE_BRICK = 'go-to-manage-brick';
|
||||
public const ENUM_RULE_GO_TO_MANAGE_BRICK = 'go-to-manage-brick';
|
||||
/** @var string ENUM_RULE_GO_TO_BROWSE_BRICK */
|
||||
const ENUM_RULE_GO_TO_BROWSE_BRICK = 'go-to-browse-brick';
|
||||
public const ENUM_RULE_GO_TO_BROWSE_BRICK = 'go-to-browse-brick';
|
||||
// - Defaults
|
||||
/** @var string DEFAULT_RULE_SUBMIT_PAGE */
|
||||
const DEFAULT_RULE_SUBMIT_PAGE = self::ENUM_RULE_GO_TO_OBJECT;
|
||||
public const DEFAULT_RULE_SUBMIT_PAGE = self::ENUM_RULE_GO_TO_OBJECT;
|
||||
/** @var string DEFAULT_RULE_SUBMIT_MODAL */
|
||||
const DEFAULT_RULE_SUBMIT_MODAL = self::ENUM_RULE_CLOSE;
|
||||
public const DEFAULT_RULE_SUBMIT_MODAL = self::ENUM_RULE_CLOSE;
|
||||
/** @var string DEFAULT_RULE_CANCEL_PAGE */
|
||||
const DEFAULT_RULE_CANCEL_PAGE = self::ENUM_RULE_CLOSE;
|
||||
public const DEFAULT_RULE_CANCEL_PAGE = self::ENUM_RULE_CLOSE;
|
||||
/** @var string DEFAULT_RULE_CANCEL_MODAL */
|
||||
const DEFAULT_RULE_CANCEL_MODAL = self::ENUM_RULE_CLOSE;
|
||||
public const DEFAULT_RULE_CANCEL_MODAL = self::ENUM_RULE_CLOSE;
|
||||
|
||||
// Rule go-to-object properties
|
||||
/** @var string DEFAULT_RULE_GO_TO_OBJECT_PROP_MODE */
|
||||
const DEFAULT_RULE_GO_TO_OBJECT_PROP_MODE = ObjectFormHandlerHelper::ENUM_MODE_VIEW;
|
||||
public const DEFAULT_RULE_GO_TO_OBJECT_PROP_MODE = ObjectFormHandlerHelper::ENUM_MODE_VIEW;
|
||||
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL */
|
||||
const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL = 'modal';
|
||||
public const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL = 'modal';
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_PAGE */
|
||||
const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_PAGE = 'page';
|
||||
public const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_PAGE = 'page';
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT */
|
||||
const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT = 'current';
|
||||
public const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT = 'current';
|
||||
/** @var string DEFAULT_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET */
|
||||
const DEFAULT_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET = self::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL;
|
||||
public const DEFAULT_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET = self::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL;
|
||||
|
||||
// Rule go-to-brick properties
|
||||
// TODO
|
||||
@@ -112,9 +112,12 @@ class NavigationRuleHelper
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
public function __construct(
|
||||
ModuleDesign $oModuleDesign, RouterInterface $oRouter, BrickCollection $oBrickCollection, ScopeValidatorHelper $oScopeValidator
|
||||
ModuleDesign $oModuleDesign,
|
||||
RouterInterface $oRouter,
|
||||
BrickCollection $oBrickCollection,
|
||||
ScopeValidatorHelper $oScopeValidator
|
||||
) {
|
||||
$this->aRules = array();
|
||||
$this->aRules = [];
|
||||
$this->oRouter = $oRouter;
|
||||
$this->oBrickCollection = $oBrickCollection;
|
||||
|
||||
@@ -132,31 +135,29 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public function Init(DOMNodeList $oNodes)
|
||||
{
|
||||
$this->aRules = array();
|
||||
$this->aRules = [];
|
||||
|
||||
// Iterating over the navigation_rule nodes
|
||||
/** @var \Combodo\iTop\DesignElement $oRuleNode */
|
||||
foreach ($oNodes as $oRuleNode)
|
||||
{
|
||||
foreach ($oNodes as $oRuleNode) {
|
||||
// Checking node name
|
||||
if ($oRuleNode->nodeName !== 'navigation_rule')
|
||||
{
|
||||
if ($oRuleNode->nodeName !== 'navigation_rule') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Retrieving mandatory attributes
|
||||
// - ID
|
||||
$sRuleId = $oRuleNode->getAttribute('id');
|
||||
if ($sRuleId === '')
|
||||
{
|
||||
if ($sRuleId === '') {
|
||||
throw new DOMFormatException('Rule tag must have an id attribute.', null, null, $oRuleNode);
|
||||
}
|
||||
// - Type
|
||||
$sRuleType = $oRuleNode->getAttribute('xsi:type');
|
||||
if (($sRuleType === '') || !in_array($sRuleType, static::GetAllowedTypes()))
|
||||
{
|
||||
throw new DOMFormatException('Navigation rule tag must have a valid xsi:type, "'.$sRuleType.'" given, expected '.implode('|',
|
||||
static::GetAllowedTypes()), null, null, $oRuleNode);
|
||||
if (($sRuleType === '') || !in_array($sRuleType, static::GetAllowedTypes())) {
|
||||
throw new DOMFormatException('Navigation rule tag must have a valid xsi:type, "'.$sRuleType.'" given, expected '.implode(
|
||||
'|',
|
||||
static::GetAllowedTypes()
|
||||
), null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
// Load rule from XML
|
||||
@@ -176,10 +177,10 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public static function GetAllowedOrigins()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
static::ENUM_ORIGIN_PAGE,
|
||||
static::ENUM_ORIGIN_MODAL,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,14 +190,14 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public static function GetAllowedTypes()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
static::ENUM_RULE_CLOSE,
|
||||
static::ENUM_RULE_GO_TO_HOMEPAGE,
|
||||
static::ENUM_RULE_GO_TO_OBJECT,
|
||||
static::ENUM_RULE_GO_TO_BRICK,
|
||||
static::ENUM_RULE_GO_TO_BROWSE_BRICK,
|
||||
static::ENUM_RULE_GO_TO_MANAGE_BRICK,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,8 +210,7 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public function GetRuleDefinition($sId)
|
||||
{
|
||||
if (!array_key_exists($sId, $this->aRules))
|
||||
{
|
||||
if (!array_key_exists($sId, $this->aRules)) {
|
||||
throw new Exception('NavigationRuleHelper: Could not find "'.$sId.'" in the rules list');
|
||||
}
|
||||
|
||||
@@ -251,10 +251,10 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public function GetDefaultCloseRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'category' => static::ENUM_RULE_CAT_CLOSE,
|
||||
'type' => static::ENUM_RULE_CLOSE,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,10 +264,10 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public function GetDefaultGoToHomepageRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'type' => static::ENUM_RULE_GO_TO_HOMEPAGE,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,15 +277,15 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public function GetDefaultGoToObjectRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'type' => static::ENUM_RULE_GO_TO_OBJECT,
|
||||
'properties' => array(
|
||||
'properties' => [
|
||||
'mode' => static::DEFAULT_RULE_GO_TO_OBJECT_PROP_MODE,
|
||||
'opening_target' => static::DEFAULT_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET,
|
||||
'oql' => null,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,16 +295,16 @@ class NavigationRuleHelper
|
||||
*/
|
||||
public function GetDefaultGoToBrickRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'type' => static::ENUM_RULE_GO_TO_BRICK,
|
||||
'properties' => array(
|
||||
'route' => array(
|
||||
'properties' => [
|
||||
'route' => [
|
||||
'id' => null,
|
||||
'params' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
'params' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
//----------------------------
|
||||
@@ -351,21 +351,18 @@ class NavigationRuleHelper
|
||||
// Default values
|
||||
$aRule = $this->GetDefaultGoToObjectRuleDefinition();
|
||||
|
||||
$aAllowedOpeningTarget = array(
|
||||
$aAllowedOpeningTarget = [
|
||||
static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT,
|
||||
static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL,
|
||||
static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_PAGE,
|
||||
);
|
||||
];
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->GetNodes('*') as $oPropNode)
|
||||
{
|
||||
switch($oPropNode->nodeName)
|
||||
{
|
||||
foreach ($oRuleNode->GetNodes('*') as $oPropNode) {
|
||||
switch ($oPropNode->nodeName) {
|
||||
case 'mode':
|
||||
$sMode = $oPropNode->GetText();
|
||||
if(!in_array($sMode, ObjectFormHandlerHelper::GetAllowedModes()))
|
||||
{
|
||||
if (!in_array($sMode, ObjectFormHandlerHelper::GetAllowedModes())) {
|
||||
throw new DOMFormatException('mode tag of navigation_rule "'.$sRuleId.'" must be valid. Expected '.implode('|', ObjectFormHandlerHelper::GetAllowedModes()).', "'.$sMode.'" given.', null, null, $oRuleNode);
|
||||
}
|
||||
$aRule['properties']['mode'] = $sMode;
|
||||
@@ -373,8 +370,7 @@ class NavigationRuleHelper
|
||||
|
||||
case 'opening_target':
|
||||
$sOpeningTarget = $oPropNode->GetText();
|
||||
if(!in_array($sOpeningTarget, $aAllowedOpeningTarget))
|
||||
{
|
||||
if (!in_array($sOpeningTarget, $aAllowedOpeningTarget)) {
|
||||
throw new DOMFormatException('opening_target tag of navigation_rule "'.$sRuleId.'" must be valid. Expected '.implode('|', $aAllowedOpeningTarget).', "'.$sOpeningTarget.'" given.', null, null, $oRuleNode);
|
||||
}
|
||||
$aRule['properties']['opening_target'] = $sOpeningTarget;
|
||||
@@ -382,8 +378,7 @@ class NavigationRuleHelper
|
||||
|
||||
case 'oql':
|
||||
$sOQL = $oPropNode->GetText();
|
||||
if(empty($sOQL))
|
||||
{
|
||||
if (empty($sOQL)) {
|
||||
throw new DOMFormatException('oql tag of navigation_rule "'.$sRuleId.'" can not be empty.');
|
||||
}
|
||||
$aRule['properties']['oql'] = $sOQL;
|
||||
@@ -409,30 +404,24 @@ class NavigationRuleHelper
|
||||
$aRule = $this->GetDefaultGoToBrickRuleDefinition();
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->GetNodes('*') as $oPropNode)
|
||||
{
|
||||
switch($oPropNode->nodeName)
|
||||
{
|
||||
foreach ($oRuleNode->GetNodes('*') as $oPropNode) {
|
||||
switch ($oPropNode->nodeName) {
|
||||
case 'route':
|
||||
/** @var array $aRouteProperties Route ID and parameters */
|
||||
$aRouteProperties = array();
|
||||
$aRouteProperties = [];
|
||||
/** @var DesignElement $oRoutePropNode */
|
||||
foreach($oPropNode->GetNodes('*') as $oRoutePropNode)
|
||||
{
|
||||
switch($oRoutePropNode->nodeName)
|
||||
{
|
||||
foreach ($oPropNode->GetNodes('*') as $oRoutePropNode) {
|
||||
switch ($oRoutePropNode->nodeName) {
|
||||
case 'id':
|
||||
$aRouteProperties['id'] = $oRoutePropNode->GetText();
|
||||
break;
|
||||
|
||||
case 'params':
|
||||
/** @var DesignElement $oRouteParamNode */
|
||||
foreach($oRoutePropNode->GetNodes('*') as $oRouteParamNode)
|
||||
{
|
||||
foreach ($oRoutePropNode->GetNodes('*') as $oRouteParamNode) {
|
||||
$sRouteParamId = $oRouteParamNode->getAttribute('id');
|
||||
$sRouteParamValue = $oRouteParamNode->GetText();
|
||||
if(empty($sRouteParamId) || empty($sRouteParamValue))
|
||||
{
|
||||
if (empty($sRouteParamId) || empty($sRouteParamValue)) {
|
||||
throw new DOMFormatException('param tag of navigation_rule "'.$sRuleId.'" must have a valid ID and value.', null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
@@ -443,8 +432,7 @@ class NavigationRuleHelper
|
||||
}
|
||||
|
||||
// Consistency check
|
||||
if(empty($aRouteProperties['id']))
|
||||
{
|
||||
if (empty($aRouteProperties['id'])) {
|
||||
throw new DOMFormatException('navigation_rule "'.$sRuleId.'" must have a valid ID', null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
@@ -474,16 +462,15 @@ class NavigationRuleHelper
|
||||
$aRule['properties']['route']['params']['sDisplayMode'] = ManageBrick::DEFAULT_DISPLAY_MODE;
|
||||
|
||||
// Rule parameters to automatically map to the route parameters
|
||||
$aParamsMapping = array(
|
||||
$aParamsMapping = [
|
||||
'id' => 'sBrickId',
|
||||
'display_mode' => 'sDisplayMode',
|
||||
'grouping_tab' => 'sGroupingTab',
|
||||
'filter' => 'sSearchValue',
|
||||
);
|
||||
];
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->GetNodes('*') as $oPropNode)
|
||||
{
|
||||
foreach ($oRuleNode->GetNodes('*') as $oPropNode) {
|
||||
$sRouteParamId = (array_key_exists($oPropNode->nodeName, $aParamsMapping)) ? $aParamsMapping[$oPropNode->nodeName] : $oPropNode->nodeName;
|
||||
$aRule['properties']['route']['params'][$sRouteParamId] = $oPropNode->GetText();
|
||||
}
|
||||
@@ -509,15 +496,14 @@ class NavigationRuleHelper
|
||||
$aRule['properties']['route']['params']['sBrowseMode'] = BrowseBrick::DEFAULT_BROWSE_MODE;
|
||||
|
||||
// Rule parameters to automatically map to the route parameters
|
||||
$aParamsMapping = array(
|
||||
$aParamsMapping = [
|
||||
'id' => 'sBrickId',
|
||||
'browse_mode' => 'sBrowseMode',
|
||||
'filter' => 'sSearchValue',
|
||||
);
|
||||
];
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->GetNodes('*') as $oPropNode)
|
||||
{
|
||||
foreach ($oRuleNode->GetNodes('*') as $oPropNode) {
|
||||
$sRouteParamId = (array_key_exists($oPropNode->nodeName, $aParamsMapping)) ? $aParamsMapping[$oPropNode->nodeName] : $oPropNode->nodeName;
|
||||
$aRule['properties']['route']['params'][$sRouteParamId] = $oPropNode->GetText();
|
||||
}
|
||||
@@ -555,33 +541,30 @@ class NavigationRuleHelper
|
||||
public function PrepareRulesForForm(array $aFormProperties, DBObject $oCurrentObject, $bIsCurrentFormInModal = false)
|
||||
{
|
||||
// Default values
|
||||
$aResults = array(
|
||||
'submit' => array(
|
||||
$aResults = [
|
||||
'submit' => [
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'url' => null,
|
||||
'modal' => false,
|
||||
),
|
||||
'cancel' => array(
|
||||
],
|
||||
'cancel' => [
|
||||
'category' => static::ENUM_RULE_CAT_CLOSE,
|
||||
'url' => null,
|
||||
'modal' => false,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// Get form's navigation rules
|
||||
$aFormNavRules = (isset($aFormProperties['properties']['navigation_rules'])) ? $aFormProperties['properties']['navigation_rules'] : array('submit' => null, 'cancel' => null);
|
||||
$aFormNavRules = (isset($aFormProperties['properties']['navigation_rules'])) ? $aFormProperties['properties']['navigation_rules'] : ['submit' => null, 'cancel' => null];
|
||||
|
||||
// Check from which origin the rule will be called
|
||||
$sRuleCallOrigin = ($bIsCurrentFormInModal) ? 'modal' : 'default';
|
||||
|
||||
foreach(array_keys($aResults) as $sButtonCode)
|
||||
{
|
||||
foreach (array_keys($aResults) as $sButtonCode) {
|
||||
// Retrieve rule definition
|
||||
// - Default behavior when no rule specified
|
||||
if(empty($aFormNavRules[$sButtonCode][$sRuleCallOrigin]))
|
||||
{
|
||||
switch($sButtonCode)
|
||||
{
|
||||
if (empty($aFormNavRules[$sButtonCode][$sRuleCallOrigin])) {
|
||||
switch ($sButtonCode) {
|
||||
case 'submit':
|
||||
$sDefaultRuleType = ($bIsCurrentFormInModal) ? static::DEFAULT_RULE_SUBMIT_MODAL : static::DEFAULT_RULE_SUBMIT_PAGE;
|
||||
break;
|
||||
@@ -593,8 +576,7 @@ class NavigationRuleHelper
|
||||
$aRuleDef = $this->GetDefaultRuleDefinitionFromType($sDefaultRuleType);
|
||||
}
|
||||
// - Specified rule
|
||||
else
|
||||
{
|
||||
else {
|
||||
$sRuleId = $aFormNavRules[$sButtonCode][$sRuleCallOrigin];
|
||||
$aRuleDef = $this->GetRuleDefinition($sRuleId);
|
||||
}
|
||||
@@ -603,36 +585,31 @@ class NavigationRuleHelper
|
||||
$aResults[$sButtonCode]['category'] = $aRuleDef['category'];
|
||||
|
||||
// Set properties regarding the type
|
||||
switch($aRuleDef['type'])
|
||||
{
|
||||
switch ($aRuleDef['type']) {
|
||||
case static::ENUM_RULE_GO_TO_HOMEPAGE:
|
||||
$aResults[$sButtonCode]['url'] = $this->oRouter->generate('p_home');
|
||||
break;
|
||||
|
||||
case static::ENUM_RULE_GO_TO_OBJECT:
|
||||
// Target opening mode to modal if specified or should be as current form
|
||||
if( ($aRuleDef['properties']['opening_target'] === static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL)
|
||||
if (($aRuleDef['properties']['opening_target'] === static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL)
|
||||
|| (($aRuleDef['properties']['opening_target'] === static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT) && ($bIsCurrentFormInModal === true))
|
||||
)
|
||||
{
|
||||
) {
|
||||
$aResults[$sButtonCode]['modal'] = true;
|
||||
}
|
||||
|
||||
// Target URL
|
||||
// - Find object
|
||||
if(empty($aRuleDef['properties']['oql']))
|
||||
{
|
||||
if (empty($aRuleDef['properties']['oql'])) {
|
||||
$oTargetObject = $oCurrentObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oSearch = DBSearch::FromOQL($aRuleDef['properties']['oql']);
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('this' => $oCurrentObject));
|
||||
$oSet->OptimizeColumnLoad(array($oSearch->GetClassAlias() => array()));
|
||||
$oSet = new DBObjectSet($oSearch, [], ['this' => $oCurrentObject]);
|
||||
$oSet->OptimizeColumnLoad([$oSearch->GetClassAlias() => []]);
|
||||
$oTargetObject = $oSet->Fetch();
|
||||
}
|
||||
// - Build URL
|
||||
$aResults[$sButtonCode]['url'] = $this->oRouter->generate('p_object_'.$aRuleDef['properties']['mode'], array('sObjectClass' => get_class($oTargetObject), 'sObjectId' => $oTargetObject->GetKey()));
|
||||
$aResults[$sButtonCode]['url'] = $this->oRouter->generate('p_object_'.$aRuleDef['properties']['mode'], ['sObjectClass' => get_class($oTargetObject), 'sObjectId' => $oTargetObject->GetKey()]);
|
||||
break;
|
||||
|
||||
case static::ENUM_RULE_GO_TO_BRICK:
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Portal\Helper;
|
||||
|
||||
use ApplicationContext;
|
||||
@@ -51,16 +50,16 @@ use UserRights;
|
||||
class ObjectFormHandlerHelper
|
||||
{
|
||||
/** @var string */
|
||||
const ENUM_MODE_VIEW = 'view';
|
||||
public const ENUM_MODE_VIEW = 'view';
|
||||
/** @var string */
|
||||
const ENUM_MODE_EDIT = 'edit';
|
||||
public const ENUM_MODE_EDIT = 'edit';
|
||||
/** @var string */
|
||||
const ENUM_MODE_CREATE = 'create';
|
||||
public const ENUM_MODE_CREATE = 'create';
|
||||
/**
|
||||
* @var string
|
||||
* @since 2.7.7 3.0.1 3.1.0
|
||||
*/
|
||||
const ENUM_MODE_APPLY_STIMULUS = 'apply_stimulus';
|
||||
public const ENUM_MODE_APPLY_STIMULUS = 'apply_stimulus';
|
||||
|
||||
/** @var \Combodo\iTop\Portal\Helper\RequestManipulatorHelper $oRequestManipulator */
|
||||
private $oRequestManipulator;
|
||||
@@ -95,10 +94,16 @@ class ObjectFormHandlerHelper
|
||||
* @param \Combodo\iTop\Portal\Twig\AppExtension $oAppExtension
|
||||
*/
|
||||
public function __construct(
|
||||
RequestManipulatorHelper $oRequestManipulator, ContextManipulatorHelper $oContextManipulator, NavigationRuleHelper $oNavigationRuleHelper, ScopeValidatorHelper $oScopeValidator, SecurityHelper $oSecurityHelper, UrlGeneratorInterface $oUrlGenerator, $aCombodoPortalInstanceConf, $sPortalId,
|
||||
RequestManipulatorHelper $oRequestManipulator,
|
||||
ContextManipulatorHelper $oContextManipulator,
|
||||
NavigationRuleHelper $oNavigationRuleHelper,
|
||||
ScopeValidatorHelper $oScopeValidator,
|
||||
SecurityHelper $oSecurityHelper,
|
||||
UrlGeneratorInterface $oUrlGenerator,
|
||||
$aCombodoPortalInstanceConf,
|
||||
$sPortalId,
|
||||
AppExtension $oAppExtension
|
||||
)
|
||||
{
|
||||
) {
|
||||
$this->oRequestManipulator = $oRequestManipulator;
|
||||
$this->oContextManipulator = $oContextManipulator;
|
||||
$this->oNavigationRuleHelper = $oNavigationRuleHelper;
|
||||
@@ -126,7 +131,7 @@ class ObjectFormHandlerHelper
|
||||
*/
|
||||
public function HandleForm(Request $oRequest, $sMode, $sObjectClass, $sObjectId = null, array $aFormProperties = null)
|
||||
{
|
||||
$aFormData = array();
|
||||
$aFormData = [];
|
||||
$sOperation = $this->oRequestManipulator->ReadParam('operation', '');
|
||||
$bModal = ($oRequest->isXmlHttpRequest() && empty($sOperation));
|
||||
|
||||
@@ -134,71 +139,58 @@ class ObjectFormHandlerHelper
|
||||
$aFormProperties = $aFormProperties ?? ApplicationHelper::GetLoadedFormFromClass($this->aCombodoPortalInstanceConf['forms'], $sObjectClass, $sMode);
|
||||
|
||||
// - Create and
|
||||
if (empty($sOperation))
|
||||
{
|
||||
if (empty($sOperation)) {
|
||||
// Retrieving action rules
|
||||
//
|
||||
// Note : The action rules must be a base64-encoded JSON object, this is just so users are tempted to changes values.
|
||||
// But it would not be a security issue as it only presets values in the form.
|
||||
$sActionRulesToken = $this->oRequestManipulator->ReadParam('ar_token', '');
|
||||
$aActionRules = (!empty($sActionRulesToken)) ? ContextManipulatorHelper::DecodeRulesToken($sActionRulesToken) : array();
|
||||
$aActionRules = (!empty($sActionRulesToken)) ? ContextManipulatorHelper::DecodeRulesToken($sActionRulesToken) : [];
|
||||
|
||||
// Preparing object
|
||||
if ($sObjectId === null)
|
||||
{
|
||||
if ($sObjectId === null) {
|
||||
// Create new UserRequest
|
||||
$oObject = MetaModel::NewObject($sObjectClass);
|
||||
|
||||
// Retrieve action rules information to auto-fill the form if available
|
||||
// Preparing object
|
||||
$this->oContextManipulator->PrepareObject($aActionRules, $oObject);
|
||||
$aPrefillFormParam = array(
|
||||
$aPrefillFormParam = [
|
||||
'user' => UserRights::GetUser(),
|
||||
'origin' => 'portal',
|
||||
);
|
||||
];
|
||||
$oObject->PrefillForm('creation_from_0', $aPrefillFormParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oObject = MetaModel::GetObject($sObjectClass, $sObjectId, true, $this->oScopeValidator->IsAllDataAllowedForScope(UserRights::ListProfiles(), $sObjectClass));
|
||||
}
|
||||
|
||||
// Preparing buttons
|
||||
$aFormData['buttons'] = array(
|
||||
'transitions' => array(),
|
||||
'actions' => array(),
|
||||
'links' => array(),
|
||||
'submit' => array(
|
||||
$aFormData['buttons'] = [
|
||||
'transitions' => [],
|
||||
'actions' => [],
|
||||
'links' => [],
|
||||
'submit' => [
|
||||
'label' => Dict::S('Portal:Button:Submit'),
|
||||
),
|
||||
);
|
||||
if ($sMode !== static::ENUM_MODE_APPLY_STIMULUS)
|
||||
{
|
||||
],
|
||||
];
|
||||
if ($sMode !== static::ENUM_MODE_APPLY_STIMULUS) {
|
||||
// Add transition buttons
|
||||
$oSetToCheckRights = DBObjectSet::FromObject($oObject);
|
||||
$aStimuli = Metamodel::EnumStimuli($sObjectClass);
|
||||
foreach ($oObject->EnumTransitions() as $sStimulusCode => $aTransitionDef)
|
||||
{
|
||||
if ($this->oSecurityHelper->IsStimulusAllowed($sStimulusCode, $sObjectClass, $oSetToCheckRights))
|
||||
{
|
||||
foreach ($oObject->EnumTransitions() as $sStimulusCode => $aTransitionDef) {
|
||||
if ($this->oSecurityHelper->IsStimulusAllowed($sStimulusCode, $sObjectClass, $oSetToCheckRights)) {
|
||||
$aFormData['buttons']['transitions'][$sStimulusCode] = $aStimuli[$sStimulusCode]->GetLabel();
|
||||
}
|
||||
}
|
||||
|
||||
// Add plugin buttons
|
||||
/** @var \iPopupMenuExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance)
|
||||
{
|
||||
foreach ($oExtensionInstance->EnumItems(iPopupMenuExtension::PORTAL_OBJDETAILS_ACTIONS, array('portal_id' => $this->sPortalId, 'object' => $oObject, 'mode' => $sMode)) as $oMenuItem)
|
||||
{
|
||||
if (is_object($oMenuItem))
|
||||
{
|
||||
if ($oMenuItem instanceof JSButtonItem)
|
||||
{
|
||||
$aFormData['buttons']['actions'][] = $oMenuItem->GetMenuItem() + array('js_files' => $oMenuItem->GetLinkedScripts());
|
||||
}
|
||||
elseif ($oMenuItem instanceof URLButtonItem)
|
||||
{
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) {
|
||||
foreach ($oExtensionInstance->EnumItems(iPopupMenuExtension::PORTAL_OBJDETAILS_ACTIONS, ['portal_id' => $this->sPortalId, 'object' => $oObject, 'mode' => $sMode]) as $oMenuItem) {
|
||||
if (is_object($oMenuItem)) {
|
||||
if ($oMenuItem instanceof JSButtonItem) {
|
||||
$aFormData['buttons']['actions'][] = $oMenuItem->GetMenuItem() + ['js_files' => $oMenuItem->GetLinkedScripts()];
|
||||
} elseif ($oMenuItem instanceof URLButtonItem) {
|
||||
$aFormData['buttons']['links'][] = $oMenuItem->GetMenuItem();
|
||||
}
|
||||
}
|
||||
@@ -206,22 +198,17 @@ class ObjectFormHandlerHelper
|
||||
}
|
||||
|
||||
// Hiding submit button or changing its label if necessary
|
||||
if (!empty($aFormData['buttons']['transitions']) && isset($aFormProperties['properties']) && $aFormProperties['properties']['always_show_submit'] === false)
|
||||
{
|
||||
if (!empty($aFormData['buttons']['transitions']) && isset($aFormProperties['properties']) && $aFormProperties['properties']['always_show_submit'] === false) {
|
||||
unset($aFormData['buttons']['submit']);
|
||||
}
|
||||
elseif ($sMode === static::ENUM_MODE_EDIT)
|
||||
{
|
||||
} elseif ($sMode === static::ENUM_MODE_EDIT) {
|
||||
$aFormData['buttons']['submit']['label'] = Dict::S('Portal:Button:Apply');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aPrefillFormParam = array(
|
||||
} else {
|
||||
$aPrefillFormParam = [
|
||||
'user' => UserRights::GetUser(),
|
||||
'origin' => 'portal',
|
||||
'stimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY)['code'],
|
||||
);
|
||||
];
|
||||
$oObject->PrefillForm('state_change', $aPrefillFormParam);
|
||||
}
|
||||
|
||||
@@ -235,32 +222,31 @@ class ObjectFormHandlerHelper
|
||||
|
||||
// Preparing renderer
|
||||
// Note : We might need to distinguish form & renderer endpoints
|
||||
switch($sMode)
|
||||
{
|
||||
switch ($sMode) {
|
||||
case static::ENUM_MODE_CREATE:
|
||||
case static::ENUM_MODE_EDIT:
|
||||
case static::ENUM_MODE_VIEW:
|
||||
if(array_key_exists('submit_endpoint', $aFormProperties)) {
|
||||
$sFormEndpoint = $aFormProperties['submit_endpoint'];
|
||||
} else {
|
||||
$sFormEndpoint = $this->oUrlGenerator->generate(
|
||||
'p_object_' . $sMode,
|
||||
array(
|
||||
'sObjectClass' => $sObjectClass,
|
||||
'sObjectId' => $sObjectId,
|
||||
)
|
||||
);
|
||||
}
|
||||
if (array_key_exists('submit_endpoint', $aFormProperties)) {
|
||||
$sFormEndpoint = $aFormProperties['submit_endpoint'];
|
||||
} else {
|
||||
$sFormEndpoint = $this->oUrlGenerator->generate(
|
||||
'p_object_'.$sMode,
|
||||
[
|
||||
'sObjectClass' => $sObjectClass,
|
||||
'sObjectId' => $sObjectId,
|
||||
]
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case static::ENUM_MODE_APPLY_STIMULUS:
|
||||
$sFormEndpoint = $this->oUrlGenerator->generate(
|
||||
'p_object_apply_stimulus',
|
||||
array(
|
||||
[
|
||||
'sObjectClass' => $sObjectClass,
|
||||
'sObjectId' => $sObjectId,
|
||||
'sStimulusCode' => $this->oRequestManipulator->ReadParam('sStimulusCode'),
|
||||
)
|
||||
]
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -294,8 +280,7 @@ class ObjectFormHandlerHelper
|
||||
/** @var \Combodo\iTop\Portal\Form\ObjectFormManager $sFormManagerClass */
|
||||
$sFormManagerClass = $this->oRequestManipulator->ReadParam('formmanager_class', '', FILTER_UNSAFE_RAW);
|
||||
$sFormManagerData = $this->oRequestManipulator->ReadParam('formmanager_data', '', FILTER_UNSAFE_RAW);
|
||||
if (empty($sFormManagerClass) || empty($sFormManagerData))
|
||||
{
|
||||
if (empty($sFormManagerClass) || empty($sFormManagerData)) {
|
||||
IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameters formmanager_class and formmanager_data must be defined.');
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameters formmanager_class and formmanager_data must be defined.');
|
||||
}
|
||||
@@ -312,48 +297,45 @@ class ObjectFormHandlerHelper
|
||||
$oFormManager->SetObject($oObj);
|
||||
}
|
||||
|
||||
switch ($sOperation)
|
||||
{
|
||||
switch ($sOperation) {
|
||||
case 'submit':
|
||||
// Applying modification to object
|
||||
$aFormData['validation'] = $oFormManager->OnSubmit(
|
||||
array(
|
||||
'currentValues' => $this->oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
'attachmentIds' => $this->oRequestManipulator->ReadParam('attachment_ids', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
[
|
||||
'currentValues' => $this->oRequestManipulator->ReadParam('current_values', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
'attachmentIds' => $this->oRequestManipulator->ReadParam('attachment_ids', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
'formProperties' => $aFormProperties,
|
||||
'applyStimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY),
|
||||
)
|
||||
]
|
||||
);
|
||||
if ($aFormData['validation']['valid'] === true)
|
||||
{
|
||||
if ($aFormData['validation']['valid'] === true) {
|
||||
// Note : We don't use $sObjectId there as it can be null if we are creating a new one. Instead we use the id from the created object once it has been serialized
|
||||
// Check if stimulus has to be applied
|
||||
$sStimulusCode = $this->oRequestManipulator->ReadParam('stimulus_code', '');
|
||||
if (!empty($sStimulusCode))
|
||||
{
|
||||
$aFormData['validation']['redirection'] = array(
|
||||
'url' => $this->oUrlGenerator->generate('p_object_apply_stimulus', array('sObjectClass' => $sObjectClass, 'sObjectId' => $oFormManager->GetObject()->GetKey(), 'sStimulusCode' => $sStimulusCode)),
|
||||
if (!empty($sStimulusCode)) {
|
||||
$aFormData['validation']['redirection'] = [
|
||||
'url' => $this->oUrlGenerator->generate('p_object_apply_stimulus', ['sObjectClass' => $sObjectClass, 'sObjectId' => $oFormManager->GetObject()->GetKey(), 'sStimulusCode' => $sStimulusCode]),
|
||||
'modal' => true,
|
||||
);
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$sErrorMessages = '';
|
||||
foreach ($aFormData['validation']['messages']['error'] as $sFieldId => $aMessages) {
|
||||
if ($sFieldId == '_main') {
|
||||
$sErrorMessages .= implode(' - ', $aFormData['validation']['messages']['error']['_main']);
|
||||
} else {
|
||||
$oObj = $oFormManager->GetObject();
|
||||
$sLabel = $oObj->GetLabel($sFieldId);
|
||||
$sErrorMessages .= Dict::Format('Portal:Error:CheckToWriteFailed', $sLabel, (is_array($aMessages) ? implode(' - ', $aMessages) : $aMessages));
|
||||
}
|
||||
}
|
||||
$sErrorMessages = '';
|
||||
foreach ($aFormData['validation']['messages']['error'] as $sFieldId => $aMessages) {
|
||||
if ($sFieldId == '_main') {
|
||||
$sErrorMessages .= implode(' - ', $aFormData['validation']['messages']['error']['_main']);
|
||||
} else {
|
||||
$oObj = $oFormManager->GetObject();
|
||||
$sLabel = $oObj->GetLabel($sFieldId);
|
||||
$sErrorMessages .= Dict::Format('Portal:Error:CheckToWriteFailed', $sLabel, (is_array($aMessages) ? implode(' - ', $aMessages) : $aMessages));
|
||||
}
|
||||
}
|
||||
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, $sErrorMessages);
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, $sErrorMessages);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$oFormManager->OnUpdate(array('currentValues' => $this->oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), 'formProperties' => $aFormProperties));
|
||||
$oFormManager->OnUpdate(['currentValues' => $this->oRequestManipulator->ReadParam('current_values', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), 'formProperties' => $aFormProperties]);
|
||||
break;
|
||||
|
||||
case 'cancel':
|
||||
@@ -363,33 +345,27 @@ class ObjectFormHandlerHelper
|
||||
}
|
||||
|
||||
// Preparing field_set data
|
||||
$aFieldSetData = array(
|
||||
$aFieldSetData = [
|
||||
//'fields_list' => $oFormManager->GetRenderer()->Render(), // GLA : This should be done just after in the if statement.
|
||||
'fields_impacts' => $oFormManager->GetForm()->GetFieldsImpacts(),
|
||||
'form_path' => $oFormManager->GetForm()->GetId(),
|
||||
);
|
||||
];
|
||||
|
||||
// Preparing fields list regarding the operation
|
||||
if ($sOperation === 'update')
|
||||
{
|
||||
$aRequestedFields = $this->oRequestManipulator->ReadParam('requested_fields', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
|
||||
if ($sOperation === 'update') {
|
||||
$aRequestedFields = $this->oRequestManipulator->ReadParam('requested_fields', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
|
||||
$sFormPath = $this->oRequestManipulator->ReadParam('form_path', '');
|
||||
|
||||
// Checking if the update was on a subform, if so we need to make the rendering for that part only
|
||||
if (!empty($sFormPath) && $sFormPath !== $oFormManager->GetForm()->GetId())
|
||||
{
|
||||
if (!empty($sFormPath) && $sFormPath !== $oFormManager->GetForm()->GetId()) {
|
||||
$oSubForm = $oFormManager->GetForm()->FindSubForm($sFormPath);
|
||||
$oSubFormRenderer = new BsFormRenderer($oSubForm);
|
||||
$oSubFormRenderer->SetEndpoint($oFormManager->GetRenderer()->GetEndpoint());
|
||||
$aFormData['updated_fields'] = $oSubFormRenderer->Render($aRequestedFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aFormData['updated_fields'] = $oFormManager->GetRenderer()->Render($aRequestedFields);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aFieldSetData['fields_list'] = $oFormManager->GetRenderer()->Render();
|
||||
}
|
||||
|
||||
@@ -407,8 +383,7 @@ class ObjectFormHandlerHelper
|
||||
$aFormData['display_mode'] = (isset($aFormProperties['properties'])) ? $aFormProperties['properties']['display_mode'] : ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE;
|
||||
$aFormData['hidden_fields'] = $oFormManager->GetHiddenFieldsId();
|
||||
// - Set a text to be copied on title if the object is not in creation
|
||||
if($sMode !== static::ENUM_MODE_CREATE && !empty($sObjectId))
|
||||
{
|
||||
if ($sMode !== static::ENUM_MODE_CREATE && !empty($sObjectId)) {
|
||||
$aFormData['title_clipboard_text'] = Dict::Format(
|
||||
'Brick:Portal:Object:Copy:TextToCopy',
|
||||
$aFormData['object_name'],
|
||||
@@ -435,17 +410,15 @@ class ObjectFormHandlerHelper
|
||||
public function RenderFormFromTwig($sId, $sTwigString, $aData)
|
||||
{
|
||||
// Creating sandbox twig env. to load and test the custom form template
|
||||
$oTwig = new Environment(new ArrayLoader(array($sId => $sTwigString)));
|
||||
$oTwig = new Environment(new ArrayLoader([$sId => $sTwigString]));
|
||||
|
||||
// Manually registering filters and functions as we didn't find how to do it automatically
|
||||
$aFilters = $this->oAppExtension->getFilters();
|
||||
foreach ($aFilters as $oFilter)
|
||||
{
|
||||
foreach ($aFilters as $oFilter) {
|
||||
$oTwig->addFilter($oFilter);
|
||||
}
|
||||
$aFunctions = $this->oAppExtension->getFunctions();
|
||||
foreach ($aFunctions as $oFunction)
|
||||
{
|
||||
foreach ($aFunctions as $oFunction) {
|
||||
$oTwig->addFunction($oFunction);
|
||||
}
|
||||
|
||||
@@ -469,9 +442,9 @@ class ObjectFormHandlerHelper
|
||||
public function CheckReadFormDataAllowed($sFormManagerData)
|
||||
{
|
||||
$aJsonFromData = ObjectFormManager::DecodeFormManagerData($sFormManagerData);
|
||||
if(isset($aJsonFromData['formobject_class'])
|
||||
if (isset($aJsonFromData['formobject_class'])
|
||||
&& isset($aJsonFromData['formobject_id'])
|
||||
&& !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $aJsonFromData['formobject_class'], $aJsonFromData['formobject_id'])){
|
||||
&& !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $aJsonFromData['formobject_class'], $aJsonFromData['formobject_id'])) {
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Form data access denied.');
|
||||
}
|
||||
}
|
||||
@@ -484,11 +457,11 @@ class ObjectFormHandlerHelper
|
||||
*/
|
||||
public static function GetAllowedModes()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
static::ENUM_MODE_VIEW,
|
||||
static::ENUM_MODE_EDIT,
|
||||
static::ENUM_MODE_CREATE,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -530,4 +503,4 @@ class ObjectFormHandlerHelper
|
||||
{
|
||||
return $this->aCombodoPortalInstanceConf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,18 +63,15 @@ class RequestManipulatorHelper
|
||||
*/
|
||||
public function HasParam($sKey)
|
||||
{
|
||||
if ($this->GetCurrentRequest()->query->has($sKey))
|
||||
{
|
||||
if ($this->GetCurrentRequest()->query->has($sKey)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->GetCurrentRequest()->attributes->has($sKey))
|
||||
{
|
||||
if ($this->GetCurrentRequest()->attributes->has($sKey)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->GetCurrentRequest()->request->has($sKey))
|
||||
{
|
||||
if ($this->GetCurrentRequest()->request->has($sKey)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,7 +87,7 @@ class RequestManipulatorHelper
|
||||
* @param string $sKey
|
||||
* @param mixed $default
|
||||
* @param int $iFilter Default is FILTER_SANITIZE_SPECIAL_CHARS
|
||||
* @param int $aFilterOptions @since 3.2.0 - N°6934 - Symfony 6.4 - upgrade Symfony bundles to 6.4
|
||||
* @param int $aFilterOptions @since 3.2.0 - N°6934 - Symfony 6.4 - upgrade Symfony bundles to 6.4
|
||||
*
|
||||
* @return mixed|null
|
||||
*
|
||||
@@ -98,18 +95,15 @@ class RequestManipulatorHelper
|
||||
*/
|
||||
public function ReadParam($sKey, $default = null, $iFilter = FILTER_SANITIZE_SPECIAL_CHARS, $aFilterOptions = [])
|
||||
{
|
||||
if ($this->GetCurrentRequest()->query->has($sKey))
|
||||
{
|
||||
if ($this->GetCurrentRequest()->query->has($sKey)) {
|
||||
return $this->GetCurrentRequest()->query->filter($sKey, $default, $iFilter, $aFilterOptions);
|
||||
}
|
||||
|
||||
if ($this->GetCurrentRequest()->attributes->has($sKey))
|
||||
{
|
||||
if ($this->GetCurrentRequest()->attributes->has($sKey)) {
|
||||
return $this->GetCurrentRequest()->attributes->filter($sKey, $default, $iFilter, $aFilterOptions);
|
||||
}
|
||||
|
||||
if ($this->GetCurrentRequest()->request->has($sKey))
|
||||
{
|
||||
if ($this->GetCurrentRequest()->request->has($sKey)) {
|
||||
return $this->GetCurrentRequest()->request->filter($sKey, $default, $iFilter, $aFilterOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,18 +41,18 @@ use utils;
|
||||
class ScopeValidatorHelper
|
||||
{
|
||||
/** @var string ENUM_MODE_READ */
|
||||
const ENUM_MODE_READ = 'r';
|
||||
public const ENUM_MODE_READ = 'r';
|
||||
/** @var string ENUM_MODE_WRITE */
|
||||
const ENUM_MODE_WRITE = 'w';
|
||||
public const ENUM_MODE_WRITE = 'w';
|
||||
/** @var string ENUM_TYPE_ALLOW */
|
||||
const ENUM_TYPE_ALLOW = 'allow';
|
||||
public const ENUM_TYPE_ALLOW = 'allow';
|
||||
/** @var string ENUM_TYPE_RESTRICT */
|
||||
const ENUM_TYPE_RESTRICT = 'restrict';
|
||||
public const ENUM_TYPE_RESTRICT = 'restrict';
|
||||
|
||||
/** @var string DEFAULT_GENERATED_CLASS */
|
||||
const DEFAULT_GENERATED_CLASS = '\\PortalScopesValues';
|
||||
public const DEFAULT_GENERATED_CLASS = '\\PortalScopesValues';
|
||||
/** @var bool DEFAULT_IGNORE_SILOS */
|
||||
const DEFAULT_IGNORE_SILOS = false;
|
||||
public const DEFAULT_IGNORE_SILOS = false;
|
||||
|
||||
/** @var string|null $sCachePath */
|
||||
protected $sCachePath;
|
||||
@@ -80,7 +80,7 @@ class ScopeValidatorHelper
|
||||
$this->sCachePath = $sPortalCachePath;
|
||||
$this->sInstancePrefix = "{$sPortalId}-";
|
||||
$this->sGeneratedClass = static::DEFAULT_GENERATED_CLASS;
|
||||
$this->aProfilesMatrix = array();
|
||||
$this->aProfilesMatrix = [];
|
||||
|
||||
$this->Init($moduleDesign->GetNodes('/module_design/classes/class'));
|
||||
}
|
||||
@@ -96,8 +96,7 @@ class ScopeValidatorHelper
|
||||
public function Init(DOMNodeList $oNodes)
|
||||
{
|
||||
// Checking cache path
|
||||
if ($this->sCachePath === null)
|
||||
{
|
||||
if ($this->sCachePath === null) {
|
||||
$this->sCachePath = utils::GetCachePath();
|
||||
}
|
||||
// Building full pathname for file
|
||||
@@ -105,20 +104,18 @@ class ScopeValidatorHelper
|
||||
|
||||
// Creating file if not existing
|
||||
// Note : This is a temporary cache system, it should soon evolve to a cache provider (fs, apc, memcache, ...)
|
||||
if (!file_exists($sFilePath))
|
||||
{
|
||||
if (!file_exists($sFilePath)) {
|
||||
$this->InitGenerateAndWriteCache($oNodes, $sFilePath);
|
||||
}
|
||||
|
||||
if (!class_exists($this->sGeneratedClass))
|
||||
{
|
||||
if (!class_exists($this->sGeneratedClass)) {
|
||||
require_once $this->sCachePath.$this->sFilename;
|
||||
}
|
||||
}
|
||||
|
||||
public static function EnumTypeValues()
|
||||
{
|
||||
return array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT);
|
||||
return [static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,7 +194,7 @@ class ScopeValidatorHelper
|
||||
*/
|
||||
public function GetScopeFilterForProfile($sProfile, $sClass, $iAction = null)
|
||||
{
|
||||
return $this->GetScopeFilterForProfiles(array($sProfile), $sClass, $iAction);
|
||||
return $this->GetScopeFilterForProfiles([$sProfile], $sClass, $iAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,19 +214,17 @@ class ScopeValidatorHelper
|
||||
public function GetScopeFilterForProfiles($aProfiles, $sClass, $iAction = null)
|
||||
{
|
||||
$oSearch = null;
|
||||
$aAllowSearches = array();
|
||||
$aRestrictSearches = array();
|
||||
$aAllowSearches = [];
|
||||
$aRestrictSearches = [];
|
||||
$bIgnoreSilos = static::DEFAULT_IGNORE_SILOS;
|
||||
|
||||
// Checking the default mode
|
||||
if ($iAction === null)
|
||||
{
|
||||
if ($iAction === null) {
|
||||
$iAction = UR_ACTION_READ;
|
||||
}
|
||||
|
||||
// Iterating on profiles to retrieving the different OQLs parts
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
foreach ($aProfiles as $sProfile) {
|
||||
// Retrieving matrix information
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfile);
|
||||
$sMode = ($iAction === UR_ACTION_READ) ? static::ENUM_MODE_READ : static::ENUM_MODE_WRITE;
|
||||
@@ -237,39 +232,31 @@ class ScopeValidatorHelper
|
||||
// Retrieving profile OQLs
|
||||
$sScopeValuesClass = $this->sGeneratedClass;
|
||||
$aProfileMatrix = $sScopeValuesClass::GetProfileScope($iProfileId, $sClass, $sMode);
|
||||
if ($aProfileMatrix !== null)
|
||||
{
|
||||
if (isset($aProfileMatrix['allow']) && $aProfileMatrix['allow'] !== null)
|
||||
{
|
||||
if ($aProfileMatrix !== null) {
|
||||
if (isset($aProfileMatrix['allow']) && $aProfileMatrix['allow'] !== null) {
|
||||
$aAllowSearches[] = DBSearch::FromOQL($aProfileMatrix['allow']);
|
||||
}
|
||||
if (isset($aProfileMatrix['restrict']) && $aProfileMatrix['restrict'] !== null)
|
||||
{
|
||||
if (isset($aProfileMatrix['restrict']) && $aProfileMatrix['restrict'] !== null) {
|
||||
$aRestrictSearches[] = DBSearch::FromOQL($aProfileMatrix['restrict']);
|
||||
}
|
||||
// If a profile should ignore allowed org, we set it for all its queries no matter the profile
|
||||
if (isset($aProfileMatrix['ignore_silos']) && $aProfileMatrix['ignore_silos'] === true)
|
||||
{
|
||||
if (isset($aProfileMatrix['ignore_silos']) && $aProfileMatrix['ignore_silos'] === true) {
|
||||
$bIgnoreSilos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Building the real OQL from all the parts from the different profiles
|
||||
for ($i = 0; $i < count($aAllowSearches); $i++)
|
||||
{
|
||||
foreach ($aRestrictSearches as $oRestrictSearch)
|
||||
{
|
||||
for ($i = 0; $i < count($aAllowSearches); $i++) {
|
||||
foreach ($aRestrictSearches as $oRestrictSearch) {
|
||||
$aAllowSearches[$i] = $aAllowSearches[$i]->Intersect($oRestrictSearch);
|
||||
}
|
||||
}
|
||||
if (count($aAllowSearches) > 0)
|
||||
{
|
||||
if (count($aAllowSearches) > 0) {
|
||||
$oSearch = new DBUnionSearch($aAllowSearches);
|
||||
$oSearch = $oSearch->RemoveDuplicateQueries();
|
||||
}
|
||||
if ($bIgnoreSilos === true)
|
||||
{
|
||||
if ($bIgnoreSilos === true) {
|
||||
$oSearch->AllowAllData();
|
||||
}
|
||||
|
||||
@@ -291,12 +278,10 @@ class ScopeValidatorHelper
|
||||
public function AddScopeToQuery(DBSearch &$oQuery, $sClass, $sAction = UR_ACTION_READ)
|
||||
{
|
||||
$oScopeQuery = $this->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sClass, $sAction);
|
||||
if ($oScopeQuery !== null)
|
||||
{
|
||||
if ($oScopeQuery !== null) {
|
||||
$oQuery = $oQuery->Intersect($oScopeQuery);
|
||||
// - Allowing all data if necessary
|
||||
if ($oScopeQuery->IsAllDataAllowed())
|
||||
{
|
||||
if ($oScopeQuery->IsAllDataAllowed()) {
|
||||
$oQuery->AllowAllData();
|
||||
}
|
||||
|
||||
@@ -321,19 +306,16 @@ class ScopeValidatorHelper
|
||||
$bIgnoreSilos = false;
|
||||
|
||||
// Iterating on profiles to retrieving the different OQLs parts
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
foreach ($aProfiles as $sProfile) {
|
||||
// Retrieving matrix information
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfile);
|
||||
|
||||
// Retrieving profile OQLs
|
||||
$sScopeValuesClass = $this->sGeneratedClass;
|
||||
$aProfileMatrix = $sScopeValuesClass::GetProfileScope($iProfileId, $sClass, static::ENUM_MODE_READ);
|
||||
if ($aProfileMatrix !== null)
|
||||
{
|
||||
if ($aProfileMatrix !== null) {
|
||||
// If a profile should ignore allowed org, we set it for all its queries no matter the profile
|
||||
if (isset($aProfileMatrix['ignore_silos']) && $aProfileMatrix['ignore_silos'] === true)
|
||||
{
|
||||
if (isset($aProfileMatrix['ignore_silos']) && $aProfileMatrix['ignore_silos'] === true) {
|
||||
$bIgnoreSilos = true;
|
||||
}
|
||||
}
|
||||
@@ -357,18 +339,12 @@ class ScopeValidatorHelper
|
||||
|
||||
// We try to find the profile from its name in order to retrieve it's id
|
||||
// - If the regular UserRights add-on is installed we check the profiles array
|
||||
if (class_exists('ProfilesConfig'))
|
||||
{
|
||||
if (defined($sProfile) && in_array($sProfile, ProfilesConfig::GetProfilesValues()))
|
||||
{
|
||||
if (class_exists('ProfilesConfig')) {
|
||||
if (defined($sProfile) && in_array($sProfile, ProfilesConfig::GetProfilesValues())) {
|
||||
$iProfileId = constant($sProfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
if ($aValue['name'] === $sProfile)
|
||||
{
|
||||
} else {
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) {
|
||||
if ($aValue['name'] === $sProfile) {
|
||||
$iProfileId = $iKey;
|
||||
break;
|
||||
}
|
||||
@@ -376,14 +352,12 @@ class ScopeValidatorHelper
|
||||
}
|
||||
}
|
||||
// - Else, we can't find the id from the name as we don't know the used UserRights add-on. It has to be a constant
|
||||
else
|
||||
{
|
||||
else {
|
||||
throw new Exception('Scope validator : Unknown UserRights addon, scope\'s profile must be a constant');
|
||||
}
|
||||
|
||||
// If profile was not found from its name or from a constant, we throw an exception
|
||||
if ($iProfileId === null)
|
||||
{
|
||||
if ($iProfileId === null) {
|
||||
throw new Exception('Scope validator : Could not find "'.$sProfile.'" in the profiles list');
|
||||
}
|
||||
|
||||
@@ -397,7 +371,7 @@ class ScopeValidatorHelper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function BuildPHPClass($aProfiles = array())
|
||||
protected function BuildPHPClass($aProfiles = [])
|
||||
{
|
||||
$sProfiles = var_export($aProfiles, true);
|
||||
$sClassName = ltrim($this->sGeneratedClass, '\\');
|
||||
@@ -450,31 +424,26 @@ EOF;
|
||||
protected function InitGenerateAndWriteCache(DOMNodeList $oNodes, $sFilePath)
|
||||
{
|
||||
// - Build php array from xml
|
||||
$aProfiles = array();
|
||||
$aProfiles = [];
|
||||
// This will be used to know which classes have been set, so we can set the missing ones.
|
||||
$aProfileClasses = array();
|
||||
$aProfileClasses = [];
|
||||
// Iterating over the class nodes
|
||||
/** @var \Combodo\iTop\DesignElement $oClassNode */
|
||||
foreach ($oNodes as $oClassNode)
|
||||
{
|
||||
foreach ($oNodes as $oClassNode) {
|
||||
// retrieving mandatory class id attribute
|
||||
$sClass = $oClassNode->getAttribute('id');
|
||||
if ($sClass === '')
|
||||
{
|
||||
if ($sClass === '') {
|
||||
throw new DOMFormatException('Class tag must have an id attribute.', null, null, $oClassNode);
|
||||
}
|
||||
|
||||
// Iterating over scope nodes of the class
|
||||
$oScopesNode = $oClassNode->GetOptionalElement('scopes');
|
||||
if ($oScopesNode !== null)
|
||||
{
|
||||
if ($oScopesNode !== null) {
|
||||
/** @var \Combodo\iTop\DesignElement $oScopeNode */
|
||||
foreach ($oScopesNode->GetNodes('./scope') as $oScopeNode)
|
||||
{
|
||||
foreach ($oScopesNode->GetNodes('./scope') as $oScopeNode) {
|
||||
// Retrieving mandatory scope id attribute
|
||||
$sScopeId = $oScopeNode->getAttribute('id');
|
||||
if ($sScopeId === '')
|
||||
{
|
||||
if ($sScopeId === '') {
|
||||
throw new DOMFormatException('Scope tag must have an id attribute.', null, null, $oScopeNode);
|
||||
}
|
||||
|
||||
@@ -486,8 +455,7 @@ EOF;
|
||||
// Retrieving the view query
|
||||
$oOqlViewNode = $oScopeNode->GetUniqueElement('oql_view');
|
||||
$sOqlView = $oOqlViewNode->GetText();
|
||||
if ($sOqlView === null)
|
||||
{
|
||||
if ($sOqlView === null) {
|
||||
throw new DOMFormatException(
|
||||
'Scope tag in class must have a not empty oql_view tag',
|
||||
0,
|
||||
@@ -504,24 +472,18 @@ EOF;
|
||||
|
||||
// Retrieving profiles for the scope
|
||||
$oProfilesNode = $oScopeNode->GetOptionalElement('allowed_profiles');
|
||||
$aProfilesNames = array();
|
||||
$aProfilesNames = [];
|
||||
// If no profile is specified, we consider that it's for ALL the profiles
|
||||
if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./allowed_profile')->length === 0))
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./allowed_profile')->length === 0)) {
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) {
|
||||
$aProfilesNames[] = $aValue['name'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/** @var \Combodo\iTop\DesignElement $oProfileNode */
|
||||
foreach ($oProfilesNode->GetNodes('./allowed_profile') as $oProfileNode)
|
||||
{
|
||||
foreach ($oProfilesNode->GetNodes('./allowed_profile') as $oProfileNode) {
|
||||
// Retrieving mandatory profile id attribute
|
||||
$sProfileId = $oProfileNode->getAttribute('id');
|
||||
if ($sProfileId === '')
|
||||
{
|
||||
if ($sProfileId === '') {
|
||||
throw new DOMFormatException(
|
||||
'Scope tag must have an id attribute.',
|
||||
null,
|
||||
@@ -534,8 +496,7 @@ EOF;
|
||||
}
|
||||
|
||||
//
|
||||
foreach ($aProfilesNames as $sProfileName)
|
||||
{
|
||||
foreach ($aProfilesNames as $sProfileName) {
|
||||
// Scope profile id
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfileName);
|
||||
|
||||
@@ -545,48 +506,37 @@ EOF;
|
||||
$oViewFilter = DBSearch::FromOQL($sOqlView);
|
||||
// ... We have to union the query if this profile has another scope for that class
|
||||
if (array_key_exists($sMatrixPrefix.static::ENUM_MODE_READ, $aProfiles) && array_key_exists(
|
||||
$sOqlViewType,
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ]
|
||||
))
|
||||
{
|
||||
$sOqlViewType,
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ]
|
||||
)) {
|
||||
$oExistingFilter = DBSearch::FromOQL(
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ][$sOqlViewType]
|
||||
);
|
||||
$aFilters = array($oExistingFilter, $oViewFilter);
|
||||
$aFilters = [$oExistingFilter, $oViewFilter];
|
||||
$oResFilter = new DBUnionSearch($aFilters);
|
||||
|
||||
// Applying ignore_silos flag on result filter if necessary (As the union will remove it if it is not on all sub-queries)
|
||||
if ($aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ]['ignore_silos'] === true)
|
||||
{
|
||||
if ($aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ]['ignore_silos'] === true) {
|
||||
$bIgnoreSilos = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oResFilter = $oViewFilter;
|
||||
}
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ] = array(
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ] = [
|
||||
$sOqlViewType => $oResFilter->ToOQL(),
|
||||
'ignore_silos' => $bIgnoreSilos,
|
||||
);
|
||||
];
|
||||
// - Edit query
|
||||
if ($sOqlEdit !== null)
|
||||
{
|
||||
if ($sOqlEdit !== null) {
|
||||
$oEditFilter = DBSearch::FromOQL($sOqlEdit);
|
||||
// - If the queries are the same, we don't make an intersect, we just reuse the view query
|
||||
if ($sOqlEdit === $sOqlView)
|
||||
{
|
||||
if ($sOqlEdit === $sOqlView) {
|
||||
// Do not intersect, edit query is identical to view query
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($oEditFilter->GetClass() === $oViewFilter->GetClass()) && $oEditFilter->IsAny())
|
||||
{
|
||||
} else {
|
||||
if (($oEditFilter->GetClass() === $oViewFilter->GetClass()) && $oEditFilter->IsAny()) {
|
||||
$oEditFilter = $oViewFilter;
|
||||
// Do not intersect, edit query is identical to view query
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Intersect
|
||||
$oEditFilter = $oViewFilter->Intersect($oEditFilter);
|
||||
}
|
||||
@@ -594,27 +544,24 @@ EOF;
|
||||
|
||||
// ... We have to union the query if this profile has another scope for that class
|
||||
if (array_key_exists(
|
||||
$sMatrixPrefix.static::ENUM_MODE_WRITE,
|
||||
$aProfiles
|
||||
) && array_key_exists(
|
||||
$sOqlViewType,
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE]
|
||||
))
|
||||
{
|
||||
$sMatrixPrefix.static::ENUM_MODE_WRITE,
|
||||
$aProfiles
|
||||
) && array_key_exists(
|
||||
$sOqlViewType,
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE]
|
||||
)) {
|
||||
$oExistingFilter = DBSearch::FromOQL(
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE][$sOqlViewType]
|
||||
);
|
||||
$aFilters = array($oExistingFilter, $oEditFilter);
|
||||
$aFilters = [$oExistingFilter, $oEditFilter];
|
||||
$oResFilter = new DBUnionSearch($aFilters);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oResFilter = $oEditFilter;
|
||||
}
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE] = array(
|
||||
$aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE] = [
|
||||
$sOqlViewType => $oResFilter->ToOQL(),
|
||||
'ignore_silos' => $bIgnoreSilos,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -626,27 +573,19 @@ EOF;
|
||||
// Filling the array with missing classes from MetaModel, so we can have an inheritance principle on the scope
|
||||
// For each class explicitly given in the scopes, we check if its child classes were also in the scope :
|
||||
// If not, we add them with the same OQL
|
||||
foreach ($aProfileClasses as $sProfileClass)
|
||||
{
|
||||
foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass)
|
||||
{
|
||||
foreach ($aProfileClasses as $sProfileClass) {
|
||||
foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass) {
|
||||
// If the child class is not in the scope, we are going to try to add it
|
||||
if (!in_array($sChildClass, $aProfileClasses))
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
if (!in_array($sChildClass, $aProfileClasses)) {
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) {
|
||||
$iProfileId = $iKey;
|
||||
foreach (array(static::ENUM_MODE_READ, static::ENUM_MODE_WRITE) as $sAction)
|
||||
{
|
||||
foreach ([static::ENUM_MODE_READ, static::ENUM_MODE_WRITE] as $sAction) {
|
||||
// If the current profile has scope for that class in that mode, we duplicate it
|
||||
if (isset($aProfiles[$iProfileId.'_'.$sProfileClass.'_'.$sAction]))
|
||||
{
|
||||
if (isset($aProfiles[$iProfileId.'_'.$sProfileClass.'_'.$sAction])) {
|
||||
$aTmpProfile = $aProfiles[$iProfileId.'_'.$sProfileClass.'_'.$sAction];
|
||||
foreach ($aTmpProfile as $sType => $sOql)
|
||||
{
|
||||
foreach ($aTmpProfile as $sType => $sOql) {
|
||||
// IF condition is just to skip the 'ignore_silos' flag
|
||||
if (in_array($sType, array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT)))
|
||||
{
|
||||
if (in_array($sType, [static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT])) {
|
||||
$oTmpFilter = DBSearch::FromOQL($sOql);
|
||||
$oTmpFilter->ChangeClass($sChildClass);
|
||||
|
||||
@@ -667,14 +606,12 @@ EOF;
|
||||
|
||||
// - Write file on disk
|
||||
// - Creating dir if necessary
|
||||
if (!is_dir($this->sCachePath))
|
||||
{
|
||||
if (!is_dir($this->sCachePath)) {
|
||||
mkdir($this->sCachePath, 0777, true);
|
||||
}
|
||||
// -- Then creating the file
|
||||
$ret = file_put_contents($sFilePath, $sPHP);
|
||||
if ($ret === false)
|
||||
{
|
||||
if ($ret === false) {
|
||||
$iLen = strlen($sPHP);
|
||||
$fFree = @disk_free_space(dirname($sFilePath));
|
||||
$aErr = error_get_last();
|
||||
@@ -685,4 +622,3 @@ EOF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ use BinaryExpression;
|
||||
class SecurityHelper
|
||||
{
|
||||
/** @var array $aAllowedScopeObjectsCache */
|
||||
public static $aAllowedScopeObjectsCache = array(
|
||||
UR_ACTION_READ => array(),
|
||||
UR_ACTION_MODIFY => array(),
|
||||
);
|
||||
public static $aAllowedScopeObjectsCache = [
|
||||
UR_ACTION_READ => [],
|
||||
UR_ACTION_MODIFY => [],
|
||||
];
|
||||
|
||||
/** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator */
|
||||
private $oScopeValidator;
|
||||
@@ -69,7 +69,6 @@ class SecurityHelper
|
||||
$this->bDebug = $bDebug;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the current user is allowed to do the $sAction on an $sObjectClass object (with optional $sObjectId id)
|
||||
* Checks are:
|
||||
@@ -94,45 +93,37 @@ class SecurityHelper
|
||||
$sDebugTracePrefix = __CLASS__.' / '.__METHOD__.' : Returned false for action '.$sAction.' on '.$sObjectClass.'::'.$sObjectId;
|
||||
|
||||
// Checking action type
|
||||
if (!in_array($sAction, array(UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_CREATE)))
|
||||
{
|
||||
if (!in_array($sAction, [UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_CREATE])) {
|
||||
IssueLog::Debug($sDebugTracePrefix.' as the action value could not be understood ('.UR_ACTION_READ.'/'.UR_ACTION_MODIFY.'/'.UR_ACTION_CREATE.' expected', LogChannels::PORTAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Forcing allowed writing on the object if necessary. This is used in some particular cases.
|
||||
$bObjectIsCurrentUser = ($sObjectClass === 'Person' && $sObjectId == UserRights::GetContactId());
|
||||
if(in_array($sAction , array(UR_ACTION_MODIFY, UR_ACTION_READ)) && $bObjectIsCurrentUser){
|
||||
if (in_array($sAction, [UR_ACTION_MODIFY, UR_ACTION_READ]) && $bObjectIsCurrentUser) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Checking the scopes layer
|
||||
// - Transforming scope action as there is only 2 values
|
||||
$sScopeAction = ($sAction === UR_ACTION_READ) ? UR_ACTION_READ : UR_ACTION_MODIFY;
|
||||
// - Retrieving the query. If user has no scope, it can't access that kind of objects
|
||||
$oScopeQuery = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sObjectClass, $sScopeAction);
|
||||
if ($oScopeQuery === null)
|
||||
{
|
||||
if ($oScopeQuery === null) {
|
||||
IssueLog::Debug($sDebugTracePrefix.' as there was no scope defined for action '.$sScopeAction.' and profiles '.implode('/', UserRights::ListProfiles()), LogChannels::PORTAL);
|
||||
return false;
|
||||
}
|
||||
// - If action != create we do some additionnal checks
|
||||
if ($sAction !== UR_ACTION_CREATE)
|
||||
{
|
||||
if ($sAction !== UR_ACTION_CREATE) {
|
||||
// - Checking specific object if id is specified
|
||||
if ($sObjectId !== null)
|
||||
{
|
||||
if ($sObjectId !== null) {
|
||||
// Checking if object status is in cache (to avoid unnecessary query)
|
||||
if (isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId]))
|
||||
{
|
||||
if (static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] === false)
|
||||
{
|
||||
if (isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId])) {
|
||||
if (static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] === false) {
|
||||
IssueLog::Debug($sDebugTracePrefix.' as it was denied in the scope objects cache', LogChannels::PORTAL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Modifying query to filter on the ID
|
||||
// - Adding expression
|
||||
$sObjectKeyAtt = MetaModel::DBGetKey($sObjectClass);
|
||||
@@ -147,8 +138,7 @@ class SecurityHelper
|
||||
|
||||
// - Checking if query result is null (which means that the user has no right to view this specific object)
|
||||
$oSet = new DBObjectSet($oScopeQuery);
|
||||
if ($oSet->Count() === 0)
|
||||
{
|
||||
if ($oSet->Count() === 0) {
|
||||
// Updating cache
|
||||
static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] = false;
|
||||
|
||||
@@ -163,8 +153,7 @@ class SecurityHelper
|
||||
}
|
||||
|
||||
// Checking reading security layer. The object could be listed, check if it is actually allowed to view it
|
||||
if (UserRights::IsActionAllowed($sObjectClass, $sAction) == UR_ALLOWED_NO)
|
||||
{
|
||||
if (UserRights::IsActionAllowed($sObjectClass, $sAction) == UR_ALLOWED_NO) {
|
||||
// For security reasons, we don't want to give the user too many information on why he cannot access the object.
|
||||
//throw new SecurityException('User not allowed to view this object', array('class' => $sObjectClass, 'id' => $sObjectId));
|
||||
IssueLog::Debug($sDebugTracePrefix.' as the user is not allowed to access this object according to the datamodel security (cf. Console settings)', LogChannels::PORTAL);
|
||||
@@ -187,15 +176,13 @@ class SecurityHelper
|
||||
// Checking DataModel layer
|
||||
$aStimuliFromDatamodel = Metamodel::EnumStimuli($sObjectClass);
|
||||
$iActionAllowed = (get_class($aStimuliFromDatamodel[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sObjectClass, $sStimulusCode, $oInstanceSet) : UR_ALLOWED_NO;
|
||||
if (($iActionAllowed === false) || ($iActionAllowed === UR_ALLOWED_NO))
|
||||
{
|
||||
if (($iActionAllowed === false) || ($iActionAllowed === UR_ALLOWED_NO)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checking portal security layer
|
||||
$aStimuliFromPortal = $this->oLifecycleValidator->GetStimuliForProfiles(UserRights::ListProfiles(), $sObjectClass);
|
||||
if (!in_array($sStimulusCode, $aStimuliFromPortal))
|
||||
{
|
||||
if (!in_array($sStimulusCode, $aStimuliFromPortal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -217,20 +204,17 @@ class SecurityHelper
|
||||
public function PreloadForCache(DBSearch $oSearch, $aExtKeysToPreload = null)
|
||||
{
|
||||
$sObjectClass = $oSearch->GetClass();
|
||||
$aObjectIds = array();
|
||||
$aExtKeysIds = array();
|
||||
$aColumnsToLoad = array();
|
||||
$aObjectIds = [];
|
||||
$aExtKeysIds = [];
|
||||
$aColumnsToLoad = [];
|
||||
|
||||
if ($aExtKeysToPreload !== null)
|
||||
{
|
||||
foreach ($aExtKeysToPreload as $sAttCode)
|
||||
{
|
||||
if ($aExtKeysToPreload !== null) {
|
||||
foreach ($aExtKeysToPreload as $sAttCode) {
|
||||
/** @var \AttributeDefinition $oAttDef */
|
||||
$oAttDef = MetaModel::GetAttributeDef($sObjectClass, $sAttCode);
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
if ($oAttDef->IsExternalKey()) {
|
||||
/** @var \AttributeExternalKey $oAttDef */
|
||||
$aExtKeysIds[$oAttDef->GetTargetClass()] = array();
|
||||
$aExtKeysIds[$oAttDef->GetTargetClass()] = [];
|
||||
$aColumnsToLoad[] = $sAttCode;
|
||||
}
|
||||
}
|
||||
@@ -239,69 +223,56 @@ class SecurityHelper
|
||||
// Retrieving IDs of all objects
|
||||
// Note: We have to clone $oSet otherwise the source object will be modified
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$oSet->OptimizeColumnLoad(array($oSearch->GetClassAlias() => $aColumnsToLoad));
|
||||
while ($oCurrentRow = $oSet->Fetch())
|
||||
{
|
||||
$oSet->OptimizeColumnLoad([$oSearch->GetClassAlias() => $aColumnsToLoad]);
|
||||
while ($oCurrentRow = $oSet->Fetch()) {
|
||||
// Note: By presetting value to false, it is quicker to find which objects where not returned by the scope query later
|
||||
$aObjectIds[$oCurrentRow->GetKey()] = false;
|
||||
|
||||
// Preparing ExtKeys to preload
|
||||
foreach ($aColumnsToLoad as $sAttCode)
|
||||
{
|
||||
foreach ($aColumnsToLoad as $sAttCode) {
|
||||
$iExtKey = $oCurrentRow->Get($sAttCode);
|
||||
if ($iExtKey > 0)
|
||||
{
|
||||
if ($iExtKey > 0) {
|
||||
/** @var \AttributeExternalKey $oAttDef */
|
||||
$oAttDef = MetaModel::GetAttributeDef($sObjectClass, $sAttCode);
|
||||
if (!in_array($iExtKey, $aExtKeysIds[$oAttDef->GetTargetClass()]))
|
||||
{
|
||||
if (!in_array($iExtKey, $aExtKeysIds[$oAttDef->GetTargetClass()])) {
|
||||
$aExtKeysIds[$oAttDef->GetTargetClass()][] = $iExtKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array(UR_ACTION_READ, UR_ACTION_MODIFY) as $sScopeAction)
|
||||
{
|
||||
foreach ([UR_ACTION_READ, UR_ACTION_MODIFY] as $sScopeAction) {
|
||||
// Retrieving scope query
|
||||
/** @var DBSearch $oScopeQuery */
|
||||
$oScopeQuery = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sObjectClass, $sScopeAction);
|
||||
if ($oScopeQuery !== null)
|
||||
{
|
||||
if ($oScopeQuery !== null) {
|
||||
// Restricting scope if specified
|
||||
if (!empty($aObjectIds))
|
||||
{
|
||||
if (!empty($aObjectIds)) {
|
||||
$oScopeQuery->AddCondition('id', array_keys($aObjectIds), 'IN');
|
||||
}
|
||||
|
||||
// Preparing object set
|
||||
$oScopeSet = new DBObjectSet($oScopeQuery);
|
||||
$oScopeSet->OptimizeColumnLoad(array($oScopeQuery->GetClassAlias() => array()));
|
||||
$oScopeSet->OptimizeColumnLoad([$oScopeQuery->GetClassAlias() => []]);
|
||||
|
||||
// Checking objects status
|
||||
$aScopeObjectIds = $aObjectIds;
|
||||
while ($oCurrentRow = $oScopeSet->Fetch())
|
||||
{
|
||||
while ($oCurrentRow = $oScopeSet->Fetch()) {
|
||||
$aScopeObjectIds[$oCurrentRow->GetKey()] = true;
|
||||
}
|
||||
|
||||
// Updating cache
|
||||
if (!isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass]))
|
||||
{
|
||||
if (!isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass])) {
|
||||
static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass] = $aScopeObjectIds;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass] = array_merge_recursive(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass], $aScopeObjectIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Preloading ExtKeys
|
||||
foreach ($aExtKeysIds as $sTargetClass => $aTargetIds)
|
||||
{
|
||||
if (!empty($aTargetIds))
|
||||
{
|
||||
foreach ($aExtKeysIds as $sTargetClass => $aTargetIds) {
|
||||
if (!empty($aTargetIds)) {
|
||||
$oTargetSearch = new DBObjectSearch($sTargetClass);
|
||||
$oTargetSearch->AddCondition('id', $aTargetIds, 'IN');
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -35,21 +36,21 @@ use utils;
|
||||
class SessionMessageHelper implements IteratorAggregate
|
||||
{
|
||||
/** @var string ENUM_SEVERITY_INFO */
|
||||
const ENUM_SEVERITY_INFO = 'info';
|
||||
public const ENUM_SEVERITY_INFO = 'info';
|
||||
/** @var string ENUM_SEVERITY_OK */
|
||||
const ENUM_SEVERITY_OK = 'ok';
|
||||
public const ENUM_SEVERITY_OK = 'ok';
|
||||
/** @var string ENUM_SEVERITY_WARNING */
|
||||
const ENUM_SEVERITY_WARNING = 'warning';
|
||||
public const ENUM_SEVERITY_WARNING = 'warning';
|
||||
/** @var string ENUM_SEVERITY_ERROR */
|
||||
const ENUM_SEVERITY_ERROR = 'error';
|
||||
public const ENUM_SEVERITY_ERROR = 'error';
|
||||
|
||||
/** @var string DEFAULT_SEVERITY */
|
||||
const DEFAULT_SEVERITY = self::ENUM_SEVERITY_INFO;
|
||||
public const DEFAULT_SEVERITY = self::ENUM_SEVERITY_INFO;
|
||||
|
||||
/** @var \Symfony\Component\DependencyInjection\ContainerInterface $oContainer */
|
||||
private $oContainer;
|
||||
/** @var array $aAllMessages */
|
||||
private $aAllMessages = array();
|
||||
private $aAllMessages = [];
|
||||
|
||||
/**
|
||||
* SessionMessageHelper constructor.
|
||||
@@ -71,11 +72,10 @@ class SessionMessageHelper implements IteratorAggregate
|
||||
* @param array $aMetadata An array of key => scalar value
|
||||
* @param int $iRank
|
||||
*/
|
||||
public function AddMessage($sId, $sContent, $sSeverity = self::DEFAULT_SEVERITY, $aMetadata = array(), $iRank = 1)
|
||||
public function AddMessage($sId, $sContent, $sSeverity = self::DEFAULT_SEVERITY, $aMetadata = [], $iRank = 1)
|
||||
{
|
||||
$sKey = $this->GetMessagesKey();
|
||||
if(!Session::IsSet(['obj_messages', $sKey]))
|
||||
{
|
||||
if (!Session::IsSet(['obj_messages', $sKey])) {
|
||||
Session::Set(['obj_messages', $sKey], []);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ class SessionMessageHelper implements IteratorAggregate
|
||||
*/
|
||||
private function GetMessagesKey()
|
||||
{
|
||||
return 'GUI:' . $this->oContainer->getParameter('combodo.portal.instance.id');
|
||||
return 'GUI:'.$this->oContainer->getParameter('combodo.portal.instance.id');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,23 +126,18 @@ class SessionMessageHelper implements IteratorAggregate
|
||||
*/
|
||||
private function FetchMessages()
|
||||
{
|
||||
if (!empty($this->aAllMessages))
|
||||
{
|
||||
if (!empty($this->aAllMessages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->aAllMessages = array();
|
||||
if (is_array(Session::Get('obj_messages')))
|
||||
{
|
||||
foreach (Session::Get('obj_messages') as $sMessageKey => $aMessageObjectData)
|
||||
{
|
||||
$aObjectMessages = array();
|
||||
$aRanks = array();
|
||||
foreach ($aMessageObjectData as $sMessageId => $aMessageData)
|
||||
{
|
||||
$this->aAllMessages = [];
|
||||
if (is_array(Session::Get('obj_messages'))) {
|
||||
foreach (Session::Get('obj_messages') as $sMessageKey => $aMessageObjectData) {
|
||||
$aObjectMessages = [];
|
||||
$aRanks = [];
|
||||
foreach ($aMessageObjectData as $sMessageId => $aMessageData) {
|
||||
$sMsgClass = 'alert alert-dismissible alert-';
|
||||
switch ($aMessageData['severity'])
|
||||
{
|
||||
switch ($aMessageData['severity']) {
|
||||
case static::ENUM_SEVERITY_INFO:
|
||||
$sMsgClass .= 'info';
|
||||
break;
|
||||
@@ -168,17 +163,16 @@ class SessionMessageHelper implements IteratorAggregate
|
||||
$sMsgMetadata .= 'data-'.str_replace('_', '-', $sMetadatumName).'="'.utils::HtmlEntities($sMetadatumValue).'" ';
|
||||
}
|
||||
}
|
||||
$aObjectMessages[] = array('css_classes' => $sMsgClass, 'message' => $aMessageData['message'], 'metadata' => $sMsgMetadata);
|
||||
$aObjectMessages[] = ['css_classes' => $sMsgClass, 'message' => $aMessageData['message'], 'metadata' => $sMsgMetadata];
|
||||
$aRanks[] = $aMessageData['rank'];
|
||||
}
|
||||
Session::Unset(['obj_messages', $sMessageKey]);
|
||||
|
||||
array_multisort($aRanks, $aObjectMessages);
|
||||
foreach ($aObjectMessages as $aObjectMessage)
|
||||
{
|
||||
foreach ($aObjectMessages as $aObjectMessage) {
|
||||
$this->aAllMessages[] = $aObjectMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,8 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Portal\Helper;
|
||||
|
||||
|
||||
use InvalidParameterException;
|
||||
use iPortalUIExtension;
|
||||
use MetaModel;
|
||||
@@ -66,13 +64,11 @@ class UIExtensionsHelper
|
||||
*/
|
||||
public function __get($sPropName)
|
||||
{
|
||||
if ($this->aUIExtensions === null)
|
||||
{
|
||||
if ($this->aUIExtensions === null) {
|
||||
$this->InitUIExtensions();
|
||||
}
|
||||
|
||||
if (array_key_exists($sPropName, $this->aUIExtensions))
|
||||
{
|
||||
if (array_key_exists($sPropName, $this->aUIExtensions)) {
|
||||
return $this->aUIExtensions[$sPropName];
|
||||
}
|
||||
|
||||
@@ -87,8 +83,7 @@ class UIExtensionsHelper
|
||||
*/
|
||||
public function __isset($sPropName)
|
||||
{
|
||||
if ($this->aUIExtensions === null)
|
||||
{
|
||||
if ($this->aUIExtensions === null) {
|
||||
$this->InitUIExtensions();
|
||||
}
|
||||
|
||||
@@ -110,67 +105,63 @@ class UIExtensionsHelper
|
||||
*/
|
||||
protected function InitUIExtensions()
|
||||
{
|
||||
$aUIExtensions = array(
|
||||
'css_files' => array(),
|
||||
$aUIExtensions = [
|
||||
'css_files' => [],
|
||||
'css_inline' => null,
|
||||
'js_files' => array(),
|
||||
'js_files' => [],
|
||||
'js_inline' => null,
|
||||
'html' => array(),
|
||||
);
|
||||
'html' => [],
|
||||
];
|
||||
|
||||
$aUIExtensionHooks = array(
|
||||
$aUIExtensionHooks = [
|
||||
iPortalUIExtension::ENUM_PORTAL_EXT_UI_BODY,
|
||||
iPortalUIExtension::ENUM_PORTAL_EXT_UI_NAVIGATION_MENU,
|
||||
iPortalUIExtension::ENUM_PORTAL_EXT_UI_MAIN_CONTENT,
|
||||
);
|
||||
];
|
||||
|
||||
/** @var iPortalUIExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPortalUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
foreach (MetaModel::EnumPlugins('iPortalUIExtension') as $oExtensionInstance) {
|
||||
// Adding CSS files
|
||||
$aImportPaths = array($_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/');
|
||||
foreach ($oExtensionInstance->GetCSSFiles($this->oContainer) as $sCSSFile)
|
||||
{
|
||||
$aImportPaths = [$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/'];
|
||||
foreach ($oExtensionInstance->GetCSSFiles($this->oContainer) as $sCSSFile) {
|
||||
// Removing app root url as we need to pass a path on the file system (relative to app root)
|
||||
$sCSSFilePath = str_replace(utils::GetAbsoluteUrlAppRoot(), '', $sCSSFile);
|
||||
// Compiling SCSS file
|
||||
$sCSSFileCompiled = utils::GetAbsoluteUrlAppRoot().utils::GetCSSFromSASS($sCSSFilePath,
|
||||
$aImportPaths);
|
||||
$sCSSFileCompiled = utils::GetAbsoluteUrlAppRoot().utils::GetCSSFromSASS(
|
||||
$sCSSFilePath,
|
||||
$aImportPaths
|
||||
);
|
||||
|
||||
if (!in_array($sCSSFileCompiled, $aUIExtensions['css_files']))
|
||||
{
|
||||
if (!in_array($sCSSFileCompiled, $aUIExtensions['css_files'])) {
|
||||
$aUIExtensions['css_files'][] = $sCSSFileCompiled;
|
||||
}
|
||||
}
|
||||
|
||||
// Adding CSS inline
|
||||
$sCSSInline = $oExtensionInstance->GetCSSInline($this->oContainer);
|
||||
if ($sCSSInline !== null)
|
||||
{
|
||||
if ($sCSSInline !== null) {
|
||||
$aUIExtensions['css_inline'] .= "\n\n".$sCSSInline;
|
||||
}
|
||||
|
||||
// Adding JS files
|
||||
$aUIExtensions['js_files'] = array_merge($aUIExtensions['js_files'],
|
||||
$oExtensionInstance->GetJSFiles($this->oContainer));
|
||||
$aUIExtensions['js_files'] = array_merge(
|
||||
$aUIExtensions['js_files'],
|
||||
$oExtensionInstance->GetJSFiles($this->oContainer)
|
||||
);
|
||||
|
||||
// Adding JS inline
|
||||
$sJSInline = $oExtensionInstance->GetJSInline($this->oContainer);
|
||||
if ($sJSInline !== null)
|
||||
{
|
||||
if ($sJSInline !== null) {
|
||||
// Note: Semi-colon is to prevent previous script that would have omitted it.
|
||||
$aUIExtensions['js_inline'] .= "\n\n;\n".$sJSInline;
|
||||
}
|
||||
|
||||
// Adding HTML for each hook
|
||||
foreach ($aUIExtensionHooks as $sUIExtensionHook)
|
||||
{
|
||||
foreach ($aUIExtensionHooks as $sUIExtensionHook) {
|
||||
$sFunctionName = 'Get'.$sUIExtensionHook.'HTML';
|
||||
$sHTML = $oExtensionInstance->$sFunctionName($this->oContainer);
|
||||
if ($sHTML !== null)
|
||||
{
|
||||
if (!array_key_exists($sUIExtensionHook, $aUIExtensions['html']))
|
||||
{
|
||||
if ($sHTML !== null) {
|
||||
if (!array_key_exists($sUIExtensionHook, $aUIExtensions['html'])) {
|
||||
$aUIExtensions['html'][$sUIExtensionHook] = '';
|
||||
}
|
||||
$aUIExtensions['html'][$sUIExtensionHook] .= "\n\n".$sHTML;
|
||||
@@ -180,4 +171,4 @@ class UIExtensionsHelper
|
||||
|
||||
$this->aUIExtensions = $aUIExtensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -70,4 +71,4 @@ interface iAbstractPortalTabContentExtension
|
||||
* @since iTop 3.2.1
|
||||
*/
|
||||
public function GetSectionRank(): float;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -59,4 +60,4 @@ interface iAbstractPortalTabExtension
|
||||
* @since iTop 3.2.1
|
||||
*/
|
||||
public function GetTabLabel(): string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,5 +15,4 @@ namespace Combodo\iTop\Portal\Hook;
|
||||
*/
|
||||
interface iUserProfileTabContentExtension extends iAbstractPortalTabContentExtension
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,5 +15,4 @@ namespace Combodo\iTop\Portal\Hook;
|
||||
*/
|
||||
interface iUserProfileTabExtension extends iAbstractPortalTabExtension
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -37,8 +38,8 @@ class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
|
||||
/** @var string CONFIG_EXTS */
|
||||
const CONFIG_EXTS = '.{php,xml,yaml,yml}';
|
||||
/** @var string CONFIG_EXTS */
|
||||
public const CONFIG_EXTS = '.{php,xml,yaml,yml}';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
@@ -55,23 +56,23 @@ class Kernel extends BaseKernel
|
||||
*/
|
||||
public function getLogDir(): string
|
||||
{
|
||||
$logDir = $_ENV['PORTAL_ID'] . '-' . $this->environment;
|
||||
$logDir = $_ENV['PORTAL_ID'].'-'.$this->environment;
|
||||
|
||||
return utils::GetLogPath() . "/portals/$logDir";
|
||||
}
|
||||
return utils::GetLogPath()."/portals/$logDir";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Generator|iterable|\Symfony\Component\HttpKernel\Bundle\BundleInterface[]
|
||||
*/
|
||||
public function registerBundles(): iterable
|
||||
{
|
||||
$contents = require $this->getProjectDir().'/config/bundles.php';
|
||||
foreach ($contents as $class => $envs) {
|
||||
if (isset($envs[$this->environment]) || isset($envs['all'])) {
|
||||
yield new $class();
|
||||
}
|
||||
}
|
||||
}
|
||||
$contents = require $this->getProjectDir().'/config/bundles.php';
|
||||
foreach ($contents as $class => $envs) {
|
||||
if (isset($envs[$this->environment]) || isset($envs['all'])) {
|
||||
yield new $class();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator $container
|
||||
@@ -106,7 +107,6 @@ class Kernel extends BaseKernel
|
||||
$routes->import($confDir.'/{routes}'.self::CONFIG_EXTS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a given class name belongs to an active bundle.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -19,7 +20,6 @@
|
||||
|
||||
namespace Combodo\iTop\Portal\Routing;
|
||||
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
@@ -32,13 +32,13 @@ use Exception;
|
||||
class ItopExtensionsExtraRoutes
|
||||
{
|
||||
/** @var array $aRoutes */
|
||||
static private $aRoutes = array();
|
||||
private static $aRoutes = [];
|
||||
|
||||
/**
|
||||
* @var array $aControllersClasses
|
||||
* @since 3.1.0
|
||||
*/
|
||||
static private $aControllersClasses = array();
|
||||
private static $aControllersClasses = [];
|
||||
|
||||
/**
|
||||
* @param array $extraRoutes
|
||||
@@ -85,4 +85,4 @@ class ItopExtensionsExtraRoutes
|
||||
{
|
||||
return self::$aControllersClasses;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -117,4 +118,4 @@ class UrlGenerator implements RouterInterface
|
||||
|
||||
return $aParameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,8 +64,7 @@ class TemplateDefinitionDto
|
||||
private ?string $sPath = null,
|
||||
private readonly ?bool $bIsOverridable = false,
|
||||
private readonly ?string $sAlias = null,
|
||||
)
|
||||
{
|
||||
) {
|
||||
// save overridable values
|
||||
$this->sInitialValue = $sPath;
|
||||
}
|
||||
@@ -89,7 +88,7 @@ class TemplateDefinitionDto
|
||||
*/
|
||||
public function GetPath(bool $bInitialValue = false): string
|
||||
{
|
||||
if($bInitialValue){
|
||||
if ($bInitialValue) {
|
||||
return $this->sInitialValue !== null ? $this->sInitialValue : '';
|
||||
}
|
||||
|
||||
@@ -142,4 +141,4 @@ class TemplateDefinitionDto
|
||||
return $this->bIsOverridden;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,4 @@ interface TemplatesProviderInterface
|
||||
* @return void
|
||||
*/
|
||||
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,8 +275,7 @@ class TemplatesProviderService
|
||||
if ($oParent) {
|
||||
$sCurrentClass = $oReflexion->getParentClass()->getName();
|
||||
}
|
||||
}
|
||||
catch (Exception) {
|
||||
} catch (Exception) {
|
||||
}
|
||||
|
||||
} while ($oParent); // continue while parent class exists
|
||||
@@ -321,4 +320,4 @@ class TemplatesProviderService
|
||||
&& array_key_exists($sTemplateId, $this->aInstancesOverriddenTemplatesPaths[$sObjectId]['templates']));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,9 @@ namespace Combodo\iTop\Portal\Service\TemplatesProvider;
|
||||
*/
|
||||
class TemplatesRegister
|
||||
{
|
||||
|
||||
/** @var array Templates definitions (possibly altered by portal configuration) */
|
||||
private array $aTemplatesDefinitions = [];
|
||||
|
||||
|
||||
public function __construct(private string $sTemplateUIVersion = 'unset')
|
||||
{
|
||||
|
||||
@@ -118,7 +116,7 @@ class TemplatesRegister
|
||||
*/
|
||||
public function GetProviderTemplatesIds(string $sProviderId): array
|
||||
{
|
||||
return array_map(fn($oTemplateDefinition) => $oTemplateDefinition->GetId(), $this->aTemplatesDefinitions[$sProviderId] ?? ['tile', 'page']);
|
||||
return array_map(fn ($oTemplateDefinition) => $oTemplateDefinition->GetId(), $this->aTemplatesDefinitions[$sProviderId] ?? ['tile', 'page']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,4 +128,4 @@ class TemplatesRegister
|
||||
{
|
||||
return $this->aTemplatesDefinitions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -22,7 +23,6 @@ namespace Combodo\iTop\Portal\Twig;
|
||||
use Combodo\iTop\Application\TwigBase\Twig\Extension;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
|
||||
|
||||
/**
|
||||
* Class AppExtension
|
||||
*
|
||||
@@ -50,4 +50,4 @@ class AppExtension extends AbstractExtension
|
||||
{
|
||||
return Extension::GetFunctions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -54,10 +55,10 @@ class AppGlobal extends AbstractExtension implements GlobalsInterface
|
||||
*/
|
||||
public function getGlobals(): array
|
||||
{
|
||||
$data = array();
|
||||
$data = [];
|
||||
$data['allowed_portals'] = $this->userProvider->getAllowedPortals();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -33,93 +34,92 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*/
|
||||
class AppVariable implements ArrayAccess
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
private $container;
|
||||
/** @var ContainerInterface */
|
||||
private $container;
|
||||
|
||||
/** @var DecoratedAppVariable */
|
||||
private $decorated;
|
||||
/** @var DecoratedAppVariable */
|
||||
private $decorated;
|
||||
|
||||
public function __construct(DecoratedAppVariable $decorated, ContainerInterface $container = null)
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function __construct(DecoratedAppVariable $decorated, ContainerInterface $container = null)
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
$this->container = $container;
|
||||
}
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if ($this->silexApplicationEmulation->offsetExists($name)) {
|
||||
return $this->silexApplicationEmulation->offsetGet($name);
|
||||
}
|
||||
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if ($this->silexApplicationEmulation->offsetExists($name)) {
|
||||
return $this->silexApplicationEmulation->offsetGet($name);
|
||||
}
|
||||
return $this->decorated->$name(...$arguments); //WARNING: use of http://php.net/manual/fr/functions.arguments.php#functions.variable-arg-list
|
||||
}
|
||||
|
||||
return $this->decorated->$name(...$arguments); //WARNING: use of http://php.net/manual/fr/functions.arguments.php#functions.variable-arg-list
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
return true;
|
||||
}
|
||||
if ($this->container->has($offset)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
return true;
|
||||
}
|
||||
if ($this->container->has($offset)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
return $this->container->getParameter($offset);
|
||||
}
|
||||
if ($this->container->has($offset)) {
|
||||
return $this->container->get($offset);
|
||||
}
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
return $this->container->getParameter($offset);
|
||||
}
|
||||
if ($this->container->has($offset)) {
|
||||
return $this->container->get($offset);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
$this->container->setParameter($offset, $value);
|
||||
return;
|
||||
}
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
$this->container->setParameter($offset, $value);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->container->has($offset)) {
|
||||
$this->container->set($offset, $value);
|
||||
return;
|
||||
}
|
||||
if ($this->container->has($offset)) {
|
||||
$this->container->set($offset, $value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
$this->container->set($offset, $value);
|
||||
return;
|
||||
}
|
||||
if (is_object($value)) {
|
||||
$this->container->set($offset, $value);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->container->setParameter($offset, $value);
|
||||
}
|
||||
$this->container->setParameter($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
$this->container->setParameter($offset, null);
|
||||
} else if ($this->container->has($offset)) {
|
||||
$this->container->set($offset, null);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
if ($this->container->hasParameter($offset)) {
|
||||
$this->container->setParameter($offset, null);
|
||||
} elseif ($this->container->has($offset)) {
|
||||
$this->container->set($offset, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
@@ -35,7 +36,7 @@ use Twig\TwigFunction;
|
||||
class CKEditorExtension extends AbstractExtension
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function getFunctions() : array
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
new TwigFunction('inject_ckeditor_resources', [$this, 'injectCKEditorResources']),
|
||||
@@ -48,17 +49,17 @@ class CKEditorExtension extends AbstractExtension
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function injectCKEditorResources() : string
|
||||
public function injectCKEditorResources(): string
|
||||
{
|
||||
$sScriptTemplate = '';
|
||||
$aJSFilesRelPaths = CKEditorHelper::GetJSFilesRelPathsForCKEditor();
|
||||
|
||||
foreach ($aJSFilesRelPaths as $sJSFileRelPath){
|
||||
$sUrl = \utils::GetAbsoluteUrlAppRoot() . $sJSFileRelPath;
|
||||
foreach ($aJSFilesRelPaths as $sJSFileRelPath) {
|
||||
$sUrl = \utils::GetAbsoluteUrlAppRoot().$sJSFileRelPath;
|
||||
$sUrl = \utils::AddParameterToUrl($sUrl, 't', \utils::GetCacheBusterTimestamp());
|
||||
$sScriptTemplate .= '<script type="text/javascript" src="' . $sUrl . '"></script>';
|
||||
$sScriptTemplate .= '<script type="text/javascript" src="'.$sUrl.'"></script>';
|
||||
}
|
||||
|
||||
return $sScriptTemplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -70,4 +71,4 @@ class CurrentUserAccessor
|
||||
{
|
||||
return $this->userProvider->getCurrentUserCanLogOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -34,7 +35,7 @@ class PortalBlockExtension
|
||||
*
|
||||
* @since iTop 3.2.1
|
||||
*/
|
||||
function __construct(string $sTwig, array $aData = [])
|
||||
public function __construct(string $sTwig, array $aData = [])
|
||||
{
|
||||
$this->sTwig = $sTwig;
|
||||
$this->aData = $aData;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -16,7 +17,6 @@ namespace Combodo\iTop\Portal\Twig;
|
||||
*/
|
||||
class PortalTwigContext
|
||||
{
|
||||
|
||||
private array $aBlockExtension;
|
||||
|
||||
public function __construct()
|
||||
@@ -35,7 +35,7 @@ class PortalTwigContext
|
||||
*
|
||||
* @since iTop 3.2.1
|
||||
*/
|
||||
function AddBlockExtension(string $sBlockName, PortalBlockExtension $oBlockExtension): void
|
||||
public function AddBlockExtension(string $sBlockName, PortalBlockExtension $oBlockExtension): void
|
||||
{
|
||||
$this->aBlockExtension[$sBlockName] = $oBlockExtension;
|
||||
}
|
||||
@@ -58,4 +58,4 @@ class PortalTwigContext
|
||||
$oBlockExtension = $this->aBlockExtension[$sBlockName] ?? null;
|
||||
return $oBlockExtension;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
@@ -31,7 +32,7 @@ use Twig\TwigFunction;
|
||||
*/
|
||||
class TemplatesTwigExtension extends AbstractExtension
|
||||
{
|
||||
const DEFAULT_PROVIDER_CLASS = 'Combodo\\iTop\\Portal\\Controller\\AbstractController';
|
||||
public const DEFAULT_PROVIDER_CLASS = 'Combodo\\iTop\\Portal\\Controller\\AbstractController';
|
||||
|
||||
public function __construct(private readonly TemplatesProviderService $oTemplatesService)
|
||||
{
|
||||
@@ -78,4 +79,4 @@ class TemplatesTwigExtension extends AbstractExtension
|
||||
{
|
||||
return $this->oTemplatesService->GetTemplatePath($sProviderClass, $sId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ use utils;
|
||||
abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker
|
||||
{
|
||||
/** @var string PORTAL_ID */
|
||||
const PORTAL_ID = '';
|
||||
public const PORTAL_ID = '';
|
||||
|
||||
/** @var \Combodo\iTop\Portal\Kernel[] $aKernels */
|
||||
private static $aKernels = array();
|
||||
private static $aKernels = [];
|
||||
|
||||
/**
|
||||
* Generate an (absolute) URL to an object, either in view or edit mode.
|
||||
@@ -64,8 +64,7 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker
|
||||
|
||||
$sUrl = self::DoPrepareObjectURL($sClass, $iId, $sMode);
|
||||
|
||||
if (!empty($sPreviousPortalId))
|
||||
{
|
||||
if (!empty($sPreviousPortalId)) {
|
||||
$_ENV['PORTAL_ID'] = $sPreviousPortalId;
|
||||
}
|
||||
|
||||
@@ -97,48 +96,39 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker
|
||||
//
|
||||
// Note: Scopes only apply when URL check is triggered from the portal GUI.
|
||||
$sObjectQueryString = null;
|
||||
switch ($sMode)
|
||||
{
|
||||
switch ($sMode) {
|
||||
case 'view':
|
||||
if (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId))
|
||||
{
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId));
|
||||
if (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId)) {
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_view', ['sObjectClass' => $sClass, 'sObjectId' => $iId]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
default:
|
||||
// Checking if user is allowed to edit object, if not we check if it can at least view it.
|
||||
if (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sClass, $iId))
|
||||
{
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_edit', array('sObjectClass' => $sClass, 'sObjectId' => $iId));
|
||||
}
|
||||
elseif (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId))
|
||||
{
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId));
|
||||
if (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sClass, $iId)) {
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_edit', ['sObjectClass' => $sClass, 'sObjectId' => $iId]);
|
||||
} elseif (!ContextTag::Check(ContextTag::TAG_PORTAL) || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId)) {
|
||||
$sObjectQueryString = $oUrlGenerator->generate('p_object_view', ['sObjectClass' => $sClass, 'sObjectId' => $iId]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$sPortalAbsoluteUrl = utils::GetAbsoluteUrlModulePage('itop-portal-base', 'index.php', array('portal_id' => $sPortalId));
|
||||
if ($sObjectQueryString === null)
|
||||
{
|
||||
$sPortalAbsoluteUrl = utils::GetAbsoluteUrlModulePage('itop-portal-base', 'index.php', ['portal_id' => $sPortalId]);
|
||||
if ($sObjectQueryString === null) {
|
||||
$sUrl = null;
|
||||
}
|
||||
elseif (strpos($sPortalAbsoluteUrl, '?') !== false)
|
||||
{
|
||||
} elseif (strpos($sPortalAbsoluteUrl, '?') !== false) {
|
||||
// Removing generated url query parameters so it can be replaced with those from the absolute url
|
||||
// Mostly necessary when iTop instance has multiple portals
|
||||
if (strpos($sObjectQueryString, '?') !== false)
|
||||
{
|
||||
if (strpos($sObjectQueryString, '?') !== false) {
|
||||
$sObjectQueryString = substr($sObjectQueryString, 0, strpos($sObjectQueryString, '?'));
|
||||
}
|
||||
|
||||
$sUrl = substr($sPortalAbsoluteUrl, 0, strpos($sPortalAbsoluteUrl, '?')).$sObjectQueryString.substr($sPortalAbsoluteUrl,
|
||||
strpos($sPortalAbsoluteUrl, '?'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUrl = substr($sPortalAbsoluteUrl, 0, strpos($sPortalAbsoluteUrl, '?')).$sObjectQueryString.substr(
|
||||
$sPortalAbsoluteUrl,
|
||||
strpos($sPortalAbsoluteUrl, '?')
|
||||
);
|
||||
} else {
|
||||
$sUrl = $sPortalAbsoluteUrl.$sObjectQueryString;
|
||||
}
|
||||
|
||||
@@ -153,8 +143,7 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker
|
||||
*/
|
||||
private static function GetKernelInstance()
|
||||
{
|
||||
if (!array_key_exists(static::PORTAL_ID, self::$aKernels))
|
||||
{
|
||||
if (!array_key_exists(static::PORTAL_ID, self::$aKernels)) {
|
||||
self::$aKernels[static::PORTAL_ID] = new Kernel($_SERVER['APP_ENV'], (bool)$_SERVER['APP_DEBUG']);
|
||||
self::$aKernels[static::PORTAL_ID]->boot();
|
||||
}
|
||||
@@ -175,4 +164,3 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker
|
||||
return static::PrepareObjectURL($sClass, $iId, 'edit');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -34,4 +35,4 @@ abstract class AbstractStringVariableAccessor extends AbstractVariableAccessor
|
||||
{
|
||||
return $this->getVariable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -27,22 +28,22 @@ namespace Combodo\iTop\Portal\VariableAccessor;
|
||||
*/
|
||||
abstract class AbstractVariableAccessor
|
||||
{
|
||||
/** @var string $storedVariable */
|
||||
private $storedVariable;
|
||||
/** @var string $storedVariable */
|
||||
private $storedVariable;
|
||||
|
||||
/**
|
||||
* @param string $variableToStore
|
||||
*/
|
||||
public function __construct($variableToStore)
|
||||
{
|
||||
$this->storedVariable = $variableToStore;
|
||||
}
|
||||
/**
|
||||
* @param string $variableToStore
|
||||
*/
|
||||
public function __construct($variableToStore)
|
||||
{
|
||||
$this->storedVariable = $variableToStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getVariable()
|
||||
{
|
||||
return $this->storedVariable;
|
||||
}
|
||||
}
|
||||
public function getVariable()
|
||||
{
|
||||
return $this->storedVariable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -19,7 +20,6 @@
|
||||
|
||||
namespace Combodo\iTop\Portal\VariableAccessor;
|
||||
|
||||
|
||||
use Combodo\iTop\Portal\EventListener\UserProvider;
|
||||
use Exception;
|
||||
use MetaModel;
|
||||
@@ -85,8 +85,7 @@ class CombodoCurrentContactPhotoUrl
|
||||
try {
|
||||
/** @var \cmdbAbstractObject $oContact */
|
||||
$oContact = UserRights::GetContactObject();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$oUser = $this->oUserProvider->getCurrentUser();
|
||||
$oAllowedOrgSet = $oUser->Get('allowed_org_list');
|
||||
if ($oAllowedOrgSet->Count() > 0) {
|
||||
@@ -118,4 +117,4 @@ class CombodoCurrentContactPhotoUrl
|
||||
|
||||
return $sContactPhotoUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -28,5 +29,4 @@ namespace Combodo\iTop\Portal\VariableAccessor;
|
||||
*/
|
||||
class CombodoPortalInstanceConf extends AbstractVariableAccessor
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user