mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Merge branch 'develop' into release/3.1.0-beta
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
@@ -205,6 +205,16 @@ class Set extends AbstractInput
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* HasAddOptionButtonJsOnClick.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasAddOptionButtonJsOnClick(): bool
|
||||
{
|
||||
return $this->sAddOptionButtonJsOnClick != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetAddOptionButtonJsOnClick.
|
||||
*
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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()})");
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)");
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user