mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 23:44:11 +01:00
Compare commits
12 Commits
issue/3.2-
...
feature/56
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9400b697eb | ||
|
|
e1807f598f | ||
|
|
02e63fff64 | ||
|
|
c8fade6013 | ||
|
|
ad052dd861 | ||
|
|
a5ea868609 | ||
|
|
0b03b3ef4d | ||
|
|
174cace20a | ||
|
|
e3f5dbfc80 | ||
|
|
c6e4466c53 | ||
|
|
6638eb4adc | ||
|
|
eb40968e34 |
@@ -1238,6 +1238,14 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'navigation_menu.show_organization_filter' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'Display organization filter in menu',
|
||||
'default' => true,
|
||||
'value' => true,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'quick_create.enabled' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'Whether or not the quick create is enabled',
|
||||
@@ -1861,7 +1869,7 @@ class Config
|
||||
}
|
||||
if (strlen($sNoise) > 0)
|
||||
{
|
||||
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
|
||||
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
|
||||
throw new ConfigException('Syntax error in configuration file',
|
||||
array('file' => $sConfigFile, 'error' => '<tt>'.htmlentities($sNoise, ENT_QUOTES, 'UTF-8').'</tt>'));
|
||||
}
|
||||
@@ -2671,7 +2679,7 @@ class ConfigPlaceholdersResolver
|
||||
}
|
||||
|
||||
$sPattern = '/\%(env|server)\((\w+)\)(?:\?:(\w*))?\%/'; //3 capturing groups, ie `%env(HTTP_PORT)?:8080%` produce: `env` `HTTP_PORT` and `8080`.
|
||||
|
||||
|
||||
if (! preg_match_all($sPattern, $rawValue, $aMatchesCollection, PREG_SET_ORDER))
|
||||
{
|
||||
return $rawValue;
|
||||
|
||||
@@ -139,55 +139,58 @@ JS
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$oFavoriteOrganizationsBlock = new Panel(Dict::S('UI:FavoriteOrganizations'), array(), 'grey', 'ibo-favorite-organizations');
|
||||
$oFavoriteOrganizationsBlock->SetSubTitle(Dict::S('UI:FavoriteOrganizations+'));
|
||||
$oFavoriteOrganizationsBlock->AddCSSClass('ibo-datatable-panel');
|
||||
$oFavoriteOrganizationsForm = new Form();
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oFavoriteOrganizationsForm);
|
||||
// Favorite organizations: the organizations listed in the drop-down menu
|
||||
$sOQL = ApplicationMenu::GetFavoriteSiloQuery();
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$bIsSiloSelectionEnabled = MetaModel::GetConfig()->Get('navigation_menu.show_organization_filter');
|
||||
if ($bIsSiloSelectionEnabled)
|
||||
{
|
||||
$oFavoriteOrganizationsBlock = new Panel(Dict::S('UI:FavoriteOrganizations'), array(), 'grey', 'ibo-favorite-organizations');
|
||||
$oFavoriteOrganizationsBlock->SetSubTitle(Dict::S('UI:FavoriteOrganizations+'));
|
||||
$oFavoriteOrganizationsBlock->AddCSSClass('ibo-datatable-panel');
|
||||
$oFavoriteOrganizationsForm = new Form();
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oFavoriteOrganizationsForm);
|
||||
// Favorite organizations: the organizations listed in the drop-down menu
|
||||
$sOQL = ApplicationMenu::GetFavoriteSiloQuery();
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
|
||||
$aFavoriteOrgs = appUserPreferences::GetPref('favorite_orgs', null);
|
||||
$aFavoriteOrgs = appUserPreferences::GetPref('favorite_orgs', null);
|
||||
|
||||
$sIdFavoriteOrganizations = 1;
|
||||
$oFavoriteOrganizationsForm->AddSubBlock($oBlock->GetDisplay($oP, $sIdFavoriteOrganizations, [
|
||||
'menu' => false,
|
||||
'selection_mode' => true,
|
||||
'selection_type' => 'multiple',
|
||||
'table_id' => 'user_prefs',
|
||||
'surround_with_panel' => false,
|
||||
'selected_rows' => $aFavoriteOrgs,
|
||||
]));
|
||||
$oFavoriteOrganizationsForm->AddSubBlock($oAppContext->GetForFormBlock());
|
||||
$sIdFavoriteOrganizations = 1;
|
||||
$oFavoriteOrganizationsForm->AddSubBlock($oBlock->GetDisplay($oP, $sIdFavoriteOrganizations, [
|
||||
'menu' => false,
|
||||
'selection_mode' => true,
|
||||
'selection_type' => 'multiple',
|
||||
'table_id' => 'user_prefs',
|
||||
'surround_with_panel' => false,
|
||||
'selected_rows' => $aFavoriteOrgs,
|
||||
]));
|
||||
$oFavoriteOrganizationsForm->AddSubBlock($oAppContext->GetForFormBlock());
|
||||
|
||||
// Button toolbar
|
||||
$oFavoriteOrganizationsToolBar = ToolbarUIBlockFactory::MakeForButton(null, ['ibo-is-fullwidth']);
|
||||
$oFavoriteOrganizationsForm->AddSubBlock($oFavoriteOrganizationsToolBar);
|
||||
// Button toolbar
|
||||
$oFavoriteOrganizationsToolBar = ToolbarUIBlockFactory::MakeForButton(null, ['ibo-is-fullwidth']);
|
||||
$oFavoriteOrganizationsForm->AddSubBlock($oFavoriteOrganizationsToolBar);
|
||||
|
||||
// - Cancel button
|
||||
$oFavoriteOrganizationsCancelButton = ButtonUIBlockFactory::MakeForCancel(Dict::S('UI:Button:Cancel'));
|
||||
$oFavoriteOrganizationsToolBar->AddSubBlock($oFavoriteOrganizationsCancelButton);
|
||||
$oFavoriteOrganizationsCancelButton->SetOnClickJsCode("window.location.href = '$sURL'");
|
||||
// - Submit button
|
||||
$oFavoriteOrganizationsSubmitButton = ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Apply'), 'operation', 'apply', true);
|
||||
$oFavoriteOrganizationsToolBar->AddSubBlock($oFavoriteOrganizationsSubmitButton);
|
||||
// - Cancel button
|
||||
$oFavoriteOrganizationsCancelButton = ButtonUIBlockFactory::MakeForCancel(Dict::S('UI:Button:Cancel'));
|
||||
$oFavoriteOrganizationsToolBar->AddSubBlock($oFavoriteOrganizationsCancelButton);
|
||||
$oFavoriteOrganizationsCancelButton->SetOnClickJsCode("window.location.href = '$sURL'");
|
||||
// - Submit button
|
||||
$oFavoriteOrganizationsSubmitButton = ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Apply'), 'operation', 'apply', true);
|
||||
$oFavoriteOrganizationsToolBar->AddSubBlock($oFavoriteOrganizationsSubmitButton);
|
||||
|
||||
// TODO 3.0 have this code work again, currently it prevents the display of favorite organizations and shortcuts.
|
||||
// if ($aFavoriteOrgs == null) {
|
||||
// // All checked
|
||||
// $oP->add_ready_script(
|
||||
// <<<JS
|
||||
// $('#$sIdFavoriteOrganizations.checkAll').prop('checked', true);
|
||||
// checkAllDataTable('datatable_$sIdFavoriteOrganizations',true,'$sIdFavoriteOrganizations');
|
||||
//JS
|
||||
// );
|
||||
//
|
||||
// }
|
||||
|
||||
$oContentLayout->AddMainBlock($oFavoriteOrganizationsBlock);
|
||||
// TODO 3.0 have this code work again, currently it prevents the display of favorite organizations and shortcuts.
|
||||
// if ($aFavoriteOrgs == null) {
|
||||
// // All checked
|
||||
// $oP->add_ready_script(
|
||||
// <<<JS
|
||||
// $('#$sIdFavoriteOrganizations.checkAll').prop('checked', true);
|
||||
// checkAllDataTable('datatable_$sIdFavoriteOrganizations',true,'$sIdFavoriteOrganizations');
|
||||
//JS
|
||||
// );
|
||||
//
|
||||
// }
|
||||
|
||||
$oContentLayout->AddMainBlock($oFavoriteOrganizationsBlock);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shortcuts
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\NavigationMenu;
|
||||
|
||||
|
||||
use ApplicationContext;
|
||||
use ApplicationMenu;
|
||||
use appUserPreferences;
|
||||
@@ -196,7 +195,7 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -290,6 +289,14 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the silo selection is enabled, false otherwise
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public function IsSiloSelectionEnabled() : bool {
|
||||
return MetaModel::GetConfig()->Get('navigation_menu.show_organization_filter');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
@@ -301,6 +308,10 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
|
||||
$this->bHasSiloSelected = false;
|
||||
$this->sSiloLabel = null;
|
||||
|
||||
if (! $this->IsSiloSelectionEnabled()){
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO 3.0 Use components if we have the time to build select/autocomplete components before release
|
||||
// List of visible Organizations
|
||||
$iCount = 0;
|
||||
@@ -343,7 +354,7 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
|
||||
$this->aSiloSelection['html'] = '<form data-role="ibo-navigation-menu--silo-selection--form" action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">';
|
||||
|
||||
$oPage = new \CaptureWebPage();
|
||||
|
||||
|
||||
$oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true /* search mode */);
|
||||
$iMaxComboLength = MetaModel::GetConfig()->Get('max_combo_length');
|
||||
$this->aSiloSelection['html'] .= $oWidget->DisplaySelect($oPage, $iMaxComboLength, false, Dict::S('UI:Layout:NavigationMenu:Silo:Label'), $oSet, $iCurrentOrganization, false, 'c[org_id]', '',
|
||||
@@ -376,7 +387,7 @@ $sAddClearButton
|
||||
JS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute if the menu is expanded or collapsed
|
||||
*
|
||||
@@ -479,4 +490,4 @@ JS;
|
||||
{
|
||||
return "[data-role='".static::BLOCK_CODE."']";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,10 +410,25 @@ class ItopDataTestCase extends ItopTestCase
|
||||
* @param string $sLogin
|
||||
* @param int $iProfileId
|
||||
*
|
||||
* @return \DBObject
|
||||
* @return \UserLocal
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function CreateUser($sLogin, $iProfileId, $sPassword=null, $iContactid=2)
|
||||
{
|
||||
$oUser = $this->CreateContactlessUser($sLogin, $iProfileId, $sPassword);
|
||||
$oUser->Set('contactid', $iContactid);
|
||||
$oUser->DBWrite();
|
||||
return $oUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sLogin
|
||||
* @param int $iProfileId
|
||||
*
|
||||
* @return \UserLocal
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function CreateContactlessUser($sLogin, $iProfileId, $sPassword=null)
|
||||
{
|
||||
if (empty($sPassword)){
|
||||
$sPassword = $sLogin;
|
||||
@@ -423,8 +438,8 @@ class ItopDataTestCase extends ItopTestCase
|
||||
$oUserProfile->Set('profileid', $iProfileId);
|
||||
$oUserProfile->Set('reason', 'UNIT Tests');
|
||||
$oSet = DBObjectSet::FromObject($oUserProfile);
|
||||
/** @var \UserLocal $oUser */
|
||||
$oUser = $this->createObject('UserLocal', array(
|
||||
'contactid' => $iContactid,
|
||||
'login' => $sLogin,
|
||||
'password' => $sPassword,
|
||||
'language' => 'EN US',
|
||||
|
||||
67
test/application/UI/Base/Layout/NavigationMenuTest.php
Normal file
67
test/application/UI/Base/Layout/NavigationMenuTest.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace UI\Base\Layout;
|
||||
|
||||
use ApplicationContext;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\NavigationMenu\NavigationMenu;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
* @backupGlobals disabled
|
||||
* Class NavigationMenuTest
|
||||
*
|
||||
* @package UI\Base\Layout
|
||||
*/
|
||||
class NavigationMenuTest extends ItopDataTestCase {
|
||||
public function IsAllowedProvider(){
|
||||
return [
|
||||
'show menu' => [ true ],
|
||||
'hide menu' => [ false ],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider IsAllowedProvider
|
||||
* test used to make sure backward compatibility is ensured
|
||||
*/
|
||||
public function testIsAllowed($bExpectedIsAllowed=true){
|
||||
\MetaModel::GetConfig()->Set('navigation_menu.show_organization_filter', $bExpectedIsAllowed);
|
||||
$oNavigationMenu = new NavigationMenu(
|
||||
$this->createMock(ApplicationContext::class),
|
||||
$this->createMock(PopoverMenu::class));
|
||||
|
||||
$isAllowed = $oNavigationMenu->IsSiloSelectionEnabled();
|
||||
$this->assertEquals($bExpectedIsAllowed, $isAllowed);
|
||||
}
|
||||
|
||||
public function testIsAllowed_BackwardCompatibility_NoVariableInConfFile(){
|
||||
\MetaModel::GetConfig()->Set('navigation_menu.show_organization_filter', false);
|
||||
|
||||
$sTmpFilePath = tempnam(sys_get_temp_dir(), 'test_');
|
||||
$oInitConfig = \MetaModel::GetConfig();
|
||||
$oInitConfig->WriteToFile($sTmpFilePath);
|
||||
|
||||
//remove variable for the test
|
||||
$aLines = file($sTmpFilePath);
|
||||
|
||||
$aRows = array();
|
||||
|
||||
foreach ($aLines as $key => $sLine) {
|
||||
if (!preg_match('/navigation_menu.show_organization_filter/', $sLine)) {
|
||||
$aRows[] = $sLine;
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($sTmpFilePath, implode("\n", $aRows));
|
||||
$oTempConfig = new \Config($sTmpFilePath);
|
||||
|
||||
$isAllowed = $oTempConfig->Get('navigation_menu.show_organization_filter');
|
||||
|
||||
$this->assertEquals(true, $isAllowed);
|
||||
unlink($sTmpFilePath);
|
||||
}
|
||||
}
|
||||
@@ -108,8 +108,8 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
$sAdminLogin = "admin-user-".$sUid;
|
||||
$sImpersonatedLogin = "impersonated-user-".$sUid;
|
||||
|
||||
$iAdminUserId = $this->CreateUserForImpersonation($sAdminLogin, 'Administrator', 'AdminName', 'AdminSurName');
|
||||
$this->CreateUserForImpersonation($sImpersonatedLogin, 'Configuration Manager', 'ImpersonatedName', 'ImpersonatedSurName');
|
||||
$oAdminUser = $this->CreateUserForImpersonation($sAdminLogin, 'Administrator', 'AdminName', 'AdminSurName');
|
||||
$oImpersonatedUser = $this->CreateUserForImpersonation($sImpersonatedLogin, 'Configuration Manager', 'ImpersonatedName', 'ImpersonatedSurName');
|
||||
|
||||
$_SESSION = [];
|
||||
\UserRights::Login($sAdminLogin);
|
||||
@@ -124,28 +124,31 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
if (is_null($sTrackInfo)){
|
||||
CMDBObject::SetTrackInfo(null);
|
||||
} else {
|
||||
$sTrackInfo = $this->ReplaceByFriendlyNames($sTrackInfo, $oAdminUser, $oImpersonatedUser);
|
||||
CMDBObject::SetTrackInfo($sTrackInfo);
|
||||
}
|
||||
|
||||
$this->CreateSimpleObject();
|
||||
if (is_null($sTrackInfo)){
|
||||
self::assertEquals("AdminSurName AdminName", CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
self::assertEquals($oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
} else {
|
||||
self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
}
|
||||
self::assertEquals($iAdminUserId, CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
self::assertEquals($oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : admin userid');
|
||||
|
||||
\UserRights::Impersonate($sImpersonatedLogin);
|
||||
$this->CreateSimpleObject();
|
||||
|
||||
if (is_null($sExpectedChangeLogWhenImpersonation)){
|
||||
self::assertEquals("AdminSurName AdminName on behalf of ImpersonatedSurName ImpersonatedName", CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
$sExpectedMsg = $this->ReplaceByFriendlyNames("AdminSurName AdminName on behalf of ImpersonatedSurName ImpersonatedName", $oAdminUser, $oImpersonatedUser);
|
||||
self::assertEquals($sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : impersonation');
|
||||
} else {
|
||||
self::assertEquals($sExpectedChangeLogWhenImpersonation, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
$sExpectedMsg = $this->ReplaceByFriendlyNames($sExpectedChangeLogWhenImpersonation, $oAdminUser, $oImpersonatedUser);
|
||||
self::assertEquals($sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : impersonation');
|
||||
}
|
||||
|
||||
@@ -155,13 +158,13 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
\UserRights::Deimpersonate();
|
||||
$this->CreateSimpleObject();
|
||||
if (is_null($sTrackInfo)){
|
||||
self::assertEquals("AdminSurName AdminName", CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
self::assertEquals($oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
} else {
|
||||
self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'),
|
||||
'TrackInfo : no impersonation');
|
||||
}
|
||||
self::assertEquals($iAdminUserId, CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
self::assertEquals($oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'),
|
||||
'TrackInfo : admin userid');
|
||||
|
||||
// restore initial conditions
|
||||
@@ -169,6 +172,12 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
CMDBObject::SetTrackInfo($sInitialTrackInfo);
|
||||
}
|
||||
|
||||
private function ReplaceByFriendlyNames($sMessage, $oAdminUser, $oImpersonatedUser) : string {
|
||||
$sNewMessage = str_replace('AdminSurName AdminName', $oAdminUser->GetFriendlyName(), $sMessage);
|
||||
$sNewMessage = str_replace('ImpersonatedSurName ImpersonatedName', $oImpersonatedUser->GetFriendlyName(), $sNewMessage);
|
||||
return $sNewMessage;
|
||||
}
|
||||
|
||||
private function CreateSimpleObject(){
|
||||
/** @var \DocumentWeb $oTestObject */
|
||||
$oTestObject = MetaModel::NewObject('DocumentWeb');
|
||||
@@ -178,7 +187,7 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
$oTestObject->DBWrite();
|
||||
}
|
||||
|
||||
private function CreateUserForImpersonation($sLogin, $sProfileName, $sName, $sSurname): int {
|
||||
private function CreateUserForImpersonation($sLogin, $sProfileName, $sName, $sSurname): \UserLocal {
|
||||
/** @var \Person $oPerson */
|
||||
$oPerson = $this->createObject('Person', array(
|
||||
'name' => $sName,
|
||||
@@ -187,8 +196,9 @@ class CMDBObjectTest extends ItopDataTestCase
|
||||
));
|
||||
|
||||
$oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => $sProfileName), true);
|
||||
/** @var \UserLocal $oUser */
|
||||
$oUser = $this->CreateUser($sLogin, $oProfile->GetKey(), "1234567Azert@", $oPerson->GetKey());
|
||||
|
||||
return $oUser->GetKey();
|
||||
return $oUser;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user