Files
scripts/Perl OTRS/Kernel/GenericInterface/Operation/ConfigItem/ConfigItemSearch.pm
2024-10-14 00:08:40 +02:00

1082 lines
35 KiB
Perl

# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::GenericInterface::Operation::ConfigItem::ConfigItemSearch;
use strict;
use warnings;
use Kernel::System::VariableCheck qw(:all);
use parent qw(
Kernel::GenericInterface::Operation::Common
Kernel::GenericInterface::Operation::ConfigItem::Common
);
our $ObjectManagerDisabled = 1;
=head1 NAME
Kernel::GenericInterface::Operation::ConfigItem::ConfigItemSearch - GenericInterface ConfigItem ConfigItemSearch Operation backend
=head1 PUBLIC INTERFACE
=head2 new()
usually, you want to create an instance of this
by using Kernel::GenericInterface::Operation->new();
=cut
sub new {
my ( $Type, %Param ) = @_;
my $Self = {};
bless( $Self, $Type );
# check needed objects
for my $Needed (qw( DebuggerObject WebserviceID )) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
ErrorMessage => "Got no $Needed!",
};
}
$Self->{$Needed} = $Param{$Needed};
}
$Self->{OperationName} = 'ConfigItemSearch';
$Self->{Config} = $Kernel::OM->Get('Kernel::Config')->Get('GenericInterface::Operation::ConfigItemSearch');
$Self->{Config}->{DefaultValue} = 'Not Defined';
my $GeneralCatalogObject = $Kernel::OM->Get('Kernel::System::GeneralCatalog');
# get a list of all config item classes
$Self->{ClassList} = $GeneralCatalogObject->ItemList(
Class => 'ITSM::ConfigItem::Class',
);
if ( !IsHashRefWithData( $Self->{ClassList} ) ) {
return $Self->{DebuggerObject}->Error(
Summary => 'Error when trying to get class listing of ITSM::ConfigItem::Class',
);
}
# get a list of all incistates
$Self->{InciStateList} = $GeneralCatalogObject->ItemList(
Class => 'ITSM::Core::IncidentState',
);
if ( !IsHashRefWithData( $Self->{InciStateList} ) ) {
return $Self->{DebuggerObject}->Error(
Summary => 'Error when trying to get incident state listing of'
. ' ITSM::Core::IncidentState',
);
}
# get a list of all deplstates
$Self->{DeplStateList} = $GeneralCatalogObject->ItemList(
Class => 'ITSM::ConfigItem::DeploymentState',
);
if ( !IsHashRefWithData( $Self->{DeplStateList} ) ) {
return $Self->{DebuggerObject}->Error(
Summary => 'Error when trying to get incident state listing of'
. ' ITSM::ConfigItem::DeploymentState',
);
}
# also provide the classlist in reversed form for easier reverse lookups
my %ReverseClassList = reverse %{ $Self->{ClassList} };
$Self->{ReverseClassList} = \%ReverseClassList;
# also provide the incistatelist in reversed form for easier reverse lookups
my %ReverseInciStateList = reverse %{ $Self->{InciStateList} };
$Self->{ReverseInciStateList} = \%ReverseInciStateList;
# also provide the deplstatelist in reversed form for easier reverse lookups
my %ReverseDeplStateList = reverse %{ $Self->{DeplStateList} };
$Self->{ReverseDeplStateList} = \%ReverseDeplStateList;
return $Self;
}
=head2 Run()
perform ConfigItemCreate Operation. This will return the created config item number.
my $Result = $OperationObject->Run(
Data => {
UserLogin => 'some agent login', # UserLogin or SessionID is
SessionID => 123, # required
Password => 'some password', # if UserLogin is sent then
# Password is required
ConfigItem => {
Class => 'The ConfigItem Class', # (optional)
Number => 'The ConfigItem Number', # (optional)
Name => 'The ConfigItem Name', # (optional)
DeplStates => ['deployment state'], # (optional)
InciStates => ['incident state'], # (optional)
# config items with created time after ...
ConfigItemCreateTimeNewerDate => '2006-01-09 00:00:01', # (optional)
# config items with created time before then ....
ConfigItemCreateTimeOlderDate => '2006-01-19 23:59:59', # (optional)
# config items with changed time after ...
ConfigItemChangeTimeNewerDate => '2006-01-09 00:00:01', # (optional)
# config items with changed time before then ....
ConfigItemChangeTimeOlderDate => '2006-01-19 23:59:59', # (optional)
CIXMLData => $ArrayHashRef, # (optional), it depends on the Configuration
# Item class and definition
PreviousVersionSearch => 1, # (optional) default 0 (0|1)
OrderBy => [ 'ConfigItemID', 'Number' ], # (optional)
# default: [ 'ConfigItemID' ]
# (ConfigItemID, Number, ClassID, DeplStateID, InciStateID,
# CreateTime, CreateBy, ChangeTime, ChangeBy)
# Additional information for OrderBy:
# The OrderByDirection can be specified for each OrderBy attribute.
# The pairing is made by the array indices.
OrderByDirection => [ 'Down', 'Up' ], # (optional)
# default: [ 'Down' ]
# (Down | Up)
Limit => 122, # (optional)
},
},
);
$Result = {
Success => 1, # 0 or 1
ErrorMessage => '', # in case of error
Data => { # result data payload after Operation
ConfigItemID => [123, 456], # Configuration Item IDs number in OTRS::ITSM (Service desk system)
Error => { # should not return errors
ErrorCode => 'ConfigItemSearch.ErrorCode'
ErrorMessage => 'Error Description'
},
},
};
=cut
sub Run {
my ( $Self, %Param ) = @_;
my $Result = $Self->Init(
WebserviceID => $Self->{WebserviceID},
);
if ( !$Result->{Success} ) {
$Self->ReturnError(
ErrorCode => 'Webservice.InvalidConfiguration',
ErrorMessage => $Result->{ErrorMessage},
);
}
# check needed stuff
if (
!$Param{Data}->{UserLogin}
&& !$Param{Data}->{SessionID}
)
{
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.MissingParameter",
ErrorMessage =>
"$Self->{OperationName}: UserLogin or SessionID is required!",
);
}
if ( $Param{Data}->{UserLogin} ) {
if ( !$Param{Data}->{Password} )
{
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.MissingParameter",
ErrorMessage => "$Self->{OperationName}: Password or SessionID is required!",
);
}
}
# authenticate user
my ( $UserID, $UserType ) = $Self->Auth(%Param);
if ( !$UserID ) {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.AuthFail",
ErrorMessage => "$Self->{OperationName}: User could not be authenticated!",
);
}
# check needed hashes
for my $Needed (qw(ConfigItem)) {
if ( !IsHashRefWithData( $Param{Data}->{$Needed} ) ) {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.MissingParameter",
ErrorMessage =>
"$Self->{OperationName}: $Needed parameter is missing or not valid!",
);
}
}
# isolate config item parameter
my $ConfigItem = $Param{Data}->{ConfigItem};
# remove leading and trailing spaces
for my $Attribute ( sort keys %{$ConfigItem} ) {
if ( ref $Attribute ne 'HASH' && ref $Attribute ne 'ARRAY' ) {
#remove leading spaces
$ConfigItem->{$Attribute} =~ s{\A\s+}{};
#remove trailing spaces
$ConfigItem->{$Attribute} =~ s{\s+\z}{};
}
}
if ( defined $ConfigItem->{CIXMLData} ) {
if ( !IsHashRefWithData( $ConfigItem->{CIXMLData} ) ) {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage => "$Self->{OperationName}: ConfigItem->CIXMLData is invalid!",
);
}
# remove leading and trailing spaces for CIXMLData
$Self->_CleanXMLData( XMLData => $ConfigItem->{CIXMLData} );
}
if ( !( $ConfigItem->{Class} ) ) {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.MissingParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->Class parameter is missing!",
);
}
# convert search params to arrays
if ( defined $ConfigItem->{InciStates} ) {
my @InciStates;
if ( IsStringWithData( $ConfigItem->{InciStates} ) ) {
@InciStates = split( /,/, $ConfigItem->{InciStates} );
}
elsif ( IsArrayRefWithData( $ConfigItem->{InciStates} ) ) {
@InciStates = @{ $ConfigItem->{InciStates} };
}
else {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.WrongStructure",
ErrorMessage =>
"$Self->{OperationName}: Structure for ConfigItem->InciStates is not correct!",
);
}
$ConfigItem->{InciStates} = \@InciStates;
}
if ( defined $ConfigItem->{DeplStates} ) {
my @DeplStates;
if ( IsStringWithData( $ConfigItem->{DeplStates} ) ) {
@DeplStates = split( /,/, $ConfigItem->{DeplStates} );
}
elsif ( IsArrayRefWithData( $ConfigItem->{DeplStates} ) ) {
@DeplStates = @{ $ConfigItem->{DeplStates} };
}
else {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.WrongStructure",
ErrorMessage => "$Self->{OperationName}: Structure for DeplStates is not correct!",
);
}
$ConfigItem->{DeplStates} = \@DeplStates;
}
if ( defined $ConfigItem->{OrderBy} ) {
my @OrderBy;
if ( IsStringWithData( $ConfigItem->{OrderBy} ) ) {
@OrderBy = split( /,/, $ConfigItem->{OrderBy} );
}
elsif ( IsArrayRefWithData( $ConfigItem->{OrderBy} ) ) {
@OrderBy = @{ $ConfigItem->{OrderBy} };
}
else {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.WrongStructure",
ErrorMessage => "$Self->{OperationName}: Structure for OrderBy is not correct!",
);
}
$ConfigItem->{OrderBy} = \@OrderBy;
}
if ( defined $ConfigItem->{OrderByDirection} ) {
my @OrderByDirection;
if ( IsStringWithData( $ConfigItem->{OrderByDirection} ) ) {
@OrderByDirection = split( /,/, $ConfigItem->{OrderByDirection} );
}
elsif ( IsArrayRefWithData( $ConfigItem->{OrderByDirection} ) ) {
@OrderByDirection = @{ $ConfigItem->{OrderByDirection} };
}
else {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.WrongStructure",
ErrorMessage =>
"$Self->{OperationName}: Structure for OrderByDirection is not correct!",
);
}
$ConfigItem->{OrderByDirection} = \@OrderByDirection;
}
# check ConfigItem attribute values
my $ConfigItemCheck = $Self->_CheckConfigItem( ConfigItem => $ConfigItem );
if ( !$ConfigItemCheck->{Success} ) {
return $Self->ReturnError( %{$ConfigItemCheck} );
}
# check search permissions
my $Permission = $Kernel::OM->Get('Kernel::System::ITSMConfigItem')->Permission(
Scope => 'Class',
ClassID => $Self->{ReverseClassList}->{ $ConfigItem->{Class} },
UserID => $UserID,
Type => $Self->{Config}->{Permission},
);
if ( !$Permission ) {
return $Self->ReturnError(
ErrorCode => "$Self->{OperationName}.AccessDenied",
ErrorMessage => "$Self->{OperationName}: Can not search configuration items!",
);
}
return $Self->_ConfigItemSearch(
ConfigItem => $ConfigItem,
UserID => $UserID,
);
}
=head1 INTERNAL INTERFACE
=head2 _CleanXMLData()
removed trailing and leading white spaces in the XMLData.
my $XMLDataClean = $OperationObject->_CleanXMLData(
Definition => $DefinitionArrayRef, # Config Item Definition ot just part of it
XMLData => $XMLDataHashRef,
);
returns:
$XMLDataClean = {
Success => 1, # if everything is OK
}
$XMLDataClean = {
ErrorCode => 'Function.Error', # if error
ErrorMessage => 'Error description',
}
=cut
sub _CleanXMLData {
my ( $Self, %Param ) = @_;
my $XMLData = $Param{XMLData};
KEY:
for my $Key ( sort keys %{$XMLData} ) {
if ( ref $XMLData->{$Key} eq 'ARRAY' ) {
ELEMENT:
for my $Element ( @{ $XMLData->{$Key} } ) {
if ( ref $Element eq 'HASH' ) {
# start recursion
$Self->_CleanXMLData( XMLData => $Element );
next ELEMENT;
}
elsif ( ref $Element eq '' ) {
#remove leading spaces
$Element =~ s{\A\s+}{};
#remove trailing spaces
$Element =~ s{\s+\z}{};
}
}
}
elsif ( ref $XMLData->{$Key} eq 'HASH' ) {
# start recursion
$Self->_CleanXMLData( XMLData => $XMLData->{$Key} );
next KEY;
}
elsif ( ref $XMLData->{$Key} eq '' ) {
#remove leading spaces
$XMLData->{$Key} =~ s{\A\s+}{};
#remove trailing spaces
$XMLData->{$Key} =~ s{\s+\z}{};
}
}
return 1;
}
=head2 _CheckConfigItem()
checks if the given config item parameters are valid.
my $ConfigItemCheck = $OperationObject->_CheckConfigItem(
ConfigItem => $ConfigItem, # all config item parameters
);
returns:
$ConfigItemCheck = {
Success => 1, # if everything is OK
}
$ConfigItemCheck = {
ErrorCode => 'Function.Error', # if error
ErrorMessage => 'Error description',
}
=cut
sub _CheckConfigItem {
my ( $Self, %Param ) = @_;
my $ConfigItem = $Param{ConfigItem};
# check config item internally
# check needed stuff
for my $Needed (qw(Class)) {
if ( !$ConfigItem->{$Needed} ) {
return {
ErrorCode => "$Self->{OperationName}.MissingParameter",
ErrorMessage => "$Self->{OperationName}: ConfigItem->$Needed parameter is missing!",
};
}
}
# check ConfigItem->Class
if ( !$Self->ValidateClass( %{$ConfigItem} ) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->Class parameter is invalid!",
};
}
# check optional stuff
if ( IsArrayRefWithData( $ConfigItem->{InciStates} ) ) {
for my $InciState ( @{ $ConfigItem->{InciStates} } ) {
# check ConfigItem->InciStates
if ( !$Self->ValidateInciState( InciState => $InciState ) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->InciStates parameter is invalid!",
};
}
}
}
if ( IsArrayRefWithData( $ConfigItem->{DeplStates} ) ) {
for my $DeplState ( @{ $ConfigItem->{DeplStates} } ) {
# check ConfigItem->InciStates
if ( !$Self->ValidateDeplState( DeplState => $DeplState ) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->DeplStates parameter is invalid!",
};
}
}
}
for my $TimeParam (
qw(CreateTimeNewerDate CreateTimeOlderDate ChangeTimeNewerDate ChangeTimeOlderDate)
)
{
if ( defined $ConfigItem->{"ConfigItem$TimeParam"} ) {
if (
!$Self->ValidateInputDateTime(
Value => $ConfigItem->{"ConfigItem$TimeParam"},
)
)
{
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->ConfigItem$TimeParam parameter is invalid!",
};
}
}
}
if ( defined $ConfigItem->{Limit} ) {
if ( !IsNumber( $ConfigItem->{Limit} ) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->Limit parameter is invalid!",
};
}
}
if ( IsHashRefWithData( $ConfigItem->{CIXMLData} ) ) {
# get last config item defintion
my $DefinitionData = $Kernel::OM->Get('Kernel::System::ITSMConfigItem')->DefinitionGet(
ClassID => $Self->{ReverseClassList}->{ $ConfigItem->{Class} },
);
my $XMLDataCheckResult = $Self->_CheckSearchXMLData(
Definition => $DefinitionData->{DefinitionRef},
XMLData => $ConfigItem->{CIXMLData},
);
if ( !$XMLDataCheckResult->{Success} ) {
return $XMLDataCheckResult;
}
}
# if everything is OK then return Success
return {
Success => 1,
};
}
=head2 _ConfigItemSearch()
search a configuration items.
my $Response = $OperationObject->_ConfigItemSearch(
ConfigItem => $ConfigItem, # all configuration item parameters
UserID => 123,
);
returns:
$Response = {
Success => 1, # if everething is OK
Data => {
ConfigItemIDs => [123, 456],
}
}
$Response = {
Success => 0, # if unexpected error
ErrorMessage => "$Param{ErrorCode}: $Param{ErrorMessage}",
}
=cut
sub _ConfigItemSearch {
my ( $Self, %Param ) = @_;
my $ConfigItem = $Param{ConfigItem};
my %SearchParams;
# set search parameters that does not need any conversion
for my $PlainParam (
qw(
Name Number PreviousVersionSearch OrderBy OrderByDirection Limit
ConfigItemCreateTimeNewerDate ConfigItemCreateTimeOlderDate ConfigItemChangeTimeNewerDate
ConfigItemChangeTimeOlderDate
)
)
{
if ( defined $ConfigItem->{$PlainParam} ) {
$SearchParams{$PlainParam} = $ConfigItem->{$PlainParam};
}
}
# set seach class
my $ClassID = $Self->{ReverseClassList}->{ $ConfigItem->{Class} };
$SearchParams{ClassIDs} = [$ClassID];
# set search incident states
if ( defined $ConfigItem->{InciStates} ) {
my @InciStateIDs;
for my $InciState ( @{ $ConfigItem->{InciStates} } ) {
my $InciStateID = $Self->{ReverseInciStateList}->{$InciState};
push @InciStateIDs, $InciStateID;
}
$SearchParams{InciStateIDs} = \@InciStateIDs;
}
# set search deployment states
if ( defined $ConfigItem->{DeplStates} ) {
my @DeplStateIDs;
for my $DeplState ( @{ $ConfigItem->{DeplStates} } ) {
my $DeplStateID = $Self->{ReverseDeplStateList}->{$DeplState};
push @DeplStateIDs, $DeplStateID;
}
$SearchParams{DeplStateIDs} = \@DeplStateIDs;
}
my $RawXMLData = $ConfigItem->{CIXMLData};
my $ConfigItemObject = $Kernel::OM->Get('Kernel::System::ITSMConfigItem');
if ( IsHashRefWithData($RawXMLData) ) {
# get last config item defintion
my $DefinitionData = $ConfigItemObject->DefinitionGet(
ClassID => $Self->{ReverseClassList}->{ $ConfigItem->{Class} },
);
# replace date, date time, customer, company and general catalog values
my $ReplacedXMLData = $Self->ReplaceXMLData(
XMLData => $RawXMLData,
Definition => $DefinitionData->{DefinitionRef},
);
# create an XMLData structure suitable for ConfigItemSearch
my $XMLData = $Self->_FormatSearchXMLData(
XMLData => $ReplacedXMLData,
);
if ( IsArrayRefWithData($XMLData) ) {
$SearchParams{What} = $XMLData;
}
}
$Self->{DebuggerObject}->Info(
Summary => "$Self->{OperationName}: Search Parameters",
Data => \%SearchParams,
);
my $ConfigItemIDs = $ConfigItemObject->ConfigItemSearchExtended(%SearchParams);
if ( IsArrayRefWithData($ConfigItemIDs) ) {
return {
Success => 1,
Data => {
ConfigItemIDs => $ConfigItemIDs,
},
};
}
return {
Success => 1,
Data => {
ConfigItemIDs => '',
},
};
}
=head2 _CheckSearchXMLData()
checks if the given XMLData value are valid.
my $XMLDataCheck = $CommonObject->_CheckSearchXMLData(
Definition => $DefinitionArrayRef, # Config Item Definition ot just part of it
XMLData => $XMLDataHashRef,
Parent => 'some parent',
);
returns:
$XMLDataCheck = {
Success => 1, # if everything is OK
}
$XMLDataCheck = {
ErrorCode => 'Function.Error', # if error
ErrorMessage => 'Error description',
}
=cut
sub _CheckSearchXMLData {
my ( $Self, %Param ) = @_;
my $Definition = $Param{Definition};
my $XMLData = $Param{XMLData};
my $Parent = $Param{Parent} || '';
my $CheckValueResult;
for my $DefItem ( @{$Definition} ) {
my $ItemKey = $DefItem->{Key};
if ( ref $XMLData->{$ItemKey} eq 'ARRAY' ) {
for my $ArrayItem ( @{ $XMLData->{$ItemKey} } ) {
if ( ref $ArrayItem eq 'HASH' ) {
$CheckValueResult = $Self->_CheckValue(
Value => $ArrayItem->{$ItemKey},
Input => $DefItem->{Input},
ItemKey => $ItemKey,
Parent => $Parent,
);
if ( !$CheckValueResult->{Success} ) {
return $CheckValueResult;
}
}
elsif ( ref $ArrayItem eq '' ) {
$CheckValueResult = $Self->_CheckValue(
Value => $ArrayItem,
Input => $DefItem->{Input},
ItemKey => $ItemKey,
Parent => $Parent,
);
if ( !$CheckValueResult->{Success} ) {
return $CheckValueResult;
}
}
else {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter"
. " is invalid!",
};
}
}
}
elsif ( ref $XMLData->{$ItemKey} eq 'HASH' ) {
if ( $XMLData->{$ItemKey}->{$ItemKey} ) {
$CheckValueResult = $Self->_CheckValue(
Value => $XMLData->{$ItemKey}->{$ItemKey},
Input => $DefItem->{Input},
ItemKey => $ItemKey,
Parent => $Parent,
);
if ( !$CheckValueResult->{Success} ) {
return $CheckValueResult;
}
}
}
else {
# only perform checks if item really exits in the XMLData
# CountNin checks was verified and passed before!, so it is safe to skip if needed
if ( $XMLData->{$ItemKey} ) {
$CheckValueResult = $Self->_CheckValue(
Value => $XMLData->{$ItemKey},
Input => $DefItem->{Input},
ItemKey => $ItemKey,
Parent => $Parent,
);
if ( !$CheckValueResult->{Success} ) {
return $CheckValueResult;
}
}
}
# check if there is a sub and start recursion
if ( defined $DefItem->{Sub} ) {
if ( ref $XMLData->{$ItemKey} eq 'ARRAY' ) {
my $Counter = 0;
for my $ArrayItem ( @{ $XMLData->{$ItemKey} } ) {
# start recursion for each array item
my $XMLDataCheck = $Self->_CheckSearchXMLData(
Definition => $DefItem->{Sub},
XMLData => $ArrayItem,
Parent => $Parent . $ItemKey . "[$Counter]->",
);
if ( !$XMLDataCheck->{Success} ) {
return $XMLDataCheck;
}
$Counter++;
}
}
elsif ( ref $XMLData->{$ItemKey} eq 'HASH' ) {
# start recursion
my $XMLDataCheck = $Self->_CheckSearchXMLData(
Definition => $DefItem->{Sub},
XMLData => $XMLData->{$ItemKey},
Parent => $Parent . $ItemKey . '->',
);
if ( !$XMLDataCheck->{Success} ) {
return $XMLDataCheck;
}
}
else {
# start recusrsion
my $XMLDataCheck = $Self->_CheckSearchXMLData(
Definition => $DefItem->{Sub},
XMLData => {},
Parent => $Parent . $ItemKey . '->',
);
if ( !$XMLDataCheck->{Success} ) {
return $XMLDataCheck;
}
}
}
}
return {
Success => 1,
};
}
=head2 _CheckValue()
checks if the given value is valid.
my $ValueCheck = $CommonObject->_CheckValue(
Value => $Value # $Value could be a string, a time stamp,
# general catalog class name, or a integer
Input => $InputDefinitionHashRef, # The definition of the element input extracted
# from the Configuration Item definition for
# for each value
ItemKey => 'some key', # The name of the value as sent in the SOAP
# request
Parent => 'soem parent key->', # The name of the parent followed by -> or empty
# for root key items
);
returns:
$ValueCheck = {
Success => 1, # if everything is OK
}
$ValueCheck = {
ErrorCode => 'Function.Error', # if error
ErrorMessage => 'Error description',
}
=cut
sub _CheckValue {
my ( $Self, %Param ) = @_;
my $Parent = $Param{Parent};
my $ItemKey = $Param{ItemKey};
if ( $Param{Input}->{Type} eq 'Text' || $Param{Input}->{Type} eq 'TextArea' ) {
# run Text validations
if ( !$Self->ValidateInputText(%Param) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter value"
. " excedes the maxium length!",
};
}
}
elsif ( $Param{Input}->{Type} eq 'Date' ) {
# run Date validations
if ( !$Self->ValidateInputDate(%Param) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter value"
. " is not a valid Date format!",
};
}
}
elsif ( $Param{Input}->{Type} eq 'DateTime' ) {
# run DateTime validations
if ( !$Self->ValidateInputDateTime(%Param) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter value"
. " is not a valid DateTime format!",
};
}
}
elsif ( $Param{Input}->{Type} eq 'Customer' ) {
# run Customer validations
if ( !$Self->ValidateInputCustomer(%Param) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter value"
. " is not a valid customer!",
};
}
}
elsif ( $Param{Input}->{Type} eq 'CustomerCompany' ) {
# run CustomerCompany validations
if ( !$Self->ValidateInputCustomerCompany(%Param) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter value"
. " is not a valid customer company!",
};
}
}
elsif ( $Param{Input}->{Type} eq 'Integer' ) {
# run Integer validations
if ( !$Self->ValidateInputInteger(%Param) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter value"
. " is not a valid Integer or out of range!",
};
}
}
elsif ( $Param{Input}->{Type} eq 'GeneralCatalog' ) {
# run General Catalog validations
if ( !$Self->ValidateInputGeneralCatalog(%Param) ) {
return {
ErrorCode => "$Self->{OperationName}.InvalidParameter",
ErrorMessage =>
"$Self->{OperationName}: ConfigItem->CIXMLData->$Parent$ItemKey parameter value"
. " is not a valid for General Catalog '$Param{Input}->{Class}'!",
};
}
}
else {
# The type is dummy, do nothing
}
return {
Success => 1,
};
}
=head2 _FormatSearchXMLData()
Create a XMLData suitable for ConfigItemSeach.
my $NewXMLData = $OperationObject->_FormatSearchXMLData(
XMLData => $XMLDataHashRef,
Child => 1, # or 0, optional
);
returns:
$NewXMLData = $XMLDataHashRef, # suitable for version add
=cut
sub _FormatSearchXMLData {
my ( $Self, %Param ) = @_;
my $XMLData = $Param{XMLData};
my $Parent = $Param{Parent} || '';
my $Child = $Param{Child};
my $NewXMLData = $Param{NewXMLData} || {};
for my $RootKey ( sort keys %{$XMLData} ) {
if ( ref $XMLData->{$RootKey} eq 'ARRAY' ) {
for my $ArrayItem ( @{ $XMLData->{$RootKey} } ) {
if ( ref $ArrayItem eq 'HASH' ) {
# extract the root key from the hash and assing it to content key
my $Content = delete $ArrayItem->{$RootKey};
# start recursion
my $NewXMLDataPart = $Self->_FormatSearchXMLData(
XMLData => $ArrayItem,
Parent => $Parent . $RootKey . '::',
Child => 1,
);
if ($Content) {
push @{ $NewXMLData->{ $Parent . $RootKey } }, $Content;
}
# assamble the final value from the parts
for my $NewKey ( %{$NewXMLDataPart} ) {
for my $Item ( @{ $NewXMLDataPart->{$NewKey} } ) {
push @{ $NewXMLData->{$NewKey} }, $Item;
}
}
}
elsif ( ref $ArrayItem eq '' ) {
push @{ $NewXMLData->{ $Parent . $RootKey } }, $ArrayItem;
}
}
}
elsif ( ref $XMLData->{$RootKey} eq 'HASH' ) {
# extract the root key from the hash and assing it to content key
my $Content = delete $XMLData->{$RootKey}->{$RootKey};
# start recursion
my $NewXMLDataPart = $Self->_FormatSearchXMLData(
XMLData => $XMLData->{$RootKey},
Parent => $Parent . $RootKey . "::",
Child => 1,
);
if ($Content) {
push @{ $NewXMLData->{ $Parent . $RootKey } }, $Content;
}
# assamble the final value from the part
%{$NewXMLData} = ( %{$NewXMLData}, %{$NewXMLDataPart} );
}
elsif ( ref $XMLData->{$RootKey} eq '' ) {
push @{ $NewXMLData->{ $Parent . $RootKey } }, $XMLData->{$RootKey};
}
}
# return only the part on recursion
if ($Child) {
return $NewXMLData;
}
# return the complete XMLData as needed for ConfigItemSearch
my @ReturnStructure;
for my $SearchParam ( sort keys %{$NewXMLData} ) {
my $SearchKey = $SearchParam;
$SearchKey =~ s{ :: }{\'\}[%]\{\'}xmsg;
$SearchKey = "[1]{'Version'}[1]{'$SearchKey'}[%]{'Content'}";
push @ReturnStructure, {
$SearchKey => $NewXMLData->{$SearchParam},
};
}
return \@ReturnStructure;
}
1;
=head1 TERMS AND CONDITIONS
This software is part of the OTRS project (L<https://otrs.org/>).
This software comes with ABSOLUTELY NO WARRANTY. For details, see
the enclosed file COPYING for license information (GPL). If you
did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
=cut