Merge branch 'develop' into release/3.1.0-beta

This commit is contained in:
Pierre Goiffon
2023-06-16 10:47:37 +02:00
11 changed files with 81 additions and 42 deletions

View File

@@ -2904,7 +2904,8 @@ HTML;
if ($sClassNameFilter !== '' && strpos($sPHPClass, $sClassNameFilter) === false) {
$bSkipped = true;
}
else {
// For some PHP classes we don't have their file path as they are already in memory, so we never filter on their paths
elseif (utils::IsNotNullOrEmptyString($sPHPFile)) {
$sPHPFile = self::LocalPath($sPHPFile);
if ($sPHPFile !== false) {
$sPHPFile = '/'.$sPHPFile; // for regex

View File

@@ -3,7 +3,7 @@
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
@@ -58,6 +58,16 @@ class ContextTag
public const TAG_SETUP = 'Setup';
public const TAG_SYNCHRO = 'Synchro';
public const TAG_REST = 'REST/JSON';
/**
* @since 3.1.0 N°6047
*/
public const TAG_IMPORT = 'Import';
/**
* @since 3.1.0 N°6047
*/
public const TAG_EXPORT = 'Export';
/**
* @var string
* @since 3.1.0 N°3200
@@ -75,7 +85,7 @@ class ContextTag
{
static::$aStack[] = $sTag;
}
public static function AddContext($sTag)
{
static::$aStack[] = $sTag;

View File

@@ -1230,7 +1230,9 @@ class DeprecatedCallsLog extends LogAPI
}
/**
* @throws \ConfigException
* @since 3.0.1 3.1.0 N°4725 silently handles ConfigException
* @since 3.0.4 3.1.0 N°4725 remove forgotten throw PHPDoc annotation
*
* @link https://www.php.net/debug_backtrace
* @uses \debug_backtrace()
*/

View File

@@ -205,6 +205,16 @@ class Set extends AbstractInput
return $this;
}
/**
* HasAddOptionButtonJsOnClick.
*
* @return bool
*/
public function HasAddOptionButtonJsOnClick(): bool
{
return $this->sAddOptionButtonJsOnClick != null;
}
/**
* GetAddOptionButtonJsOnClick.
*

View File

@@ -412,23 +412,23 @@ JS
<<<JS
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").portal_form_field({
'validators': {$this->GetValidatorsAsJson()},
'on_validation_callback': function(){
const aLinkedSetInputs = $('#{$sFieldWrapperId} input,select,textarea', this.element);
'on_validation_callback': function(oFormField){
const aLinkedSetInputs = $('#{$sFieldWrapperId} input,select,textarea', oFormField.element);
aLinkedSetInputs.each(function(e){
const oInput = $(this);
const aInputValidity = oInput[0].validity;
const oFormField = oInput.closest('.form_field_control');
const oFormFieldControl = oInput.closest('.form_field_control');
if(aInputValidity.valueMissing){
oFormField.toggleClass('has-error', true);
$('.help-block', oFormField).html('$aErrorMessagesMandatory');
oFormFieldControl.toggleClass('has-error', true);
$('.help-block', oFormFieldControl).html('$aErrorMessagesMandatory');
}
else if(aInputValidity.patternMismatch){
oFormField.toggleClass('has-error', true);
$('.help-block', oFormField).html('$aErrorMessagesDefault');
oFormFieldControl.toggleClass('has-error', true);
$('.help-block', oFormFieldControl).html('$aErrorMessagesDefault');
}
else{
oFormField.toggleClass('has-error', false);
$('.help-block', oFormField).empty();
oFormFieldControl.toggleClass('has-error', false);
$('.help-block', oFormFieldControl).empty();
}
});
},

View File

@@ -19,7 +19,7 @@ let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
plugins: {
{# PLUGIN update operations #}
'combodo_update_operations' : {
initial: {{ oUIBlock.GetInitialValue()|raw }},
initial: {{ oUIBlock.GetInitialValue()|raw }}
},
{# PLUGIN combodo auto position #}
'combodo_auto_position' : {
@@ -42,7 +42,7 @@ let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
tooltip_links_will_be_deleted_from_x_objects: '{{ 'UI:Links:Bulk:LinkWillBeDeletedFromXObjects'|dict_s }}',
tooltip_links_exist_for_all_objects: '{{ 'UI:Links:Bulk:LinkExistForAllObjects'|dict_s }}',
tooltip_links_exist_for_one_object: '{{ 'UI:Links:Bulk:LinkExistForOneObject'|dict_s }}',
tooltip_links_exist_for_x_objects: '{{ 'UI:Links:Bulk:LinkExistForXObjects'|dict_s }}',
tooltip_links_exist_for_x_objects: '{{ 'UI:Links:Bulk:LinkExistForXObjects'|dict_s }}'
},
{% endif %}
{# PLUGIN remove button #}
@@ -200,7 +200,7 @@ let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
},
{# plugin combodo_add_button #}
{% if oUIBlock.HasAddOptionButton() %}
{% if oUIBlock.HasAddOptionButton() and oUIBlock.HasAddOptionButtonJsOnClick() %}
onAdd: function(){
{{ oUIBlock.GetAddOptionButtonJsOnClick()|raw }}

View File

@@ -334,7 +334,8 @@ $oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Fieldset/field examples', 2
$oDashletFieldset1 = new FieldSet('Fieldset 1');
$oDashletField1 = FieldUIBlockFactory::MakeStandard('Field A');
$oDashletInput1 = InputUIBlockFactory::MakeStandard('text', 'input1', 'Input 1');
$oDashletField2 = FieldUIBlockFactory::MakeStandard('Field B');
$oDashletField2 = FieldUIBlockFactory::MakeStandard('Field B (with a description in a tooltip)')
->SetDescription('Description for the field B');
$oDashletInput2 = InputUIBlockFactory::MakeStandard('text', 'input2', 'Input 2');
$oDashletField3 = FieldUIBlockFactory::MakeStandard('Field C');
$oDashletInput3 = InputUIBlockFactory::MakeStandard('text', 'input3', 'Input 3');

View File

@@ -48,6 +48,7 @@ use Server;
use TagSetFieldData;
use Ticket;
use URP_UserProfile;
use User;
use UserRequest;
use VirtualHost;
use VirtualMachine;
@@ -482,7 +483,7 @@ class ItopDataTestCase extends ItopTestCase
/** @var \ormLinkSet $oSet */
$oSet = $oUser->Get('profile_list');
$oSet->AddItem($oUserProfile);
$oUser = $this->updateObject('UserLocal', $oUser->GetKey(), array(
$oUser = $this->updateObject(User::class, $oUser->GetKey(), array(
'profile_list' => $oSet,
));
$this->debug("Updated {$oUser->GetName()} ({$oUser->GetKey()})");

View File

@@ -548,6 +548,12 @@ function DoExport(WebPage $oP, BulkExport $oExporter, $bInteractive = false)
// Command Line mode
//
/////////////////////////////////////////////////////////////////////////////
///
/**
* @since 3.1.0 N°6047
*/
$oCtx = new ContextTag(ContextTag::TAG_EXPORT);
if (utils::IsModeCLI()) {
SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('iTop - Export'));
@@ -722,4 +728,4 @@ catch (Exception $e) {
$oP->add('Error: '.utils::HtmlEntities($e->getMessage()));
IssueLog::Error(utils::HtmlEntities($e->getMessage())."\n".$e->getTraceAsString());
$oP->output();
}
}

View File

@@ -48,29 +48,33 @@ catch(Exception $e)
exit(EXIT_CODE_FATAL);
}
if (utils::IsModeCLI())
/**
* @since 3.1.0 N°6047
*/
$oCtx = new ContextTag(ContextTag::TAG_EXPORT);
if (utils::IsModeCLI())
{
$oP = new CLIPage("iTop - Export");
SetupUtils::CheckPhpAndExtensionsForCli($oP, EXIT_CODE_FATAL);
$sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data');
$sAuthPwd = utils::ReadParam('auth_pwd', null, true /* Allow CLI */, 'raw_data');
$sAuthPwd = utils::ReadParam('auth_pwd', null, true /* Allow CLI */, 'raw_data');
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd))
{
UserRights::Login($sAuthUser); // Login & set the user's language
}
else
{
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd))
{
UserRights::Login($sAuthUser); // Login & set the user's language
}
else
{
$oP->p("Access restricted or wrong credentials ('$sAuthUser')");
$oP->output();
$oP->output();
exit(EXIT_CODE_ERROR);
}
}
else
}
else
{
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
}
ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');
@@ -111,7 +115,7 @@ if (strlen($sExpression) == 0)
if (strlen($sFields) == 0)
{
$sFields = trim($oQuery->Get('fields'));
}
}
}
}
}
@@ -279,13 +283,13 @@ if (!empty($sExpression))
}
$oP->add($sOutputData);
break;
case 'spreadsheet':
$oP = new WebPage("iTop - Export for spreadsheet");
// Integration within MS-Excel web queries + HTTPS + IIS:
// MS-IIS set these header values with no-cache... while Excel fails to do the job if using HTTPS
// Then the fix is to force the reset of header values Pragma and Cache-control
// Then the fix is to force the reset of header values Pragma and Cache-control
header("Pragma:", true);
header("Cache-control:", true);
@@ -298,12 +302,12 @@ if (!empty($sExpression))
$oP = new XMLPage("iTop - Export", true /* passthrough */);
cmdbAbstractObject::DisplaySetAsXML($oP, $oSet, array('localize_values' => $bLocalize));
break;
case 'xlsx':
$oP = new AjaxPage('');
$oExporter = new ExcelExporter();
$oExporter->SetObjectList($oFilter);
// Run the export by chunk of 1000 objects to limit memory usage
$oExporter->SetChunkSize(1000);
do
@@ -311,7 +315,7 @@ if (!empty($sExpression))
$aStatus = $oExporter->Run(); // process one chunk
}
while( ($aStatus['code'] != 'done') && ($aStatus['code'] != 'error'));
if ($aStatus['code'] == 'done')
{
$oP->SetContentType('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
@@ -324,7 +328,7 @@ if (!empty($sExpression))
$oP->add('Error, xlsx export failed: '.$aStatus['message']);
}
break;
default:
$oP = new WebPage("iTop - Export");
$oP->add("Unsupported format '$sFormat'. Possible values are: html, csv, spreadsheet or xml.");
@@ -336,13 +340,13 @@ if (!empty($sExpression))
$oP = new WebPage("iTop - Export");
$oP->p("Error the query can not be executed.");
if ($e instanceof CoreException)
{
{
$oP->p($e->GetHtmlDesc());
}
else
{
$oP->p($e->getMessage());
}
}
}
}
if (!$oP)
@@ -356,7 +360,7 @@ if (!$oP)
else
{
$oP = new WebPage("iTop - Export");
}
}
$oP->p("General purpose export page.");
$oP->p("Parameters:");
$oP->p(" * expression: an OQL expression (URL encoded if needed)");

View File

@@ -206,6 +206,10 @@ function ReadMandatoryParam($oP, $sParam, $sSanitizationFilter)
/////////////////////////////////
// Main program
/**
* @since 3.1.0 N°6047
*/
$oCtx = new ContextTag(ContextTag::TAG_IMPORT);
if (utils::IsModeCLI())
{
$oP = new CLIPage("iTop - Bulk import");