init III
This commit is contained in:
1649
Perl OTRS/Kernel/GenericInterface/Operation/ConfigItem/Common.pm
Normal file
1649
Perl OTRS/Kernel/GenericInterface/Operation/ConfigItem/Common.pm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,707 @@
|
||||
# --
|
||||
# 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::ConfigItemCreate;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
## nofilter(TidyAll::Plugin::OTRS::Migrations::OTRS6::SysConfig)
|
||||
|
||||
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::ConfigItemCreate - GenericInterface ConfigItem ConfigItemCreate 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} = 'ConfigItemCreate';
|
||||
|
||||
$Self->{Config} = $Kernel::OM->Get('Kernel::Config')->Get('GenericInterface::Operation::ConfigItemCreate');
|
||||
|
||||
$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
|
||||
# required
|
||||
SessionID => 123,
|
||||
|
||||
Password => 'some password', # if UserLogin is sent then
|
||||
# Password is required
|
||||
ConfigItem => {
|
||||
Number => '111', # optional
|
||||
Class => 'Config Item Class',
|
||||
Name => 'The Name',
|
||||
DeplState => 'deployment state',
|
||||
InciState => 'incident state',
|
||||
CIXMLData => $ArrayHashRef, # it depends on the Configuration Item class and definition
|
||||
|
||||
Attachment => [
|
||||
{
|
||||
Content => 'content' # base64 encoded
|
||||
ContentType => 'some content type'
|
||||
Filename => 'some fine name'
|
||||
},
|
||||
# ...
|
||||
],
|
||||
#or
|
||||
#Attachment => {
|
||||
# Content => 'content'
|
||||
# ContentType => 'some content type'
|
||||
# Filename => 'some fine name'
|
||||
#},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
$Result = {
|
||||
Success => 1, # 0 or 1
|
||||
ErrorMessage => '', # in case of error
|
||||
Data => { # result data payload after Operation
|
||||
ConfigItemID => 123, # Configuration Item ID number in OTRS::ITSM (Service desk system)
|
||||
Number => 2324454323322 # Configuration Item Number in OTRS::ITSM (Service desk system)
|
||||
Error => { # should not return errors
|
||||
ErrorCode => 'ConfigItemCreate.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}{};
|
||||
}
|
||||
}
|
||||
|
||||
# CIXMLData is not mandatory, but it must be HashRef if exists.
|
||||
if ( defined $ConfigItem->{CIXMLData} ) {
|
||||
if ( !IsHashRefWithData( $ConfigItem->{CIXMLData} ) ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.MissingParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: ConfigItem->CIXMLData is missing or invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# Remove leading and trailing spaces for CIXMLData (must be HashRef).
|
||||
$Self->_CleanXMLData( XMLData => $ConfigItem->{CIXMLData} );
|
||||
}
|
||||
|
||||
# check ConfigItem attribute values
|
||||
my $ConfigItemCheck = $Self->_CheckConfigItem( ConfigItem => $ConfigItem );
|
||||
|
||||
if ( !$ConfigItemCheck->{Success} ) {
|
||||
return $Self->ReturnError( %{$ConfigItemCheck} );
|
||||
}
|
||||
|
||||
# check create 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 create configuration items!",
|
||||
);
|
||||
}
|
||||
|
||||
my $Attachment;
|
||||
my @AttachmentList;
|
||||
|
||||
if ( defined $Param{Data}->{ConfigItem}->{Attachment} ) {
|
||||
|
||||
# isolate Attachment parameter
|
||||
$Attachment = delete $Param{Data}->{ConfigItem}->{Attachment};
|
||||
|
||||
# homologate imput to array
|
||||
if ( IsHashRefWithData($Attachment) ) {
|
||||
push @AttachmentList, $Attachment;
|
||||
}
|
||||
elsif ( IsArrayRefWithData($Attachment) ) {
|
||||
@AttachmentList = @{$Attachment};
|
||||
}
|
||||
else {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->Attachment parameter is invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# check Attachment internal structure
|
||||
for my $AttachmentItem (@AttachmentList) {
|
||||
if ( !IsHashRefWithData($AttachmentItem) ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->Attachment parameter is invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# remove leading and trailing spaces
|
||||
for my $Attribute ( sort keys %{$AttachmentItem} ) {
|
||||
if ( ref $Attribute ne 'HASH' && ref $Attribute ne 'ARRAY' ) {
|
||||
|
||||
#remove leading spaces
|
||||
$AttachmentItem->{$Attribute} =~ s{\A\s+}{};
|
||||
|
||||
#remove trailing spaces
|
||||
$AttachmentItem->{$Attribute} =~ s{\s+\z}{};
|
||||
}
|
||||
}
|
||||
|
||||
# check Attachment attribute values
|
||||
my $AttachmentCheck = $Self->_CheckAttachment( Attachment => $AttachmentItem );
|
||||
|
||||
if ( !$AttachmentCheck->{Success} ) {
|
||||
return $Self->ReturnError( %{$AttachmentCheck} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $Self->_ConfigItemCreate(
|
||||
ConfigItem => $ConfigItem,
|
||||
AttachmentList => \@AttachmentList,
|
||||
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
|
||||
for my $Needed (qw(Class Name DeplState InciState)) {
|
||||
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 ConfigItem->DeplState
|
||||
if ( !$Self->ValidateDeplState( %{$ConfigItem} ) ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->DeplState parameter is invalid!",
|
||||
};
|
||||
}
|
||||
|
||||
# check ConfigItem->DeplState
|
||||
if ( !$Self->ValidateInciState( %{$ConfigItem} ) ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->InciState parameter is invalid!",
|
||||
};
|
||||
}
|
||||
|
||||
# get last config item defintion
|
||||
my $DefinitionData = $Kernel::OM->Get('Kernel::System::ITSMConfigItem')->DefinitionGet(
|
||||
ClassID => $Self->{ReverseClassList}->{ $ConfigItem->{Class} },
|
||||
);
|
||||
|
||||
my $XMLDataCheckResult = $Self->CheckXMLData(
|
||||
Definition => $DefinitionData->{DefinitionRef},
|
||||
XMLData => $ConfigItem->{CIXMLData},
|
||||
);
|
||||
|
||||
if ( !$XMLDataCheckResult->{Success} ) {
|
||||
return $XMLDataCheckResult;
|
||||
}
|
||||
|
||||
# if everything is OK then return Success
|
||||
return {
|
||||
Success => 1,
|
||||
};
|
||||
}
|
||||
|
||||
=head2 _CheckAttachment()
|
||||
|
||||
checks if the given attachment parameter is valid.
|
||||
|
||||
my $AttachmentCheck = $OperationObject->_CheckAttachment(
|
||||
Attachment => $Attachment, # all attachment parameters
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
$AttachmentCheck = {
|
||||
Success => 1, # if everething is OK
|
||||
}
|
||||
|
||||
$AttachmentCheck = {
|
||||
ErrorCode => 'Function.Error', # if error
|
||||
ErrorMessage => 'Error description',
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub _CheckAttachment {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Attachment = $Param{Attachment};
|
||||
|
||||
# check attachment item internally
|
||||
for my $Needed (qw(Content ContentType Filename)) {
|
||||
if ( !$Attachment->{$Needed} ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.MissingParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: Attachment->$Needed parameter is missing!",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# check Article->ContentType
|
||||
if ( $Attachment->{ContentType} ) {
|
||||
|
||||
$Attachment->{ContentType} = lc $Attachment->{ContentType};
|
||||
|
||||
# check Charset part
|
||||
my $Charset = '';
|
||||
if ( $Attachment->{ContentType} =~ /charset=/i ) {
|
||||
$Charset = $Attachment->{ContentType};
|
||||
$Charset =~ s/.+?charset=("|'|)(\w+)/$2/gi;
|
||||
$Charset =~ s/"|'//g;
|
||||
$Charset =~ s/(.+?);.*/$1/g;
|
||||
}
|
||||
|
||||
if ( $Charset && !$Self->ValidateCharset( Charset => $Charset ) )
|
||||
{
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: Attachment->ContentType is invalid!",
|
||||
};
|
||||
}
|
||||
|
||||
# check MimeType part
|
||||
my $MimeType = '';
|
||||
if ( $Attachment->{ContentType} =~ /^(\w+\/\w+)/i ) {
|
||||
$MimeType = $1;
|
||||
$MimeType =~ s/"|'//g;
|
||||
}
|
||||
|
||||
if ( !$Self->ValidateMimeType( MimeType => $MimeType ) ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: Attachment->ContentType is invalid!",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# if everything is OK then return Success
|
||||
return {
|
||||
Success => 1,
|
||||
};
|
||||
}
|
||||
|
||||
=head2 _ConfigItemCreate()
|
||||
|
||||
creates a configuration item with attachments if specified.
|
||||
|
||||
my $Response = $OperationObject->_ConfigItemCreate(
|
||||
ConfigItem => $ConfigItem, # all configuration item parameters
|
||||
AttachmentList => $Attachment, # a list of all attachments
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
$Response = {
|
||||
Success => 1, # if everething is OK
|
||||
Data => {
|
||||
ConfigItemID => 123,
|
||||
ConfigItemNumber => 'CN123',
|
||||
}
|
||||
}
|
||||
|
||||
$Response = {
|
||||
Success => 0, # if unexpected error
|
||||
ErrorMessage => "$Param{ErrorCode}: $Param{ErrorMessage}",
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub _ConfigItemCreate {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $ConfigItem = $Param{ConfigItem};
|
||||
my $AttachmentList = $Param{AttachmentList};
|
||||
|
||||
my $DeplStateID = $Self->{ReverseDeplStateList}->{ $ConfigItem->{DeplState} };
|
||||
my $InciStateID = $Self->{ReverseInciStateList}->{ $ConfigItem->{InciState} };
|
||||
|
||||
my $RawXMLData = $ConfigItem->{CIXMLData};
|
||||
|
||||
my $ConfigItemObject = $Kernel::OM->Get('Kernel::System::ITSMConfigItem');
|
||||
|
||||
# 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 VersionAdd
|
||||
my $XMLData = $Self->FormatXMLData(
|
||||
XMLData => $ReplacedXMLData,
|
||||
);
|
||||
|
||||
# create new config item
|
||||
my $ConfigItemID = $ConfigItemObject->ConfigItemAdd(
|
||||
Number => $ConfigItem->{Number},
|
||||
ClassID => $Self->{ReverseClassList}->{ $ConfigItem->{Class} },
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
my $VersionID = $ConfigItemObject->VersionAdd(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
Name => $ConfigItem->{Name},
|
||||
DefinitionID => $DefinitionData->{DefinitionID},
|
||||
DeplStateID => $DeplStateID,
|
||||
InciStateID => $InciStateID,
|
||||
XMLData => $XMLData,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
if ( !$ConfigItemID && !$VersionID ) {
|
||||
return {
|
||||
Success => 0,
|
||||
ErrorMessage => 'Configuration Item could not be created, please contact the system'
|
||||
. 'administrator',
|
||||
};
|
||||
}
|
||||
|
||||
# set attachments
|
||||
if ( IsArrayRefWithData($AttachmentList) ) {
|
||||
|
||||
for my $Attachment ( @{$AttachmentList} ) {
|
||||
my $Result = $Self->CreateAttachment(
|
||||
Attachment => $Attachment,
|
||||
ConfigItemID => $ConfigItemID,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
if ( !$Result->{Success} ) {
|
||||
my $ErrorMessage =
|
||||
$Result->{ErrorMessage} || "Attachment could not be created, please contact"
|
||||
. " the system administrator";
|
||||
|
||||
return {
|
||||
Success => 0,
|
||||
ErrorMessage => $ErrorMessage,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# get ConfigItem data
|
||||
my $ConfigItemData = $ConfigItemObject->ConfigItemGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
);
|
||||
|
||||
if ( !IsHashRefWithData($ConfigItemData) ) {
|
||||
return {
|
||||
Success => 0,
|
||||
ErrorMessage => 'Could not get new configuration item information, please contact the'
|
||||
. ' system administrator',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
Success => 1,
|
||||
Data => {
|
||||
ConfigItemID => $ConfigItemID,
|
||||
Number => $ConfigItemData->{Number},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,214 @@
|
||||
# --
|
||||
# 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::ConfigItemDelete;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use MIME::Base64;
|
||||
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::ConfigItemDelete - GenericInterface Configuration Item Delete 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} = 'ConfigItemDelete';
|
||||
|
||||
$Self->{Config} = $Kernel::OM->Get('Kernel::Config')->Get('GenericInterface::Operation::ConfigItemDelete');
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 Run()
|
||||
|
||||
perform ConfigItemDelete Operation. This function is able to return
|
||||
one or more ConfigItem entries in one call.
|
||||
|
||||
my $Result = $OperationObject->Run(
|
||||
Data => {
|
||||
UserLogin => 'some agent login', # UserLogin or CustomerUserLogin or SessionID is
|
||||
# required
|
||||
CustomerUserLogin => 'some customer login',
|
||||
SessionID => 123,
|
||||
|
||||
Password => 'some password', # if UserLogin or customerUserLogin is sent then
|
||||
# Password is required
|
||||
ConfigItemID => '32,33', # required, could be coma separated IDs or an Array
|
||||
},
|
||||
);
|
||||
|
||||
$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 => 'ConfigItemDelete.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},
|
||||
);
|
||||
}
|
||||
|
||||
my ( $UserID, $UserType ) = $Self->Auth(
|
||||
%Param
|
||||
);
|
||||
|
||||
if ( !$UserID ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => '$Self->{OperationName}.AuthFail',
|
||||
ErrorMessage => "$Self->{OperationName}: Authorization failing!",
|
||||
);
|
||||
}
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(ConfigItemID)) {
|
||||
if ( !$Param{Data}->{$Needed} ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.MissingParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: $Needed parameter is missing!",
|
||||
);
|
||||
}
|
||||
}
|
||||
my $ErrorMessage = '';
|
||||
|
||||
# all needed variables
|
||||
my @ConfigItemIDs;
|
||||
if ( IsStringWithData( $Param{Data}->{ConfigItemID} ) ) {
|
||||
@ConfigItemIDs = split /\s*,\s*/, $Param{Data}->{ConfigItemID};
|
||||
}
|
||||
elsif ( IsArrayRefWithData( $Param{Data}->{ConfigItemID} ) ) {
|
||||
@ConfigItemIDs = @{ $Param{Data}->{ConfigItemID} };
|
||||
}
|
||||
else {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.WrongStructure",
|
||||
ErrorMessage => "$Self->{OperationName}: Structure for ConfigItemID is not correct!",
|
||||
);
|
||||
}
|
||||
|
||||
my $ConfigItemObject = $Kernel::OM->Get('Kernel::System::ITSMConfigItem');
|
||||
|
||||
my @DeletedConfigItemIDs;
|
||||
|
||||
# start ConfigItem loop
|
||||
CONFIGITEM:
|
||||
for my $ConfigItemID (@ConfigItemIDs) {
|
||||
|
||||
# check create permissions
|
||||
my $Permission = $ConfigItemObject->Permission(
|
||||
Scope => 'Item',
|
||||
ItemID => $ConfigItemID,
|
||||
UserID => $UserID,
|
||||
Type => $Self->{Config}->{Permission},
|
||||
);
|
||||
|
||||
if ( !$Permission ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.AccessDenied",
|
||||
ErrorMessage => "$Self->{OperationName}: Can not delete configuration item!",
|
||||
);
|
||||
}
|
||||
|
||||
# delete the configitem
|
||||
my $DeleteSuccess = $ConfigItemObject->ConfigItemDelete(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
UserID => $UserID,
|
||||
);
|
||||
|
||||
if ( !$DeleteSuccess ) {
|
||||
|
||||
$ErrorMessage = 'Could not delete ConfigItem ID ' . $ConfigItemID
|
||||
. ' in Kernel::GenericInterface::Operation::ConfigItem::ConfigItemDelete::Run()';
|
||||
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => '$Self->{OperationName}.DeleteError',
|
||||
ErrorMessage => "$Self->{OperationName}: $ErrorMessage",
|
||||
);
|
||||
}
|
||||
|
||||
push @DeletedConfigItemIDs, $ConfigItemID;
|
||||
|
||||
} # finish ConfigItem loop
|
||||
|
||||
if ( !IsArrayRefWithData( \@DeletedConfigItemIDs ) ) {
|
||||
return {
|
||||
Success => 0,
|
||||
ErrorMessage => 'Could not delete ConfigItems!',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
Success => 1,
|
||||
Data => {
|
||||
ConfigItemID => \@DeletedConfigItemIDs,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,324 @@
|
||||
# --
|
||||
# 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::ConfigItemGet;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
## nofilter(TidyAll::Plugin::OTRS::Migrations::OTRS6::SysConfig)
|
||||
|
||||
use MIME::Base64;
|
||||
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::ConfigItemGet - GenericInterface Configuration Item Get 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} = 'ConfigItemGet';
|
||||
|
||||
$Self->{Config} = $Kernel::OM->Get('Kernel::Config')->Get('GenericInterface::Operation::ConfigItemGet');
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 Run()
|
||||
|
||||
perform ConfigItemGet Operation. This function is able to return
|
||||
one or more ConfigItem entries in one call.
|
||||
|
||||
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
|
||||
ConfigItemID => '32,33', # required, could be coma separated IDs or an Array
|
||||
Attachments => 1, # Optional, 1 as default. If it's set with the value 1,
|
||||
# attachments for articles will be included on ConfigItem data
|
||||
},
|
||||
);
|
||||
|
||||
$Result = {
|
||||
Success => 1, # 0 or 1
|
||||
ErrorMessage => '', # In case of an error
|
||||
Data => {
|
||||
ConfigItem => [
|
||||
{
|
||||
|
||||
Number => '20101027000001',
|
||||
ConfigItemID => 123,
|
||||
Name => 'some name',
|
||||
Class => 'some class',
|
||||
VersionID => 123,
|
||||
LastVersionID => 123,
|
||||
DefinitionID => 123,
|
||||
InciState => 'some incident state',
|
||||
InciStateType => 'some incident state type',
|
||||
DeplState => 'some deployment state',
|
||||
DeplStateType => 'some deployment state type',
|
||||
CurInciState => 'some incident state',
|
||||
CurInciStateType => 'some incident state type',
|
||||
CurDeplState => 'some deployment state',
|
||||
CurDeplStateType => 'some deployment state type',
|
||||
CreateTime => '2010-10-27 20:15:00'
|
||||
CreateBy => 123,
|
||||
CIXMLData => $XMLDataHashRef,
|
||||
|
||||
Attachment => [
|
||||
{
|
||||
Content => "xxxx", # actual attachment contents, base64 enconded
|
||||
ContentType => "application/pdf",
|
||||
Filename => "StdAttachment-Test1.pdf",
|
||||
Filesize => "4.6 KBytes",
|
||||
Preferences => $PreferencesHashRef,
|
||||
},
|
||||
{
|
||||
# . . .
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
# . . .
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
=cut
|
||||
|
||||
sub Run {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Result = $Self->Init(
|
||||
WebserviceID => $Self->{WebserviceID},
|
||||
);
|
||||
|
||||
if ( !$Result->{Success} ) {
|
||||
$Self->ReturnError(
|
||||
ErrorCode => 'Webservice.InvalidConfiguration',
|
||||
ErrorMessage => $Result->{ErrorMessage},
|
||||
);
|
||||
}
|
||||
|
||||
my ( $UserID, $UserType ) = $Self->Auth(
|
||||
%Param
|
||||
);
|
||||
|
||||
if ( !$UserID ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => '$Self->{OperationName}.AuthFail',
|
||||
ErrorMessage => "$Self->{OperationName}: Authorization failing!",
|
||||
);
|
||||
}
|
||||
|
||||
# check needed stuff
|
||||
for my $Needed (qw(ConfigItemID)) {
|
||||
if ( !$Param{Data}->{$Needed} ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.MissingParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: $Needed parameter is missing!",
|
||||
);
|
||||
}
|
||||
}
|
||||
my $ErrorMessage = '';
|
||||
|
||||
# all needed variables
|
||||
my @ConfigItemIDs;
|
||||
if ( IsStringWithData( $Param{Data}->{ConfigItemID} ) ) {
|
||||
@ConfigItemIDs = split( /,/, $Param{Data}->{ConfigItemID} );
|
||||
}
|
||||
elsif ( IsArrayRefWithData( $Param{Data}->{ConfigItemID} ) ) {
|
||||
@ConfigItemIDs = @{ $Param{Data}->{ConfigItemID} };
|
||||
}
|
||||
else {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.WrongStructure",
|
||||
ErrorMessage => "$Self->{OperationName}: Structure for ConfigItemID is not correct!",
|
||||
);
|
||||
}
|
||||
my $Attachments = $Param{Data}->{Attachments} || 0;
|
||||
my $ReturnData = {
|
||||
Success => 1,
|
||||
};
|
||||
|
||||
my @Item;
|
||||
|
||||
my $ConfigItemObject = $Kernel::OM->Get('Kernel::System::ITSMConfigItem');
|
||||
|
||||
# start ConfigItem loop
|
||||
CONFIGITEM:
|
||||
for my $ConfigItemID (@ConfigItemIDs) {
|
||||
|
||||
# check create permissions
|
||||
my $Permission = $ConfigItemObject->Permission(
|
||||
Scope => 'Item',
|
||||
ItemID => $ConfigItemID,
|
||||
UserID => $UserID,
|
||||
Type => $Self->{Config}->{Permission},
|
||||
);
|
||||
|
||||
if ( !$Permission ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.AccessDenied",
|
||||
ErrorMessage => "$Self->{OperationName}: Can not get configuration item!",
|
||||
);
|
||||
}
|
||||
|
||||
# get the ConfigItem entry
|
||||
my $ConfigItem = $ConfigItemObject->ConfigItemGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
UserID => $UserID,
|
||||
);
|
||||
|
||||
# get latest version
|
||||
my $Version = $ConfigItemObject->VersionGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
UserID => $UserID,
|
||||
);
|
||||
|
||||
if ( !IsHashRefWithData($Version) ) {
|
||||
|
||||
$ErrorMessage = 'Could not get ConfigItem data'
|
||||
. ' in Kernel::GenericInterface::Operation::ConfigItem::ConfigItemGet::Run()';
|
||||
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => '$Self->{OperationName}.InvalidParameter',
|
||||
ErrorMessage => "$Self->{OperationName}: $ErrorMessage",
|
||||
);
|
||||
}
|
||||
|
||||
# remove unneeded items
|
||||
delete $Version->{ClassID};
|
||||
delete $Version->{CurDeplStateID};
|
||||
delete $Version->{CurInciStateID};
|
||||
delete $Version->{DeplStateID};
|
||||
delete $Version->{InciStateID};
|
||||
delete $Version->{XMLDefinitionID};
|
||||
|
||||
my $Definition = delete $Version->{XMLDefinition};
|
||||
|
||||
my $FormatedXMLData = $Self->InvertFormatXMLData(
|
||||
XMLData => $Version->{XMLData}->[1]->{Version},
|
||||
);
|
||||
|
||||
my $ReplacedXMLData = $Self->InvertReplaceXMLData(
|
||||
XMLData => $FormatedXMLData,
|
||||
Definition => $Definition,
|
||||
);
|
||||
|
||||
$Version->{XMLData} = $ReplacedXMLData;
|
||||
|
||||
# rename XMLData since SOAP transport complains about XML prefix on names
|
||||
$Version->{CIXMLData} = delete $Version->{XMLData};
|
||||
|
||||
# set ConfigItem entry data
|
||||
my $ConfigItemBundle = $Version;
|
||||
|
||||
if ($Attachments) {
|
||||
|
||||
my @Attachments = $ConfigItemObject->ConfigItemAttachmentList(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
);
|
||||
|
||||
my @AttachmentDetails;
|
||||
ATTACHMENT:
|
||||
for my $Filename (@Attachments) {
|
||||
|
||||
next ATTACHMENT if !$Filename;
|
||||
|
||||
my $Attachment = $ConfigItemObject->ConfigItemAttachmentGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
Filename => $Filename,
|
||||
);
|
||||
|
||||
# next if not attachment
|
||||
next ATTACHMENT if !IsHashRefWithData($Attachment);
|
||||
|
||||
# convert content to base64
|
||||
$Attachment->{Content} = encode_base64( $Attachment->{Content} );
|
||||
push @AttachmentDetails, $Attachment;
|
||||
}
|
||||
|
||||
# set ConfigItem entry data
|
||||
$ConfigItemBundle->{Attachment} = '';
|
||||
if ( IsArrayRefWithData( \@AttachmentDetails ) ) {
|
||||
$ConfigItemBundle->{Attachment} = \@AttachmentDetails;
|
||||
}
|
||||
}
|
||||
|
||||
# add
|
||||
push @Item, $ConfigItemBundle;
|
||||
|
||||
} # finish ConfigItem loop
|
||||
|
||||
if ( !scalar @Item ) {
|
||||
$ErrorMessage = 'Could not get ConfigItem data'
|
||||
. ' in Kernel::GenericInterface::Operation::ConfigItem::ConfigItemGet::Run()';
|
||||
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => '$Self->{OperationName}.NoConfigItemData',
|
||||
ErrorMessage => "$Self->{OperationName}: $ErrorMessage",
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
# set ConfigItem data into return structure
|
||||
$ReturnData->{Data}->{ConfigItem} = '';
|
||||
if ( IsArrayRefWithData( \@Item ) ) {
|
||||
$ReturnData->{Data}->{ConfigItem} = \@Item;
|
||||
}
|
||||
|
||||
# return result
|
||||
return $ReturnData;
|
||||
}
|
||||
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,848 @@
|
||||
# --
|
||||
# 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::ConfigItemUpdate;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
## nofilter(TidyAll::Plugin::OTRS::Migrations::OTRS6::SysConfig)
|
||||
|
||||
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::ConfigItemUpdate - GenericInterface ConfigItem ConfigItemUpdate 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};
|
||||
}
|
||||
|
||||
# define operation name
|
||||
$Self->{OperationName} = 'ConfigItemUpdate';
|
||||
|
||||
$Self->{Config} = $Kernel::OM->Get('Kernel::Config')->Get('GenericInterface::Operation::ConfigItemUpdate');
|
||||
|
||||
$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 ConfigItemUpdate Operation. This will return the updated 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
|
||||
|
||||
ReplaceExistingData => 0, # optional, 0 or 1, default 0
|
||||
# this will replace the existing XML data and attachments
|
||||
ConfigItemID => 123,
|
||||
|
||||
ConfigItem => {
|
||||
Class => 'Config Item Class',
|
||||
Name => 'The Name',
|
||||
DeplState => 'deployment state',
|
||||
InciState => 'incident state',
|
||||
CIXMLData => $ArrayHashRef, # it depends on the Configuration Item class and definition
|
||||
|
||||
Attachment => [
|
||||
{
|
||||
Content => 'content' # base64 encoded
|
||||
ContentType => 'some content type'
|
||||
Filename => 'some fine name'
|
||||
},
|
||||
# ...
|
||||
],
|
||||
# or
|
||||
#Attachment => {
|
||||
# Content => 'content'
|
||||
# ContentType => 'some content type'
|
||||
# Filename => 'some fine name'
|
||||
#},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
$Result = {
|
||||
Success => 1, # 0 or 1
|
||||
ErrorMessage => '', # in case of error
|
||||
Data => { # result data payload after Operation
|
||||
ConfigItemID => 123, # Configuration Item ID number in OTRS::ITSM (Service desk system)
|
||||
Number => 2324454323322 # Configuration Item Number in OTRS::ITSM (Service desk system)
|
||||
Error => { # should not return errors
|
||||
ErrorCode => 'ConfigItemUpdate.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!",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# check needed items
|
||||
for my $Needed (qw(ConfigItemID)) {
|
||||
if ( !IsPositiveInteger( $Param{Data}->{$Needed} ) ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.MissingParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: $Needed parameter is missing or not valid!",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# check for valid ConfigItemID
|
||||
my $ConfigItemID = $Param{Data}->{ConfigItemID};
|
||||
|
||||
# get config item object
|
||||
my $ConfigItemObject = $Kernel::OM->Get('Kernel::System::ITSMConfigItem');
|
||||
|
||||
# get ConfigItem data
|
||||
my $ConfigItemData = $ConfigItemObject->ConfigItemGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
);
|
||||
|
||||
if ( !IsHashRefWithData($ConfigItemData) ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: ConfigItemID is invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# 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 the parameter ReplaceExistingData is set to 0 or if it is missing
|
||||
# then missing, empty or only partially defined CIXMLData parameter attributes are allowed
|
||||
# in this case the existing CIXMLData is used for the missing parts.
|
||||
# A missing (undefined) CIXMLData attribute has the same effect
|
||||
# the ReplaceExistingData parameter also influences if existing attachments should be replaced or kept
|
||||
if ( !$Param{Data}->{ReplaceExistingData} || !defined $ConfigItem->{CIXMLData} ) {
|
||||
|
||||
# set to empty hash reference if empty or not defined
|
||||
$ConfigItem->{CIXMLData} ||= {};
|
||||
|
||||
# CIXMLData must be a hash reference
|
||||
if ( ref $ConfigItem->{CIXMLData} ne 'HASH' ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.MissingParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: ConfigItem->CIXMLData is missing or invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# get latest version data from configitem
|
||||
my $Version = $ConfigItemObject->VersionGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
UserID => $UserID,
|
||||
);
|
||||
|
||||
if ( !IsHashRefWithData($Version) ) {
|
||||
|
||||
my $ErrorMessage = 'Could not get ConfigItem data'
|
||||
. ' in Kernel::GenericInterface::Operation::ConfigItem::ConfigItemUpdate::Run()';
|
||||
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => '$Self->{OperationName}.InvalidParameter',
|
||||
ErrorMessage => "$Self->{OperationName}: $ErrorMessage",
|
||||
);
|
||||
}
|
||||
|
||||
# remove unneeded items
|
||||
delete $Version->{ClassID};
|
||||
delete $Version->{CurDeplStateID};
|
||||
delete $Version->{CurInciStateID};
|
||||
delete $Version->{DeplStateID};
|
||||
delete $Version->{InciStateID};
|
||||
delete $Version->{XMLDefinitionID};
|
||||
|
||||
my $Definition = delete $Version->{XMLDefinition};
|
||||
|
||||
my $FormatedXMLData = $Self->InvertFormatXMLData(
|
||||
XMLData => $Version->{XMLData}->[1]->{Version},
|
||||
);
|
||||
|
||||
my $ReplacedXMLData = $Self->InvertReplaceXMLData(
|
||||
XMLData => $FormatedXMLData,
|
||||
Definition => $Definition,
|
||||
);
|
||||
|
||||
$Version->{XMLData} = $ReplacedXMLData;
|
||||
|
||||
# rename XMLData since SOAP transport complains about XML prefix on names
|
||||
$Version->{CIXMLData} = delete $Version->{XMLData};
|
||||
|
||||
# merge existing data and new data from parameters
|
||||
$ConfigItem->{CIXMLData} = {
|
||||
%{ $Version->{CIXMLData} },
|
||||
%{ $ConfigItem->{CIXMLData} },
|
||||
};
|
||||
}
|
||||
|
||||
if ( !IsHashRefWithData( $ConfigItem->{CIXMLData} ) ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: ConfigItem->CIXMLData is empty or invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# remove leading and trailing spaces for CIXMLData
|
||||
$Self->_CleanXMLData( XMLData => $ConfigItem->{CIXMLData} );
|
||||
|
||||
# check ConfigItem attribute values
|
||||
my $ConfigItemCheck = $Self->_CheckConfigItem( ConfigItem => $ConfigItem );
|
||||
|
||||
if ( !$ConfigItemCheck->{Success} ) {
|
||||
return $Self->ReturnError( %{$ConfigItemCheck} );
|
||||
}
|
||||
|
||||
# check update permissions
|
||||
my $Permission = $ConfigItemObject->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 update configuration items!",
|
||||
);
|
||||
}
|
||||
|
||||
# handle attachments
|
||||
my $Attachment;
|
||||
my @AttachmentList;
|
||||
|
||||
if ( defined $Param{Data}->{ConfigItem}->{Attachment} ) {
|
||||
|
||||
# isolate Attachment parameter
|
||||
$Attachment = delete $Param{Data}->{ConfigItem}->{Attachment};
|
||||
|
||||
# homologate imput to array
|
||||
if ( IsHashRefWithData($Attachment) ) {
|
||||
push @AttachmentList, $Attachment;
|
||||
}
|
||||
elsif ( IsArrayRefWithData($Attachment) ) {
|
||||
@AttachmentList = @{$Attachment};
|
||||
}
|
||||
else {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->Attachment parameter is invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# check Attachment internal structure
|
||||
for my $AttachmentItem (@AttachmentList) {
|
||||
if ( !IsHashRefWithData($AttachmentItem) ) {
|
||||
return $Self->ReturnError(
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->Attachment parameter is invalid!",
|
||||
);
|
||||
}
|
||||
|
||||
# remove leading and trailing spaces
|
||||
for my $Attribute ( sort keys %{$AttachmentItem} ) {
|
||||
if ( ref $Attribute ne 'HASH' && ref $Attribute ne 'ARRAY' ) {
|
||||
|
||||
#remove leading spaces
|
||||
$AttachmentItem->{$Attribute} =~ s{\A\s+}{};
|
||||
|
||||
#remove trailing spaces
|
||||
$AttachmentItem->{$Attribute} =~ s{\s+\z}{};
|
||||
}
|
||||
}
|
||||
|
||||
# check Attachment attribute values
|
||||
my $AttachmentCheck = $Self->_CheckAttachment( Attachment => $AttachmentItem );
|
||||
|
||||
if ( !$AttachmentCheck->{Success} ) {
|
||||
return $Self->ReturnError( %{$AttachmentCheck} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $Self->_ConfigItemUpdate(
|
||||
ConfigItem => $ConfigItem,
|
||||
ConfigItemID => $ConfigItemID,
|
||||
AttachmentList => \@AttachmentList,
|
||||
ReplaceExistingData => $Param{Data}->{ReplaceExistingData},
|
||||
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 '' ) {
|
||||
|
||||
# TODO: Use StringClean function!
|
||||
|
||||
#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
|
||||
for my $Needed (qw(Class Name DeplState InciState CIXMLData)) {
|
||||
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 ConfigItem->DeplState
|
||||
if ( !$Self->ValidateDeplState( %{$ConfigItem} ) ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->DeplState parameter is invalid!",
|
||||
};
|
||||
}
|
||||
|
||||
# check ConfigItem->DeplState
|
||||
if ( !$Self->ValidateInciState( %{$ConfigItem} ) ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: ConfigItem->InciState parameter is invalid!",
|
||||
};
|
||||
}
|
||||
|
||||
# get last config item defintion
|
||||
my $DefinitionData = $Kernel::OM->Get('Kernel::System::ITSMConfigItem')->DefinitionGet(
|
||||
ClassID => $Self->{ReverseClassList}->{ $ConfigItem->{Class} },
|
||||
);
|
||||
|
||||
my $XMLDataCheckResult = $Self->CheckXMLData(
|
||||
Definition => $DefinitionData->{DefinitionRef},
|
||||
XMLData => $ConfigItem->{CIXMLData},
|
||||
);
|
||||
|
||||
if ( !$XMLDataCheckResult->{Success} ) {
|
||||
return $XMLDataCheckResult;
|
||||
}
|
||||
|
||||
# if everything is OK then return Success
|
||||
return {
|
||||
Success => 1,
|
||||
};
|
||||
}
|
||||
|
||||
=head2 _CheckAttachment()
|
||||
|
||||
checks if the given attachment parameter is valid.
|
||||
|
||||
my $AttachmentCheck = $OperationObject->_CheckAttachment(
|
||||
Attachment => $Attachment, # all attachment parameters
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
$AttachmentCheck = {
|
||||
Success => 1, # if everething is OK
|
||||
}
|
||||
|
||||
$AttachmentCheck = {
|
||||
ErrorCode => 'Function.Error', # if error
|
||||
ErrorMessage => 'Error description',
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub _CheckAttachment {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $Attachment = $Param{Attachment};
|
||||
|
||||
# check attachment item internally
|
||||
for my $Needed (qw(Content ContentType Filename)) {
|
||||
if ( !$Attachment->{$Needed} ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.MissingParameter",
|
||||
ErrorMessage =>
|
||||
"$Self->{OperationName}: Attachment->$Needed parameter is missing!",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# check Article->ContentType
|
||||
if ( $Attachment->{ContentType} ) {
|
||||
|
||||
$Attachment->{ContentType} = lc $Attachment->{ContentType};
|
||||
|
||||
# check Charset part
|
||||
my $Charset = '';
|
||||
if ( $Attachment->{ContentType} =~ /charset=/i ) {
|
||||
$Charset = $Attachment->{ContentType};
|
||||
$Charset =~ s/.+?charset=("|'|)(\w+)/$2/gi;
|
||||
$Charset =~ s/"|'//g;
|
||||
$Charset =~ s/(.+?);.*/$1/g;
|
||||
}
|
||||
|
||||
if ( $Charset && !$Self->ValidateCharset( Charset => $Charset ) )
|
||||
{
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: Attachment->ContentType is invalid!",
|
||||
};
|
||||
}
|
||||
|
||||
# check MimeType part
|
||||
my $MimeType = '';
|
||||
if ( $Attachment->{ContentType} =~ /^(\w+\/\w+)/i ) {
|
||||
$MimeType = $1;
|
||||
$MimeType =~ s/"|'//g;
|
||||
}
|
||||
|
||||
if ( !$Self->ValidateMimeType( MimeType => $MimeType ) ) {
|
||||
return {
|
||||
ErrorCode => "$Self->{OperationName}.InvalidParameter",
|
||||
ErrorMessage => "$Self->{OperationName}: Attachment->ContentType is invalid!",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# if everything is OK then return Success
|
||||
return {
|
||||
Success => 1,
|
||||
};
|
||||
}
|
||||
|
||||
=head2 _ConfigItemUpdate()
|
||||
|
||||
updates a configuration item with attachments if specified.
|
||||
|
||||
my $Response = $OperationObject->_ConfigItemUpdate(
|
||||
ConfigItemID => 123,
|
||||
ConfigItem => $ConfigItem, # all configuration item parameters
|
||||
AttachmentList => $Attachment, # a list of all attachments
|
||||
ReplaceExistingData => 0, # if the existing xml attributes and attachments should be replaced or kept
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns:
|
||||
|
||||
$Response = {
|
||||
Success => 1, # if everething is OK
|
||||
Data => {
|
||||
ConfigItemID => 123,
|
||||
ConfigItemNumber => 'CN123',
|
||||
}
|
||||
}
|
||||
|
||||
$Response = {
|
||||
Success => 0, # if unexpected error
|
||||
ErrorMessage => "$Param{ErrorCode}: $Param{ErrorMessage}",
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub _ConfigItemUpdate {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
my $ConfigItemID = $Param{ConfigItemID};
|
||||
my $ConfigItem = $Param{ConfigItem};
|
||||
my $AttachmentList = $Param{AttachmentList};
|
||||
|
||||
my $DeplStateID = $Self->{ReverseDeplStateList}->{ $ConfigItem->{DeplState} };
|
||||
my $InciStateID = $Self->{ReverseInciStateList}->{ $ConfigItem->{InciState} };
|
||||
|
||||
my $RawXMLData = $ConfigItem->{CIXMLData};
|
||||
|
||||
# get config item object
|
||||
my $ConfigItemObject = $Kernel::OM->Get('Kernel::System::ITSMConfigItem');
|
||||
|
||||
# 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 VersionAdd
|
||||
my $XMLData = $Self->FormatXMLData(
|
||||
XMLData => $ReplacedXMLData,
|
||||
);
|
||||
|
||||
# get the current config item version data
|
||||
my $CurrentVersion = $ConfigItemObject->VersionGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
my $VersionID = $ConfigItemObject->VersionAdd(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
Name => $ConfigItem->{Name},
|
||||
DefinitionID => $DefinitionData->{DefinitionID},
|
||||
DeplStateID => $DeplStateID,
|
||||
InciStateID => $InciStateID,
|
||||
XMLData => $XMLData,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
if ( !$VersionID ) {
|
||||
return {
|
||||
Success => 0,
|
||||
ErrorMessage => 'Configuration Item could not be updated, please contact the system'
|
||||
. 'administrator'
|
||||
};
|
||||
}
|
||||
|
||||
# get the version ID of the config item before the update
|
||||
my $CurrentVersionID = $CurrentVersion->{VersionID} || '';
|
||||
|
||||
# compare old version and new version IDs
|
||||
if ( $CurrentVersionID eq $VersionID ) {
|
||||
$Self->{DebuggerObject}->Notice(
|
||||
Summary => "$Self->{OperationName}: No change in configuration item version",
|
||||
Data => 'The internal structure of the configuration item was indentical to the last'
|
||||
. ' one, no update was performed',
|
||||
);
|
||||
}
|
||||
|
||||
# the ReplaceExistingData flag is set
|
||||
if ( $Param{ReplaceExistingData} ) {
|
||||
|
||||
# get a list of all attachments
|
||||
my @ExistingAttachments = $ConfigItemObject->ConfigItemAttachmentList(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
);
|
||||
|
||||
# delete all attachments of this config item
|
||||
FILENAME:
|
||||
for my $Filename (@ExistingAttachments) {
|
||||
|
||||
# delete the attachment
|
||||
my $DeletionSuccess = $ConfigItemObject->ConfigItemAttachmentDelete(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
Filename => $Filename,
|
||||
UserID => $Param{UserID},
|
||||
);
|
||||
|
||||
if ( !$DeletionSuccess ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Unknown problem when deleting attachment $Filename of ConfigItem "
|
||||
. "$ConfigItemID. Please check the VirtualFS backend for stale files!",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# set attachments
|
||||
if ( IsArrayRefWithData($AttachmentList) ) {
|
||||
|
||||
for my $Attachment ( @{$AttachmentList} ) {
|
||||
my $Result = $Self->CreateAttachment(
|
||||
Attachment => $Attachment,
|
||||
ConfigItemID => $ConfigItemID,
|
||||
UserID => $Param{UserID}
|
||||
);
|
||||
|
||||
if ( !$Result->{Success} ) {
|
||||
my $ErrorMessage = $Result->{ErrorMessage}
|
||||
|| "Attachment could not be created, please contact the system administrator";
|
||||
|
||||
return {
|
||||
Success => 0,
|
||||
ErrorMessage => $ErrorMessage,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# get ConfigItem data
|
||||
my $ConfigItemData = $ConfigItemObject->ConfigItemGet(
|
||||
ConfigItemID => $ConfigItemID,
|
||||
);
|
||||
|
||||
if ( !IsHashRefWithData($ConfigItemData) ) {
|
||||
return {
|
||||
Success => 0,
|
||||
ErrorMessage => 'Could not get new configuration item information, please contact the system administrator',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
Success => 1,
|
||||
Data => {
|
||||
ConfigItemID => $ConfigItemID,
|
||||
Number => $ConfigItemData->{Number},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user